--- a/langtools/README Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/README Tue Sep 17 08:21:11 2013 -0700
@@ -32,7 +32,7 @@
JLS and JVMS.
In addition, there is a substantial collection of regression and unit
-tests for all the tools in the maain langtools test/ directory.
+tests for all the tools in the main langtools test/ directory.
Finally, there is a small set of tests to do basic validation of a build
of the langtools workspace for use by JDK. These tests check the contents
--- a/langtools/make/netbeans/langtools/build.xml Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/make/netbeans/langtools/build.xml Tue Sep 17 08:21:11 2013 -0700
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -55,10 +55,18 @@
description="Build one or all langtools tools"
/>
+ <condition property="bootstrap" value="bootstrap-" else="">
+ <isset property="langtools.tool.bootstrap"/>
+ </condition>
+
+ <condition property="bcp" value="${build.bootstrap.dir}/classes" else="${build.classes.dir}">
+ <isset property="langtools.tool.bootstrap"/>
+ </condition>
+
<target name="-build-tool" if="langtools.tool.name">
- <echo level="info" message="Building ${langtools.tool.name}"/>
+ <echo level="info" message="Building ${bootstrap}${langtools.tool.name}"/>
<echo level="verbose" message="(Unset langtools.tool.name to build all tools)"/>
- <antcall target="build-${langtools.tool.name}"/>
+ <antcall target="build-${bootstrap}${langtools.tool.name}"/>
</target>
<target name="-build-all" unless="langtools.tool.name">
@@ -89,8 +97,9 @@
<target name="run" depends="-check-target.java.home,build,-def-run,-get-tool-and-args"
description="run tool">
- <echo level="info" message="Run ${langtools.tool.name} with args ${langtools.tool.args}"/>
- <run mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}"/>
+ <echo level="info" message="${bcp}"/>
+ <echo level="info" message="Run ${bootstrap}${langtools.tool.name} with args ${langtools.tool.args}"/>
+ <run bcp="${bcp}" mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}"/>
</target>
<!-- Run a selected class. (action: run.single; shift-F6) -->
@@ -136,9 +145,9 @@
<!-- Debug tool in NetBeans. -->
<target name="debug" depends="-check-target.java.home,-def-run,-def-start-debugger,-get-tool-and-args,build" if="netbeans.home">
- <echo level="info" message="Debug ${langtools.tool.name} with args ${langtools.tool.args}"/>
+ <echo level="info" message="Debug ${boostrap}${langtools.tool.name} with args ${langtools.tool.args}"/>
<start-debugger/>
- <run mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}" jpda.jvmargs="${jpda.jvmargs}"/>
+ <run bcp="${bcp}" mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}" jpda.jvmargs="${jpda.jvmargs}"/>
</target>
<!-- Debug a selected class . -->
@@ -207,6 +216,7 @@
<target name="-get-tool-if-set" depends="-def-select-tool">
<select-tool
toolproperty="langtools.tool.name"
+ bootstrapproperty="langtools.tool.bootstrap"
propertyfile="${langtools.properties}"
askIfUnset="false"
/>
@@ -216,6 +226,7 @@
<select-tool
toolproperty="langtools.tool.name"
argsproperty="langtools.tool.args"
+ bootstrapproperty="langtools.tool.bootstrap"
propertyfile="${langtools.properties}"
askIfUnset="true"
/>
@@ -226,10 +237,12 @@
<macrodef name="run">
<attribute name="mainclass"/>
<attribute name="args" default=""/>
+ <attribute name="bcp" default="${build.classes.dir}"/>
<attribute name="jpda.jvmargs" default=""/>
+
<sequential>
<java fork="true" jvm="${target.java}" classname="@{mainclass}">
- <jvmarg line="-Xbootclasspath/p:${build.classes.dir}"/>
+ <jvmarg line="-Xbootclasspath/p:${bcp}"/>
<jvmarg line="@{jpda.jvmargs}"/>
<arg line="@{args}"/>
</java>
--- a/langtools/make/tools/anttasks/SelectToolTask.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/make/tools/anttasks/SelectToolTask.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,7 @@
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.EnumSet;
import java.util.List;
import java.util.Properties;
import javax.swing.JButton;
@@ -71,6 +72,31 @@
* is invoked to allow the user to set or reset values for use in property mode.
*/
public class SelectToolTask extends Task {
+
+ enum ToolChoices {
+ NONE(""),
+ JAVAC("javac"),
+ JAVADOC("javadoc"),
+ JAVAH("javah"),
+ JAVAP("javap");
+
+ String toolName;
+ boolean bootstrap;
+
+ ToolChoices(String toolName) {
+ this(toolName, false);
+ }
+
+ ToolChoices(String toolName, boolean boostrap) {
+ this.toolName = toolName;
+ }
+
+ @Override
+ public String toString() {
+ return toolName;
+ }
+ }
+
/**
* Set the location of the private properties file used to keep the retain
* user preferences for this repository.
@@ -97,6 +123,14 @@
}
/**
+ * Set the name of the property which will be set to the execution args of the
+ * selected tool, if any. The args default to an empty string.
+ */
+ public void setBootstrapProperty(String bootstrapProperty) {
+ this.bootstrapProperty = bootstrapProperty;
+ }
+
+ /**
* Specify whether or not to pop up a dialog if the user has not specified
* a default value for a property.
*/
@@ -110,6 +144,7 @@
Properties props = readProperties(propertyFile);
toolName = props.getProperty("tool.name");
+ toolBootstrap = props.getProperty("tool.bootstrap") != null;
if (toolName != null) {
toolArgs = props.getProperty(toolName + ".args", "");
}
@@ -123,6 +158,8 @@
// finally, return required values, if any
if (toolProperty != null && !(toolName == null || toolName.equals(""))) {
p.setProperty(toolProperty, toolName);
+ if (toolBootstrap)
+ p.setProperty(bootstrapProperty, "true");
if (argsProperty != null && toolArgs != null)
p.setProperty(argsProperty, toolArgs);
@@ -134,14 +171,20 @@
JOptionPane p = createPane(guiProps);
p.createDialog("Select Tool").setVisible(true);
- toolName = (String) toolChoice.getSelectedItem();
+ toolName = ((ToolChoices)toolChoice.getSelectedItem()).toolName;
toolArgs = argsField.getText();
-
+ toolBootstrap = bootstrapCheckbox.isSelected();
if (defaultCheck.isSelected()) {
if (toolName.equals("")) {
fileProps.remove("tool.name");
+ fileProps.remove("tool.bootstrap");
} else {
fileProps.put("tool.name", toolName);
+ if (toolBootstrap) {
+ fileProps.put("tool.bootstrap", "true");
+ } else {
+ fileProps.remove("tool.bootstrap");
+ }
fileProps.put(toolName + ".args", toolArgs);
}
writeProperties(propertyFile, fileProps);
@@ -154,32 +197,38 @@
lc.insets.right = 10;
lc.insets.bottom = 3;
GridBagConstraints fc = new GridBagConstraints();
- fc.anchor = GridBagConstraints.WEST;
fc.gridx = 1;
- fc.gridwidth = GridBagConstraints.REMAINDER;
+ fc.gridwidth = GridBagConstraints.NONE;
fc.insets.bottom = 3;
+ JPanel toolPane = new JPanel(new GridBagLayout());
+
JLabel toolLabel = new JLabel("Tool:");
body.add(toolLabel, lc);
- String[] toolChoices = { "apt", "javac", "javadoc", "javah", "javap" };
- if (true || toolProperty == null) {
- // include empty value in setup mode
- List<String> l = new ArrayList<String>(Arrays.asList(toolChoices));
- l.add(0, "");
- toolChoices = l.toArray(new String[l.size()]);
- }
- toolChoice = new JComboBox(toolChoices);
+ EnumSet<ToolChoices> toolChoices = toolProperty == null ?
+ EnumSet.allOf(ToolChoices.class) : EnumSet.range(ToolChoices.JAVAC, ToolChoices.JAVAP);
+ toolChoice = new JComboBox(toolChoices.toArray());
if (toolName != null)
- toolChoice.setSelectedItem(toolName);
+ toolChoice.setSelectedItem(ToolChoices.valueOf(toolName.toUpperCase()));
toolChoice.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
- String tn = (String) e.getItem();
+ String tn = ((ToolChoices)e.getItem()).toolName;
argsField.setText(getDefaultArgsForTool(props, tn));
if (toolProperty != null)
okButton.setEnabled(!tn.equals(""));
}
});
- body.add(toolChoice, fc);
+ GridBagConstraints checkConstraint = new GridBagConstraints();
+ fc.anchor = GridBagConstraints.EAST;
+
+ GridBagConstraints toolConstraint = new GridBagConstraints();
+ fc.anchor = GridBagConstraints.WEST;
+
+ toolPane.add(toolChoice, toolConstraint);
+ bootstrapCheckbox = new JCheckBox("bootstrap", toolBootstrap);
+ toolPane.add(bootstrapCheckbox, checkConstraint);
+
+ body.add(toolPane, fc);
argsField = new JTextField(getDefaultArgsForTool(props, toolName), 40);
if (toolProperty == null || argsProperty != null) {
@@ -190,7 +239,7 @@
public void focusGained(FocusEvent e) {
}
public void focusLost(FocusEvent e) {
- String toolName = (String) toolChoice.getSelectedItem();
+ String toolName = ((ToolChoices)toolChoice.getSelectedItem()).toolName;
if (toolName.length() > 0)
props.put(toolName + ".args", argsField.getText());
}
@@ -271,16 +320,19 @@
// Ant task parameters
private boolean askIfUnset;
private String toolProperty;
+ private String bootstrapProperty;
private String argsProperty;
private File propertyFile;
// GUI components
private JComboBox toolChoice;
+ private JCheckBox bootstrapCheckbox;
private JTextField argsField;
private JCheckBox defaultCheck;
private JButton okButton;
// Result values for the client
private String toolName;
+ private boolean toolBootstrap;
private String toolArgs;
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java Tue Sep 17 08:21:11 2013 -0700
@@ -157,7 +157,7 @@
addAllProfilesLink(div);
}
body.addContent(div);
- if (configuration.showProfiles) {
+ if (configuration.showProfiles && configuration.profilePackages.size() > 0) {
Content profileSummary = configuration.getResource("doclet.Profiles");
addProfilesList(profileSummary, body);
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java Tue Sep 17 08:21:11 2013 -0700
@@ -118,7 +118,7 @@
if (prev != null) {
Content prevLink = getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.CLASS, prev.asClassDoc())
- .label(configuration.getText("doclet.Prev_Class")).strong(true));
+ .label(prevclassLabel).strong(true));
li = HtmlTree.LI(prevLink);
}
else
@@ -136,7 +136,7 @@
if (next != null) {
Content nextLink = getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.CLASS, next.asClassDoc())
- .label(configuration.getText("doclet.Next_Class")).strong(true));
+ .label(nextclassLabel).strong(true));
li = HtmlTree.LI(nextLink);
}
else
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java Tue Sep 17 08:21:11 2013 -0700
@@ -126,7 +126,7 @@
if (prev != null) {
Content prevLink = getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.CLASS, prev)
- .label(configuration.getText("doclet.Prev_Class")).strong(true));
+ .label(prevclassLabel).strong(true));
li = HtmlTree.LI(prevLink);
}
else
@@ -144,7 +144,7 @@
if (next != null) {
Content nextLink = getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.CLASS, next)
- .label(configuration.getText("doclet.Next_Class")).strong(true));
+ .label(nextclassLabel).strong(true));
li = HtmlTree.LI(nextLink);
}
else
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java Tue Sep 17 08:21:11 2013 -0700
@@ -205,13 +205,20 @@
* {@inheritDoc}
*/
protected void generateProfileFiles() throws Exception {
- if (configuration.showProfiles) {
+ if (configuration.showProfiles && configuration.profilePackages.size() > 0) {
ProfileIndexFrameWriter.generate(configuration);
Profile prevProfile = null, nextProfile;
+ String profileName;
for (int i = 1; i < configuration.profiles.getProfileCount(); i++) {
- ProfilePackageIndexFrameWriter.generate(configuration, Profile.lookup(i).name);
+ profileName = Profile.lookup(i).name;
+ // Generate profile package pages only if there are any packages
+ // in a profile to be documented. The profilePackages map will not
+ // contain an entry for the profile if there are no packages to be documented.
+ if (!configuration.shouldDocumentProfile(profileName))
+ continue;
+ ProfilePackageIndexFrameWriter.generate(configuration, profileName);
PackageDoc[] packages = configuration.profilePackages.get(
- Profile.lookup(i).name);
+ profileName);
PackageDoc prev = null, next;
for (int j = 0; j < packages.length; j++) {
// if -nodeprecated option is set and the package is marked as
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Tue Sep 17 08:21:11 2013 -0700
@@ -406,10 +406,7 @@
Content htmlDocType = DocType.TRANSITIONAL;
Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
Content head = new HtmlTree(HtmlTag.HEAD);
- if (!configuration.notimestamp) {
- Content headComment = new Comment(getGeneratedByString());
- head.addContent(headComment);
- }
+ head.addContent(getGeneratedBy(!configuration.notimestamp));
if (configuration.charset.length() > 0) {
Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
configuration.charset);
@@ -502,16 +499,17 @@
if (!configuration.nonavbar) {
String allClassesId = "allclasses_";
HtmlTree navDiv = new HtmlTree(HtmlTag.DIV);
+ Content skipNavLinks = configuration.getResource("doclet.Skip_navigation_links");
if (header) {
body.addContent(HtmlConstants.START_OF_TOP_NAVBAR);
navDiv.addStyle(HtmlStyle.topNav);
allClassesId += "navbar_top";
Content a = getMarkerAnchor("navbar_top");
+ //WCAG - Hyperlinks should contain text or an image with alt text - for AT tools
navDiv.addContent(a);
- Content skipLinkContent = getHyperLink(DocLink.fragment("skip-navbar_top"),
- HtmlTree.EMPTY,
- configuration.getText("doclet.Skip_navigation_links"),
- "");
+ Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink(
+ DocLink.fragment("skip-navbar_top"), skipNavLinks,
+ skipNavLinks.toString(), ""));
navDiv.addContent(skipLinkContent);
} else {
body.addContent(HtmlConstants.START_OF_BOTTOM_NAVBAR);
@@ -519,10 +517,9 @@
allClassesId += "navbar_bottom";
Content a = getMarkerAnchor("navbar_bottom");
navDiv.addContent(a);
- Content skipLinkContent = getHyperLink(DocLink.fragment("skip-navbar_bottom"),
- HtmlTree.EMPTY,
- configuration.getText("doclet.Skip_navigation_links"),
- "");
+ Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink(
+ DocLink.fragment("skip-navbar_bottom"), skipNavLinks,
+ skipNavLinks.toString(), ""));
navDiv.addContent(skipLinkContent);
}
if (header) {
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java Tue Sep 17 08:21:11 2013 -0700
@@ -130,10 +130,14 @@
String profileName;
for (int i = 1; i < configuration.profiles.getProfileCount(); i++) {
profileName = Profile.lookup(i).name;
- Content profileLinkContent = getTargetProfileLink("classFrame",
- new StringContent(profileName), profileName);
- Content li = HtmlTree.LI(profileLinkContent);
- ul.addContent(li);
+ // If the profile has valid packages to be documented, add it to the
+ // profiles list on overview-summary.html page.
+ if (configuration.shouldDocumentProfile(profileName)) {
+ Content profileLinkContent = getTargetProfileLink("classFrame",
+ new StringContent(profileName), profileName);
+ Content li = HtmlTree.LI(profileLinkContent);
+ ul.addContent(li);
+ }
}
profilesDiv.addContent(ul);
Content div = HtmlTree.DIV(HtmlStyle.contentContainer, profilesDiv);
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java Tue Sep 17 08:21:11 2013 -0700
@@ -88,8 +88,13 @@
Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading);
HtmlTree ul = new HtmlTree(HtmlTag.UL);
ul.setTitle(profilesLabel);
+ String profileName;
for (int i = 1; i < profiles.getProfileCount(); i++) {
- ul.addContent(getProfile(i));
+ profileName = (Profile.lookup(i)).name;
+ // If the profile has valid packages to be documented, add it to the
+ // left-frame generated for profile index.
+ if (configuration.shouldDocumentProfile(profileName))
+ ul.addContent(getProfile(profileName));
}
div.addContent(ul);
body.addContent(div);
@@ -98,13 +103,12 @@
/**
* Gets each profile name as a separate link.
*
- * @param profile the profile being documented
+ * @param profileName the profile being documented
* @return content for the profile link
*/
- protected Content getProfile(int profile) {
+ protected Content getProfile(String profileName) {
Content profileLinkContent;
Content profileLabel;
- String profileName = (Profile.lookup(profile)).name;
profileLabel = new StringContent(profileName);
profileLinkContent = getHyperLink(DocPaths.profileFrame(profileName), profileLabel, "",
"packageListFrame");
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileWriterImpl.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileWriterImpl.java Tue Sep 17 08:21:11 2013 -0700
@@ -138,6 +138,7 @@
"classFrame", new StringContent(pkg.name()), profile.name);
Content heading = HtmlTree.HEADING(HtmlTag.H3, pkgName);
HtmlTree li = HtmlTree.LI(HtmlStyle.blockList, heading);
+ addPackageDeprecationInfo(li, pkg);
return li;
}
@@ -175,6 +176,30 @@
}
/**
+ * Add the profile package deprecation information to the documentation tree.
+ *
+ * @param li the content tree to which the deprecation information will be added
+ * @param pkg the PackageDoc that is added
+ */
+ public void addPackageDeprecationInfo(Content li, PackageDoc pkg) {
+ Tag[] deprs;
+ if (Util.isDeprecated(pkg)) {
+ deprs = pkg.tags("deprecated");
+ HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
+ deprDiv.addStyle(HtmlStyle.deprecatedContent);
+ Content deprPhrase = HtmlTree.SPAN(HtmlStyle.strong, deprecatedPhrase);
+ deprDiv.addContent(deprPhrase);
+ if (deprs.length > 0) {
+ Tag[] commentTags = deprs[0].inlineTags();
+ if (commentTags.length > 0) {
+ addInlineDeprecatedComment(pkg, deprs[0], deprDiv);
+ }
+ }
+ li.addContent(deprDiv);
+ }
+ }
+
+ /**
* Get "PREV PROFILE" link in the navigation bar.
*
* @return a content tree for the previous link
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java Tue Sep 17 08:21:11 2013 -0700
@@ -191,10 +191,7 @@
Content htmlDocType = DocType.FRAMESET;
Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
Content head = new HtmlTree(HtmlTag.HEAD);
- if (! noTimeStamp) {
- Content headComment = new Comment(getGeneratedByString());
- head.addContent(headComment);
- }
+ head.addContent(getGeneratedBy(!noTimeStamp));
if (configuration.charset.length() > 0) {
Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
configuration.charset);
@@ -210,9 +207,13 @@
write(htmlDocument);
}
- protected String getGeneratedByString() {
- Calendar calendar = new GregorianCalendar(TimeZone.getDefault());
- Date today = calendar.getTime();
- return "Generated by javadoc ("+ ConfigurationImpl.BUILD_DATE + ") on " + today;
+ protected Comment getGeneratedBy(boolean timestamp) {
+ String text = "Generated by javadoc"; // marker string, deliberately not localized
+ if (timestamp) {
+ Calendar calendar = new GregorianCalendar(TimeZone.getDefault());
+ Date today = calendar.getTime();
+ text += " ("+ ConfigurationImpl.BUILD_DATE + ") on " + today;
+ }
+ return new Comment(text);
}
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlStyle.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlStyle.java Tue Sep 17 08:21:11 2013 -0700
@@ -68,6 +68,7 @@
packageSummary,
rowColor,
serializedFormContainer,
+ skipNav,
sourceContainer,
sourceLineNo,
strong,
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Tue Sep 17 08:21:11 2013 -0700
@@ -203,27 +203,27 @@
useLabel = getResource("doclet.navClassUse");
prevLabel = getResource("doclet.Prev");
nextLabel = getResource("doclet.Next");
- prevclassLabel = getResource("doclet.Prev_Class");
- nextclassLabel = getResource("doclet.Next_Class");
+ prevclassLabel = getNonBreakResource("doclet.Prev_Class");
+ nextclassLabel = getNonBreakResource("doclet.Next_Class");
summaryLabel = getResource("doclet.Summary");
detailLabel = getResource("doclet.Detail");
framesLabel = getResource("doclet.Frames");
- noframesLabel = getResource("doclet.No_Frames");
+ noframesLabel = getNonBreakResource("doclet.No_Frames");
treeLabel = getResource("doclet.Tree");
classLabel = getResource("doclet.Class");
deprecatedLabel = getResource("doclet.navDeprecated");
deprecatedPhrase = getResource("doclet.Deprecated");
- allclassesLabel = getResource("doclet.All_Classes");
- allpackagesLabel = getResource("doclet.All_Packages");
- allprofilesLabel = getResource("doclet.All_Profiles");
+ allclassesLabel = getNonBreakResource("doclet.All_Classes");
+ allpackagesLabel = getNonBreakResource("doclet.All_Packages");
+ allprofilesLabel = getNonBreakResource("doclet.All_Profiles");
indexLabel = getResource("doclet.Index");
helpLabel = getResource("doclet.Help");
seeLabel = getResource("doclet.See");
descriptionLabel = getResource("doclet.Description");
- prevpackageLabel = getResource("doclet.Prev_Package");
- nextpackageLabel = getResource("doclet.Next_Package");
- prevprofileLabel = getResource("doclet.Prev_Profile");
- nextprofileLabel = getResource("doclet.Next_Profile");
+ prevpackageLabel = getNonBreakResource("doclet.Prev_Package");
+ nextpackageLabel = getNonBreakResource("doclet.Next_Package");
+ prevprofileLabel = getNonBreakResource("doclet.Prev_Profile");
+ nextprofileLabel = getNonBreakResource("doclet.Next_Profile");
packagesLabel = getResource("doclet.Packages");
profilesLabel = getResource("doclet.Profiles");
methodDetailsLabel = getResource("doclet.Method_Detail");
@@ -257,6 +257,27 @@
}
/**
+ * Get the configuration string as a content, replacing spaces
+ * with non-breaking spaces.
+ *
+ * @param key the key to look for in the configuration file
+ * @return a content tree for the text
+ */
+ public Content getNonBreakResource(String key) {
+ String text = configuration.getText(key);
+ Content c = configuration.newContent();
+ int start = 0;
+ int p;
+ while ((p = text.indexOf(" ", start)) != -1) {
+ c.addContent(text.substring(start, p));
+ c.addContent(RawHtml.nbsp);
+ start = p + 1;
+ }
+ c.addContent(text.substring(start));
+ return c;
+ }
+
+ /**
* Get the configuration string as a content.
*
* @param key the key to look for in the configuration file
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Tue Sep 17 08:21:11 2013 -0700
@@ -383,35 +383,52 @@
DocErrorReporter reporter);
private void initProfiles() throws IOException {
+ if (profilespath.isEmpty())
+ return;
+
profiles = Profiles.read(new File(profilespath));
- // Generate profiles documentation only is profilespath is set and if
- // profiles is not null and profiles count is 1 or more.
- showProfiles = (!profilespath.isEmpty() && profiles != null &&
- profiles.getProfileCount() > 0);
- }
+
+ // Group the packages to be documented by the lowest profile (if any)
+ // in which each appears
+ Map<Profile, List<PackageDoc>> interimResults =
+ new EnumMap<Profile, List<PackageDoc>>(Profile.class);
+ for (Profile p: Profile.values())
+ interimResults.put(p, new ArrayList<PackageDoc>());
- private void initProfilePackages() throws IOException {
- profilePackages = new HashMap<String,PackageDoc[]>();
- ArrayList<PackageDoc> results;
- Map<String,PackageDoc> packageIndex = new HashMap<String,PackageDoc>();
- for (int i = 0; i < packages.length; i++) {
- PackageDoc pkg = packages[i];
- packageIndex.put(pkg.name(), pkg);
+ for (PackageDoc pkg: packages) {
+ if (nodeprecated && Util.isDeprecated(pkg)) {
+ continue;
+ }
+ // the getProfile method takes a type name, not a package name,
+ // but isn't particularly fussy about the simple name -- so just use *
+ int i = profiles.getProfile(pkg.name().replace(".", "/") + "/*");
+ Profile p = Profile.lookup(i);
+ if (p != null) {
+ List<PackageDoc> pkgs = interimResults.get(p);
+ pkgs.add(pkg);
+ }
}
- for (int i = 1; i < profiles.getProfileCount(); i++) {
- Set<String> profPkgs = profiles.getPackages(i);
- results = new ArrayList<PackageDoc>();
- for (String packageName : profPkgs) {
- packageName = packageName.replace("/", ".");
- PackageDoc profPkg = packageIndex.get(packageName);
- if (profPkg != null) {
- results.add(profPkg);
- }
- }
- Collections.sort(results);
- PackageDoc[] profilePkgs = results.toArray(new PackageDoc[]{});
- profilePackages.put(Profile.lookup(i).name, profilePkgs);
+
+ // Build the profilePackages structure used by the doclet
+ profilePackages = new HashMap<String,PackageDoc[]>();
+ List<PackageDoc> prev = Collections.<PackageDoc>emptyList();
+ int size;
+ for (Map.Entry<Profile,List<PackageDoc>> e: interimResults.entrySet()) {
+ Profile p = e.getKey();
+ List<PackageDoc> pkgs = e.getValue();
+ pkgs.addAll(prev); // each profile contains all lower profiles
+ Collections.sort(pkgs);
+ size = pkgs.size();
+ // For a profile, if there are no packages to be documented, do not add
+ // it to profilePackages map.
+ if (size > 0)
+ profilePackages.put(p.name, pkgs.toArray(new PackageDoc[pkgs.size()]));
+ prev = pkgs;
}
+
+ // Generate profiles documentation if any profile contains any
+ // of the packages to be documented.
+ showProfiles = !prev.isEmpty();
}
private void initPackageArray() {
@@ -534,13 +551,10 @@
public void setOptions() throws Fault {
initPackageArray();
setOptions(root.options());
- if (!profilespath.isEmpty()) {
- try {
- initProfiles();
- initProfilePackages();
- } catch (Exception e) {
- throw new DocletAbortException(e);
- }
+ try {
+ initProfiles();
+ } catch (Exception e) {
+ throw new DocletAbortException(e);
}
setSpecificDocletOptions(root.options());
}
@@ -713,6 +727,17 @@
}
/**
+ * Check the validity of the given profile. Return false if there are no
+ * valid packages to be documented for the profile.
+ *
+ * @param profileName the profile that needs to be validated.
+ * @return true if the profile has valid packages to be documented.
+ */
+ public boolean shouldDocumentProfile(String profileName) {
+ return profilePackages.containsKey(profileName);
+ }
+
+ /**
* Check the validity of the given Source or Output File encoding on this
* platform.
*
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css Tue Sep 17 08:21:11 2013 -0700
@@ -180,6 +180,12 @@
margin: auto 5px;
border:1px solid #c9aa44;
}
+.skipNav {
+ position:absolute;
+ top:auto;
+ left:-9999px;
+ overflow:hidden;
+ }
/*
Page header and footer styles
*/
@@ -372,7 +378,6 @@
overflow:hidden;
padding:0px;
margin:0px;
- white-space:pre;
}
caption a:link, caption a:hover, caption a:active, caption a:visited {
color:#FFFFFF;
@@ -381,35 +386,32 @@
white-space:nowrap;
padding-top:8px;
padding-left:8px;
- display:block;
+ display:inline-block;
float:left;
background-image:url(resources/titlebar.gif);
- height:18px;
}
.contentContainer ul.blockList li.blockList caption span.activeTableTab span {
white-space:nowrap;
padding-top:8px;
padding-left:8px;
- display:block;
+ display:inline-block;
float:left;
background-image:url(resources/activetitlebar.gif);
- height:18px;
}
.contentContainer ul.blockList li.blockList caption span.tableTab span {
white-space:nowrap;
padding-top:8px;
padding-left:8px;
- display:block;
+ display:inline-block;
float:left;
background-image:url(resources/titlebar.gif);
- height:18px;
}
.contentContainer ul.blockList li.blockList caption span.tableTab, .contentContainer ul.blockList li.blockList caption span.activeTableTab {
padding-top:0px;
padding-left:0px;
background-image:none;
float:none;
- display:inline;
+ display:inline-block;
}
.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd {
width:10px;
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/LegacyTaglet.java Tue Sep 17 08:21:11 2013 -0700
@@ -130,7 +130,13 @@
public Content getTagletOutput(Doc holder, TagletWriter writer)
throws IllegalArgumentException {
Content output = writer.getOutputInstance();
- output.addContent(new RawHtml(legacyTaglet.toString(holder.tags(getName()))));
+ Tag[] tags = holder.tags(getName());
+ if (tags.length > 0) {
+ String tagString = legacyTaglet.toString(tags);
+ if (tagString != null) {
+ output.addContent(new RawHtml(tagString));
+ }
+ }
return output;
}
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java Tue Sep 17 08:21:11 2013 -0700
@@ -34,6 +34,7 @@
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
+import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -221,8 +222,10 @@
/** If the file is a directory, list its contents. */
public Iterable<DocFile> list() throws IOException {
List<DocFile> files = new ArrayList<DocFile>();
- for (Path f: Files.newDirectoryStream(file)) {
- files.add(new StandardDocFile(f));
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(file)) {
+ for (Path f: ds) {
+ files.add(new StandardDocFile(f));
+ }
}
return files;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/Main.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/Main.java Tue Sep 17 08:21:11 2013 -0700
@@ -30,14 +30,6 @@
/**
* The programmatic interface for the Java Programming Language
* compiler, javac.
- *
- * <p>Except for the two methods
- * {@link #compile(java.lang.String[])}
- * {@link #compile(java.lang.String[],java.io.PrintWriter)},
- * nothing described in this source file is part of any supported
- * API. If you write code that depends on this, you do so at your own
- * risk. This code and its internal interfaces are subject to change
- * or deletion without notice.
*/
@jdk.Supported
public class Main {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Thu Sep 12 11:09:20 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,451 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.javac.code;
-
-import java.util.Map;
-
-import javax.tools.JavaFileObject;
-
-import com.sun.tools.javac.comp.Annotate;
-import com.sun.tools.javac.comp.AttrContext;
-import com.sun.tools.javac.comp.Env;
-import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.Assert;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Pair;
-import static com.sun.tools.javac.code.Kinds.PCK;
-
-/**
- * Container for all annotations (attributes in javac) on a Symbol.
- *
- * This class is explicitly mutable. Its contents will change when attributes
- * are annotated onto the Symbol. However this class depends on the facts that
- * List (in javac) is immutable.
- *
- * An instance of this class can be in one of three states:
- *
- * NOT_STARTED indicates that the Symbol this instance belongs to has not been
- * annotated (yet). Specifically if the declaration is not annotated this
- * instance will never move past NOT_STARTED. You can never go back to
- * NOT_STARTED.
- *
- * IN_PROGRESS annotations have been found on the declaration. Will be processed
- * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list
- * of attributes (and this moves out of the IN_PROGRESS state).
- *
- * "unnamed" this Annotations contains some attributes, possibly the final set.
- * While in this state you can only prepend or append to the attributes not set
- * it directly. You can also move back to the IN_PROGRESS state using reset().
- *
- * <p><b>This is NOT part of any supported API. If you write code that depends
- * on this, you do so at your own risk. This code and its internal interfaces
- * are subject to change or deletion without notice.</b>
- */
-public class Annotations {
-
- private static final List<Attribute.Compound> DECL_NOT_STARTED = List.of(null);
- private static final List<Attribute.Compound> DECL_IN_PROGRESS = List.of(null);
-
- /*
- * This field should never be null
- */
- private List<Attribute.Compound> attributes = DECL_NOT_STARTED;
-
- /*
- * Type attributes for this symbol.
- * This field should never be null.
- */
- private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil();
-
- /*
- * Type attributes of initializers in this class.
- * Unused if the current symbol is not a ClassSymbol.
- */
- private List<Attribute.TypeCompound> init_type_attributes = List.<Attribute.TypeCompound>nil();
-
- /*
- * Type attributes of class initializers in this class.
- * Unused if the current symbol is not a ClassSymbol.
- */
- private List<Attribute.TypeCompound> clinit_type_attributes = List.<Attribute.TypeCompound>nil();
-
- /*
- * The Symbol this Annotations instance belongs to
- */
- private final Symbol sym;
-
- public Annotations(Symbol sym) {
- this.sym = sym;
- }
-
- public List<Attribute.Compound> getDeclarationAttributes() {
- return filterDeclSentinels(attributes);
- }
-
- public List<Attribute.TypeCompound> getTypeAttributes() {
- return type_attributes;
- }
-
- public List<Attribute.TypeCompound> getInitTypeAttributes() {
- return init_type_attributes;
- }
-
- public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
- return clinit_type_attributes;
- }
-
- public void setDeclarationAttributes(List<Attribute.Compound> a) {
- Assert.check(pendingCompletion() || !isStarted());
- if (a == null) {
- throw new NullPointerException();
- }
- attributes = a;
- }
-
- public void setTypeAttributes(List<Attribute.TypeCompound> a) {
- if (a == null) {
- throw new NullPointerException();
- }
- type_attributes = a;
- }
-
- public void setInitTypeAttributes(List<Attribute.TypeCompound> a) {
- if (a == null) {
- throw new NullPointerException();
- }
- init_type_attributes = a;
- }
-
- public void setClassInitTypeAttributes(List<Attribute.TypeCompound> a) {
- if (a == null) {
- throw new NullPointerException();
- }
- clinit_type_attributes = a;
- }
-
- public void setAttributes(Annotations other) {
- if (other == null) {
- throw new NullPointerException();
- }
- setDeclarationAttributes(other.getDeclarationAttributes());
- setTypeAttributes(other.getTypeAttributes());
- setInitTypeAttributes(other.getInitTypeAttributes());
- setClassInitTypeAttributes(other.getClassInitTypeAttributes());
- }
-
- public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) {
- Assert.check(pendingCompletion() || (!isStarted() && sym.kind == PCK));
- this.setDeclarationAttributes(getAttributesForCompletion(ctx));
- }
-
- public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.TypeCompound> ctx) {
- this.appendUniqueTypes(getAttributesForCompletion(ctx));
- }
-
- private <T extends Attribute.Compound> List<T> getAttributesForCompletion(
- final Annotate.AnnotateRepeatedContext<T> ctx) {
-
- Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = ctx.annotated;
- boolean atLeastOneRepeated = false;
- List<T> buf = List.<T>nil();
- for (ListBuffer<T> lb : annotated.values()) {
- if (lb.size() == 1) {
- buf = buf.prepend(lb.first());
- } else { // repeated
- // This will break when other subtypes of Attributs.Compound
- // are introduced, because PlaceHolder is a subtype of TypeCompound.
- T res;
- @SuppressWarnings("unchecked")
- T ph = (T) new Placeholder<T>(ctx, lb.toList(), sym);
- res = ph;
- buf = buf.prepend(res);
- atLeastOneRepeated = true;
- }
- }
-
- if (atLeastOneRepeated) {
- // The Symbol s is now annotated with a combination of
- // finished non-repeating annotations and placeholders for
- // repeating annotations.
- //
- // We need to do this in two passes because when creating
- // a container for a repeating annotation we must
- // guarantee that the @Repeatable on the
- // contained annotation is fully annotated
- //
- // The way we force this order is to do all repeating
- // annotations in a pass after all non-repeating are
- // finished. This will work because @Repeatable
- // is non-repeating and therefore will be annotated in the
- // fist pass.
-
- // Queue a pass that will replace Attribute.Placeholders
- // with Attribute.Compound (made from synthesized containers).
- ctx.annotateRepeated(new Annotate.Annotator() {
- @Override
- public String toString() {
- return "repeated annotation pass of: " + sym + " in: " + sym.owner;
- }
-
- @Override
- public void enterAnnotation() {
- complete(ctx);
- }
- });
- }
- // Add non-repeating attributes
- return buf.reverse();
- }
-
- public Annotations reset() {
- attributes = DECL_IN_PROGRESS;
- return this;
- }
-
- public boolean isEmpty() {
- return !isStarted()
- || pendingCompletion()
- || attributes.isEmpty();
- }
-
- public boolean isTypesEmpty() {
- return type_attributes.isEmpty();
- }
-
- public boolean pendingCompletion() {
- return attributes == DECL_IN_PROGRESS;
- }
-
- public Annotations append(List<Attribute.Compound> l) {
- attributes = filterDeclSentinels(attributes);
-
- if (l.isEmpty()) {
- ; // no-op
- } else if (attributes.isEmpty()) {
- attributes = l;
- } else {
- attributes = attributes.appendList(l);
- }
- return this;
- }
-
- public Annotations appendUniqueTypes(List<Attribute.TypeCompound> l) {
- if (l.isEmpty()) {
- ; // no-op
- } else if (type_attributes.isEmpty()) {
- type_attributes = l;
- } else {
- // TODO: in case we expect a large number of annotations, this
- // might be inefficient.
- for (Attribute.TypeCompound tc : l) {
- if (!type_attributes.contains(tc))
- type_attributes = type_attributes.append(tc);
- }
- }
- return this;
- }
-
- public Annotations appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
- if (l.isEmpty()) {
- ; // no-op
- } else if (init_type_attributes.isEmpty()) {
- init_type_attributes = l;
- } else {
- init_type_attributes = init_type_attributes.appendList(l);
- }
- return this;
- }
-
- public Annotations appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
- if (l.isEmpty()) {
- ; // no-op
- } else if (clinit_type_attributes.isEmpty()) {
- clinit_type_attributes = l;
- } else {
- clinit_type_attributes = clinit_type_attributes.appendList(l);
- }
- return this;
- }
-
- public Annotations prepend(List<Attribute.Compound> l) {
- attributes = filterDeclSentinels(attributes);
-
- if (l.isEmpty()) {
- ; // no-op
- } else if (attributes.isEmpty()) {
- attributes = l;
- } else {
- attributes = attributes.prependList(l);
- }
- return this;
- }
-
- private List<Attribute.Compound> filterDeclSentinels(List<Attribute.Compound> a) {
- return (a == DECL_IN_PROGRESS || a == DECL_NOT_STARTED)
- ? List.<Attribute.Compound>nil()
- : a;
- }
-
- private boolean isStarted() {
- return attributes != DECL_NOT_STARTED;
- }
-
- private List<Attribute.Compound> getPlaceholders() {
- List<Attribute.Compound> res = List.<Attribute.Compound>nil();
- for (Attribute.Compound a : filterDeclSentinels(attributes)) {
- if (a instanceof Placeholder) {
- res = res.prepend(a);
- }
- }
- return res.reverse();
- }
-
- private List<Attribute.TypeCompound> getTypePlaceholders() {
- List<Attribute.TypeCompound> res = List.<Attribute.TypeCompound>nil();
- for (Attribute.TypeCompound a : type_attributes) {
- if (a instanceof Placeholder) {
- res = res.prepend(a);
- }
- }
- return res.reverse();
- }
-
- /*
- * Replace Placeholders for repeating annotations with their containers
- */
- private <T extends Attribute.Compound> void complete(Annotate.AnnotateRepeatedContext<T> ctx) {
- Log log = ctx.log;
- Env<AttrContext> env = ctx.env;
- JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
- try {
- // TODO: can we reduce duplication in the following branches?
- if (ctx.isTypeCompound) {
- Assert.check(!isTypesEmpty());
-
- if (isTypesEmpty()) {
- return;
- }
-
- List<Attribute.TypeCompound> result = List.nil();
- for (Attribute.TypeCompound a : getTypeAttributes()) {
- if (a instanceof Placeholder) {
- @SuppressWarnings("unchecked")
- Placeholder<Attribute.TypeCompound> ph = (Placeholder<Attribute.TypeCompound>) a;
- Attribute.TypeCompound replacement = replaceOne(ph, ph.getRepeatedContext());
-
- if (null != replacement) {
- result = result.prepend(replacement);
- }
- } else {
- result = result.prepend(a);
- }
- }
-
- type_attributes = result.reverse();
-
- Assert.check(Annotations.this.getTypePlaceholders().isEmpty());
- } else {
- Assert.check(!pendingCompletion());
-
- if (isEmpty()) {
- return;
- }
-
- List<Attribute.Compound> result = List.nil();
- for (Attribute.Compound a : getDeclarationAttributes()) {
- if (a instanceof Placeholder) {
- @SuppressWarnings("unchecked")
- Attribute.Compound replacement = replaceOne((Placeholder<T>) a, ctx);
-
- if (null != replacement) {
- result = result.prepend(replacement);
- }
- } else {
- result = result.prepend(a);
- }
- }
-
- attributes = result.reverse();
-
- Assert.check(Annotations.this.getPlaceholders().isEmpty());
- }
- } finally {
- log.useSource(oldSource);
- }
- }
-
- private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> ctx) {
- Log log = ctx.log;
-
- // Process repeated annotations
- T validRepeated = ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym);
-
- if (validRepeated != null) {
- // Check that the container isn't manually
- // present along with repeated instances of
- // its contained annotation.
- ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
- if (manualContainer != null) {
- log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present",
- manualContainer.first().type.tsym);
- }
- }
-
- // A null return will delete the Placeholder
- return validRepeated;
- }
-
- private static class Placeholder<T extends Attribute.Compound> extends Attribute.TypeCompound {
-
- private final Annotate.AnnotateRepeatedContext<T> ctx;
- private final List<T> placeholderFor;
- private final Symbol on;
-
- public Placeholder(Annotate.AnnotateRepeatedContext<T> ctx, List<T> placeholderFor, Symbol on) {
- super(on.type, List.<Pair<Symbol.MethodSymbol, Attribute>>nil(),
- ctx.isTypeCompound ?
- ((Attribute.TypeCompound)placeholderFor.head).position :
- null);
- this.ctx = ctx;
- this.placeholderFor = placeholderFor;
- this.on = on;
- }
-
- @Override
- public String toString() {
- return "<placeholder: " + placeholderFor + " on: " + on + ">";
- }
-
- public List<T> getPlaceholderFor() {
- return placeholderFor;
- }
-
- public Annotate.AnnotateRepeatedContext<T> getRepeatedContext() {
- return ctx;
- }
- }
-}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
import java.util.HashMap;
import java.util.Map;
+import com.sun.tools.javac.tree.EndPosTable;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -53,10 +55,13 @@
protected DeferredLintHandler(Context context) {
context.put(deferredLintHandlerKey, this);
+ this.currentPos = IMMEDIATE_POSITION;
}
- private DeferredLintHandler() {}
-
+ /**An interface for deferred lint reporting - loggers passed to
+ * {@link #report(LintLogger) } will be called when
+ * {@link #flush(DiagnosticPosition) } is invoked.
+ */
public interface LintLogger {
void report();
}
@@ -64,12 +69,26 @@
private DiagnosticPosition currentPos;
private Map<DiagnosticPosition, ListBuffer<LintLogger>> loggersQueue = new HashMap<DiagnosticPosition, ListBuffer<LintLogger>>();
+ /**Associate the given logger with the current position as set by {@link #setPos(DiagnosticPosition) }.
+ * Will be invoked when {@link #flush(DiagnosticPosition) } will be invoked with the same position.
+ * <br>
+ * Will invoke the logger synchronously if {@link #immediate() } was called
+ * instead of {@link #setPos(DiagnosticPosition) }.
+ */
public void report(LintLogger logger) {
- ListBuffer<LintLogger> loggers = loggersQueue.get(currentPos);
- Assert.checkNonNull(loggers);
- loggers.append(logger);
+ if (currentPos == IMMEDIATE_POSITION) {
+ logger.report();
+ } else {
+ ListBuffer<LintLogger> loggers = loggersQueue.get(currentPos);
+ if (loggers == null) {
+ loggersQueue.put(currentPos, loggers = ListBuffer.<LintLogger>lb());
+ }
+ loggers.append(logger);
+ }
}
+ /**Invoke all {@link LintLogger}s that were associated with the provided {@code pos}.
+ */
public void flush(DiagnosticPosition pos) {
ListBuffer<LintLogger> loggers = loggersQueue.get(pos);
if (loggers != null) {
@@ -80,16 +99,46 @@
}
}
- public DeferredLintHandler setPos(DiagnosticPosition currentPos) {
+ /**Sets the current position to the provided {@code currentPos}. {@link LintLogger}s
+ * passed to subsequent invocations of {@link #report(LintLogger) } will be associated
+ * with the given position.
+ */
+ public DiagnosticPosition setPos(DiagnosticPosition currentPos) {
+ DiagnosticPosition prevPosition = this.currentPos;
this.currentPos = currentPos;
- loggersQueue.put(currentPos, ListBuffer.<LintLogger>lb());
- return this;
+ return prevPosition;
+ }
+
+ /**{@link LintLogger}s passed to subsequent invocations of
+ * {@link #report(LintLogger) } will be invoked immediately.
+ */
+ public DiagnosticPosition immediate() {
+ return setPos(IMMEDIATE_POSITION);
}
- public static final DeferredLintHandler immediateHandler = new DeferredLintHandler() {
+ private static final DiagnosticPosition IMMEDIATE_POSITION = new DiagnosticPosition() {
+ @Override
+ public JCTree getTree() {
+ Assert.error();
+ return null;
+ }
+
@Override
- public void report(LintLogger logger) {
- logger.report();
+ public int getStartPosition() {
+ Assert.error();
+ return -1;
+ }
+
+ @Override
+ public int getPreferredPosition() {
+ Assert.error();
+ return -1;
+ }
+
+ @Override
+ public int getEndPosition(EndPosTable endPosTable) {
+ Assert.error();
+ return -1;
}
};
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Tue Sep 17 08:21:11 2013 -0700
@@ -97,7 +97,6 @@
public static final int MANDATED = 1<<15;
public static final int StandardFlags = 0x0fff;
- public static final int ModifierFlags = StandardFlags & ~INTERFACE;
// Because the following access flags are overloaded with other
// bit positions, we translate them when reading and writing class
@@ -266,6 +265,11 @@
*/
public static final long THROWS = 1L<<47;
+ /**
+ * Flag that marks potentially ambiguous overloads
+ */
+ public static final long POTENTIALLY_AMBIGUOUS = 1L<<48;
+
/** Modifier masks.
*/
public static final int
@@ -282,7 +286,9 @@
SYNCHRONIZED | FINAL | STRICTFP;
public static final long
ExtendedStandardFlags = (long)StandardFlags | DEFAULT,
+ ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT,
InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT,
+ AnnotationTypeElementMask = FINAL | ABSTRACT | PUBLIC | STRICTFP,
LocalVarFlags = FINAL | PARAMETER;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Tue Sep 17 08:21:11 2013 -0700
@@ -33,9 +33,6 @@
import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.util.Pair;
-import static com.sun.tools.javac.code.Flags.*;
-
-
/**
* A class for handling -Xlint suboptions and @SuppresssWarnings.
*
@@ -81,7 +78,6 @@
return l;
}
-
private final AugmentVisitor augmentor;
private final EnumSet<LintCategory> values;
@@ -90,7 +86,6 @@
private static final Map<String, LintCategory> map =
new java.util.concurrent.ConcurrentHashMap<String, LintCategory>(20);
-
protected Lint(Context context) {
// initialize values according to the lint options
Options options = Options.instance(context);
@@ -175,6 +170,11 @@
OPTIONS("options"),
/**
+ * Warn about issues regarding method overloads.
+ */
+ OVERLOADS("overloads"),
+
+ /**
* Warn about issues regarding method overrides.
*/
OVERRIDES("overrides"),
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Tue Sep 17 08:21:11 2013 -0700
@@ -46,6 +46,7 @@
import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.code.TypeTag.FORALL;
import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
/** Root class for Java symbols. It contains subclasses
* for specific sorts of symbols, such as variables, methods and operators,
@@ -98,9 +99,9 @@
// <editor-fold defaultstate="collapsed" desc="annotations">
/** The attributes of this symbol are contained in this
- * Annotations. The Annotations instance is NOT immutable.
+ * SymbolMetadata. The SymbolMetadata instance is NOT immutable.
*/
- protected Annotations annotations;
+ protected SymbolMetadata annotations;
/** An accessor method for the attributes of this symbol.
* Attributes of class symbols should be accessed through the accessor
@@ -217,19 +218,19 @@
public void setTypeAttributes(List<Attribute.TypeCompound> a) {
if (annotations != null || a.nonEmpty()) {
if (annotations == null)
- annotations = new Annotations(this);
+ annotations = new SymbolMetadata(this);
annotations.setTypeAttributes(a);
}
}
- private Annotations initedAnnos() {
+ private SymbolMetadata initedAnnos() {
if (annotations == null)
- annotations = new Annotations(this);
+ annotations = new SymbolMetadata(this);
return annotations;
}
/** This method is intended for debugging only. */
- public Annotations getAnnotations() {
+ public SymbolMetadata getAnnotations() {
return annotations;
}
@@ -852,7 +853,7 @@
private void mergeAttributes() {
if (annotations == null &&
package_info.annotations != null) {
- annotations = new Annotations(this);
+ annotations = new SymbolMetadata(this);
annotations.setAttributes(package_info.annotations);
}
}
@@ -1167,11 +1168,11 @@
public void setLazyConstValue(final Env<AttrContext> env,
final Attr attr,
- final JCTree.JCExpression initializer)
+ final JCVariableDecl variable)
{
setData(new Callable<Object>() {
public Object call() {
- return attr.attribLazyConstantValue(env, initializer, type);
+ return attr.attribLazyConstantValue(env, variable, type);
}
});
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.code;
+
+import java.util.Map;
+
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.comp.Annotate;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Pair;
+import static com.sun.tools.javac.code.Kinds.PCK;
+
+/**
+ * Container for all annotations (attributes in javac) on a Symbol.
+ *
+ * This class is explicitly mutable. Its contents will change when attributes
+ * are annotated onto the Symbol. However this class depends on the facts that
+ * List (in javac) is immutable.
+ *
+ * An instance of this class can be in one of three states:
+ *
+ * NOT_STARTED indicates that the Symbol this instance belongs to has not been
+ * annotated (yet). Specifically if the declaration is not annotated this
+ * instance will never move past NOT_STARTED. You can never go back to
+ * NOT_STARTED.
+ *
+ * IN_PROGRESS annotations have been found on the declaration. Will be processed
+ * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list
+ * of attributes (and this moves out of the IN_PROGRESS state).
+ *
+ * "unnamed" this SymbolMetadata contains some attributes, possibly the final set.
+ * While in this state you can only prepend or append to the attributes not set
+ * it directly. You can also move back to the IN_PROGRESS state using reset().
+ *
+ * <p><b>This is NOT part of any supported API. If you write code that depends
+ * on this, you do so at your own risk. This code and its internal interfaces
+ * are subject to change or deletion without notice.</b>
+ */
+public class SymbolMetadata {
+
+ private static final List<Attribute.Compound> DECL_NOT_STARTED = List.of(null);
+ private static final List<Attribute.Compound> DECL_IN_PROGRESS = List.of(null);
+
+ /*
+ * This field should never be null
+ */
+ private List<Attribute.Compound> attributes = DECL_NOT_STARTED;
+
+ /*
+ * Type attributes for this symbol.
+ * This field should never be null.
+ */
+ private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil();
+
+ /*
+ * Type attributes of initializers in this class.
+ * Unused if the current symbol is not a ClassSymbol.
+ */
+ private List<Attribute.TypeCompound> init_type_attributes = List.<Attribute.TypeCompound>nil();
+
+ /*
+ * Type attributes of class initializers in this class.
+ * Unused if the current symbol is not a ClassSymbol.
+ */
+ private List<Attribute.TypeCompound> clinit_type_attributes = List.<Attribute.TypeCompound>nil();
+
+ /*
+ * The Symbol this SymbolMetadata instance belongs to
+ */
+ private final Symbol sym;
+
+ public SymbolMetadata(Symbol sym) {
+ this.sym = sym;
+ }
+
+ public List<Attribute.Compound> getDeclarationAttributes() {
+ return filterDeclSentinels(attributes);
+ }
+
+ public List<Attribute.TypeCompound> getTypeAttributes() {
+ return type_attributes;
+ }
+
+ public List<Attribute.TypeCompound> getInitTypeAttributes() {
+ return init_type_attributes;
+ }
+
+ public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
+ return clinit_type_attributes;
+ }
+
+ public void setDeclarationAttributes(List<Attribute.Compound> a) {
+ Assert.check(pendingCompletion() || !isStarted());
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ attributes = a;
+ }
+
+ public void setTypeAttributes(List<Attribute.TypeCompound> a) {
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ type_attributes = a;
+ }
+
+ public void setInitTypeAttributes(List<Attribute.TypeCompound> a) {
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ init_type_attributes = a;
+ }
+
+ public void setClassInitTypeAttributes(List<Attribute.TypeCompound> a) {
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ clinit_type_attributes = a;
+ }
+
+ public void setAttributes(SymbolMetadata other) {
+ if (other == null) {
+ throw new NullPointerException();
+ }
+ setDeclarationAttributes(other.getDeclarationAttributes());
+ setTypeAttributes(other.getTypeAttributes());
+ setInitTypeAttributes(other.getInitTypeAttributes());
+ setClassInitTypeAttributes(other.getClassInitTypeAttributes());
+ }
+
+ public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) {
+ Assert.check(pendingCompletion() || (!isStarted() && sym.kind == PCK));
+ this.setDeclarationAttributes(getAttributesForCompletion(ctx));
+ }
+
+ public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.TypeCompound> ctx) {
+ this.appendUniqueTypes(getAttributesForCompletion(ctx));
+ }
+
+ private <T extends Attribute.Compound> List<T> getAttributesForCompletion(
+ final Annotate.AnnotateRepeatedContext<T> ctx) {
+
+ Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = ctx.annotated;
+ boolean atLeastOneRepeated = false;
+ List<T> buf = List.<T>nil();
+ for (ListBuffer<T> lb : annotated.values()) {
+ if (lb.size() == 1) {
+ buf = buf.prepend(lb.first());
+ } else { // repeated
+ // This will break when other subtypes of Attributs.Compound
+ // are introduced, because PlaceHolder is a subtype of TypeCompound.
+ T res;
+ @SuppressWarnings("unchecked")
+ T ph = (T) new Placeholder<T>(ctx, lb.toList(), sym);
+ res = ph;
+ buf = buf.prepend(res);
+ atLeastOneRepeated = true;
+ }
+ }
+
+ if (atLeastOneRepeated) {
+ // The Symbol s is now annotated with a combination of
+ // finished non-repeating annotations and placeholders for
+ // repeating annotations.
+ //
+ // We need to do this in two passes because when creating
+ // a container for a repeating annotation we must
+ // guarantee that the @Repeatable on the
+ // contained annotation is fully annotated
+ //
+ // The way we force this order is to do all repeating
+ // annotations in a pass after all non-repeating are
+ // finished. This will work because @Repeatable
+ // is non-repeating and therefore will be annotated in the
+ // fist pass.
+
+ // Queue a pass that will replace Attribute.Placeholders
+ // with Attribute.Compound (made from synthesized containers).
+ ctx.annotateRepeated(new Annotate.Annotator() {
+ @Override
+ public String toString() {
+ return "repeated annotation pass of: " + sym + " in: " + sym.owner;
+ }
+
+ @Override
+ public void enterAnnotation() {
+ complete(ctx);
+ }
+ });
+ }
+ // Add non-repeating attributes
+ return buf.reverse();
+ }
+
+ public SymbolMetadata reset() {
+ attributes = DECL_IN_PROGRESS;
+ return this;
+ }
+
+ public boolean isEmpty() {
+ return !isStarted()
+ || pendingCompletion()
+ || attributes.isEmpty();
+ }
+
+ public boolean isTypesEmpty() {
+ return type_attributes.isEmpty();
+ }
+
+ public boolean pendingCompletion() {
+ return attributes == DECL_IN_PROGRESS;
+ }
+
+ public SymbolMetadata append(List<Attribute.Compound> l) {
+ attributes = filterDeclSentinels(attributes);
+
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (attributes.isEmpty()) {
+ attributes = l;
+ } else {
+ attributes = attributes.appendList(l);
+ }
+ return this;
+ }
+
+ public SymbolMetadata appendUniqueTypes(List<Attribute.TypeCompound> l) {
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (type_attributes.isEmpty()) {
+ type_attributes = l;
+ } else {
+ // TODO: in case we expect a large number of annotations, this
+ // might be inefficient.
+ for (Attribute.TypeCompound tc : l) {
+ if (!type_attributes.contains(tc))
+ type_attributes = type_attributes.append(tc);
+ }
+ }
+ return this;
+ }
+
+ public SymbolMetadata appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (init_type_attributes.isEmpty()) {
+ init_type_attributes = l;
+ } else {
+ init_type_attributes = init_type_attributes.appendList(l);
+ }
+ return this;
+ }
+
+ public SymbolMetadata appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (clinit_type_attributes.isEmpty()) {
+ clinit_type_attributes = l;
+ } else {
+ clinit_type_attributes = clinit_type_attributes.appendList(l);
+ }
+ return this;
+ }
+
+ public SymbolMetadata prepend(List<Attribute.Compound> l) {
+ attributes = filterDeclSentinels(attributes);
+
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (attributes.isEmpty()) {
+ attributes = l;
+ } else {
+ attributes = attributes.prependList(l);
+ }
+ return this;
+ }
+
+ private List<Attribute.Compound> filterDeclSentinels(List<Attribute.Compound> a) {
+ return (a == DECL_IN_PROGRESS || a == DECL_NOT_STARTED)
+ ? List.<Attribute.Compound>nil()
+ : a;
+ }
+
+ private boolean isStarted() {
+ return attributes != DECL_NOT_STARTED;
+ }
+
+ private List<Attribute.Compound> getPlaceholders() {
+ List<Attribute.Compound> res = List.<Attribute.Compound>nil();
+ for (Attribute.Compound a : filterDeclSentinels(attributes)) {
+ if (a instanceof Placeholder) {
+ res = res.prepend(a);
+ }
+ }
+ return res.reverse();
+ }
+
+ private List<Attribute.TypeCompound> getTypePlaceholders() {
+ List<Attribute.TypeCompound> res = List.<Attribute.TypeCompound>nil();
+ for (Attribute.TypeCompound a : type_attributes) {
+ if (a instanceof Placeholder) {
+ res = res.prepend(a);
+ }
+ }
+ return res.reverse();
+ }
+
+ /*
+ * Replace Placeholders for repeating annotations with their containers
+ */
+ private <T extends Attribute.Compound> void complete(Annotate.AnnotateRepeatedContext<T> ctx) {
+ Log log = ctx.log;
+ Env<AttrContext> env = ctx.env;
+ JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
+ try {
+ // TODO: can we reduce duplication in the following branches?
+ if (ctx.isTypeCompound) {
+ Assert.check(!isTypesEmpty());
+
+ if (isTypesEmpty()) {
+ return;
+ }
+
+ List<Attribute.TypeCompound> result = List.nil();
+ for (Attribute.TypeCompound a : getTypeAttributes()) {
+ if (a instanceof Placeholder) {
+ @SuppressWarnings("unchecked")
+ Placeholder<Attribute.TypeCompound> ph = (Placeholder<Attribute.TypeCompound>) a;
+ Attribute.TypeCompound replacement = replaceOne(ph, ph.getRepeatedContext());
+
+ if (null != replacement) {
+ result = result.prepend(replacement);
+ }
+ } else {
+ result = result.prepend(a);
+ }
+ }
+
+ type_attributes = result.reverse();
+
+ Assert.check(SymbolMetadata.this.getTypePlaceholders().isEmpty());
+ } else {
+ Assert.check(!pendingCompletion());
+
+ if (isEmpty()) {
+ return;
+ }
+
+ List<Attribute.Compound> result = List.nil();
+ for (Attribute.Compound a : getDeclarationAttributes()) {
+ if (a instanceof Placeholder) {
+ @SuppressWarnings("unchecked")
+ Attribute.Compound replacement = replaceOne((Placeholder<T>) a, ctx);
+
+ if (null != replacement) {
+ result = result.prepend(replacement);
+ }
+ } else {
+ result = result.prepend(a);
+ }
+ }
+
+ attributes = result.reverse();
+
+ Assert.check(SymbolMetadata.this.getPlaceholders().isEmpty());
+ }
+ } finally {
+ log.useSource(oldSource);
+ }
+ }
+
+ private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> ctx) {
+ Log log = ctx.log;
+
+ // Process repeated annotations
+ T validRepeated = ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym);
+
+ if (validRepeated != null) {
+ // Check that the container isn't manually
+ // present along with repeated instances of
+ // its contained annotation.
+ ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
+ if (manualContainer != null) {
+ log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present",
+ manualContainer.first().type.tsym);
+ }
+ }
+
+ // A null return will delete the Placeholder
+ return validRepeated;
+ }
+
+ private static class Placeholder<T extends Attribute.Compound> extends Attribute.TypeCompound {
+
+ private final Annotate.AnnotateRepeatedContext<T> ctx;
+ private final List<T> placeholderFor;
+ private final Symbol on;
+
+ public Placeholder(Annotate.AnnotateRepeatedContext<T> ctx, List<T> placeholderFor, Symbol on) {
+ super(on.type, List.<Pair<Symbol.MethodSymbol, Attribute>>nil(),
+ ctx.isTypeCompound ?
+ ((Attribute.TypeCompound)placeholderFor.head).position :
+ null);
+ this.ctx = ctx;
+ this.placeholderFor = placeholderFor;
+ this.on = on;
+ }
+
+ @Override
+ public String toString() {
+ return "<placeholder: " + placeholderFor + " on: " + on + ">";
+ }
+
+ public List<T> getPlaceholderFor() {
+ return placeholderFor;
+ }
+
+ public Annotate.AnnotateRepeatedContext<T> getRepeatedContext() {
+ return ctx;
+ }
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Sep 17 08:21:11 2013 -0700
@@ -3055,7 +3055,7 @@
/**
* Does t have the same bounds for quantified variables as s?
*/
- boolean hasSameBounds(ForAll t, ForAll s) {
+ public boolean hasSameBounds(ForAll t, ForAll s) {
List<Type> l1 = t.tvars;
List<Type> l2 = s.tvars;
while (l1.nonEmpty() && l2.nonEmpty() &&
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Sep 17 08:21:11 2013 -0700
@@ -748,19 +748,11 @@
* @see VarSymbol#setLazyConstValue
*/
public Object attribLazyConstantValue(Env<AttrContext> env,
- JCTree.JCExpression initializer,
+ JCVariableDecl variable,
Type type) {
- /* When this env was created, it didn't have the correct lint nor had
- * annotations has been processed.
- * But now at this phase we have already processed annotations and the
- * correct lint must have been set in chk, so we should use that one to
- * attribute the initializer.
- */
- Lint prevLint = env.info.lint;
- env.info.lint = chk.getLint();
-
- JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
+ DiagnosticPosition prevLintPos
+ = deferredLintHandler.setPos(variable.pos());
try {
// Use null as symbol to not attach the type annotation to any symbol.
@@ -768,17 +760,16 @@
// to the symbol.
// This prevents having multiple type annotations, just because of
// lazy constant value evaluation.
- memberEnter.typeAnnotate(initializer, env, null);
+ memberEnter.typeAnnotate(variable.init, env, null, variable.pos());
annotate.flush();
- Type itype = attribExpr(initializer, env, type);
+ Type itype = attribExpr(variable.init, env, type);
if (itype.constValue() != null) {
return coerce(itype, type).constValue();
} else {
return null;
}
} finally {
- env.info.lint = prevLint;
- log.useSource(prevSource);
+ deferredLintHandler.setPos(prevLintPos);
}
}
@@ -1012,7 +1003,7 @@
}
// Attribute all type annotations in the body
- memberEnter.typeAnnotate(tree.body, localEnv, m);
+ memberEnter.typeAnnotate(tree.body, localEnv, m, null);
annotate.flush();
// Attribute method body.
@@ -1042,7 +1033,7 @@
} else {
if (tree.init != null) {
// Field initializer expression need to be entered.
- memberEnter.typeAnnotate(tree.init, env, tree.sym);
+ memberEnter.typeAnnotate(tree.init, env, tree.sym, tree.pos());
annotate.flush();
}
}
@@ -1056,18 +1047,16 @@
((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
(tree.sym.flags() & PARAMETER) != 0;
chk.validate(tree.vartype, env, !isImplicitLambdaParameter);
- deferredLintHandler.flush(tree.pos());
try {
+ v.getConstValue(); // ensure compile-time constant initializer is evaluated
+ deferredLintHandler.flush(tree.pos());
chk.checkDeprecatedAnnotation(tree.pos(), v);
if (tree.init != null) {
- if ((v.flags_field & FINAL) != 0 &&
- memberEnter.needsLazyConstValue(tree.init)) {
- // In this case, `v' is final. Ensure that it's initializer is
- // evaluated.
- v.getConstValue(); // ensure initializer is evaluated
- } else {
+ if ((v.flags_field & FINAL) == 0 ||
+ !memberEnter.needsLazyConstValue(tree.init)) {
+ // Not a compile-time constant
// Attribute initializer in a new environment
// with the declared variable as owner.
// Check that initializer conforms to variable's declared type.
@@ -1106,7 +1095,7 @@
if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
// Attribute all type annotations in the block
- memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner);
+ memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
annotate.flush();
{
@@ -2319,30 +2308,37 @@
boolean needsRecovery =
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
try {
- Type target = pt();
+ Type currentTarget = pt();
List<Type> explicitParamTypes = null;
if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
//attribute lambda parameters
attribStats(that.params, localEnv);
explicitParamTypes = TreeInfo.types(that.params);
- target = infer.instantiateFunctionalInterface(that, target, explicitParamTypes, resultInfo.checkContext);
}
Type lambdaType;
if (pt() != Type.recoveryType) {
- target = targetChecker.visit(target, that);
- lambdaType = types.findDescriptorType(target);
+ /* We need to adjust the target. If the target is an
+ * intersection type, for example: SAM & I1 & I2 ...
+ * the target will be updated to SAM
+ */
+ currentTarget = targetChecker.visit(currentTarget, that);
+ if (explicitParamTypes != null) {
+ currentTarget = infer.instantiateFunctionalInterface(that,
+ currentTarget, explicitParamTypes, resultInfo.checkContext);
+ }
+ lambdaType = types.findDescriptorType(currentTarget);
} else {
- target = Type.recoveryType;
+ currentTarget = Type.recoveryType;
lambdaType = fallbackDescriptorType(that);
}
- setFunctionalInfo(localEnv, that, pt(), lambdaType, target, resultInfo.checkContext);
+ setFunctionalInfo(localEnv, that, pt(), lambdaType, currentTarget, resultInfo.checkContext);
if (lambdaType.hasTag(FORALL)) {
//lambda expression target desc cannot be a generic method
resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
- lambdaType, kindName(target.tsym), target.tsym));
+ lambdaType, kindName(currentTarget.tsym), currentTarget.tsym));
result = that.type = types.createErrorType(pt());
return;
}
@@ -2376,7 +2372,7 @@
if (arityMismatch) {
resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda"));
- result = that.type = types.createErrorType(target);
+ result = that.type = types.createErrorType(currentTarget);
return;
}
}
@@ -2396,38 +2392,14 @@
new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
localEnv.info.returnResult = bodyResultInfo;
- Log.DeferredDiagnosticHandler lambdaDeferredHandler = new Log.DeferredDiagnosticHandler(log);
- try {
- if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
- attribTree(that.getBody(), localEnv, bodyResultInfo);
- } else {
- JCBlock body = (JCBlock)that.body;
- attribStats(body.stats, localEnv);
- }
-
- if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.SPECULATIVE) {
- //check for errors in lambda body
- for (JCDiagnostic deferredDiag : lambdaDeferredHandler.getDiagnostics()) {
- if (deferredDiag.getKind() == JCDiagnostic.Kind.ERROR) {
- resultInfo.checkContext
- .report(that, diags.fragment("bad.arg.types.in.lambda", TreeInfo.types(that.params),
- deferredDiag)); //hidden diag parameter
- //we mark the lambda as erroneous - this is crucial in the recovery step
- //as parameter-dependent type error won't be reported in that stage,
- //meaning that a lambda will be deemed erroeneous only if there is
- //a target-independent error (which will cause method diagnostic
- //to be skipped).
- result = that.type = types.createErrorType(target);
- return;
- }
- }
- }
- } finally {
- lambdaDeferredHandler.reportDeferredDiagnostics();
- log.popDiagnosticHandler(lambdaDeferredHandler);
+ if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
+ attribTree(that.getBody(), localEnv, bodyResultInfo);
+ } else {
+ JCBlock body = (JCBlock)that.body;
+ attribStats(body.stats, localEnv);
}
- result = check(that, target, VAL, resultInfo);
+ result = check(that, currentTarget, VAL, resultInfo);
boolean isSpeculativeRound =
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
@@ -2435,12 +2407,20 @@
preFlow(that);
flow.analyzeLambda(env, that, make, isSpeculativeRound);
- checkLambdaCompatible(that, lambdaType, resultInfo.checkContext, isSpeculativeRound);
+ checkLambdaCompatible(that, lambdaType, resultInfo.checkContext);
if (!isSpeculativeRound) {
- checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, target);
+ //add thrown types as bounds to the thrown types free variables if needed:
+ if (resultInfo.checkContext.inferenceContext().free(lambdaType.getThrownTypes())) {
+ List<Type> inferredThrownTypes = flow.analyzeLambdaThrownTypes(env, that, make);
+ List<Type> thrownTypes = resultInfo.checkContext.inferenceContext().asFree(lambdaType.getThrownTypes());
+
+ chk.unhandled(inferredThrownTypes, thrownTypes);
+ }
+
+ checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, currentTarget);
}
- result = check(that, target, VAL, resultInfo);
+ result = check(that, currentTarget, VAL, resultInfo);
} catch (Types.FunctionDescriptorLookupError ex) {
JCDiagnostic cause = ex.getDiagnostic();
resultInfo.checkContext.report(that, cause);
@@ -2604,10 +2584,9 @@
* Lambda compatibility. Check that given return types, thrown types, parameter types
* are compatible with the expected functional interface descriptor. This means that:
* (i) parameter types must be identical to those of the target descriptor; (ii) return
- * types must be compatible with the return type of the expected descriptor;
- * (iii) finish inference of thrown types if required.
+ * types must be compatible with the return type of the expected descriptor.
*/
- private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext, boolean speculativeAttr) {
+ private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext) {
Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType());
//return values have already been checked - but if lambda has no return
@@ -2624,11 +2603,6 @@
if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) {
checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
}
-
- if (!speculativeAttr) {
- List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes());
- chk.unhandled(tree.inferredThrownTypes == null ? List.<Type>nil() : tree.inferredThrownTypes, thrownTypes);
- }
}
private Env<AttrContext> lambdaEnv(JCLambda that, Env<AttrContext> env) {
@@ -2664,6 +2638,13 @@
if (that.getMode() == JCMemberReference.ReferenceMode.NEW) {
exprType = chk.checkConstructorRefType(that.expr, exprType);
+ if (!exprType.isErroneous() &&
+ exprType.isRaw() &&
+ that.typeargs != null) {
+ log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
+ diags.fragment("mref.infer.and.explicit.params"));
+ exprType = types.createErrorType(exprType);
+ }
}
if (exprType.isErroneous()) {
@@ -3731,7 +3712,7 @@
* Check that method arguments conform to its instantiation.
**/
public Type checkMethod(Type site,
- Symbol sym,
+ final Symbol sym,
ResultInfo resultInfo,
Env<AttrContext> env,
final List<JCExpression> argtrees,
@@ -3820,8 +3801,19 @@
resultInfo.checkContext.report(env.tree.pos(), ex.getDiagnostic());
return types.createErrorType(site);
} catch (Resolve.InapplicableMethodException ex) {
- Assert.error(ex.getDiagnostic().getMessage(Locale.getDefault()));
- return null;
+ final JCDiagnostic diag = ex.getDiagnostic();
+ Resolve.InapplicableSymbolError errSym = rs.new InapplicableSymbolError(null) {
+ @Override
+ protected Pair<Symbol, JCDiagnostic> errCandidate() {
+ return new Pair<Symbol, JCDiagnostic>(sym, diag);
+ }
+ };
+ List<Type> argtypes2 = Type.map(argtypes,
+ rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
+ JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
+ env.tree, sym, site, sym.name, argtypes2, typeargtypes);
+ log.report(errDiag);
+ return types.createErrorType(site);
}
}
@@ -4206,6 +4198,7 @@
ResultInfo prevReturnRes = env.info.returnResult;
try {
+ deferredLintHandler.flush(env.tree);
env.info.returnResult = null;
// java.lang.Enum may not be subclassed by a non-enum
if (st.tsym == syms.enumSym &&
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Sep 17 08:21:11 2013 -0700
@@ -148,7 +148,7 @@
sunApiHandler = new MandatoryWarningHandler(log, verboseSunApi,
enforceMandatoryWarnings, "sunapi", null);
- deferredLintHandler = DeferredLintHandler.immediateHandler;
+ deferredLintHandler = DeferredLintHandler.instance(context);
}
/** Switch: generics enabled?
@@ -218,20 +218,6 @@
return prev;
}
- /* This idiom should be used only in cases when it is needed to set the lint
- * of an environment that has been created in a phase previous to annotations
- * processing.
- */
- Lint getLint() {
- return lint;
- }
-
- DeferredLintHandler setDeferredLintHandler(DeferredLintHandler newDeferredLintHandler) {
- DeferredLintHandler prev = deferredLintHandler;
- deferredLintHandler = newDeferredLintHandler;
- return prev;
- }
-
MethodSymbol setMethod(MethodSymbol newMethod) {
MethodSymbol prev = method;
method = newMethod;
@@ -582,14 +568,19 @@
/** Check for redundant casts (i.e. where source type is a subtype of target type)
* The problem should only be reported for non-292 cast
*/
- public void checkRedundantCast(Env<AttrContext> env, JCTypeCast tree) {
- if (!tree.type.isErroneous() &&
- (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST))
+ public void checkRedundantCast(Env<AttrContext> env, final JCTypeCast tree) {
+ if (!tree.type.isErroneous()
&& types.isSameType(tree.expr.type, tree.clazz.type)
&& !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
&& !is292targetTypeCast(tree)) {
- log.warning(Lint.LintCategory.CAST,
- tree.pos(), "redundant.cast", tree.expr.type);
+ deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
+ @Override
+ public void report() {
+ if (lint.isEnabled(Lint.LintCategory.CAST))
+ log.warning(Lint.LintCategory.CAST,
+ tree.pos(), "redundant.cast", tree.expr.type);
+ }
+ });
}
}
//where
@@ -1050,6 +1041,7 @@
long checkFlags(DiagnosticPosition pos, long flags, Symbol sym, JCTree tree) {
long mask;
long implicit = 0;
+
switch (sym.kind) {
case VAR:
if (sym.owner.kind != TYP)
@@ -1070,7 +1062,10 @@
} else
mask = ConstructorFlags;
} else if ((sym.owner.flags_field & INTERFACE) != 0) {
- if ((flags & (DEFAULT | STATIC)) != 0) {
+ if ((sym.owner.flags_field & ANNOTATION) != 0) {
+ mask = AnnotationTypeElementMask;
+ implicit = PUBLIC | ABSTRACT;
+ } else if ((flags & (DEFAULT | STATIC)) != 0) {
mask = InterfaceMethodMask;
implicit = PUBLIC;
if ((flags & DEFAULT) != 0) {
@@ -1079,8 +1074,7 @@
} else {
mask = implicit = InterfaceMethodFlags;
}
- }
- else {
+ } else {
mask = MethodFlags;
}
// Imply STRICTFP if owner has STRICTFP set.
@@ -2368,7 +2362,10 @@
//for each method m1 that is overridden (directly or indirectly)
//by method 'sym' in 'site'...
for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
- if (!sym.overrides(m1, site.tsym, types, false)) continue;
+ if (!sym.overrides(m1, site.tsym, types, false)) {
+ checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)m1);
+ continue;
+ }
//...check each method m2 that is a member of 'site'
for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
if (m2 == m1) continue;
@@ -2406,14 +2403,17 @@
for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) {
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as
//a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
- if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck) &&
- types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
- log.error(pos,
- "name.clash.same.erasure.no.hide",
- sym, sym.location(),
- s, s.location());
- return;
- }
+ if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
+ if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
+ log.error(pos,
+ "name.clash.same.erasure.no.hide",
+ sym, sym.location(),
+ s, s.location());
+ return;
+ } else {
+ checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s);
+ }
+ }
}
}
@@ -2496,6 +2496,62 @@
}
}
+ /**
+ * Report warnings for potentially ambiguous method declarations. Two declarations
+ * are potentially ambiguous if they feature two unrelated functional interface
+ * in same argument position (in which case, a call site passing an implicit
+ * lambda would be ambiguous).
+ */
+ void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site,
+ MethodSymbol msym1, MethodSymbol msym2) {
+ if (msym1 != msym2 &&
+ allowDefaultMethods &&
+ lint.isEnabled(LintCategory.OVERLOADS) &&
+ (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 &&
+ (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) {
+ Type mt1 = types.memberType(site, msym1);
+ Type mt2 = types.memberType(site, msym2);
+ //if both generic methods, adjust type variables
+ if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) &&
+ types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) {
+ mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
+ }
+ //expand varargs methods if needed
+ int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length());
+ List<Type> args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true);
+ List<Type> args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true);
+ //if arities don't match, exit
+ if (args1.length() != args2.length()) return;
+ boolean potentiallyAmbiguous = false;
+ while (args1.nonEmpty() && args2.nonEmpty()) {
+ Type s = args1.head;
+ Type t = args2.head;
+ if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) {
+ if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) &&
+ types.findDescriptorType(s).getParameterTypes().length() > 0 &&
+ types.findDescriptorType(s).getParameterTypes().length() ==
+ types.findDescriptorType(t).getParameterTypes().length()) {
+ potentiallyAmbiguous = true;
+ } else {
+ break;
+ }
+ }
+ args1 = args1.tail;
+ args2 = args2.tail;
+ }
+ if (potentiallyAmbiguous) {
+ //we found two incompatible functional interfaces with same arity
+ //this means a call site passing an implicit lambda would be ambigiuous
+ msym1.flags_field |= POTENTIALLY_AMBIGUOUS;
+ msym2.flags_field |= POTENTIALLY_AMBIGUOUS;
+ log.warning(LintCategory.OVERLOADS, pos, "potentially.ambiguous.overload",
+ msym1, msym1.location(),
+ msym2, msym2.location());
+ return;
+ }
+ }
+ }
+
/** Report a conflict between a user symbol and a synthetic symbol.
*/
private void syntheticError(DiagnosticPosition pos, Symbol sym) {
@@ -3275,7 +3331,9 @@
(e.sym.flags() & CLASH) == 0 &&
sym.kind == e.sym.kind &&
sym.name != names.error &&
- (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
+ (sym.kind != MTH ||
+ types.hasSameArgs(sym.type, e.sym.type) ||
+ types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
varargsDuplicateError(pos, sym, e.sym);
return true;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Tue Sep 17 08:21:11 2013 -0700
@@ -25,6 +25,7 @@
package com.sun.tools.javac.comp;
+import com.sun.source.tree.MemberReferenceTree;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.util.*;
@@ -39,7 +40,9 @@
import java.util.ArrayList;
+import java.util.Collections;
import java.util.EnumSet;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@@ -98,7 +101,7 @@
emptyDeferredAttrContext =
new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) {
@Override
- void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List<Type> stuckVars) {
+ void addDeferredAttrNode(DeferredType dt, ResultInfo ri, DeferredStuckPolicy deferredStuckPolicy) {
Assert.error("Empty deferred context!");
}
@Override
@@ -149,15 +152,15 @@
class Entry {
JCTree speculativeTree;
- Resolve.MethodResolutionPhase phase;
+ ResultInfo resultInfo;
- public Entry(JCTree speculativeTree, MethodResolutionPhase phase) {
+ public Entry(JCTree speculativeTree, ResultInfo resultInfo) {
this.speculativeTree = speculativeTree;
- this.phase = phase;
+ this.resultInfo = resultInfo;
}
- boolean matches(Resolve.MethodResolutionPhase phase) {
- return this.phase == phase;
+ boolean matches(MethodResolutionPhase phase) {
+ return resultInfo.checkContext.deferredAttrContext().phase == phase;
}
}
@@ -178,12 +181,13 @@
* Stores a speculative cache entry corresponding to given symbol
* and resolution phase
*/
- void put(Symbol msym, JCTree speculativeTree, MethodResolutionPhase phase) {
+ void put(JCTree speculativeTree, ResultInfo resultInfo) {
+ Symbol msym = resultInfo.checkContext.deferredAttrContext().msym;
List<Entry> entries = cache.get(msym);
if (entries == null) {
entries = List.nil();
}
- cache.put(msym, entries.prepend(new Entry(speculativeTree, phase)));
+ cache.put(msym, entries.prepend(new Entry(speculativeTree, resultInfo)));
}
}
@@ -203,15 +207,24 @@
* attribution round must follow one or more speculative rounds.
*/
Type check(ResultInfo resultInfo) {
- return check(resultInfo, stuckVars(tree, env, resultInfo), basicCompleter);
+ DeferredStuckPolicy deferredStuckPolicy;
+ if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) {
+ deferredStuckPolicy = dummyStuckPolicy;
+ } else if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.SPECULATIVE) {
+ deferredStuckPolicy = new OverloadStuckPolicy(resultInfo, this);
+ } else {
+ deferredStuckPolicy = new CheckStuckPolicy(resultInfo, this);
+ }
+ return check(resultInfo, deferredStuckPolicy, basicCompleter);
}
- Type check(ResultInfo resultInfo, List<Type> stuckVars, DeferredTypeCompleter deferredTypeCompleter) {
+ private Type check(ResultInfo resultInfo, DeferredStuckPolicy deferredStuckPolicy,
+ DeferredTypeCompleter deferredTypeCompleter) {
DeferredAttrContext deferredAttrContext =
resultInfo.checkContext.deferredAttrContext();
Assert.check(deferredAttrContext != emptyDeferredAttrContext);
- if (stuckVars.nonEmpty()) {
- deferredAttrContext.addDeferredAttrNode(this, resultInfo, stuckVars);
+ if (deferredStuckPolicy.isStuck()) {
+ deferredAttrContext.addDeferredAttrNode(this, resultInfo, deferredStuckPolicy);
return Type.noType;
} else {
try {
@@ -236,6 +249,7 @@
Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext);
}
+
/**
* A basic completer for deferred types. This completer type-checks a deferred type
* using attribution; depending on the attribution mode, this could be either standard
@@ -249,7 +263,7 @@
//speculative rounds...
Assert.check(dt.mode == null || dt.mode == AttrMode.SPECULATIVE);
JCTree speculativeTree = attribSpeculative(dt.tree, dt.env, resultInfo);
- dt.speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase);
+ dt.speculativeCache.put(speculativeTree, resultInfo);
return speculativeTree.type;
case CHECK:
Assert.check(dt.mode != null);
@@ -268,6 +282,45 @@
};
/**
+ * Policy for detecting stuck expressions. Different criteria might cause
+ * an expression to be judged as stuck, depending on whether the check
+ * is performed during overload resolution or after most specific.
+ */
+ interface DeferredStuckPolicy {
+ /**
+ * Has the policy detected that a given expression should be considered stuck?
+ */
+ boolean isStuck();
+ /**
+ * Get the set of inference variables a given expression depends upon.
+ */
+ Set<Type> stuckVars();
+ /**
+ * Get the set of inference variables which might get new constraints
+ * if a given expression is being type-checked.
+ */
+ Set<Type> depVars();
+ }
+
+ /**
+ * Basic stuck policy; an expression is never considered to be stuck.
+ */
+ DeferredStuckPolicy dummyStuckPolicy = new DeferredStuckPolicy() {
+ @Override
+ public boolean isStuck() {
+ return false;
+ }
+ @Override
+ public Set<Type> stuckVars() {
+ return Collections.emptySet();
+ }
+ @Override
+ public Set<Type> depVars() {
+ return Collections.emptySet();
+ }
+ };
+
+ /**
* The 'mode' in which the deferred type is to be type-checked
*/
public enum AttrMode {
@@ -388,8 +441,9 @@
* Adds a node to the list of deferred attribution nodes - used by Resolve.rawCheckArgumentsApplicable
* Nodes added this way act as 'roots' for the out-of-order method checking process.
*/
- void addDeferredAttrNode(final DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
- deferredAttrNodes.add(new DeferredAttrNode(dt, resultInfo, stuckVars));
+ void addDeferredAttrNode(final DeferredType dt, ResultInfo resultInfo,
+ DeferredStuckPolicy deferredStuckPolicy) {
+ deferredAttrNodes.add(new DeferredAttrNode(dt, resultInfo, deferredStuckPolicy));
}
/**
@@ -400,23 +454,52 @@
*/
void complete() {
while (!deferredAttrNodes.isEmpty()) {
- Set<Type> stuckVars = new LinkedHashSet<Type>();
+ Map<Type, Set<Type>> depVarsMap = new LinkedHashMap<Type, Set<Type>>();
+ List<Type> stuckVars = List.nil();
boolean progress = false;
//scan a defensive copy of the node list - this is because a deferred
//attribution round can add new nodes to the list
for (DeferredAttrNode deferredAttrNode : List.from(deferredAttrNodes)) {
if (!deferredAttrNode.process(this)) {
- stuckVars.addAll(deferredAttrNode.stuckVars);
+ List<Type> restStuckVars =
+ List.from(deferredAttrNode.deferredStuckPolicy.stuckVars())
+ .intersect(inferenceContext.restvars());
+ stuckVars = stuckVars.prependList(restStuckVars);
+ //update dependency map
+ for (Type t : List.from(deferredAttrNode.deferredStuckPolicy.depVars())
+ .intersect(inferenceContext.restvars())) {
+ Set<Type> prevDeps = depVarsMap.get(t);
+ if (prevDeps == null) {
+ prevDeps = new LinkedHashSet<Type>();
+ depVarsMap.put(t, prevDeps);
+ }
+ prevDeps.addAll(restStuckVars);
+ }
} else {
deferredAttrNodes.remove(deferredAttrNode);
progress = true;
}
}
if (!progress) {
+ DeferredAttrContext dac = this;
+ while (dac != emptyDeferredAttrContext) {
+ if (dac.mode == AttrMode.SPECULATIVE) {
+ //unsticking does not take place during overload
+ break;
+ }
+ dac = dac.parent;
+ }
//remove all variables that have already been instantiated
//from the list of stuck variables
- inferenceContext.solveAny(List.from(stuckVars), warn);
- inferenceContext.notifyChange();
+ try {
+ inferenceContext.solveAny(stuckVars, depVarsMap, warn);
+ inferenceContext.notifyChange();
+ } catch (Infer.GraphStrategy.NodeNotFoundException ex) {
+ //this means that we are in speculative mode and the
+ //set of contraints are too tight for progess to be made.
+ //Just leave the remaining expressions as stuck.
+ break;
+ }
}
}
}
@@ -426,7 +509,7 @@
* Class representing a deferred attribution node. It keeps track of
* a deferred type, along with the expected target type information.
*/
- class DeferredAttrNode implements Infer.FreeTypeListener {
+ class DeferredAttrNode {
/** underlying deferred type */
DeferredType dt;
@@ -434,22 +517,13 @@
/** underlying target type information */
ResultInfo resultInfo;
- /** list of uninferred inference variables causing this node to be stuck */
- List<Type> stuckVars;
+ /** stuck policy associated with this node */
+ DeferredStuckPolicy deferredStuckPolicy;
- DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
+ DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, DeferredStuckPolicy deferredStuckPolicy) {
this.dt = dt;
this.resultInfo = resultInfo;
- this.stuckVars = stuckVars;
- if (!stuckVars.isEmpty()) {
- resultInfo.checkContext.inferenceContext().addFreeTypeListener(stuckVars, this);
- }
- }
-
- @Override
- public void typesInferred(InferenceContext inferenceContext) {
- stuckVars = List.nil();
- resultInfo = resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
+ this.deferredStuckPolicy = deferredStuckPolicy;
}
/**
@@ -457,24 +531,41 @@
* Invariant: a stuck node cannot be processed.
*/
@SuppressWarnings("fallthrough")
- boolean process(DeferredAttrContext deferredAttrContext) {
+ boolean process(final DeferredAttrContext deferredAttrContext) {
switch (deferredAttrContext.mode) {
case SPECULATIVE:
- dt.check(resultInfo, List.<Type>nil(), new StructuralStuckChecker());
- return true;
+ if (deferredStuckPolicy.isStuck()) {
+ dt.check(resultInfo, dummyStuckPolicy, new StructuralStuckChecker());
+ return true;
+ } else {
+ Assert.error("Cannot get here");
+ }
case CHECK:
- if (stuckVars.nonEmpty()) {
+ if (deferredStuckPolicy.isStuck()) {
//stuck expression - see if we can propagate
if (deferredAttrContext.parent != emptyDeferredAttrContext &&
- Type.containsAny(deferredAttrContext.parent.inferenceContext.inferencevars, List.from(stuckVars))) {
- deferredAttrContext.parent.deferredAttrNodes.add(this);
- dt.check(resultInfo, List.<Type>nil(), dummyCompleter);
+ Type.containsAny(deferredAttrContext.parent.inferenceContext.inferencevars,
+ List.from(deferredStuckPolicy.stuckVars()))) {
+ deferredAttrContext.parent.addDeferredAttrNode(dt,
+ resultInfo.dup(new Check.NestedCheckContext(resultInfo.checkContext) {
+ @Override
+ public InferenceContext inferenceContext() {
+ return deferredAttrContext.parent.inferenceContext;
+ }
+ @Override
+ public DeferredAttrContext deferredAttrContext() {
+ return deferredAttrContext.parent;
+ }
+ }), deferredStuckPolicy);
+ dt.tree.type = Type.stuckType;
return true;
} else {
return false;
}
} else {
- dt.check(resultInfo, stuckVars, basicCompleter);
+ ResultInfo instResultInfo =
+ resultInfo.dup(deferredAttrContext.inferenceContext.asInstType(resultInfo.pt));
+ dt.check(instResultInfo, dummyStuckPolicy, basicCompleter);
return true;
}
default:
@@ -489,12 +580,14 @@
ResultInfo resultInfo;
InferenceContext inferenceContext;
+ Env<AttrContext> env;
public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
this.resultInfo = resultInfo;
this.inferenceContext = deferredAttrContext.inferenceContext;
+ this.env = dt.env;
dt.tree.accept(this);
- dt.speculativeCache.put(deferredAttrContext.msym, stuckTree, deferredAttrContext.phase);
+ dt.speculativeCache.put(stuckTree, resultInfo);
return Type.noType;
}
@@ -541,15 +634,25 @@
} catch (Types.FunctionDescriptorLookupError ex) {
checkContext.report(null, ex.getDiagnostic());
}
- switch (tree.sym.kind) {
+ Env<AttrContext> localEnv = env.dup(tree);
+ JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv,
+ attr.memberReferenceQualifierResult(tree));
+ ListBuffer<Type> argtypes = ListBuffer.lb();
+ for (Type t : types.findDescriptorType(pt).getParameterTypes()) {
+ argtypes.append(Type.noType);
+ }
+ JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
+ mref2.expr = exprTree;
+ Pair<Symbol, ?> lookupRes =
+ rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type,
+ tree.name, argtypes.toList(), null, true, rs.arityMethodCheck, inferenceContext);
+ switch (lookupRes.fst.kind) {
//note: as argtypes are erroneous types, type-errors must
//have been caused by arity mismatch
case Kinds.ABSENT_MTH:
case Kinds.WRONG_MTH:
case Kinds.WRONG_MTHS:
- case Kinds.STATICERR:
- case Kinds.MISSING_ENCL:
- checkContext.report(null, diags.fragment("incompatible.arg.types.in.mref"));
+ checkContext.report(tree, diags.fragment("incompatible.arg.types.in.mref"));
}
}
}
@@ -575,18 +678,12 @@
infer.emptyContext, emptyDeferredAttrContext, types.noWarnings);
}
- protected boolean validState(DeferredType dt) {
- return dt.mode != null &&
- deferredAttrContext.mode.ordinal() <= dt.mode.ordinal();
- }
-
@Override
public Type apply(Type t) {
if (!t.hasTag(DEFERRED)) {
return t.map(this);
} else {
DeferredType dt = (DeferredType)t;
- Assert.check(validState(dt));
return typeOf(dt);
}
}
@@ -623,11 +720,6 @@
recover(dt) : owntype;
}
- @Override
- protected boolean validState(DeferredType dt) {
- return true;
- }
-
/**
* Synthesize a type for a deferred type that hasn't been previously
* reduced to an ordinary type. Functional deferred types and conditionals
@@ -647,25 +739,6 @@
}
/**
- * Retrieves the list of inference variables that need to be inferred before
- * an AST node can be type-checked
- */
- @SuppressWarnings("fallthrough")
- List<Type> stuckVars(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
- if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) {
- return List.nil();
- } else {
- return stuckVarsInternal(tree, resultInfo.pt, env, resultInfo.checkContext.inferenceContext());
- }
- }
- //where
- private List<Type> stuckVarsInternal(JCTree tree, Type pt, Env<AttrContext> env, Infer.InferenceContext inferenceContext) {
- StuckChecker sc = new StuckChecker(pt, env, inferenceContext);
- sc.scan(tree);
- return List.from(sc.stuckVars);
- }
-
- /**
* A special tree scanner that would only visit portions of a given tree.
* The set of nodes visited by the scanner can be customized at construction-time.
*/
@@ -737,17 +810,41 @@
* inferring types that make some of the nested expressions incompatible
* with their corresponding instantiated target
*/
- class StuckChecker extends PolyScanner {
+ class CheckStuckPolicy extends PolyScanner implements DeferredStuckPolicy, Infer.FreeTypeListener {
Type pt;
- Env<AttrContext> env;
Infer.InferenceContext inferenceContext;
Set<Type> stuckVars = new LinkedHashSet<Type>();
+ Set<Type> depVars = new LinkedHashSet<Type>();
- StuckChecker(Type pt, Env<AttrContext> env, Infer.InferenceContext inferenceContext) {
- this.pt = pt;
- this.env = env;
- this.inferenceContext = inferenceContext;
+ @Override
+ public boolean isStuck() {
+ return !stuckVars.isEmpty();
+ }
+
+ @Override
+ public Set<Type> stuckVars() {
+ return stuckVars;
+ }
+
+ @Override
+ public Set<Type> depVars() {
+ return depVars;
+ }
+
+ public CheckStuckPolicy(ResultInfo resultInfo, DeferredType dt) {
+ this.pt = resultInfo.pt;
+ this.inferenceContext = resultInfo.checkContext.inferenceContext();
+ scan(dt.tree);
+ if (!stuckVars.isEmpty()) {
+ resultInfo.checkContext.inferenceContext()
+ .addFreeTypeListener(List.from(stuckVars), this);
+ }
+ }
+
+ @Override
+ public void typesInferred(InferenceContext inferenceContext) {
+ stuckVars.clear();
}
@Override
@@ -763,6 +860,7 @@
if (tree.paramKind == JCLambda.ParameterKind.IMPLICIT &&
freeArgVars.nonEmpty()) {
stuckVars.addAll(freeArgVars);
+ depVars.addAll(inferenceContext.freeVarsIn(descType.getReturnType()));
}
scanLambdaBody(tree, descType.getReturnType());
}
@@ -780,41 +878,34 @@
Type descType = types.findDescriptorType(pt);
List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes());
- Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
- if (freeArgVars.nonEmpty()) {
- //perform arity-based check
- JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv,
- attr.memberReferenceQualifierResult(tree));
- ListBuffer<Type> argtypes = ListBuffer.lb();
- for (Type t : descType.getParameterTypes()) {
- argtypes.append(Type.noType);
- }
- JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
- mref2.expr = exprTree;
- Pair<Symbol, ReferenceLookupHelper> lookupRes =
- rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type,
- tree.name, argtypes.toList(), null, true, rs.arityMethodCheck,
- inferenceContext);
- Symbol res = tree.sym = lookupRes.fst;
- if (res.kind >= Kinds.ERRONEOUS ||
- res.type.hasTag(FORALL) ||
- (res.flags() & Flags.VARARGS) != 0 ||
- (TreeInfo.isStaticSelector(exprTree, tree.name.table.names) &&
- exprTree.type.isRaw())) {
- stuckVars.addAll(freeArgVars);
- }
+ if (freeArgVars.nonEmpty() &&
+ tree.overloadKind == JCMemberReference.OverloadKind.OVERLOADED) {
+ stuckVars.addAll(freeArgVars);
+ depVars.addAll(inferenceContext.freeVarsIn(descType.getReturnType()));
}
}
void scanLambdaBody(JCLambda lambda, final Type pt) {
if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
- stuckVars.addAll(stuckVarsInternal(lambda.body, pt, env, inferenceContext));
+ Type prevPt = this.pt;
+ try {
+ this.pt = pt;
+ scan(lambda.body);
+ } finally {
+ this.pt = prevPt;
+ }
} else {
LambdaReturnScanner lambdaScanner = new LambdaReturnScanner() {
@Override
public void visitReturn(JCReturn tree) {
if (tree.expr != null) {
- stuckVars.addAll(stuckVarsInternal(tree.expr, pt, env, inferenceContext));
+ Type prevPt = CheckStuckPolicy.this.pt;
+ try {
+ CheckStuckPolicy.this.pt = pt;
+ CheckStuckPolicy.this.scan(tree.expr);
+ } finally {
+ CheckStuckPolicy.this.pt = prevPt;
+ }
}
}
};
@@ -824,6 +915,42 @@
}
/**
+ * This visitor is used to check that structural expressions conform
+ * to their target - this step is required as inference could end up
+ * inferring types that make some of the nested expressions incompatible
+ * with their corresponding instantiated target
+ */
+ class OverloadStuckPolicy extends CheckStuckPolicy implements DeferredStuckPolicy {
+
+ boolean stuck;
+
+ @Override
+ public boolean isStuck() {
+ return super.isStuck() || stuck;
+ }
+
+ public OverloadStuckPolicy(ResultInfo resultInfo, DeferredType dt) {
+ super(resultInfo, dt);
+ }
+
+ @Override
+ public void visitLambda(JCLambda tree) {
+ super.visitLambda(tree);
+ if (tree.paramKind == JCLambda.ParameterKind.IMPLICIT) {
+ stuck = true;
+ }
+ }
+
+ @Override
+ public void visitReference(JCMemberReference tree) {
+ super.visitReference(tree);
+ if (tree.overloadKind == JCMemberReference.OverloadKind.OVERLOADED) {
+ stuck = true;
+ }
+ }
+ }
+
+ /**
* Does the argument expression {@code expr} need speculative type-checking?
*/
boolean isDeferred(Env<AttrContext> env, JCExpression expr) {
@@ -904,6 +1031,26 @@
@Override
public void visitReference(JCMemberReference tree) {
+ //perform arity-based check
+ Env<AttrContext> localEnv = env.dup(tree);
+ JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv,
+ attr.memberReferenceQualifierResult(tree));
+ JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
+ mref2.expr = exprTree;
+ Pair<Symbol, ReferenceLookupHelper> lookupRes =
+ rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type,
+ tree.name, List.<Type>nil(), null, true, rs.nilMethodCheck,
+ infer.emptyContext);
+ Symbol res = tree.sym = lookupRes.fst;
+ if (res.kind >= Kinds.ERRONEOUS ||
+ res.type.hasTag(FORALL) ||
+ (res.flags() & Flags.VARARGS) != 0 ||
+ (TreeInfo.isStaticSelector(exprTree, tree.name.table.names) &&
+ exprTree.type.isRaw())) {
+ tree.overloadKind = JCMemberReference.OverloadKind.OVERLOADED;
+ } else {
+ tree.overloadKind = JCMemberReference.OverloadKind.UNOVERLOADED;
+ }
//a method reference is always a poly expression
result = ArgumentExpressionKind.POLY;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Sep 17 08:21:11 2013 -0700
@@ -207,7 +207,7 @@
public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
new AliveAnalyzer().analyzeTree(env, make);
- new AssignAnalyzer().analyzeTree(env, make);
+ new AssignAnalyzer(log, syms, lint, names).analyzeTree(env);
new FlowAnalyzer().analyzeTree(env, make);
new CaptureAnalyzer().analyzeTree(env, make);
}
@@ -224,7 +224,6 @@
}
try {
new AliveAnalyzer().analyzeTree(env, that, make);
- new LambdaFlowAnalyzer().analyzeTree(env, that, make);
} finally {
if (!speculative) {
log.popDiagnosticHandler(diagHandler);
@@ -232,6 +231,23 @@
}
}
+ public List<Type> analyzeLambdaThrownTypes(Env<AttrContext> env, JCLambda that, TreeMaker make) {
+ //we need to disable diagnostics temporarily; the problem is that if
+ //a lambda expression contains e.g. an unreachable statement, an error
+ //message will be reported and will cause compilation to skip the flow analyis
+ //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
+ //related errors, which will allow for more errors to be detected
+ Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
+ try {
+ new AssignAnalyzer(log, syms, lint, names).analyzeTree(env);
+ LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
+ flowAnalyzer.analyzeTree(env, that, make);
+ return flowAnalyzer.inferredThrownTypes;
+ } finally {
+ log.popDiagnosticHandler(diagHandler);
+ }
+ }
+
/**
* Definite assignment scan mode
*/
@@ -276,15 +292,6 @@
}
/**
- * Utility method to reset several Bits instances.
- */
- private void resetBits(Bits... bits) {
- for (Bits b : bits) {
- b.reset();
- }
- }
-
- /**
* Base visitor class for all visitors implementing dataflow analysis logic.
* This class define the shared logic for handling jumps (break/continue statements).
*/
@@ -331,17 +338,17 @@
this.tree = tree;
}
- void resolveJump() {
+ void resolveJump(JCTree tree) {
//do nothing
}
}
- abstract void markDead();
+ abstract void markDead(JCTree tree);
/** Record an outward transfer of control. */
void recordExit(JCTree tree, P pe) {
pendingExits.append(pe);
- markDead();
+ markDead(tree);
}
/** Resolve all jumps of this statement. */
@@ -355,7 +362,7 @@
P exit = exits.head;
if (exit.tree.hasTag(jk.treeTag) &&
jk.getTarget(exit.tree) == tree) {
- exit.resolveJump();
+ exit.resolveJump(tree);
resolved = true;
} else {
pendingExits.append(exit);
@@ -364,12 +371,12 @@
return resolved;
}
- /** Resolve all breaks of this statement. */
+ /** Resolve all continues of this statement. */
boolean resolveContinues(JCTree tree) {
return resolveJump(tree, new ListBuffer<P>(), JumpKind.CONTINUE);
}
- /** Resolve all continues of this statement. */
+ /** Resolve all breaks of this statement. */
boolean resolveBreaks(JCTree tree, ListBuffer<P> oldPendingExits) {
return resolveJump(tree, oldPendingExits, JumpKind.BREAK);
}
@@ -398,7 +405,7 @@
private boolean alive;
@Override
- void markDead() {
+ void markDead(JCTree tree) {
alive = false;
}
@@ -680,7 +687,7 @@
public void visitThrow(JCThrow tree) {
scan(tree.expr);
- markDead();
+ markDead(tree);
}
public void visitApply(JCMethodInvocation tree) {
@@ -781,7 +788,7 @@
}
@Override
- void markDead() {
+ void markDead(JCTree tree) {
//do nothing
}
@@ -1206,7 +1213,7 @@
else {
markThrown(tree, tree.expr.type);
}
- markDead();
+ markDead(tree);
}
public void visitApply(JCMethodInvocation tree) {
@@ -1318,27 +1325,35 @@
* Specialized pass that performs inference of thrown types for lambdas.
*/
class LambdaFlowAnalyzer extends FlowAnalyzer {
+ List<Type> inferredThrownTypes;
+ boolean inLambda;
@Override
public void visitLambda(JCLambda tree) {
- if (tree.type != null &&
- tree.type.isErroneous()) {
+ if ((tree.type != null &&
+ tree.type.isErroneous()) || inLambda) {
return;
}
List<Type> prevCaught = caught;
List<Type> prevThrown = thrown;
ListBuffer<FlowPendingExit> prevPending = pendingExits;
+ inLambda = true;
try {
pendingExits = ListBuffer.lb();
caught = List.of(syms.throwableType);
thrown = List.nil();
scan(tree.body);
- tree.inferredThrownTypes = thrown;
+ inferredThrownTypes = thrown;
} finally {
pendingExits = prevPending;
caught = prevCaught;
thrown = prevThrown;
+ inLambda = false;
}
}
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ //skip
+ }
}
/**
@@ -1348,11 +1363,13 @@
* depends on the results of the liveliness analyzer. This pass is also used to mark
* effectively-final local variables/parameters.
*/
- class AssignAnalyzer extends BaseAnalyzer<AssignAnalyzer.AssignPendingExit> {
+
+ public abstract static class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer.AbstractAssignPendingExit>
+ extends BaseAnalyzer<P> {
/** The set of definitely assigned variables.
*/
- final Bits inits;
+ protected final Bits inits;
/** The set of definitely unassigned variables.
*/
@@ -1378,7 +1395,7 @@
/** A mapping from addresses to variable symbols.
*/
- JCVariableDecl[] vardecls;
+ protected JCVariableDecl[] vardecls;
/** The current class being defined.
*/
@@ -1390,11 +1407,11 @@
/** The next available variable sequence number.
*/
- int nextadr;
+ protected int nextadr;
/** The first variable sequence number in a block that can return.
*/
- int returnadr;
+ protected int returnadr;
/** The list of unreferenced automatic resources.
*/
@@ -1406,35 +1423,46 @@
/** The starting position of the analysed tree */
int startPos;
- AssignAnalyzer() {
- inits = new Bits();
+ final Symtab syms;
+
+ protected Names names;
+
+ public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
+
+ final Bits inits;
+ final Bits uninits;
+ final Bits exit_inits = new Bits(true);
+ final Bits exit_uninits = new Bits(true);
+
+ public AbstractAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
+ super(tree);
+ this.inits = inits;
+ this.uninits = uninits;
+ this.exit_inits.assign(inits);
+ this.exit_uninits.assign(uninits);
+ }
+
+ @Override
+ public void resolveJump(JCTree tree) {
+ inits.andSet(exit_inits);
+ uninits.andSet(exit_uninits);
+ }
+ }
+
+ public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names) {
+ this.inits = inits;
uninits = new Bits();
uninitsTry = new Bits();
initsWhenTrue = new Bits(true);
initsWhenFalse = new Bits(true);
uninitsWhenTrue = new Bits(true);
uninitsWhenFalse = new Bits(true);
- }
-
- class AssignPendingExit extends BaseAnalyzer.PendingExit {
-
- final Bits exit_inits = new Bits(true);
- final Bits exit_uninits = new Bits(true);
-
- AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
- super(tree);
- this.exit_inits.assign(inits);
- this.exit_uninits.assign(uninits);
- }
-
- void resolveJump() {
- inits.andSet(exit_inits);
- uninits.andSet(exit_uninits);
- }
+ this.syms = syms;
+ this.names = names;
}
@Override
- void markDead() {
+ protected void markDead(JCTree tree) {
inits.inclRange(returnadr, nextadr);
uninits.inclRange(returnadr, nextadr);
}
@@ -1444,7 +1472,7 @@
/** Do we need to track init/uninit state of this symbol?
* I.e. is symbol either a local or a blank final variable?
*/
- boolean trackable(VarSymbol sym) {
+ protected boolean trackable(VarSymbol sym) {
return
sym.pos >= startPos &&
((sym.owner.kind == MTH ||
@@ -1464,44 +1492,35 @@
}
sym.adr = nextadr;
vardecls[nextadr] = varDecl;
- inits.excl(nextadr);
+ exclVarFromInits(varDecl, nextadr);
uninits.incl(nextadr);
nextadr++;
}
+ protected void exclVarFromInits(JCTree tree, int adr) {
+ inits.excl(adr);
+ }
+
+ protected void assignToInits(JCTree tree, Bits bits) {
+ inits.assign(bits);
+ }
+
+ protected void andSetInits(JCTree tree, Bits bits) {
+ inits.andSet(bits);
+ }
+
+ protected void orSetInits(JCTree tree, Bits bits) {
+ inits.orSet(bits);
+ }
+
/** Record an initialization of a trackable variable.
*/
void letInit(DiagnosticPosition pos, VarSymbol sym) {
if (sym.adr >= firstadr && trackable(sym)) {
- if ((sym.flags() & EFFECTIVELY_FINAL) != 0) {
- if (!uninits.isMember(sym.adr)) {
- //assignment targeting an effectively final variable
- //makes the variable lose its status of effectively final
- //if the variable is _not_ definitively unassigned
- sym.flags_field &= ~EFFECTIVELY_FINAL;
- } else {
- uninit(sym);
- }
- }
- else if ((sym.flags() & FINAL) != 0) {
- if ((sym.flags() & PARAMETER) != 0) {
- if ((sym.flags() & UNION) != 0) { //multi-catch parameter
- log.error(pos, "multicatch.parameter.may.not.be.assigned",
- sym);
- }
- else {
- log.error(pos, "final.parameter.may.not.be.assigned",
- sym);
- }
- } else if (!uninits.isMember(sym.adr)) {
- log.error(pos, flowKind.errKey, sym);
- } else {
- uninit(sym);
- }
+ if (uninits.isMember(sym.adr)) {
+ uninit(sym);
}
inits.incl(sym.adr);
- } else if ((sym.flags() & FINAL) != 0) {
- log.error(pos, "var.might.already.be.assigned", sym);
}
}
//where
@@ -1535,12 +1554,14 @@
void checkInit(DiagnosticPosition pos, VarSymbol sym) {
checkInit(pos, sym, "var.might.not.have.been.initialized");
}
- void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {
- if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
- trackable(sym) &&
- !inits.isMember(sym.adr)) {
- log.error(pos, errkey, sym);
- inits.incl(sym.adr);
+
+ void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {}
+
+ /** Utility method to reset several Bits instances.
+ */
+ private void resetBits(Bits... bits) {
+ for (Bits b : bits) {
+ b.reset();
}
}
@@ -1558,7 +1579,7 @@
/** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
*/
- void merge() {
+ protected void merge(JCTree tree) {
inits.assign(initsWhenFalse.andSet(initsWhenTrue));
uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue));
}
@@ -1573,7 +1594,9 @@
void scanExpr(JCTree tree) {
if (tree != null) {
scan(tree);
- if (inits.isReset()) merge();
+ if (inits.isReset()) {
+ merge(tree);
+ }
}
}
@@ -1590,7 +1613,7 @@
*/
void scanCond(JCTree tree) {
if (tree.type.isFalse()) {
- if (inits.isReset()) merge();
+ if (inits.isReset()) merge(tree);
initsWhenTrue.assign(inits);
initsWhenTrue.inclRange(firstadr, nextadr);
uninitsWhenTrue.assign(uninits);
@@ -1598,7 +1621,7 @@
initsWhenFalse.assign(inits);
uninitsWhenFalse.assign(uninits);
} else if (tree.type.isTrue()) {
- if (inits.isReset()) merge();
+ if (inits.isReset()) merge(tree);
initsWhenFalse.assign(inits);
initsWhenFalse.inclRange(firstadr, nextadr);
uninitsWhenFalse.assign(uninits);
@@ -1617,22 +1640,22 @@
/* ------------ Visitor methods for various sorts of trees -------------*/
+ @Override
public void visitClassDef(JCClassDecl tree) {
- if (tree.sym == null) return;
+ if (tree.sym == null) {
+ return;
+ }
JCClassDecl classDefPrev = classDef;
int firstadrPrev = firstadr;
int nextadrPrev = nextadr;
- ListBuffer<AssignPendingExit> pendingExitsPrev = pendingExits;
- Lint lintPrev = lint;
+ ListBuffer<P> pendingExitsPrev = pendingExits;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ pendingExits = new ListBuffer<P>();
if (tree.name != names.empty) {
firstadr = nextadr;
}
classDef = tree;
- lint = lint.augment(tree.sym);
-
try {
// define all the static fields
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
@@ -1640,8 +1663,9 @@
JCVariableDecl def = (JCVariableDecl)l.head;
if ((def.mods.flags & STATIC) != 0) {
VarSymbol sym = def.sym;
- if (trackable(sym))
+ if (trackable(sym)) {
newVar(def);
+ }
}
}
}
@@ -1660,8 +1684,9 @@
JCVariableDecl def = (JCVariableDecl)l.head;
if ((def.mods.flags & STATIC) == 0) {
VarSymbol sym = def.sym;
- if (trackable(sym))
+ if (trackable(sym)) {
newVar(def);
+ }
}
}
}
@@ -1685,21 +1710,25 @@
nextadr = nextadrPrev;
firstadr = firstadrPrev;
classDef = classDefPrev;
- lint = lintPrev;
}
}
+ @Override
public void visitMethodDef(JCMethodDecl tree) {
- if (tree.body == null) return;
+ if (tree.body == null) {
+ return;
+ }
+ /* MemberEnter can generate synthetic methods, ignore them
+ */
+ if ((tree.sym.flags() & SYNTHETIC) != 0) {
+ return;
+ }
final Bits initsPrev = new Bits(inits);
final Bits uninitsPrev = new Bits(uninits);
int nextadrPrev = nextadr;
int firstadrPrev = firstadr;
int returnadrPrev = returnadr;
- Lint lintPrev = lint;
-
- lint = lint.augment(tree.sym);
Assert.check(pendingExits.isEmpty());
@@ -1707,13 +1736,17 @@
boolean isInitialConstructor =
TreeInfo.isInitialConstructor(tree);
- if (!isInitialConstructor)
+ if (!isInitialConstructor) {
firstadr = nextadr;
+ }
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
JCVariableDecl def = l.head;
scan(def);
- inits.incl(def.sym.adr);
- uninits.excl(def.sym.adr);
+ Assert.check((def.sym.flags() & PARAMETER) != 0, "Method parameter without PARAMETER flag");
+ /* If we are executing the code from Gen, then there can be
+ * synthetic or mandated variables, ignore them.
+ */
+ initParam(def);
}
// else we are in an instance initializer block;
// leave caught unchanged.
@@ -1737,39 +1770,42 @@
}
}
}
- List<AssignPendingExit> exits = pendingExits.toList();
- pendingExits = new ListBuffer<AssignPendingExit>();
+ List<P> exits = pendingExits.toList();
+ pendingExits = new ListBuffer<>();
while (exits.nonEmpty()) {
- AssignPendingExit exit = exits.head;
+ P exit = exits.head;
exits = exits.tail;
Assert.check(exit.tree.hasTag(RETURN), exit.tree);
if (isInitialConstructor) {
- inits.assign(exit.exit_inits);
- for (int i = firstadr; i < nextadr; i++)
+ assignToInits(exit.tree, exit.exit_inits);
+ for (int i = firstadr; i < nextadr; i++) {
checkInit(exit.tree.pos(), vardecls[i].sym);
+ }
}
}
} finally {
- inits.assign(initsPrev);
+ assignToInits(tree, initsPrev);
uninits.assign(uninitsPrev);
nextadr = nextadrPrev;
firstadr = firstadrPrev;
returnadr = returnadrPrev;
- lint = lintPrev;
}
}
+ protected void initParam(JCVariableDecl def) {
+ inits.incl(def.sym.adr);
+ uninits.excl(def.sym.adr);
+ }
+
public void visitVarDef(JCVariableDecl tree) {
boolean track = trackable(tree.sym);
- if (track && tree.sym.owner.kind == MTH) newVar(tree);
+ if (track && tree.sym.owner.kind == MTH) {
+ newVar(tree);
+ }
if (tree.init != null) {
- Lint lintPrev = lint;
- lint = lint.augment(tree.sym);
- try{
- scanExpr(tree.init);
- if (track) letInit(tree.pos(), tree.sym);
- } finally {
- lint = lintPrev;
+ scanExpr(tree.init);
+ if (track) {
+ letInit(tree.pos(), tree.sym);
}
}
}
@@ -1780,14 +1816,18 @@
nextadr = nextadrPrev;
}
+ int getLogNumberOfErrors() {
+ return 0;
+ }
+
public void visitDoLoop(JCDoWhileLoop tree) {
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+ ListBuffer<P> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL;
final Bits initsSkip = new Bits(true);
final Bits uninitsSkip = new Bits(true);
- pendingExits = new ListBuffer<AssignPendingExit>();
- int prevErrors = log.nerrors;
+ pendingExits = new ListBuffer<P>();
+ int prevErrors = getLogNumberOfErrors();
do {
final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr);
@@ -1798,28 +1838,28 @@
initsSkip.assign(initsWhenFalse);
uninitsSkip.assign(uninitsWhenFalse);
}
- if (log.nerrors != prevErrors ||
+ if (getLogNumberOfErrors() != prevErrors ||
flowKind.isFinal() ||
new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
break;
- inits.assign(initsWhenTrue);
+ assignToInits(tree.cond, initsWhenTrue);
uninits.assign(uninitsEntry.andSet(uninitsWhenTrue));
flowKind = FlowKind.SPECULATIVE_LOOP;
} while (true);
flowKind = prevFlowKind;
- inits.assign(initsSkip);
+ assignToInits(tree, initsSkip);
uninits.assign(uninitsSkip);
resolveBreaks(tree, prevPendingExits);
}
public void visitWhileLoop(JCWhileLoop tree) {
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+ ListBuffer<P> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL;
final Bits initsSkip = new Bits(true);
final Bits uninitsSkip = new Bits(true);
- pendingExits = new ListBuffer<AssignPendingExit>();
- int prevErrors = log.nerrors;
+ pendingExits = new ListBuffer<>();
+ int prevErrors = getLogNumberOfErrors();
final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr);
do {
@@ -1828,35 +1868,36 @@
initsSkip.assign(initsWhenFalse) ;
uninitsSkip.assign(uninitsWhenFalse);
}
- inits.assign(initsWhenTrue);
+ assignToInits(tree, initsWhenTrue);
uninits.assign(uninitsWhenTrue);
scan(tree.body);
resolveContinues(tree);
- if (log.nerrors != prevErrors ||
+ if (getLogNumberOfErrors() != prevErrors ||
flowKind.isFinal() ||
- new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
+ new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) {
break;
+ }
uninits.assign(uninitsEntry.andSet(uninits));
flowKind = FlowKind.SPECULATIVE_LOOP;
} while (true);
flowKind = prevFlowKind;
//a variable is DA/DU after the while statement, if it's DA/DU assuming the
//branch is not taken AND if it's DA/DU before any break statement
- inits.assign(initsSkip);
+ assignToInits(tree.body, initsSkip);
uninits.assign(uninitsSkip);
resolveBreaks(tree, prevPendingExits);
}
public void visitForLoop(JCForLoop tree) {
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+ ListBuffer<P> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL;
int nextadrPrev = nextadr;
scan(tree.init);
final Bits initsSkip = new Bits(true);
final Bits uninitsSkip = new Bits(true);
- pendingExits = new ListBuffer<AssignPendingExit>();
- int prevErrors = log.nerrors;
+ pendingExits = new ListBuffer<P>();
+ int prevErrors = getLogNumberOfErrors();
do {
final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr);
@@ -1866,7 +1907,7 @@
initsSkip.assign(initsWhenFalse);
uninitsSkip.assign(uninitsWhenFalse);
}
- inits.assign(initsWhenTrue);
+ assignToInits(tree.body, initsWhenTrue);
uninits.assign(uninitsWhenTrue);
} else if (!flowKind.isFinal()) {
initsSkip.assign(inits);
@@ -1877,7 +1918,7 @@
scan(tree.body);
resolveContinues(tree);
scan(tree.step);
- if (log.nerrors != prevErrors ||
+ if (getLogNumberOfErrors() != prevErrors ||
flowKind.isFinal() ||
new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
break;
@@ -1887,7 +1928,7 @@
flowKind = prevFlowKind;
//a variable is DA/DU after a for loop, if it's DA/DU assuming the
//branch is not taken AND if it's DA/DU before any break statement
- inits.assign(initsSkip);
+ assignToInits(tree.body, initsSkip);
uninits.assign(uninitsSkip);
resolveBreaks(tree, prevPendingExits);
nextadr = nextadrPrev;
@@ -1896,7 +1937,7 @@
public void visitForeachLoop(JCEnhancedForLoop tree) {
visitVarDef(tree.var);
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
+ ListBuffer<P> prevPendingExits = pendingExits;
FlowKind prevFlowKind = flowKind;
flowKind = FlowKind.NORMAL;
int nextadrPrev = nextadr;
@@ -1905,14 +1946,14 @@
final Bits uninitsStart = new Bits(uninits);
letInit(tree.pos(), tree.var.sym);
- pendingExits = new ListBuffer<AssignPendingExit>();
- int prevErrors = log.nerrors;
+ pendingExits = new ListBuffer<P>();
+ int prevErrors = getLogNumberOfErrors();
do {
final Bits uninitsEntry = new Bits(uninits);
uninitsEntry.excludeFrom(nextadr);
scan(tree.body);
resolveContinues(tree);
- if (log.nerrors != prevErrors ||
+ if (getLogNumberOfErrors() != prevErrors ||
flowKind.isFinal() ||
new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
break;
@@ -1920,41 +1961,50 @@
flowKind = FlowKind.SPECULATIVE_LOOP;
} while (true);
flowKind = prevFlowKind;
- inits.assign(initsStart);
+ assignToInits(tree.body, initsStart);
uninits.assign(uninitsStart.andSet(uninits));
resolveBreaks(tree, prevPendingExits);
nextadr = nextadrPrev;
}
public void visitLabelled(JCLabeledStatement tree) {
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ ListBuffer<P> prevPendingExits = pendingExits;
+ pendingExits = new ListBuffer<P>();
scan(tree.body);
resolveBreaks(tree, prevPendingExits);
}
public void visitSwitch(JCSwitch tree) {
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ ListBuffer<P> prevPendingExits = pendingExits;
+ pendingExits = new ListBuffer<>();
int nextadrPrev = nextadr;
scanExpr(tree.selector);
final Bits initsSwitch = new Bits(inits);
final Bits uninitsSwitch = new Bits(uninits);
boolean hasDefault = false;
for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
- inits.assign(initsSwitch);
+ assignToInits(l.head, initsSwitch);
uninits.assign(uninits.andSet(uninitsSwitch));
JCCase c = l.head;
- if (c.pat == null)
+ if (c.pat == null) {
hasDefault = true;
- else
+ } else {
scanExpr(c.pat);
+ }
+ if (hasDefault) {
+ assignToInits(null, initsSwitch);
+ uninits.assign(uninits.andSet(uninitsSwitch));
+ }
scan(c.stats);
addVars(c.stats, initsSwitch, uninitsSwitch);
+ if (!hasDefault) {
+ assignToInits(l.head.stats.last(), initsSwitch);
+ uninits.assign(uninits.andSet(uninitsSwitch));
+ }
// Warn about fall-through if lint switch fallthrough enabled.
}
if (!hasDefault) {
- inits.andSet(initsSwitch);
+ andSetInits(null, initsSwitch);
}
resolveBreaks(tree, prevPendingExits);
nextadr = nextadrPrev;
@@ -1973,11 +2023,17 @@
}
}
+ boolean isEnabled(Lint.LintCategory lc) {
+ return false;
+ }
+
+ void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {}
+
public void visitTry(JCTry tree) {
ListBuffer<JCVariableDecl> resourceVarDecls = ListBuffer.lb();
final Bits uninitsTryPrev = new Bits(uninitsTry);
- ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ ListBuffer<P> prevPendingExits = pendingExits;
+ pendingExits = new ListBuffer<>();
final Bits initsTry = new Bits(inits);
uninitsTry.assign(uninits);
for (JCTree resource : tree.resources) {
@@ -1999,10 +2055,10 @@
int nextadrCatch = nextadr;
if (!resourceVarDecls.isEmpty() &&
- lint.isEnabled(Lint.LintCategory.TRY)) {
+ isEnabled(Lint.LintCategory.TRY)) {
for (JCVariableDecl resVar : resourceVarDecls) {
if (unrefdResources.includes(resVar.sym)) {
- log.warning(Lint.LintCategory.TRY, resVar.pos(),
+ reportWarning(Lint.LintCategory.TRY, resVar.pos(),
"try.resource.not.referenced", resVar.sym);
unrefdResources.remove(resVar.sym);
}
@@ -2018,20 +2074,22 @@
for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
JCVariableDecl param = l.head.param;
- inits.assign(initsCatchPrev);
+ assignToInits(tree.body, initsCatchPrev);
uninits.assign(uninitsCatchPrev);
scan(param);
- inits.incl(param.sym.adr);
- uninits.excl(param.sym.adr);
+ /* If this is a TWR and we are executing the code from Gen,
+ * then there can be synthetic variables, ignore them.
+ */
+ initParam(param);
scan(l.head.body);
initsEnd.andSet(inits);
uninitsEnd.andSet(uninits);
nextadr = nextadrCatch;
}
if (tree.finalizer != null) {
- inits.assign(initsTry);
+ assignToInits(tree.finalizer, initsTry);
uninits.assign(uninitsTry);
- ListBuffer<AssignPendingExit> exits = pendingExits;
+ ListBuffer<P> exits = pendingExits;
pendingExits = prevPendingExits;
scan(tree.finalizer);
if (!tree.finallyCanCompleteNormally) {
@@ -2041,19 +2099,19 @@
// FIX: this doesn't preserve source order of exits in catch
// versus finally!
while (exits.nonEmpty()) {
- AssignPendingExit exit = exits.next();
+ P exit = exits.next();
if (exit.exit_inits != null) {
exit.exit_inits.orSet(inits);
exit.exit_uninits.andSet(uninits);
}
pendingExits.append(exit);
}
- inits.orSet(initsEnd);
+ orSetInits(tree, initsEnd);
}
} else {
- inits.assign(initsEnd);
+ assignToInits(tree, initsEnd);
uninits.assign(uninitsEnd);
- ListBuffer<AssignPendingExit> exits = pendingExits;
+ ListBuffer<P> exits = pendingExits;
pendingExits = prevPendingExits;
while (exits.nonEmpty()) pendingExits.append(exits.next());
}
@@ -2064,7 +2122,7 @@
scanCond(tree.cond);
final Bits initsBeforeElse = new Bits(initsWhenFalse);
final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
- inits.assign(initsWhenTrue);
+ assignToInits(tree.cond, initsWhenTrue);
uninits.assign(uninitsWhenTrue);
if (tree.truepart.type.hasTag(BOOLEAN) &&
tree.falsepart.type.hasTag(BOOLEAN)) {
@@ -2077,7 +2135,7 @@
final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse);
final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue);
final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse);
- inits.assign(initsBeforeElse);
+ assignToInits(tree.truepart, initsBeforeElse);
uninits.assign(uninitsBeforeElse);
scanCond(tree.falsepart);
initsWhenTrue.andSet(initsAfterThenWhenTrue);
@@ -2088,10 +2146,10 @@
scanExpr(tree.truepart);
final Bits initsAfterThen = new Bits(inits);
final Bits uninitsAfterThen = new Bits(uninits);
- inits.assign(initsBeforeElse);
+ assignToInits(tree.truepart, initsBeforeElse);
uninits.assign(uninitsBeforeElse);
scanExpr(tree.falsepart);
- inits.andSet(initsAfterThen);
+ andSetInits(tree.falsepart, initsAfterThen);
uninits.andSet(uninitsAfterThen);
}
}
@@ -2100,39 +2158,46 @@
scanCond(tree.cond);
final Bits initsBeforeElse = new Bits(initsWhenFalse);
final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
- inits.assign(initsWhenTrue);
+ assignToInits(tree.cond, initsWhenTrue);
uninits.assign(uninitsWhenTrue);
scan(tree.thenpart);
if (tree.elsepart != null) {
final Bits initsAfterThen = new Bits(inits);
final Bits uninitsAfterThen = new Bits(uninits);
- inits.assign(initsBeforeElse);
+ assignToInits(tree.thenpart, initsBeforeElse);
uninits.assign(uninitsBeforeElse);
scan(tree.elsepart);
- inits.andSet(initsAfterThen);
+ andSetInits(tree.elsepart, initsAfterThen);
uninits.andSet(uninitsAfterThen);
} else {
- inits.andSet(initsBeforeElse);
+ andSetInits(tree.thenpart, initsBeforeElse);
uninits.andSet(uninitsBeforeElse);
}
}
+ protected P createNewPendingExit(JCTree tree, Bits inits, Bits uninits) {
+ return null;
+ }
+
+ @Override
public void visitBreak(JCBreak tree) {
- recordExit(tree, new AssignPendingExit(tree, inits, uninits));
+ recordExit(tree, createNewPendingExit(tree, inits, uninits));
}
+ @Override
public void visitContinue(JCContinue tree) {
- recordExit(tree, new AssignPendingExit(tree, inits, uninits));
+ recordExit(tree, createNewPendingExit(tree, inits, uninits));
}
+ @Override
public void visitReturn(JCReturn tree) {
scanExpr(tree.expr);
- recordExit(tree, new AssignPendingExit(tree, inits, uninits));
+ recordExit(tree, createNewPendingExit(tree, inits, uninits));
}
public void visitThrow(JCThrow tree) {
scanExpr(tree.expr);
- markDead();
+ markDead(tree.expr);
}
public void visitApply(JCMethodInvocation tree) {
@@ -2151,10 +2216,10 @@
final Bits prevUninits = new Bits(uninits);
final Bits prevInits = new Bits(inits);
int returnadrPrev = returnadr;
- ListBuffer<AssignPendingExit> prevPending = pendingExits;
+ ListBuffer<P> prevPending = pendingExits;
try {
returnadr = nextadr;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ pendingExits = new ListBuffer<P>();
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
JCVariableDecl def = l.head;
scan(def);
@@ -2170,7 +2235,7 @@
finally {
returnadr = returnadrPrev;
uninits.assign(prevUninits);
- inits.assign(prevInits);
+ assignToInits(tree, prevInits);
pendingExits = prevPending;
}
}
@@ -2186,11 +2251,11 @@
scanCond(tree.cond);
uninitsExit.andSet(uninitsWhenTrue);
if (tree.detail != null) {
- inits.assign(initsWhenFalse);
+ assignToInits(tree, initsWhenFalse);
uninits.assign(uninitsWhenFalse);
scanExpr(tree.detail);
}
- inits.assign(initsExit);
+ assignToInits(tree, initsExit);
uninits.assign(uninitsExit);
}
@@ -2236,7 +2301,7 @@
scanCond(tree.lhs);
final Bits initsWhenFalseLeft = new Bits(initsWhenFalse);
final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse);
- inits.assign(initsWhenTrue);
+ assignToInits(tree.lhs, initsWhenTrue);
uninits.assign(uninitsWhenTrue);
scanCond(tree.rhs);
initsWhenFalse.andSet(initsWhenFalseLeft);
@@ -2246,7 +2311,7 @@
scanCond(tree.lhs);
final Bits initsWhenTrueLeft = new Bits(initsWhenTrue);
final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue);
- inits.assign(initsWhenFalse);
+ assignToInits(tree.lhs, initsWhenFalse);
uninits.assign(uninitsWhenFalse);
scanCond(tree.rhs);
initsWhenTrue.andSet(initsWhenTrueLeft);
@@ -2284,14 +2349,12 @@
/** Perform definite assignment/unassignment analysis on a tree.
*/
- public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
- analyzeTree(env, env.tree, make);
- }
+ public void analyzeTree(Env<?> env) {
+ analyzeTree(env, env.tree);
+ }
- public void analyzeTree(Env<AttrContext> env, JCTree tree, TreeMaker make) {
+ public void analyzeTree(Env<?> env, JCTree tree) {
try {
- attrEnv = env;
- Flow.this.make = make;
startPos = tree.pos().getStartPosition();
if (vardecls == null)
@@ -2301,7 +2364,7 @@
vardecls[i] = null;
firstadr = 0;
nextadr = 0;
- pendingExits = new ListBuffer<AssignPendingExit>();
+ pendingExits = new ListBuffer<>();
this.classDef = null;
unrefdResources = new Scope(env.enclClass.sym);
scan(tree);
@@ -2310,18 +2373,160 @@
startPos = -1;
resetBits(inits, uninits, uninitsTry, initsWhenTrue,
initsWhenFalse, uninitsWhenTrue, uninitsWhenFalse);
- if (vardecls != null) for (int i=0; i<vardecls.length; i++)
- vardecls[i] = null;
+ if (vardecls != null) {
+ for (int i=0; i<vardecls.length; i++)
+ vardecls[i] = null;
+ }
firstadr = 0;
nextadr = 0;
pendingExits = null;
- Flow.this.make = null;
this.classDef = null;
unrefdResources = null;
}
}
}
+ public static class AssignAnalyzer
+ extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> {
+
+ Log log;
+ Lint lint;
+
+ public static class AssignPendingExit
+ extends AbstractAssignAnalyzer.AbstractAssignPendingExit {
+
+ public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
+ super(tree, inits, uninits);
+ }
+ }
+
+ public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names) {
+ super(new Bits(), syms, names);
+ this.log = log;
+ this.lint = lint;
+ }
+
+ @Override
+ protected AssignPendingExit createNewPendingExit(JCTree tree,
+ Bits inits, Bits uninits) {
+ return new AssignPendingExit(tree, inits, uninits);
+ }
+
+ /** Record an initialization of a trackable variable.
+ */
+ @Override
+ void letInit(DiagnosticPosition pos, VarSymbol sym) {
+ if (sym.adr >= firstadr && trackable(sym)) {
+ if ((sym.flags() & EFFECTIVELY_FINAL) != 0) {
+ if (!uninits.isMember(sym.adr)) {
+ //assignment targeting an effectively final variable
+ //makes the variable lose its status of effectively final
+ //if the variable is _not_ definitively unassigned
+ sym.flags_field &= ~EFFECTIVELY_FINAL;
+ } else {
+ uninit(sym);
+ }
+ }
+ else if ((sym.flags() & FINAL) != 0) {
+ if ((sym.flags() & PARAMETER) != 0) {
+ if ((sym.flags() & UNION) != 0) { //multi-catch parameter
+ log.error(pos, "multicatch.parameter.may.not.be.assigned", sym);
+ }
+ else {
+ log.error(pos, "final.parameter.may.not.be.assigned",
+ sym);
+ }
+ } else if (!uninits.isMember(sym.adr)) {
+ log.error(pos, flowKind.errKey, sym);
+ } else {
+ uninit(sym);
+ }
+ }
+ inits.incl(sym.adr);
+ } else if ((sym.flags() & FINAL) != 0) {
+ log.error(pos, "var.might.already.be.assigned", sym);
+ }
+ }
+
+ @Override
+ void checkInit(DiagnosticPosition pos, VarSymbol sym, String errkey) {
+ if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
+ trackable(sym) &&
+ !inits.isMember(sym.adr)) {
+ log.error(pos, errkey, sym);
+ inits.incl(sym.adr);
+ }
+ }
+
+ @Override
+ void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos,
+ String key, Object ... args) {
+ log.warning(lc, pos, key, args);
+ }
+
+ @Override
+ int getLogNumberOfErrors() {
+ return log.nerrors;
+ }
+
+ @Override
+ boolean isEnabled(Lint.LintCategory lc) {
+ return lint.isEnabled(lc);
+ }
+
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ if (tree.sym == null) {
+ return;
+ }
+
+ Lint lintPrev = lint;
+ lint = lint.augment(tree.sym);
+ try {
+ super.visitClassDef(tree);
+ } finally {
+ lint = lintPrev;
+ }
+ }
+
+ @Override
+ public void visitMethodDef(JCMethodDecl tree) {
+ if (tree.body == null) {
+ return;
+ }
+
+ /* MemberEnter can generate synthetic methods ignore them
+ */
+ if ((tree.sym.flags() & SYNTHETIC) != 0) {
+ return;
+ }
+
+ Lint lintPrev = lint;
+ lint = lint.augment(tree.sym);
+ try {
+ super.visitMethodDef(tree);
+ } finally {
+ lint = lintPrev;
+ }
+ }
+
+ @Override
+ public void visitVarDef(JCVariableDecl tree) {
+ if (tree.init == null) {
+ super.visitVarDef(tree);
+ } else {
+ Lint lintPrev = lint;
+ lint = lint.augment(tree.sym);
+ try{
+ super.visitVarDef(tree);
+ } finally {
+ lint = lintPrev;
+ }
+ }
+ }
+
+ }
+
/**
* This pass implements the last step of the dataflow analysis, namely
* the effectively-final analysis check. This checks that every local variable
@@ -2334,7 +2539,7 @@
JCTree currentTree; //local class or lambda
@Override
- void markDead() {
+ void markDead(JCTree tree) {
//do nothing
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Sep 17 08:21:11 2013 -0700
@@ -40,17 +40,17 @@
import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph.Node;
import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
-
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
+import com.sun.tools.javac.util.GraphUtils.TarjanNode;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.EnumMap;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
import static com.sun.tools.javac.code.TypeTag.*;
@@ -114,6 +114,12 @@
}
@Override
+ InapplicableMethodException setMessage() {
+ //no message to set
+ return this;
+ }
+
+ @Override
InapplicableMethodException setMessage(JCDiagnostic diag) {
messages = messages.append(diag);
return this;
@@ -1006,10 +1012,24 @@
* and (ii) tell th engine when we are done fixing inference variables
*/
interface GraphStrategy {
+
+ /**
+ * A NodeNotFoundException is thrown whenever an inference strategy fails
+ * to pick the next node to solve in the inference graph.
+ */
+ public static class NodeNotFoundException extends RuntimeException {
+ private static final long serialVersionUID = 0;
+
+ InferenceGraph graph;
+
+ public NodeNotFoundException(InferenceGraph graph) {
+ this.graph = graph;
+ }
+ }
/**
* Pick the next node (leaf) to solve in the graph
*/
- Node pickNode(InferenceGraph g);
+ Node pickNode(InferenceGraph g) throws NodeNotFoundException;
/**
* Is this the last step?
*/
@@ -1022,7 +1042,10 @@
*/
abstract class LeafSolver implements GraphStrategy {
public Node pickNode(InferenceGraph g) {
- Assert.check(!g.nodes.isEmpty(), "No nodes to solve!");
+ if (g.nodes.isEmpty()) {
+ //should not happen
+ throw new NodeNotFoundException(g);
+ };
return g.nodes.get(0);
}
@@ -1069,6 +1092,7 @@
*/
abstract class BestLeafSolver extends LeafSolver {
+ /** list of ivars of which at least one must be solved */
List<Type> varsToSolve;
BestLeafSolver(List<Type> varsToSolve) {
@@ -1076,54 +1100,66 @@
}
/**
- * Computes the minimum path that goes from a given node to any of the nodes
- * containing a variable in {@code varsToSolve}. For any given path, the cost
- * is computed as the total number of type-variables that should be eagerly
- * instantiated across that path.
+ * Computes a path that goes from a given node to the leafs in the graph.
+ * Typically this will start from a node containing a variable in
+ * {@code varsToSolve}. For any given path, the cost is computed as the total
+ * number of type-variables that should be eagerly instantiated across that path.
*/
- int computeMinPath(InferenceGraph g, Node n) {
- return computeMinPath(g, n, List.<Node>nil(), 0);
+ Pair<List<Node>, Integer> computeTreeToLeafs(Node n) {
+ Pair<List<Node>, Integer> cachedPath = treeCache.get(n);
+ if (cachedPath == null) {
+ //cache miss
+ if (n.isLeaf()) {
+ //if leaf, stop
+ cachedPath = new Pair<List<Node>, Integer>(List.of(n), n.data.length());
+ } else {
+ //if non-leaf, proceed recursively
+ Pair<List<Node>, Integer> path = new Pair<List<Node>, Integer>(List.of(n), n.data.length());
+ for (Node n2 : n.getAllDependencies()) {
+ if (n2 == n) continue;
+ Pair<List<Node>, Integer> subpath = computeTreeToLeafs(n2);
+ path = new Pair<List<Node>, Integer>(
+ path.fst.prependList(subpath.fst),
+ path.snd + subpath.snd);
+ }
+ cachedPath = path;
+ }
+ //save results in cache
+ treeCache.put(n, cachedPath);
+ }
+ return cachedPath;
}
- int computeMinPath(InferenceGraph g, Node n, List<Node> path, int cost) {
- if (path.contains(n)) return Integer.MAX_VALUE;
- List<Node> path2 = path.prepend(n);
- int cost2 = cost + n.data.size();
- if (!Collections.disjoint(n.data, varsToSolve)) {
- return cost2;
- } else {
- int bestPath = Integer.MAX_VALUE;
- for (Node n2 : g.nodes) {
- if (n2.deps.contains(n)) {
- int res = computeMinPath(g, n2, path2, cost2);
- if (res < bestPath) {
- bestPath = res;
- }
- }
- }
- return bestPath;
- }
- }
+ /** cache used to avoid redundant computation of tree costs */
+ final Map<Node, Pair<List<Node>, Integer>> treeCache =
+ new HashMap<Node, Pair<List<Node>, Integer>>();
+
+ /** constant value used to mark non-existent paths */
+ final Pair<List<Node>, Integer> noPath =
+ new Pair<List<Node>, Integer>(null, Integer.MAX_VALUE);
/**
* Pick the leaf that minimize cost
*/
@Override
public Node pickNode(final InferenceGraph g) {
- final Map<Node, Integer> leavesMap = new HashMap<Node, Integer>();
+ treeCache.clear(); //graph changes at every step - cache must be cleared
+ Pair<List<Node>, Integer> bestPath = noPath;
for (Node n : g.nodes) {
- if (n.isLeaf(n)) {
- leavesMap.put(n, computeMinPath(g, n));
+ if (!Collections.disjoint(n.data, varsToSolve)) {
+ Pair<List<Node>, Integer> path = computeTreeToLeafs(n);
+ //discard all paths containing at least a node in the
+ //closure computed above
+ if (path.snd < bestPath.snd) {
+ bestPath = path;
+ }
}
}
- Assert.check(!leavesMap.isEmpty(), "No nodes to solve!");
- TreeSet<Node> orderedLeaves = new TreeSet<Node>(new Comparator<Node>() {
- public int compare(Node n1, Node n2) {
- return leavesMap.get(n1) - leavesMap.get(n2);
- }
- });
- orderedLeaves.addAll(leavesMap.keySet());
- return orderedLeaves.first();
+ if (bestPath == noPath) {
+ //no path leads there
+ throw new NodeNotFoundException(g);
+ }
+ return bestPath.fst.head;
}
}
@@ -1321,6 +1357,33 @@
}
/**
+ * There are two kinds of dependencies between inference variables. The basic
+ * kind of dependency (or bound dependency) arises when a variable mention
+ * another variable in one of its bounds. There's also a more subtle kind
+ * of dependency that arises when a variable 'might' lead to better constraints
+ * on another variable (this is typically the case with variables holding up
+ * stuck expressions).
+ */
+ enum DependencyKind implements GraphUtils.DependencyKind {
+
+ /** bound dependency */
+ BOUND("dotted"),
+ /** stuck dependency */
+ STUCK("dashed");
+
+ final String dotSyle;
+
+ private DependencyKind(String dotSyle) {
+ this.dotSyle = dotSyle;
+ }
+
+ @Override
+ public String getDotStyle() {
+ return dotSyle;
+ }
+ }
+
+ /**
* This is the graph inference solver - the solver organizes all inference variables in
* a given inference context by bound dependencies - in the general case, such dependencies
* would lead to a cyclic directed graph (hence the name); the dependency info is used to build
@@ -1331,10 +1394,12 @@
class GraphSolver {
InferenceContext inferenceContext;
+ Map<Type, Set<Type>> stuckDeps;
Warner warn;
- GraphSolver(InferenceContext inferenceContext, Warner warn) {
+ GraphSolver(InferenceContext inferenceContext, Map<Type, Set<Type>> stuckDeps, Warner warn) {
this.inferenceContext = inferenceContext;
+ this.stuckDeps = stuckDeps;
this.warn = warn;
}
@@ -1345,7 +1410,7 @@
*/
void solve(GraphStrategy sstrategy) {
checkWithinBounds(inferenceContext, warn); //initial propagation of bounds
- InferenceGraph inferenceGraph = new InferenceGraph();
+ InferenceGraph inferenceGraph = new InferenceGraph(stuckDeps);
while (!sstrategy.done()) {
InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph);
List<Type> varsToSolve = List.from(nodeToSolve.data);
@@ -1390,64 +1455,172 @@
*/
class Node extends GraphUtils.TarjanNode<ListBuffer<Type>> {
- Set<Node> deps;
+ /** map listing all dependencies (grouped by kind) */
+ EnumMap<DependencyKind, Set<Node>> deps;
Node(Type ivar) {
super(ListBuffer.of(ivar));
- this.deps = new HashSet<Node>();
+ this.deps = new EnumMap<DependencyKind, Set<Node>>(DependencyKind.class);
+ }
+
+ @Override
+ public GraphUtils.DependencyKind[] getSupportedDependencyKinds() {
+ return DependencyKind.values();
}
@Override
- public Iterable<? extends Node> getDependencies() {
- return deps;
+ public String getDependencyName(GraphUtils.Node<ListBuffer<Type>> to, GraphUtils.DependencyKind dk) {
+ if (dk == DependencyKind.STUCK) return "";
+ else {
+ StringBuilder buf = new StringBuilder();
+ String sep = "";
+ for (Type from : data) {
+ UndetVar uv = (UndetVar)inferenceContext.asFree(from);
+ for (Type bound : uv.getBounds(InferenceBound.values())) {
+ if (bound.containsAny(List.from(to.data))) {
+ buf.append(sep);
+ buf.append(bound);
+ sep = ",";
+ }
+ }
+ }
+ return buf.toString();
+ }
+ }
+
+ @Override
+ public Iterable<? extends Node> getAllDependencies() {
+ return getDependencies(DependencyKind.values());
}
@Override
- public String printDependency(GraphUtils.Node<ListBuffer<Type>> to) {
- StringBuilder buf = new StringBuilder();
- String sep = "";
- for (Type from : data) {
- UndetVar uv = (UndetVar)inferenceContext.asFree(from);
- for (Type bound : uv.getBounds(InferenceBound.values())) {
- if (bound.containsAny(List.from(to.data))) {
- buf.append(sep);
- buf.append(bound);
- sep = ",";
- }
+ public Iterable<? extends TarjanNode<ListBuffer<Type>>> getDependenciesByKind(GraphUtils.DependencyKind dk) {
+ return getDependencies((DependencyKind)dk);
+ }
+
+ /**
+ * Retrieves all dependencies with given kind(s).
+ */
+ protected Set<Node> getDependencies(DependencyKind... depKinds) {
+ Set<Node> buf = new LinkedHashSet<Node>();
+ for (DependencyKind dk : depKinds) {
+ Set<Node> depsByKind = deps.get(dk);
+ if (depsByKind != null) {
+ buf.addAll(depsByKind);
}
}
- return buf.toString();
+ return buf;
+ }
+
+ /**
+ * Adds dependency with given kind.
+ */
+ protected void addDependency(DependencyKind dk, Node depToAdd) {
+ Set<Node> depsByKind = deps.get(dk);
+ if (depsByKind == null) {
+ depsByKind = new LinkedHashSet<Node>();
+ deps.put(dk, depsByKind);
+ }
+ depsByKind.add(depToAdd);
+ }
+
+ /**
+ * Add multiple dependencies of same given kind.
+ */
+ protected void addDependencies(DependencyKind dk, Set<Node> depsToAdd) {
+ for (Node n : depsToAdd) {
+ addDependency(dk, n);
+ }
+ }
+
+ /**
+ * Remove a dependency, regardless of its kind.
+ */
+ protected Set<DependencyKind> removeDependency(Node n) {
+ Set<DependencyKind> removedKinds = new HashSet<>();
+ for (DependencyKind dk : DependencyKind.values()) {
+ Set<Node> depsByKind = deps.get(dk);
+ if (depsByKind == null) continue;
+ if (depsByKind.remove(n)) {
+ removedKinds.add(dk);
+ }
+ }
+ return removedKinds;
}
- boolean isLeaf(Node n) {
- //no deps, or only one self dep
- return (n.deps.isEmpty() ||
- n.deps.size() == 1 && n.deps.contains(n));
+ /**
+ * Compute closure of a give node, by recursively walking
+ * through all its dependencies (of given kinds)
+ */
+ protected Set<Node> closure(DependencyKind... depKinds) {
+ boolean progress = true;
+ Set<Node> closure = new HashSet<Node>();
+ closure.add(this);
+ while (progress) {
+ progress = false;
+ for (Node n1 : new HashSet<Node>(closure)) {
+ progress = closure.addAll(n1.getDependencies(depKinds));
+ }
+ }
+ return closure;
}
- void mergeWith(List<? extends Node> nodes) {
+ /**
+ * Is this node a leaf? This means either the node has no dependencies,
+ * or it just has self-dependencies.
+ */
+ protected boolean isLeaf() {
+ //no deps, or only one self dep
+ Set<Node> allDeps = getDependencies(DependencyKind.BOUND, DependencyKind.STUCK);
+ if (allDeps.isEmpty()) return true;
+ for (Node n : allDeps) {
+ if (n != this) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Merge this node with another node, acquiring its dependencies.
+ * This routine is used to merge all cyclic node together and
+ * form an acyclic graph.
+ */
+ protected void mergeWith(List<? extends Node> nodes) {
for (Node n : nodes) {
Assert.check(n.data.length() == 1, "Attempt to merge a compound node!");
data.appendList(n.data);
- deps.addAll(n.deps);
+ for (DependencyKind dk : DependencyKind.values()) {
+ addDependencies(dk, n.getDependencies(dk));
+ }
}
//update deps
- Set<Node> deps2 = new HashSet<Node>();
- for (Node d : deps) {
- if (data.contains(d.data.first())) {
- deps2.add(this);
- } else {
- deps2.add(d);
+ EnumMap<DependencyKind, Set<Node>> deps2 = new EnumMap<DependencyKind, Set<Node>>(DependencyKind.class);
+ for (DependencyKind dk : DependencyKind.values()) {
+ for (Node d : getDependencies(dk)) {
+ Set<Node> depsByKind = deps2.get(dk);
+ if (depsByKind == null) {
+ depsByKind = new LinkedHashSet<Node>();
+ deps2.put(dk, depsByKind);
+ }
+ if (data.contains(d.data.first())) {
+ depsByKind.add(this);
+ } else {
+ depsByKind.add(d);
+ }
}
}
deps = deps2;
}
- void graphChanged(Node from, Node to) {
- if (deps.contains(from)) {
- deps.remove(from);
+ /**
+ * Notify all nodes that something has changed in the graph
+ * topology.
+ */
+ private void graphChanged(Node from, Node to) {
+ for (DependencyKind dk : removeDependency(from)) {
if (to != null) {
- deps.add(to);
+ addDependency(dk, to);
}
}
}
@@ -1456,8 +1629,21 @@
/** the nodes in the inference graph */
ArrayList<Node> nodes;
- InferenceGraph() {
- initNodes();
+ InferenceGraph(Map<Type, Set<Type>> optDeps) {
+ initNodes(optDeps);
+ }
+
+ /**
+ * Basic lookup helper for retrieving a graph node given an inference
+ * variable type.
+ */
+ public Node findNode(Type t) {
+ for (Node n : nodes) {
+ if (n.data.contains(t)) {
+ return n;
+ }
+ }
+ return null;
}
/**
@@ -1484,24 +1670,32 @@
* Create the graph nodes. First a simple node is created for every inference
* variables to be solved. Then Tarjan is used to found all connected components
* in the graph. For each component containing more than one node, a super node is
- * created, effectively replacing the original cyclic nodes.
+ * created, effectively replacing the original cyclic nodes.
*/
- void initNodes() {
+ void initNodes(Map<Type, Set<Type>> stuckDeps) {
+ //add nodes
nodes = new ArrayList<Node>();
for (Type t : inferenceContext.restvars()) {
nodes.add(new Node(t));
}
+ //add dependencies
for (Node n_i : nodes) {
Type i = n_i.data.first();
+ Set<Type> optDepsByNode = stuckDeps.get(i);
for (Node n_j : nodes) {
Type j = n_j.data.first();
UndetVar uv_i = (UndetVar)inferenceContext.asFree(i);
if (Type.containsAny(uv_i.getBounds(InferenceBound.values()), List.of(j))) {
- //update i's deps
- n_i.deps.add(n_j);
+ //update i's bound dependencies
+ n_i.addDependency(DependencyKind.BOUND, n_j);
+ }
+ if (optDepsByNode != null && optDepsByNode.contains(j)) {
+ //update i's stuck dependencies
+ n_i.addDependency(DependencyKind.STUCK, n_j);
}
}
}
+ //merge cyclic nodes
ArrayList<Node> acyclicNodes = new ArrayList<Node>();
for (List<? extends Node> conSubGraph : GraphUtils.tarjan(nodes)) {
if (conSubGraph.length() > 1) {
@@ -1631,8 +1825,8 @@
return filterVars(new Filter<UndetVar>() {
public boolean accepts(UndetVar uv) {
return uv.getBounds(InferenceBound.UPPER)
- .diff(uv.getDeclaredBounds())
- .appendList(uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)).nonEmpty();
+ .diff(uv.getDeclaredBounds())
+ .appendList(uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)).nonEmpty();
}
});
}
@@ -1822,11 +2016,15 @@
}
}
+ private void solve(GraphStrategy ss, Warner warn) {
+ solve(ss, new HashMap<Type, Set<Type>>(), warn);
+ }
+
/**
* Solve with given graph strategy.
*/
- private void solve(GraphStrategy ss, Warner warn) {
- GraphSolver s = new GraphSolver(this, warn);
+ private void solve(GraphStrategy ss, Map<Type, Set<Type>> stuckDeps, Warner warn) {
+ GraphSolver s = new GraphSolver(this, stuckDeps, warn);
s.solve(ss);
}
@@ -1855,18 +2053,12 @@
/**
* Solve at least one variable in given list.
*/
- public void solveAny(List<Type> varsToSolve, Warner warn) {
- checkWithinBounds(this, warn); //propagate bounds
- List<Type> boundedVars = boundedVars().intersect(restvars()).intersect(varsToSolve);
- if (boundedVars.isEmpty()) {
- throw inferenceException.setMessage("cyclic.inference",
- freeVarsIn(varsToSolve));
- }
- solve(new BestLeafSolver(boundedVars) {
+ public void solveAny(List<Type> varsToSolve, Map<Type, Set<Type>> optDeps, Warner warn) {
+ solve(new BestLeafSolver(varsToSolve.intersect(restvars())) {
public boolean done() {
return instvars().intersect(varsToSolve).nonEmpty();
}
- }, warn);
+ }, optDeps, warn);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Sep 17 08:21:11 2013 -0700
@@ -1745,6 +1745,11 @@
// Just erase the type var
ret = new VarSymbol(sym.flags(), name,
types.erasure(sym.type), sym.owner);
+
+ /* this information should also be kept for LVT generation at Gen
+ * a Symbol with pos < startPos won't be tracked.
+ */
+ ((VarSymbol)ret).pos = ((VarSymbol)sym).pos;
break;
case CAPTURED_VAR:
ret = new VarSymbol(SYNTHETIC | FINAL, name, types.erasure(sym.type), translatedSym) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Sep 17 08:21:11 2013 -0700
@@ -49,7 +49,6 @@
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.jvm.ByteCodes.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
-import javax.lang.model.type.TypeKind;
/** This pass translates away some syntactic sugar: inner classes,
* class literals, assertions, foreach loops, etc.
@@ -1480,7 +1479,12 @@
* @param owner The class in which the definitions go.
*/
List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner) {
- long flags = FINAL | SYNTHETIC;
+ return freevarDefs(pos, freevars, owner, 0);
+ }
+
+ List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
+ long additionalFlags) {
+ long flags = FINAL | SYNTHETIC | additionalFlags;
if (owner.kind == TYP &&
target.usePrivateSyntheticFields())
flags |= PRIVATE;
@@ -1543,7 +1547,7 @@
(owner.isConstructor() && c.isInner() &&
!c.isPrivate() && !c.isStatic());
long flags =
- FINAL | (isMandated ? MANDATED : SYNTHETIC);
+ FINAL | (isMandated ? MANDATED : SYNTHETIC) | PARAMETER;
VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
owner.extraParams = owner.extraParams.prepend(outerThis);
return makeOuterThisVarDecl(pos, outerThis);
@@ -1627,7 +1631,8 @@
JCTree makeTwrTry(JCTry tree) {
make_at(tree.pos());
twrVars = twrVars.dup();
- JCBlock twrBlock = makeTwrBlock(tree.resources, tree.body, 0);
+ JCBlock twrBlock = makeTwrBlock(tree.resources, tree.body,
+ tree.finallyCanCompleteNormally, 0);
if (tree.catchers.isEmpty() && tree.finalizer == null)
result = translate(twrBlock);
else
@@ -1636,7 +1641,8 @@
return result;
}
- private JCBlock makeTwrBlock(List<JCTree> resources, JCBlock block, int depth) {
+ private JCBlock makeTwrBlock(List<JCTree> resources, JCBlock block,
+ boolean finallyCanCompleteNormally, int depth) {
if (resources.isEmpty())
return block;
@@ -1692,17 +1698,20 @@
make.at(TreeInfo.endPos(block));
JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr);
make.at(oldPos);
- JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
+ JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block,
+ finallyCanCompleteNormally, depth + 1),
List.<JCCatch>of(catchClause),
finallyClause);
+ outerTry.finallyCanCompleteNormally = finallyCanCompleteNormally;
stats.add(outerTry);
- return make.Block(0L, stats.toList());
+ JCBlock newBlock = make.Block(0L, stats.toList());
+ return newBlock;
}
private JCBlock makeTwrFinallyClause(Symbol primaryException, JCExpression resource) {
// primaryException.addSuppressed(catchException);
VarSymbol catchException =
- new VarSymbol(0, make.paramName(2),
+ new VarSymbol(SYNTHETIC, make.paramName(2),
syms.throwableType,
currentMethodSym);
JCStatement addSuppressionStatement =
@@ -1717,6 +1726,7 @@
JCBlock catchBlock = make.Block(0L, List.<JCStatement>of(addSuppressionStatement));
List<JCCatch> catchClauses = List.<JCCatch>of(make.Catch(catchExceptionDecl, catchBlock));
JCTry tryTree = make.Try(tryBlock, catchClauses, null);
+ tryTree.finallyCanCompleteNormally = true;
// if (primaryException != null) {try...} else resourceClose;
JCIf closeIfStatement = make.If(makeNonNullCheck(make.Ident(primaryException)),
@@ -2017,7 +2027,7 @@
// catchParam := ClassNotFoundException e1
VarSymbol catchParam =
- new VarSymbol(0, make.paramName(1),
+ new VarSymbol(SYNTHETIC, make.paramName(1),
syms.classNotFoundExceptionType,
classDollarSym);
@@ -2705,7 +2715,7 @@
JCVariableDecl otdef = null;
if (currentClass.hasOuterInstance())
otdef = outerThisDef(tree.pos, m);
- List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m);
+ List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m, PARAMETER);
// Recursively translate result type, parameters and thrown list.
tree.restype = translate(tree.restype);
@@ -3364,18 +3374,18 @@
*/
private void visitArrayForeachLoop(JCEnhancedForLoop tree) {
make_at(tree.expr.pos());
- VarSymbol arraycache = new VarSymbol(0,
+ VarSymbol arraycache = new VarSymbol(SYNTHETIC,
names.fromString("arr" + target.syntheticNameChar()),
tree.expr.type,
currentMethodSym);
JCStatement arraycachedef = make.VarDef(arraycache, tree.expr);
- VarSymbol lencache = new VarSymbol(0,
+ VarSymbol lencache = new VarSymbol(SYNTHETIC,
names.fromString("len" + target.syntheticNameChar()),
syms.intType,
currentMethodSym);
JCStatement lencachedef = make.
VarDef(lencache, make.Select(make.Ident(arraycache), syms.lengthVar));
- VarSymbol index = new VarSymbol(0,
+ VarSymbol index = new VarSymbol(SYNTHETIC,
names.fromString("i" + target.syntheticNameChar()),
syms.intType,
currentMethodSym);
@@ -3457,7 +3467,7 @@
names.iterator,
eType,
List.<Type>nil());
- VarSymbol itvar = new VarSymbol(0, names.fromString("i" + target.syntheticNameChar()),
+ VarSymbol itvar = new VarSymbol(SYNTHETIC, names.fromString("i" + target.syntheticNameChar()),
types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym)),
currentMethodSym);
@@ -3830,19 +3840,32 @@
@Override
public void visitTry(JCTry tree) {
- /* special case of try without catchers and with finally emtpy.
- * Don't give it a try, translate only the body.
- */
- if (tree.resources.isEmpty()) {
- if (tree.catchers.isEmpty() &&
- tree.finalizer.getStatements().isEmpty()) {
+ if (tree.resources.nonEmpty()) {
+ result = makeTwrTry(tree);
+ return;
+ }
+
+ boolean hasBody = tree.body.getStatements().nonEmpty();
+ boolean hasCatchers = tree.catchers.nonEmpty();
+ boolean hasFinally = tree.finalizer != null &&
+ tree.finalizer.getStatements().nonEmpty();
+
+ if (!hasCatchers && !hasFinally) {
+ result = translate(tree.body);
+ return;
+ }
+
+ if (!hasBody) {
+ if (hasFinally) {
+ result = translate(tree.finalizer);
+ } else {
result = translate(tree.body);
- } else {
- super.visitTry(tree);
}
- } else {
- result = makeTwrTry(tree);
+ return;
}
+
+ // no optimizations possible
+ super.visitTry(tree);
}
/**************************************************************************
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue Sep 17 08:21:11 2013 -0700
@@ -84,6 +84,7 @@
private final Source source;
private final Target target;
private final DeferredLintHandler deferredLintHandler;
+ private final Lint lint;
public static MemberEnter instance(Context context) {
MemberEnter instance = context.get(memberEnterKey);
@@ -109,6 +110,7 @@
source = Source.instance(context);
target = Target.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
+ lint = Lint.instance(context);
allowTypeAnnos = source.allowTypeAnnotations();
}
@@ -506,9 +508,10 @@
}
// process package annotations
- annotateLater(tree.packageAnnotations, env, tree.packge);
+ annotateLater(tree.packageAnnotations, env, tree.packge, null);
- DeferredLintHandler prevLintHandler = chk.setDeferredLintHandler(DeferredLintHandler.immediateHandler);
+ DiagnosticPosition prevLintPos = deferredLintHandler.immediate();
+ Lint prevLint = chk.setLint(lint);
try {
// Import-on-demand java.lang.
@@ -517,7 +520,8 @@
// Process all import clauses.
memberEnter(tree.defs, env);
} finally {
- chk.setDeferredLintHandler(prevLintHandler);
+ chk.setLint(prevLint);
+ deferredLintHandler.setPos(prevLintPos);
}
}
@@ -564,8 +568,7 @@
Env<AttrContext> localEnv = methodEnv(tree, env);
- DeferredLintHandler prevLintHandler =
- chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
+ DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
try {
// Compute the method type
m.type = signature(m, tree.typarams, tree.params,
@@ -573,7 +576,7 @@
tree.thrown,
localEnv);
} finally {
- chk.setDeferredLintHandler(prevLintHandler);
+ deferredLintHandler.setPos(prevLintPos);
}
if (types.isSignaturePolymorphic(m)) {
@@ -597,10 +600,10 @@
if (chk.checkUnique(tree.pos(), m, enclScope)) {
enclScope.enter(m);
}
- annotateLater(tree.mods.annotations, localEnv, m);
+ annotateLater(tree.mods.annotations, localEnv, m, tree.pos());
// Visit the signature of the method. Note that
// TypeAnnotate doesn't descend into the body.
- typeAnnotate(tree, localEnv, m);
+ typeAnnotate(tree, localEnv, m, tree.pos());
if (tree.defaultValue != null)
annotateDefaultValueLater(tree.defaultValue, localEnv, m);
@@ -630,15 +633,14 @@
localEnv = env.dup(tree, env.info.dup());
localEnv.info.staticLevel++;
}
- DeferredLintHandler prevLintHandler =
- chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
+ DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
try {
if (TreeInfo.isEnumInit(tree)) {
attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
} else {
// Make sure type annotations are processed.
// But we don't have a symbol to attach them to yet - use null.
- typeAnnotate(tree.vartype, env, null);
+ typeAnnotate(tree.vartype, env, null, tree.pos());
attr.attribType(tree.vartype, localEnv);
if (tree.nameexpr != null) {
attr.attribExpr(tree.nameexpr, localEnv);
@@ -658,7 +660,7 @@
}
}
} finally {
- chk.setDeferredLintHandler(prevLintHandler);
+ deferredLintHandler.setPos(prevLintPos);
}
if ((tree.mods.flags & VARARGS) != 0) {
@@ -680,15 +682,15 @@
needsLazyConstValue(tree.init)) {
Env<AttrContext> initEnv = getInitEnv(tree, env);
initEnv.info.enclVar = v;
- v.setLazyConstValue(initEnv(tree, initEnv), attr, tree.init);
+ v.setLazyConstValue(initEnv(tree, initEnv), attr, tree);
}
}
if (chk.checkUnique(tree.pos(), v, enclScope)) {
chk.checkTransparentVar(tree.pos(), v, enclScope);
enclScope.enter(v);
}
- annotateLater(tree.mods.annotations, localEnv, v);
- typeAnnotate(tree.vartype, env, v);
+ annotateLater(tree.mods.annotations, localEnv, v, tree.pos());
+ typeAnnotate(tree.vartype, env, v, tree.pos());
annotate.flush();
v.pos = tree.pos;
}
@@ -720,6 +722,11 @@
}
@Override
+ public void visitNewArray(JCNewArray that) {
+ result = false;
+ }
+
+ @Override
public void visitLambda(JCLambda that) {
result = false;
}
@@ -730,6 +737,11 @@
}
@Override
+ public void visitApply(JCMethodInvocation that) {
+ result = false;
+ }
+
+ @Override
public void visitSelect(JCFieldAccess tree) {
tree.selected.accept(this);
}
@@ -820,7 +832,8 @@
/** Queue annotations for later processing. */
void annotateLater(final List<JCAnnotation> annotations,
final Env<AttrContext> localEnv,
- final Symbol s) {
+ final Symbol s,
+ final DiagnosticPosition deferPos) {
if (annotations.isEmpty()) {
return;
}
@@ -837,6 +850,11 @@
public void enterAnnotation() {
Assert.check(s.kind == PCK || s.annotationsPendingCompletion());
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
+ DiagnosticPosition prevLintPos =
+ deferPos != null
+ ? deferredLintHandler.setPos(deferPos)
+ : deferredLintHandler.immediate();
+ Lint prevLint = deferPos != null ? null : chk.setLint(lint);
try {
if (s.hasAnnotations() &&
annotations.nonEmpty())
@@ -845,6 +863,9 @@
kindName(s), s);
actualEnterAnnotations(annotations, localEnv, s);
} finally {
+ if (prevLint != null)
+ chk.setLint(prevLint);
+ deferredLintHandler.setPos(prevLintPos);
log.useSource(prev);
}
}
@@ -964,6 +985,7 @@
isFirst = false;
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
+ DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
try {
// Save class environment for later member enter (2) processing.
halfcompleted.append(env);
@@ -985,9 +1007,9 @@
Env<AttrContext> baseEnv = baseEnv(tree, env);
if (tree.extending != null)
- typeAnnotate(tree.extending, baseEnv, sym);
+ typeAnnotate(tree.extending, baseEnv, sym, tree.pos());
for (JCExpression impl : tree.implementing)
- typeAnnotate(impl, baseEnv, sym);
+ typeAnnotate(impl, baseEnv, sym, tree.pos());
annotate.flush();
// Determine supertype.
@@ -1048,7 +1070,7 @@
attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
if (hasDeprecatedAnnotation(tree.mods.annotations))
c.flags_field |= DEPRECATED;
- annotateLater(tree.mods.annotations, baseEnv, c);
+ annotateLater(tree.mods.annotations, baseEnv, c, tree.pos());
// class type parameters use baseEnv but everything uses env
chk.checkNonCyclicDecl(tree);
@@ -1056,7 +1078,7 @@
attr.attribTypeVariables(tree.typarams, baseEnv);
// Do this here, where we have the symbol.
for (JCTypeParameter tp : tree.typarams)
- typeAnnotate(tp, baseEnv, sym);
+ typeAnnotate(tp, baseEnv, sym, tree.pos());
annotate.flush();
// Add default constructor if needed.
@@ -1126,6 +1148,7 @@
} catch (CompletionFailure ex) {
chk.completionError(tree.pos(), ex);
} finally {
+ deferredLintHandler.setPos(prevLintPos);
log.useSource(prev);
}
@@ -1186,9 +1209,9 @@
}
}
- public void typeAnnotate(final JCTree tree, final Env<AttrContext> env, final Symbol sym) {
+ public void typeAnnotate(final JCTree tree, final Env<AttrContext> env, final Symbol sym, DiagnosticPosition deferPos) {
if (allowTypeAnnos) {
- tree.accept(new TypeAnnotate(env, sym));
+ tree.accept(new TypeAnnotate(env, sym, deferPos));
}
}
@@ -1199,10 +1222,12 @@
private class TypeAnnotate extends TreeScanner {
private Env<AttrContext> env;
private Symbol sym;
+ private DiagnosticPosition deferPos;
- public TypeAnnotate(final Env<AttrContext> env, final Symbol sym) {
+ public TypeAnnotate(final Env<AttrContext> env, final Symbol sym, DiagnosticPosition deferPos) {
this.env = env;
this.sym = sym;
+ this.deferPos = deferPos;
}
void annotateTypeLater(final List<JCAnnotation> annotations) {
@@ -1210,6 +1235,8 @@
return;
}
+ final DiagnosticPosition deferPos = this.deferPos;
+
annotate.normal(new Annotate.Annotator() {
@Override
public String toString() {
@@ -1218,9 +1245,16 @@
@Override
public void enterAnnotation() {
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
+ DiagnosticPosition prevLintPos = null;
+
+ if (deferPos != null) {
+ prevLintPos = deferredLintHandler.setPos(deferPos);
+ }
try {
actualEnterTypeAnnotations(annotations, env, sym);
} finally {
+ if (prevLintPos != null)
+ deferredLintHandler.setPos(prevLintPos);
log.useSource(prev);
}
}
@@ -1262,13 +1296,19 @@
@Override
public void visitVarDef(final JCVariableDecl tree) {
- if (sym != null && sym.kind == Kinds.VAR) {
- // Don't visit a parameter once when the sym is the method
- // and once when the sym is the parameter.
- scan(tree.mods);
- scan(tree.vartype);
+ DiagnosticPosition prevPos = deferPos;
+ deferPos = tree.pos();
+ try {
+ if (sym != null && sym.kind == Kinds.VAR) {
+ // Don't visit a parameter once when the sym is the method
+ // and once when the sym is the parameter.
+ scan(tree.mods);
+ scan(tree.vartype);
+ }
+ scan(tree.init);
+ } finally {
+ deferPos = prevPos;
}
- scan(tree.init);
}
@Override
@@ -1532,7 +1572,7 @@
* parameters from baseInit.
*/
initParams = List.nil();
- VarSymbol param = new VarSymbol(0, make.paramName(0), argtypes.head, init);
+ VarSymbol param = new VarSymbol(PARAMETER, make.paramName(0), argtypes.head, init);
initParams = initParams.append(param);
argTypesList = argTypesList.tail;
}
@@ -1541,7 +1581,7 @@
initParams = (initParams == null) ? List.<VarSymbol>nil() : initParams;
List<VarSymbol> baseInitParams = baseInit.params;
while (baseInitParams.nonEmpty() && argTypesList.nonEmpty()) {
- VarSymbol param = new VarSymbol(baseInitParams.head.flags(),
+ VarSymbol param = new VarSymbol(baseInitParams.head.flags() | PARAMETER,
baseInitParams.head.name, argTypesList.head, init);
initParams = initParams.append(param);
baseInitParams = baseInitParams.tail;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Sep 17 08:21:11 2013 -0700
@@ -568,8 +568,10 @@
currentResolutionContext,
warn);
- currentResolutionContext.methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn),
+ DeferredAttr.DeferredAttrContext dc = currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn);
+ currentResolutionContext.methodCheck.argumentsAcceptable(env, dc,
argtypes, mt.getParameterTypes(), warn);
+ dc.complete();
return mt;
}
@@ -1053,7 +1055,8 @@
DeferredType dt = (DeferredType) actual;
DeferredType.SpeculativeCache.Entry e = dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase);
return (e == null || e.speculativeTree == deferredAttr.stuckTree)
- ? false : mostSpecific(found, req, e.speculativeTree, warn);
+ ? super.compatible(found, req, warn) :
+ mostSpecific(found, req, e.speculativeTree, warn);
default:
return standaloneMostSpecific(found, req, actual, warn);
}
@@ -1125,13 +1128,15 @@
@Override
public void visitReference(JCMemberReference tree) {
if (types.isFunctionalInterface(t.tsym) &&
- types.isFunctionalInterface(s.tsym) &&
- types.asSuper(t, s.tsym) == null &&
- types.asSuper(s, t.tsym) == null) {
+ types.isFunctionalInterface(s.tsym)) {
Type desc_t = types.findDescriptorType(t);
Type desc_s = types.findDescriptorType(s);
- if (types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
- if (!desc_s.getReturnType().hasTag(VOID)) {
+ if (types.isSameTypes(desc_t.getParameterTypes(),
+ inferenceContext().asFree(desc_s.getParameterTypes()))) {
+ if (types.asSuper(t, s.tsym) != null ||
+ types.asSuper(s, t.tsym) != null) {
+ result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+ } else if (!desc_s.getReturnType().hasTag(VOID)) {
//perform structural comparison
Type ret_t = desc_t.getReturnType();
Type ret_s = desc_s.getReturnType();
@@ -1141,25 +1146,24 @@
} else {
return;
}
- } else {
- result &= false;
}
} else {
- result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+ result &= false;
}
}
@Override
public void visitLambda(JCLambda tree) {
if (types.isFunctionalInterface(t.tsym) &&
- types.isFunctionalInterface(s.tsym) &&
- types.asSuper(t, s.tsym) == null &&
- types.asSuper(s, t.tsym) == null) {
+ types.isFunctionalInterface(s.tsym)) {
Type desc_t = types.findDescriptorType(t);
Type desc_s = types.findDescriptorType(s);
- if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT
- || types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
- if (!desc_s.getReturnType().hasTag(VOID)) {
+ if (types.isSameTypes(desc_t.getParameterTypes(),
+ inferenceContext().asFree(desc_s.getParameterTypes()))) {
+ if (types.asSuper(t, s.tsym) != null ||
+ types.asSuper(s, t.tsym) != null) {
+ result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+ } else if (!desc_s.getReturnType().hasTag(VOID)) {
//perform structural comparison
Type ret_t = desc_t.getReturnType();
Type ret_s = desc_s.getReturnType();
@@ -1167,11 +1171,9 @@
} else {
return;
}
- } else {
- result &= false;
}
} else {
- result &= MostSpecificCheckContext.super.compatible(t, s, warn);
+ result &= false;
}
}
//where
@@ -1521,7 +1523,8 @@
currentResolutionContext = prevResolutionContext;
}
}
- private List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
+
+ List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
Type varargsElem = types.elemtype(args.last());
if (varargsElem == null) {
@@ -2241,33 +2244,33 @@
public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
return (syms.operatorNames.contains(name)) ?
argtypes :
- Type.map(argtypes, new ResolveDeferredRecoveryMap(accessedSym));
- }
-
- class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
-
- public ResolveDeferredRecoveryMap(Symbol msym) {
- deferredAttr.super(AttrMode.SPECULATIVE, msym, currentResolutionContext.step);
- }
-
- @Override
- protected Type typeOf(DeferredType dt) {
- Type res = super.typeOf(dt);
- if (!res.isErroneous()) {
- switch (TreeInfo.skipParens(dt.tree).getTag()) {
- case LAMBDA:
- case REFERENCE:
- return dt;
- case CONDEXPR:
- return res == Type.recoveryType ?
- dt : res;
- }
- }
- return res;
- }
+ Type.map(argtypes, new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step));
}
};
+ class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
+
+ public ResolveDeferredRecoveryMap(AttrMode mode, Symbol msym, MethodResolutionPhase step) {
+ deferredAttr.super(mode, msym, step);
+ }
+
+ @Override
+ protected Type typeOf(DeferredType dt) {
+ Type res = super.typeOf(dt);
+ if (!res.isErroneous()) {
+ switch (TreeInfo.skipParens(dt.tree).getTag()) {
+ case LAMBDA:
+ case REFERENCE:
+ return dt;
+ case CONDEXPR:
+ return res == Type.recoveryType ?
+ dt : res;
+ }
+ }
+ return res;
+ }
+ }
+
/** Check that sym is not an abstract method.
*/
void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
@@ -2543,22 +2546,26 @@
@Override
Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
if (sym.kind >= AMBIGUOUS) {
- final JCDiagnostic details = sym.kind == WRONG_MTH ?
- ((InapplicableSymbolError)sym).errCandidate().snd :
- null;
- sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
- @Override
- JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
- Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
- String key = details == null ?
- "cant.apply.diamond" :
- "cant.apply.diamond.1";
- return diags.create(dkind, log.currentSource(), pos, key,
- diags.fragment("diamond", site.tsym), details);
- }
- };
- sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
- env.info.pendingResolutionPhase = currentResolutionContext.step;
+ if (sym.kind != WRONG_MTH && sym.kind != WRONG_MTHS) {
+ sym = super.access(env, pos, location, sym);
+ } else {
+ final JCDiagnostic details = sym.kind == WRONG_MTH ?
+ ((InapplicableSymbolError)sym).errCandidate().snd :
+ null;
+ sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
+ @Override
+ JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
+ Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
+ String key = details == null ?
+ "cant.apply.diamond" :
+ "cant.apply.diamond.1";
+ return diags.create(dkind, log.currentSource(), pos, key,
+ diags.fragment("diamond", site.tsym), details);
+ }
+ };
+ sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
+ env.info.pendingResolutionPhase = currentResolutionContext.step;
+ }
}
return sym;
}});
@@ -3969,16 +3976,6 @@
static {
String argMismatchRegex = MethodCheckDiag.ARG_MISMATCH.regex();
- rewriters.put(new Template(argMismatchRegex, new Template("(.*)(bad.arg.types.in.lambda)", skip, skip)),
- new DiagnosticRewriter() {
- @Override
- public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
- DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
- DiagnosticType preferredKind, JCDiagnostic d) {
- return (JCDiagnostic)((JCDiagnostic)d.getArgs()[0]).getArgs()[1];
- }
- });
-
rewriters.put(new Template(argMismatchRegex, skip),
new DiagnosticRewriter() {
@Override
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Tue Sep 17 08:21:11 2013 -0700
@@ -310,7 +310,7 @@
Type.MethodType mType = (Type.MethodType)bridgeType;
List<Type> argTypes = mType.argtypes;
while (implParams.nonEmpty() && argTypes.nonEmpty()) {
- VarSymbol param = new VarSymbol(implParams.head.flags() | SYNTHETIC,
+ VarSymbol param = new VarSymbol(implParams.head.flags() | SYNTHETIC | PARAMETER,
implParams.head.name, argTypes.head, bridge);
param.setAttributes(implParams.head);
bridgeParams = bridgeParams.append(param);
@@ -833,7 +833,7 @@
}
public void visitReference(JCMemberReference tree) {
- tree.expr = translate(tree.expr, null);
+ tree.expr = translate(tree.expr, erasure(tree.expr.type));
tree.type = erasure(tree.type);
result = tree;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Sep 17 08:21:11 2013 -0700
@@ -72,7 +72,7 @@
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
-public class ClassReader implements Completer {
+public class ClassReader {
/** The context key for the class reader. */
protected static final Context.Key<ClassReader> classReaderKey =
new Context.Key<ClassReader>();
@@ -234,6 +234,17 @@
*/
Set<Name> warnedAttrs = new HashSet<Name>();
+ /**
+ * Completer that delegates to the complete-method of this class.
+ */
+ private final Completer thisCompleter = new Completer() {
+ @Override
+ public void complete(Symbol sym) throws CompletionFailure {
+ ClassReader.this.complete(sym);
+ }
+ };
+
+
/** Get the ClassReader instance for this invocation. */
public static ClassReader instance(Context context) {
ClassReader instance = context.get(classReaderKey);
@@ -264,8 +275,8 @@
}
packages.put(names.empty, syms.rootPackage);
- syms.rootPackage.completer = this;
- syms.unnamedPackage.completer = this;
+ syms.rootPackage.completer = thisCompleter;
+ syms.unnamedPackage.completer = thisCompleter;
}
/** Construct a new class reader, optionally treated as the
@@ -727,12 +738,14 @@
ClassSymbol t = enterClass(names.fromUtf(signatureBuffer,
startSbp,
sbp - startSbp));
- if (outer == Type.noType)
- outer = t.erasure(types);
- else
- outer = new ClassType(outer, List.<Type>nil(), t);
- sbp = startSbp;
- return outer;
+
+ try {
+ return (outer == Type.noType) ?
+ t.erasure(types) :
+ new ClassType(outer, List.<Type>nil(), t);
+ } finally {
+ sbp = startSbp;
+ }
}
case '<': // generic arguments
@@ -797,6 +810,13 @@
continue;
case '.':
+ //we have seen an enclosing non-generic class
+ if (outer != Type.noType) {
+ t = enterClass(names.fromUtf(signatureBuffer,
+ startSbp,
+ sbp - startSbp));
+ outer = new ClassType(outer, List.<Type>nil(), t);
+ }
signatureBuffer[sbp++] = (byte)'$';
continue;
case '/':
@@ -2310,7 +2330,7 @@
ClassSymbol c = new ClassSymbol(0, name, owner);
if (owner.kind == PCK)
Assert.checkNull(classes.get(c.flatname), c);
- c.completer = this;
+ c.completer = thisCompleter;
return c;
}
@@ -2380,7 +2400,7 @@
/** Completion for classes to be loaded. Before a class is loaded
* we make sure its enclosing class (if any) is loaded.
*/
- public void complete(Symbol sym) throws CompletionFailure {
+ private void complete(Symbol sym) throws CompletionFailure {
if (sym.kind == TYP) {
ClassSymbol c = (ClassSymbol)sym;
c.members_field = new Scope.ErrorScope(c); // make sure it's always defined
@@ -2601,7 +2621,7 @@
p = new PackageSymbol(
Convert.shortName(fullname),
enterPackage(Convert.packagePart(fullname)));
- p.completer = this;
+ p.completer = thisCompleter;
packages.put(fullname, p);
}
return p;
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Tue Sep 17 08:21:11 2013 -0700
@@ -37,7 +37,6 @@
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Attribute.RetentionPolicy;
-import com.sun.tools.javac.code.Attribute.TypeCompound;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Types.UniqueType;
@@ -55,7 +54,6 @@
import static com.sun.tools.javac.main.Option.*;
import static javax.tools.StandardLocation.CLASS_OUTPUT;
-
/** This class provides operations to map an internal symbol table graph
* rooted in a ClassSymbol into a classfile.
*
@@ -1180,25 +1178,26 @@
if (code.varBufferSize > 0) {
int alenIdx = writeAttr(names.LocalVariableTable);
- databuf.appendChar(code.varBufferSize);
-
+ databuf.appendChar(code.getLVTSize());
for (int i=0; i<code.varBufferSize; i++) {
Code.LocalVar var = code.varBuffer[i];
- // write variable info
- Assert.check(var.start_pc >= 0
- && var.start_pc <= code.cp);
- databuf.appendChar(var.start_pc);
- Assert.check(var.length >= 0
- && (var.start_pc + var.length) <= code.cp);
- databuf.appendChar(var.length);
- VarSymbol sym = var.sym;
- databuf.appendChar(pool.put(sym.name));
- Type vartype = sym.erasure(types);
- if (needsLocalVariableTypeEntry(sym.type))
- nGenericVars++;
- databuf.appendChar(pool.put(typeSig(vartype)));
- databuf.appendChar(var.reg);
+ for (Code.LocalVar.Range r: var.aliveRanges) {
+ // write variable info
+ Assert.check(r.start_pc >= 0
+ && r.start_pc <= code.cp);
+ databuf.appendChar(r.start_pc);
+ Assert.check(r.length >= 0
+ && (r.start_pc + r.length) <= code.cp);
+ databuf.appendChar(r.length);
+ VarSymbol sym = var.sym;
+ databuf.appendChar(pool.put(sym.name));
+ Type vartype = sym.erasure(types);
+ databuf.appendChar(pool.put(typeSig(vartype)));
+ databuf.appendChar(var.reg);
+ if (needsLocalVariableTypeEntry(var.sym.type))
+ nGenericVars++;
+ }
}
endAttr(alenIdx);
acount++;
@@ -1214,13 +1213,15 @@
VarSymbol sym = var.sym;
if (!needsLocalVariableTypeEntry(sym.type))
continue;
- count++;
- // write variable info
- databuf.appendChar(var.start_pc);
- databuf.appendChar(var.length);
- databuf.appendChar(pool.put(sym.name));
- databuf.appendChar(pool.put(typeSig(sym.type)));
- databuf.appendChar(var.reg);
+ for (Code.LocalVar.Range r : var.aliveRanges) {
+ // write variable info
+ databuf.appendChar(r.start_pc);
+ databuf.appendChar(r.length);
+ databuf.appendChar(pool.put(sym.name));
+ databuf.appendChar(pool.put(typeSig(sym.type)));
+ databuf.appendChar(var.reg);
+ count++;
+ }
}
Assert.check(count == nGenericVars);
endAttr(alenIdx);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Tue Sep 17 08:21:11 2013 -0700
@@ -28,6 +28,7 @@
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Types.UniqueType;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -181,6 +182,8 @@
final MethodSymbol meth;
+ final LVTRanges lvtRanges;
+
/** Construct a code object, given the settings of the fatcode,
* debugging info switches and the CharacterRangeTable.
*/
@@ -193,7 +196,8 @@
CRTable crt,
Symtab syms,
Types types,
- Pool pool) {
+ Pool pool,
+ LVTRanges lvtRanges) {
this.meth = meth;
this.fatcode = fatcode;
this.lineMap = lineMap;
@@ -215,6 +219,7 @@
state = new State();
lvar = new LocalVar[20];
this.pool = pool;
+ this.lvtRanges = lvtRanges;
}
@@ -305,9 +310,19 @@
/** The current output code pointer.
*/
- public int curPc() {
- if (pendingJumps != null) resolvePending();
- if (pendingStatPos != Position.NOPOS) markStatBegin();
+ public int curCP() {
+ /*
+ * This method has side-effects because calling it can indirectly provoke
+ * extra code generation, like goto instructions, depending on the context
+ * where it's called.
+ * Use with care or even better avoid using it.
+ */
+ if (pendingJumps != null) {
+ resolvePending();
+ }
+ if (pendingStatPos != Position.NOPOS) {
+ markStatBegin();
+ }
fixedPc = true;
return cp;
}
@@ -1175,7 +1190,7 @@
/** Declare an entry point; return current code pointer
*/
public int entryPoint() {
- int pc = curPc();
+ int pc = curCP();
alive = true;
pendingStackMap = needStackMap;
return pc;
@@ -1185,7 +1200,7 @@
* return current code pointer
*/
public int entryPoint(State state) {
- int pc = curPc();
+ int pc = curCP();
alive = true;
this.state = state.dup();
Assert.check(state.stacksize <= max_stack);
@@ -1198,7 +1213,7 @@
* return current code pointer
*/
public int entryPoint(State state, Type pushed) {
- int pc = curPc();
+ int pc = curCP();
alive = true;
this.state = state.dup();
Assert.check(state.stacksize <= max_stack);
@@ -1238,7 +1253,7 @@
/** Emit a stack map entry. */
public void emitStackMap() {
- int pc = curPc();
+ int pc = curCP();
if (!needStackMap) return;
@@ -1482,6 +1497,9 @@
chain.pc + 3 == target && target == cp && !fixedPc) {
// If goto the next instruction, the jump is not needed:
// compact the code.
+ if (varDebugInfo) {
+ adjustAliveRanges(cp, -3);
+ }
cp = cp - 3;
target = target - 3;
if (chain.next == null) {
@@ -1781,8 +1799,7 @@
sym = sym.clone(sym.owner);
sym.type = newtype;
LocalVar newlv = lvar[i] = new LocalVar(sym);
- // should the following be initialized to cp?
- newlv.start_pc = lv.start_pc;
+ newlv.aliveRanges = lv.aliveRanges;
}
}
}
@@ -1870,8 +1887,36 @@
static class LocalVar {
final VarSymbol sym;
final char reg;
- char start_pc = Character.MAX_VALUE;
- char length = Character.MAX_VALUE;
+
+ class Range {
+ char start_pc = Character.MAX_VALUE;
+ char length = Character.MAX_VALUE;
+
+ Range() {}
+
+ Range(char start) {
+ this.start_pc = start;
+ }
+
+ Range(char start, char length) {
+ this.start_pc = start;
+ this.length = length;
+ }
+
+ boolean closed() {
+ return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE;
+ }
+
+ @Override
+ public String toString() {
+ int currentStartPC = start_pc;
+ int currentLength = length;
+ return "startpc = " + currentStartPC + " length " + currentLength;
+ }
+ }
+
+ java.util.List<Range> aliveRanges = new java.util.ArrayList<>();
+
LocalVar(VarSymbol v) {
this.sym = v;
this.reg = (char)v.adr;
@@ -1879,9 +1924,78 @@
public LocalVar dup() {
return new LocalVar(sym);
}
+
+ Range firstRange() {
+ return aliveRanges.isEmpty() ? null : aliveRanges.get(0);
+ }
+
+ Range lastRange() {
+ return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
+ }
+
+ @Override
public String toString() {
- return "" + sym + " in register " + ((int)reg) + " starts at pc=" + ((int)start_pc) + " length=" + ((int)length);
+ if (aliveRanges == null) {
+ return "empty local var";
+ }
+ StringBuilder sb = new StringBuilder().append(sym)
+ .append(" in register ").append((int)reg).append(" \n");
+ for (Range r : aliveRanges) {
+ sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc)))
+ .append(" length=").append(Integer.toString(((int)r.length)))
+ .append("\n");
+ }
+ return sb.toString();
+ }
+
+ public void openRange(char start) {
+ if (!hasOpenRange()) {
+ aliveRanges.add(new Range(start));
+ }
}
+
+ public void closeRange(char end) {
+ if (isLastRangeInitialized()) {
+ Range range = lastRange();
+ if (range != null) {
+ if (range.length == Character.MAX_VALUE) {
+ range.length = end;
+ }
+ }
+ } else {
+ if (!aliveRanges.isEmpty()) {
+ aliveRanges.remove(aliveRanges.size() - 1);
+ }
+ }
+ }
+
+ public boolean hasOpenRange() {
+ if (aliveRanges.isEmpty()) {
+ return false;
+ }
+ Range range = lastRange();
+ return range.length == Character.MAX_VALUE;
+ }
+
+ public boolean isLastRangeInitialized() {
+ if (aliveRanges.isEmpty()) {
+ return false;
+ }
+ Range range = lastRange();
+ return range.start_pc != Character.MAX_VALUE;
+ }
+
+ public Range getWidestRange() {
+ if (aliveRanges.isEmpty()) {
+ return new Range();
+ } else {
+ Range firstRange = firstRange();
+ Range lastRange = lastRange();
+ char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc));
+ return new Range(firstRange.start_pc, length);
+ }
+ }
+
};
/** Local variables, indexed by register. */
@@ -1892,11 +2006,60 @@
int adr = v.adr;
lvar = ArrayUtils.ensureCapacity(lvar, adr+1);
Assert.checkNull(lvar[adr]);
- if (pendingJumps != null) resolvePending();
+ if (pendingJumps != null) {
+ resolvePending();
+ }
lvar[adr] = new LocalVar(v);
state.defined.excl(adr);
}
+
+ public void closeAliveRanges(JCTree tree) {
+ closeAliveRanges(tree, cp);
+ }
+
+ public void closeAliveRanges(JCTree tree, int closingCP) {
+ List<VarSymbol> locals = lvtRanges.getVars(meth, tree);
+ for (LocalVar localVar: lvar) {
+ for (VarSymbol aliveLocal : locals) {
+ if (localVar == null) {
+ return;
+ }
+ if (localVar.sym == aliveLocal && localVar.lastRange() != null) {
+ char length = (char)(closingCP - localVar.lastRange().start_pc);
+ if (length > 0 && length < Character.MAX_VALUE) {
+ localVar.closeRange(length);
+ }
+ }
+ }
+ }
+ }
+
+ void adjustAliveRanges(int oldCP, int delta) {
+ for (LocalVar localVar: lvar) {
+ if (localVar == null) {
+ return;
+ }
+ for (LocalVar.Range range: localVar.aliveRanges) {
+ if (range.closed() && range.start_pc + range.length >= oldCP) {
+ range.length += delta;
+ }
+ }
+ }
+ }
+
+ /**
+ * Calculates the size of the LocalVariableTable.
+ */
+ public int getLVTSize() {
+ int result = varBufferSize;
+ for (int i = 0; i < varBufferSize; i++) {
+ LocalVar var = varBuffer[i];
+ result += var.aliveRanges.size() - 1;
+ }
+ return result;
+ }
+
/** Set the current variable defined state. */
public void setDefined(Bits newDefined) {
if (alive && newDefined != state.defined) {
@@ -1922,8 +2085,7 @@
} else {
state.defined.incl(adr);
if (cp < Character.MAX_VALUE) {
- if (v.start_pc == Character.MAX_VALUE)
- v.start_pc = (char)cp;
+ v.openRange((char)cp);
}
}
}
@@ -1933,15 +2095,15 @@
state.defined.excl(adr);
if (adr < lvar.length &&
lvar[adr] != null &&
- lvar[adr].start_pc != Character.MAX_VALUE) {
+ lvar[adr].isLastRangeInitialized()) {
LocalVar v = lvar[adr];
- char length = (char)(curPc() - v.start_pc);
+ char length = (char)(curCP() - v.lastRange().start_pc);
if (length > 0 && length < Character.MAX_VALUE) {
lvar[adr] = v.dup();
- v.length = length;
+ v.closeRange(length);
putVar(v);
} else {
- v.start_pc = Character.MAX_VALUE;
+ v.lastRange().start_pc = Character.MAX_VALUE;
}
}
}
@@ -1951,10 +2113,10 @@
LocalVar v = lvar[adr];
if (v != null) {
lvar[adr] = null;
- if (v.start_pc != Character.MAX_VALUE) {
- char length = (char)(curPc() - v.start_pc);
+ if (v.isLastRangeInitialized()) {
+ char length = (char)(curCP() - v.lastRange().start_pc);
if (length < Character.MAX_VALUE) {
- v.length = length;
+ v.closeRange(length);
putVar(v);
fillLocalVarPosition(v);
}
@@ -1968,8 +2130,9 @@
return;
for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
TypeAnnotationPosition p = ta.position;
- p.lvarOffset = new int[] { (int)lv.start_pc };
- p.lvarLength = new int[] { (int)lv.length };
+ LocalVar.Range widestRange = lv.getWidestRange();
+ p.lvarOffset = new int[] { (int)widestRange.start_pc };
+ p.lvarLength = new int[] { (int)widestRange.length };
p.lvarIndex = new int[] { (int)lv.reg };
p.isValidOffset = true;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Tue Sep 17 08:21:11 2013 -0700
@@ -24,6 +24,7 @@
*/
package com.sun.tools.javac.jvm;
+
import java.util.*;
import com.sun.tools.javac.util.*;
@@ -95,10 +96,14 @@
return instance;
}
- /* Constant pool, reset by genClass.
+ /** Constant pool, reset by genClass.
*/
private Pool pool;
+ /** LVTRanges info.
+ */
+ private LVTRanges lvtRanges;
+
protected Gen(Context context) {
context.put(genKey, this);
@@ -128,6 +133,9 @@
options.isUnset(G_CUSTOM)
? options.isSet(G)
: options.isSet(G_CUSTOM, "vars");
+ if (varDebugInfo) {
+ lvtRanges = LVTRanges.instance(context);
+ }
genCrt = options.isSet(XJCOV);
debugCode = options.isSet("debugcode");
allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic");
@@ -423,7 +431,7 @@
*/
void endFinalizerGap(Env<GenContext> env) {
if (env.info.gaps != null && env.info.gaps.length() % 2 == 1)
- env.info.gaps.append(code.curPc());
+ env.info.gaps.append(code.curCP());
}
/** Mark end of all gaps in catch-all ranges for finalizers of environments
@@ -743,10 +751,10 @@
genStat(tree, env);
return;
}
- int startpc = code.curPc();
+ int startpc = code.curCP();
genStat(tree, env);
if (tree.hasTag(Tag.BLOCK)) crtFlags |= CRT_BLOCK;
- code.crt.put(tree, crtFlags, startpc, code.curPc());
+ code.crt.put(tree, crtFlags, startpc, code.curCP());
}
/** Derived visitor method: generate code for a statement.
@@ -781,9 +789,9 @@
if (trees.length() == 1) { // mark one statement with the flags
genStat(trees.head, env, crtFlags | CRT_STATEMENT);
} else {
- int startpc = code.curPc();
+ int startpc = code.curCP();
genStats(trees, env);
- code.crt.put(trees, crtFlags, startpc, code.curPc());
+ code.crt.put(trees, crtFlags, startpc, code.curCP());
}
}
@@ -806,9 +814,9 @@
*/
public CondItem genCond(JCTree tree, int crtFlags) {
if (!genCrt) return genCond(tree, false);
- int startpc = code.curPc();
+ int startpc = code.curCP();
CondItem item = genCond(tree, (crtFlags & CRT_FLOW_CONTROLLER) != 0);
- code.crt.put(tree, crtFlags, startpc, code.curPc());
+ code.crt.put(tree, crtFlags, startpc, code.curCP());
return item;
}
@@ -971,7 +979,6 @@
// definition.
Env<GenContext> localEnv = env.dup(tree);
localEnv.enclMethod = tree;
-
// The expected type of every return statement in this method
// is the method's return type.
this.pt = tree.sym.erasure(types).getReturnType();
@@ -1045,7 +1052,7 @@
code.crt.put(tree.body,
CRT_BLOCK,
startpcCrt,
- code.curPc());
+ code.curCP());
code.endScopes(0);
@@ -1087,10 +1094,12 @@
: null,
syms,
types,
- pool);
+ pool,
+ varDebugInfo ? lvtRanges : null);
items = new Items(pool, code, syms, types);
- if (code.debugCode)
+ if (code.debugCode) {
System.err.println(meth + " for body " + tree);
+ }
// If method is not static, create a new local variable address
// for `this'.
@@ -1111,7 +1120,7 @@
}
// Get ready to generate code for method body.
- int startpcCrt = genCrt ? code.curPc() : 0;
+ int startpcCrt = genCrt ? code.curCP() : 0;
code.entryPoint();
// Suppress initial stackmap
@@ -1189,14 +1198,30 @@
Chain loopDone = c.jumpFalse();
code.resolve(c.trueJumps);
genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
+ if (varDebugInfo) {
+ checkLoopLocalVarRangeEnding(loop, body,
+ LoopLocalVarRangeEndingPoint.BEFORE_STEPS);
+ }
code.resolve(loopEnv.info.cont);
genStats(step, loopEnv);
+ if (varDebugInfo) {
+ checkLoopLocalVarRangeEnding(loop, body,
+ LoopLocalVarRangeEndingPoint.AFTER_STEPS);
+ }
code.resolve(code.branch(goto_), startpc);
code.resolve(loopDone);
} else {
genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
+ if (varDebugInfo) {
+ checkLoopLocalVarRangeEnding(loop, body,
+ LoopLocalVarRangeEndingPoint.BEFORE_STEPS);
+ }
code.resolve(loopEnv.info.cont);
genStats(step, loopEnv);
+ if (varDebugInfo) {
+ checkLoopLocalVarRangeEnding(loop, body,
+ LoopLocalVarRangeEndingPoint.AFTER_STEPS);
+ }
CondItem c;
if (cond != null) {
code.statBegin(cond.pos);
@@ -1210,6 +1235,44 @@
code.resolve(loopEnv.info.exit);
}
+ private enum LoopLocalVarRangeEndingPoint {
+ BEFORE_STEPS,
+ AFTER_STEPS,
+ }
+
+ /**
+ * Checks whether we have reached an alive range ending point for local
+ * variables after a loop.
+ *
+ * Local variables alive range ending point for loops varies depending
+ * on the loop type. The range can be closed before or after the code
+ * for the steps sentences has been generated.
+ *
+ * - While loops has no steps so in that case the range is closed just
+ * after the body of the loop.
+ *
+ * - For-like loops may have steps so as long as the steps sentences
+ * can possibly contain non-synthetic local variables, the alive range
+ * for local variables must be closed after the steps in this case.
+ */
+ private void checkLoopLocalVarRangeEnding(JCTree loop, JCTree body,
+ LoopLocalVarRangeEndingPoint endingPoint) {
+ if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) {
+ switch (endingPoint) {
+ case BEFORE_STEPS:
+ if (!loop.hasTag(FORLOOP)) {
+ code.closeAliveRanges(body);
+ }
+ break;
+ case AFTER_STEPS:
+ if (loop.hasTag(FORLOOP)) {
+ code.closeAliveRanges(body);
+ }
+ break;
+ }
+ }
+ }
+
public void visitForeachLoop(JCEnhancedForLoop tree) {
throw new AssertionError(); // should have been removed by Lower.
}
@@ -1223,7 +1286,7 @@
public void visitSwitch(JCSwitch tree) {
int limit = code.nextreg;
Assert.check(!tree.selector.type.hasTag(CLASS));
- int startpcCrt = genCrt ? code.curPc() : 0;
+ int startpcCrt = genCrt ? code.curCP() : 0;
Item sel = genExpr(tree.selector, syms.intType);
List<JCCase> cases = tree.cases;
if (cases.isEmpty()) {
@@ -1231,13 +1294,13 @@
sel.load().drop();
if (genCrt)
code.crt.put(TreeInfo.skipParens(tree.selector),
- CRT_FLOW_CONTROLLER, startpcCrt, code.curPc());
+ CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
} else {
// We are seeing a nonempty switch.
sel.load();
if (genCrt)
code.crt.put(TreeInfo.skipParens(tree.selector),
- CRT_FLOW_CONTROLLER, startpcCrt, code.curPc());
+ CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
Env<GenContext> switchEnv = env.dup(tree, new GenContext());
switchEnv.info.isSwitch = true;
@@ -1278,10 +1341,10 @@
?
tableswitch : lookupswitch;
- int startpc = code.curPc(); // the position of the selector operation
+ int startpc = code.curCP(); // the position of the selector operation
code.emitop0(opcode);
code.align(4);
- int tableBase = code.curPc(); // the start of the jump table
+ int tableBase = code.curCP(); // the start of the jump table
int[] offsets = null; // a table of offsets for a lookupswitch
code.emit4(-1); // leave space for default offset
if (opcode == tableswitch) {
@@ -1323,6 +1386,9 @@
// Generate code for the statements in this case.
genStats(c.stats, switchEnv, CRT_FLOW_TARGET);
+ if (varDebugInfo && lvtRanges.containsKey(code.meth, c.stats.last())) {
+ code.closeAliveRanges(c.stats.last());
+ }
}
// Resolve all breaks.
@@ -1402,7 +1468,7 @@
void gen() {
genLast();
Assert.check(syncEnv.info.gaps.length() % 2 == 0);
- syncEnv.info.gaps.append(code.curPc());
+ syncEnv.info.gaps.append(code.curCP());
}
void genLast() {
if (code.isAlive()) {
@@ -1441,10 +1507,10 @@
jsrState);
}
Assert.check(tryEnv.info.gaps.length() % 2 == 0);
- tryEnv.info.gaps.append(code.curPc());
+ tryEnv.info.gaps.append(code.curCP());
} else {
Assert.check(tryEnv.info.gaps.length() % 2 == 0);
- tryEnv.info.gaps.append(code.curPc());
+ tryEnv.info.gaps.append(code.curCP());
genLast();
}
}
@@ -1467,10 +1533,10 @@
*/
void genTry(JCTree body, List<JCCatch> catchers, Env<GenContext> env) {
int limit = code.nextreg;
- int startpc = code.curPc();
+ int startpc = code.curCP();
Code.State stateTry = code.state.dup();
genStat(body, env, CRT_BLOCK);
- int endpc = code.curPc();
+ int endpc = code.curCP();
boolean hasFinalizer =
env.info.finalize != null &&
env.info.finalize.hasFinalizer();
@@ -1478,82 +1544,77 @@
code.statBegin(TreeInfo.endPos(body));
genFinalizer(env);
code.statBegin(TreeInfo.endPos(env.tree));
- Chain exitChain;
- if (startpc != endpc) {
- exitChain = code.branch(goto_);
- } else {
- exitChain = code.branch(dontgoto);
+ Chain exitChain = code.branch(goto_);
+ if (varDebugInfo && lvtRanges.containsKey(code.meth, body)) {
+ code.closeAliveRanges(body);
}
endFinalizerGap(env);
- if (startpc != endpc) {
- for (List<JCCatch> l = catchers; l.nonEmpty(); l = l.tail) {
- // start off with exception on stack
- code.entryPoint(stateTry, l.head.param.sym.type);
- genCatch(l.head, env, startpc, endpc, gaps);
- genFinalizer(env);
- if (hasFinalizer || l.tail.nonEmpty()) {
- code.statBegin(TreeInfo.endPos(env.tree));
- exitChain = Code.mergeChains(exitChain,
- code.branch(goto_));
- }
- endFinalizerGap(env);
+ if (startpc != endpc) for (List<JCCatch> l = catchers; l.nonEmpty(); l = l.tail) {
+ // start off with exception on stack
+ code.entryPoint(stateTry, l.head.param.sym.type);
+ genCatch(l.head, env, startpc, endpc, gaps);
+ genFinalizer(env);
+ if (hasFinalizer || l.tail.nonEmpty()) {
+ code.statBegin(TreeInfo.endPos(env.tree));
+ exitChain = Code.mergeChains(exitChain,
+ code.branch(goto_));
}
+ endFinalizerGap(env);
+ }
+ if (hasFinalizer) {
+ // Create a new register segement to avoid allocating
+ // the same variables in finalizers and other statements.
+ code.newRegSegment();
+
+ // Add a catch-all clause.
+
+ // start off with exception on stack
+ int catchallpc = code.entryPoint(stateTry, syms.throwableType);
- if (hasFinalizer) {
- // Create a new register segement to avoid allocating
- // the same variables in finalizers and other statements.
- code.newRegSegment();
-
- // Add a catch-all clause.
-
- // start off with exception on stack
- int catchallpc = code.entryPoint(stateTry, syms.throwableType);
+ // Register all exception ranges for catch all clause.
+ // The range of the catch all clause is from the beginning
+ // of the try or synchronized block until the present
+ // code pointer excluding all gaps in the current
+ // environment's GenContext.
+ int startseg = startpc;
+ while (env.info.gaps.nonEmpty()) {
+ int endseg = env.info.gaps.next().intValue();
+ registerCatch(body.pos(), startseg, endseg,
+ catchallpc, 0);
+ startseg = env.info.gaps.next().intValue();
+ }
+ code.statBegin(TreeInfo.finalizerPos(env.tree));
+ code.markStatBegin();
- // Register all exception ranges for catch all clause.
- // The range of the catch all clause is from the beginning
- // of the try or synchronized block until the present
- // code pointer excluding all gaps in the current
- // environment's GenContext.
- int startseg = startpc;
- while (env.info.gaps.nonEmpty()) {
- int endseg = env.info.gaps.next().intValue();
- registerCatch(body.pos(), startseg, endseg,
- catchallpc, 0);
- startseg = env.info.gaps.next().intValue();
- }
+ Item excVar = makeTemp(syms.throwableType);
+ excVar.store();
+ genFinalizer(env);
+ excVar.load();
+ registerCatch(body.pos(), startseg,
+ env.info.gaps.next().intValue(),
+ catchallpc, 0);
+ code.emitop0(athrow);
+ code.markDead();
+
+ // If there are jsr's to this finalizer, ...
+ if (env.info.cont != null) {
+ // Resolve all jsr's.
+ code.resolve(env.info.cont);
+
+ // Mark statement line number
code.statBegin(TreeInfo.finalizerPos(env.tree));
code.markStatBegin();
- Item excVar = makeTemp(syms.throwableType);
- excVar.store();
- genFinalizer(env);
- excVar.load();
- registerCatch(body.pos(), startseg,
- env.info.gaps.next().intValue(),
- catchallpc, 0);
- code.emitop0(athrow);
- code.markDead();
-
- // If there are jsr's to this finalizer, ...
- if (env.info.cont != null) {
- // Resolve all jsr's.
- code.resolve(env.info.cont);
+ // Save return address.
+ LocalItem retVar = makeTemp(syms.throwableType);
+ retVar.store();
- // Mark statement line number
- code.statBegin(TreeInfo.finalizerPos(env.tree));
- code.markStatBegin();
-
- // Save return address.
- LocalItem retVar = makeTemp(syms.throwableType);
- retVar.store();
+ // Generate finalizer code.
+ env.info.finalize.genLast();
- // Generate finalizer code.
- env.info.finalize.genLast();
-
- // Return.
- code.emitop1w(ret, retVar.reg);
- code.markDead();
- }
+ // Return.
+ code.emitop1w(ret, retVar.reg);
+ code.markDead();
}
}
// Resolve all breaks.
@@ -1581,7 +1642,7 @@
int catchType = makeRef(tree.pos(), subCatch.type);
int end = gaps.head.intValue();
registerCatch(tree.pos(),
- startpc, end, code.curPc(),
+ startpc, end, code.curCP(),
catchType);
if (subCatch.type.isAnnotated()) {
// All compounds share the same position, simply update the
@@ -1597,7 +1658,7 @@
for (JCExpression subCatch : subClauses) {
int catchType = makeRef(tree.pos(), subCatch.type);
registerCatch(tree.pos(),
- startpc, endpc, code.curPc(),
+ startpc, endpc, code.curCP(),
catchType);
if (subCatch.type.isAnnotated()) {
// All compounds share the same position, simply update the
@@ -1740,11 +1801,19 @@
code.resolve(c.trueJumps);
genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET);
thenExit = code.branch(goto_);
+ if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) {
+ code.closeAliveRanges(tree.thenpart,
+ thenExit != null && tree.elsepart == null ? thenExit.pc : code.cp);
+ }
}
if (elseChain != null) {
code.resolve(elseChain);
- if (tree.elsepart != null)
+ if (tree.elsepart != null) {
genStat(tree.elsepart, env,CRT_STATEMENT | CRT_FLOW_TARGET);
+ if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.elsepart)) {
+ code.closeAliveRanges(tree.elsepart);
+ }
+ }
}
code.resolve(thenExit);
code.endScopes(limit);
@@ -1838,20 +1907,20 @@
Chain elseChain = c.jumpFalse();
if (!c.isFalse()) {
code.resolve(c.trueJumps);
- int startpc = genCrt ? code.curPc() : 0;
+ int startpc = genCrt ? code.curCP() : 0;
genExpr(tree.truepart, pt).load();
code.state.forceStackTop(tree.type);
if (genCrt) code.crt.put(tree.truepart, CRT_FLOW_TARGET,
- startpc, code.curPc());
+ startpc, code.curCP());
thenExit = code.branch(goto_);
}
if (elseChain != null) {
code.resolve(elseChain);
- int startpc = genCrt ? code.curPc() : 0;
+ int startpc = genCrt ? code.curCP() : 0;
genExpr(tree.falsepart, pt).load();
code.state.forceStackTop(tree.type);
if (genCrt) code.crt.put(tree.falsepart, CRT_FLOW_TARGET,
- startpc, code.curPc());
+ startpc, code.curCP());
}
code.resolve(thenExit);
result = items.makeStackItem(pt);
@@ -2431,6 +2500,19 @@
new Env<GenContext>(cdef, new GenContext());
localEnv.toplevel = env.toplevel;
localEnv.enclClass = cdef;
+
+ /* We must not analyze synthetic methods
+ */
+ if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) {
+ try {
+ LVTAssignAnalyzer lvtAssignAnalyzer = LVTAssignAnalyzer.make(
+ lvtRanges, syms, names);
+ lvtAssignAnalyzer.analyzeTree(localEnv);
+ } catch (Throwable e) {
+ throw e;
+ }
+ }
+
for (List<JCTree> l = cdef.defs; l.nonEmpty(); l = l.tail) {
genDef(l.head, localEnv);
}
@@ -2515,4 +2597,311 @@
cont = Code.mergeChains(c, cont);
}
}
+
+ static class LVTAssignAnalyzer
+ extends Flow.AbstractAssignAnalyzer<LVTAssignAnalyzer.LVTAssignPendingExit> {
+
+ final LVTBits lvtInits;
+ final LVTRanges lvtRanges;
+
+ /* This class is anchored to a context dependent tree. The tree can
+ * vary inside the same instruction for example in the switch instruction
+ * the same FlowBits instance can be anchored to the whole tree, or
+ * to a given case. The aim is to always anchor the bits to the tree
+ * capable of closing a DA range.
+ */
+ static class LVTBits extends Bits {
+
+ enum BitsOpKind {
+ INIT,
+ CLEAR,
+ INCL_BIT,
+ EXCL_BIT,
+ ASSIGN,
+ AND_SET,
+ OR_SET,
+ DIFF_SET,
+ XOR_SET,
+ INCL_RANGE,
+ EXCL_RANGE,
+ }
+
+ JCTree currentTree;
+ LVTAssignAnalyzer analyzer;
+ private int[] oldBits = null;
+ BitsState stateBeforeOp;
+
+ LVTBits() {
+ super(false);
+ }
+
+ LVTBits(int[] bits, BitsState initState) {
+ super(bits, initState);
+ }
+
+ @Override
+ public void clear() {
+ generalOp(null, -1, BitsOpKind.CLEAR);
+ }
+
+ @Override
+ protected void internalReset() {
+ super.internalReset();
+ oldBits = null;
+ }
+
+ @Override
+ public Bits assign(Bits someBits) {
+ // bits can be null
+ oldBits = bits;
+ stateBeforeOp = currentState;
+ super.assign(someBits);
+ changed();
+ return this;
+ }
+
+ @Override
+ public void excludeFrom(int start) {
+ generalOp(null, start, BitsOpKind.EXCL_RANGE);
+ }
+
+ @Override
+ public void excl(int x) {
+ Assert.check(x >= 0);
+ generalOp(null, x, BitsOpKind.EXCL_BIT);
+ }
+
+ @Override
+ public Bits andSet(Bits xs) {
+ return generalOp(xs, -1, BitsOpKind.AND_SET);
+ }
+
+ @Override
+ public Bits orSet(Bits xs) {
+ return generalOp(xs, -1, BitsOpKind.OR_SET);
+ }
+
+ @Override
+ public Bits diffSet(Bits xs) {
+ return generalOp(xs, -1, BitsOpKind.DIFF_SET);
+ }
+
+ @Override
+ public Bits xorSet(Bits xs) {
+ return generalOp(xs, -1, BitsOpKind.XOR_SET);
+ }
+
+ private Bits generalOp(Bits xs, int i, BitsOpKind opKind) {
+ Assert.check(currentState != BitsState.UNKNOWN);
+ oldBits = dupBits();
+ stateBeforeOp = currentState;
+ switch (opKind) {
+ case AND_SET:
+ super.andSet(xs);
+ break;
+ case OR_SET:
+ super.orSet(xs);
+ break;
+ case XOR_SET:
+ super.xorSet(xs);
+ break;
+ case DIFF_SET:
+ super.diffSet(xs);
+ break;
+ case CLEAR:
+ super.clear();
+ break;
+ case EXCL_BIT:
+ super.excl(i);
+ break;
+ case EXCL_RANGE:
+ super.excludeFrom(i);
+ break;
+ }
+ changed();
+ return this;
+ }
+
+ /* The tree we need to anchor the bits instance to.
+ */
+ LVTBits at(JCTree tree) {
+ this.currentTree = tree;
+ return this;
+ }
+
+ /* If the instance should be changed but the tree is not a closing
+ * tree then a reset is needed or the former tree can mistakingly be
+ * used.
+ */
+ LVTBits resetTree() {
+ this.currentTree = null;
+ return this;
+ }
+
+ /** This method will be called after any operation that causes a change to
+ * the bits. Subclasses can thus override it in order to extract information
+ * from the changes produced to the bits by the given operation.
+ */
+ public void changed() {
+ if (currentTree != null &&
+ stateBeforeOp != BitsState.UNKNOWN &&
+ trackTree(currentTree)) {
+ List<VarSymbol> locals =
+ analyzer.lvtRanges
+ .getVars(analyzer.currentMethod, currentTree);
+ locals = locals != null ?
+ locals : List.<VarSymbol>nil();
+ for (JCVariableDecl vardecl : analyzer.vardecls) {
+ //once the first is null, the rest will be so.
+ if (vardecl == null) {
+ break;
+ }
+ if (trackVar(vardecl.sym) && bitChanged(vardecl.sym.adr)) {
+ locals = locals.prepend(vardecl.sym);
+ }
+ }
+ if (!locals.isEmpty()) {
+ analyzer.lvtRanges.setEntry(analyzer.currentMethod,
+ currentTree, locals);
+ }
+ }
+ }
+
+ boolean bitChanged(int x) {
+ boolean isMemberOfBits = isMember(x);
+ int[] tmp = bits;
+ bits = oldBits;
+ boolean isMemberOfOldBits = isMember(x);
+ bits = tmp;
+ return (!isMemberOfBits && isMemberOfOldBits);
+ }
+
+ boolean trackVar(VarSymbol var) {
+ return (var.owner.kind == MTH &&
+ (var.flags() & (PARAMETER | HASINIT)) == 0 &&
+ analyzer.trackable(var));
+ }
+
+ boolean trackTree(JCTree tree) {
+ switch (tree.getTag()) {
+ // of course a method closes the alive range of a local variable.
+ case METHODDEF:
+ // for while loops we want only the body
+ case WHILELOOP:
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ public class LVTAssignPendingExit extends Flow.AssignAnalyzer.AssignPendingExit {
+
+ LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
+ super(tree, inits, uninits);
+ }
+
+ @Override
+ public void resolveJump(JCTree tree) {
+ lvtInits.at(tree);
+ super.resolveJump(tree);
+ }
+ }
+
+ private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) {
+ super(new LVTBits(), syms, names);
+ lvtInits = (LVTBits)inits;
+ this.lvtRanges = lvtRanges;
+ }
+
+ public static LVTAssignAnalyzer make(LVTRanges lvtRanges, Symtab syms, Names names) {
+ LVTAssignAnalyzer result = new LVTAssignAnalyzer(lvtRanges, syms, names);
+ result.lvtInits.analyzer = result;
+ return result;
+ }
+
+ @Override
+ protected void markDead(JCTree tree) {
+ lvtInits.at(tree).inclRange(returnadr, nextadr);
+ super.markDead(tree);
+ }
+
+ @Override
+ protected void merge(JCTree tree) {
+ lvtInits.at(tree);
+ super.merge(tree);
+ }
+
+ boolean isSyntheticOrMandated(Symbol sym) {
+ return (sym.flags() & (SYNTHETIC | MANDATED)) != 0;
+ }
+
+ @Override
+ protected boolean trackable(VarSymbol sym) {
+ if (isSyntheticOrMandated(sym)) {
+ //fast check to avoid tracking synthetic or mandated variables
+ return false;
+ }
+ return super.trackable(sym);
+ }
+
+ @Override
+ protected void initParam(JCVariableDecl def) {
+ if (!isSyntheticOrMandated(def.sym)) {
+ super.initParam(def);
+ }
+ }
+
+ @Override
+ protected void assignToInits(JCTree tree, Bits bits) {
+ lvtInits.at(tree);
+ lvtInits.assign(bits);
+ }
+
+ @Override
+ protected void andSetInits(JCTree tree, Bits bits) {
+ lvtInits.at(tree);
+ lvtInits.andSet(bits);
+ }
+
+ @Override
+ protected void orSetInits(JCTree tree, Bits bits) {
+ lvtInits.at(tree);
+ lvtInits.orSet(bits);
+ }
+
+ @Override
+ protected void exclVarFromInits(JCTree tree, int adr) {
+ lvtInits.at(tree);
+ lvtInits.excl(adr);
+ }
+
+ @Override
+ protected LVTAssignPendingExit createNewPendingExit(JCTree tree, Bits inits, Bits uninits) {
+ return new LVTAssignPendingExit(tree, inits, uninits);
+ }
+
+ MethodSymbol currentMethod;
+
+ @Override
+ public void visitMethodDef(JCMethodDecl tree) {
+ if ((tree.sym.flags() & (SYNTHETIC | GENERATEDCONSTR)) != 0) {
+ return;
+ }
+ if (tree.name.equals(names.clinit)) {
+ return;
+ }
+ boolean enumClass = (tree.sym.owner.flags() & ENUM) != 0;
+ if (enumClass &&
+ (tree.name.equals(names.valueOf) ||
+ tree.name.equals(names.values) ||
+ tree.name.equals(names.init))) {
+ return;
+ }
+ currentMethod = tree.sym;
+ super.visitMethodDef(tree);
+ }
+
+ }
+
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Tue Sep 17 08:21:11 2013 -0700
@@ -789,18 +789,18 @@
Chain jumpTrue() {
if (tree == null) return Code.mergeChains(trueJumps, code.branch(opcode));
// we should proceed further in -Xjcov mode only
- int startpc = code.curPc();
+ int startpc = code.curCP();
Chain c = Code.mergeChains(trueJumps, code.branch(opcode));
- code.crt.put(tree, CRTable.CRT_BRANCH_TRUE, startpc, code.curPc());
+ code.crt.put(tree, CRTable.CRT_BRANCH_TRUE, startpc, code.curCP());
return c;
}
Chain jumpFalse() {
if (tree == null) return Code.mergeChains(falseJumps, code.branch(Code.negate(opcode)));
// we should proceed further in -Xjcov mode only
- int startpc = code.curPc();
+ int startpc = code.curCP();
Chain c = Code.mergeChains(falseJumps, code.branch(Code.negate(opcode)));
- code.crt.put(tree, CRTable.CRT_BRANCH_FALSE, startpc, code.curPc());
+ code.crt.put(tree, CRTable.CRT_BRANCH_FALSE, startpc, code.curCP());
return c;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/LVTRanges.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.jvm;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.WeakHashMap;
+
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.List;
+
+/** This class contains a one to many relation between a tree and a set of variables.
+ * The relation implies that the given tree closes the DA (definite assignment)
+ * range for the set of variables.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class LVTRanges {
+ /** The context key for the LVT ranges. */
+ protected static final Context.Key<LVTRanges> lvtRangesKey = new Context.Key<>();
+
+ /** Get the LVTRanges instance for this context. */
+ public static LVTRanges instance(Context context) {
+ LVTRanges instance = context.get(lvtRangesKey);
+ if (instance == null) {
+ instance = new LVTRanges(context);
+ }
+ return instance;
+ }
+
+ private static final long serialVersionUID = 1812267524140424433L;
+
+ protected Context context;
+
+ protected Map<MethodSymbol, Map<JCTree, List<VarSymbol>>>
+ aliveRangeClosingTrees = new WeakHashMap<>();
+
+ public LVTRanges(Context context) {
+ this.context = context;
+ context.put(lvtRangesKey, this);
+ }
+
+ public List<VarSymbol> getVars(MethodSymbol method, JCTree tree) {
+ Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
+ return (varMap != null) ? varMap.get(tree) : null;
+ }
+
+ public boolean containsKey(MethodSymbol method, JCTree tree) {
+ Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
+ if (varMap == null) {
+ return false;
+ }
+ return varMap.containsKey(tree);
+ }
+
+ public void setEntry(MethodSymbol method, JCTree tree, List<VarSymbol> vars) {
+ Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
+ if (varMap != null) {
+ varMap.put(tree, vars);
+ } else {
+ varMap = new WeakHashMap<>();
+ varMap.put(tree, vars);
+ aliveRangeClosingTrees.put(method, varMap);
+ }
+ }
+
+ public List<VarSymbol> removeEntry(MethodSymbol method, JCTree tree) {
+ Map<JCTree, List<VarSymbol>> varMap = aliveRangeClosingTrees.get(method);
+ if (varMap != null) {
+ List<VarSymbol> result = varMap.remove(tree);
+ if (varMap.isEmpty()) {
+ aliveRangeClosingTrees.remove(method);
+ }
+ return result;
+ }
+ return null;
+ }
+
+ /* This method should be used for debugging LVT related issues.
+ */
+ @Override
+ public String toString() {
+ String result = "";
+ for (Entry<MethodSymbol, Map<JCTree, List<VarSymbol>>> mainEntry: aliveRangeClosingTrees.entrySet()) {
+ result += "Method: \n" + mainEntry.getKey().flatName() + "\n";
+ int i = 1;
+ for (Entry<JCTree, List<VarSymbol>> treeEntry: mainEntry.getValue().entrySet()) {
+ result += " Tree " + i + ": \n" + treeEntry.getKey().toString() + "\n";
+ result += " Variables closed:\n";
+ for (VarSymbol var: treeEntry.getValue()) {
+ result += " " + var.toString();
+ }
+ result += "\n";
+ i++;
+ }
+ }
+ return result;
+ }
+
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Sep 17 08:21:11 2013 -0700
@@ -80,7 +80,7 @@
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
-public class JavaCompiler implements ClassReader.SourceCompleter {
+public class JavaCompiler {
/** The context key for the compiler. */
protected static final Context.Key<JavaCompiler> compilerKey =
new Context.Key<JavaCompiler>();
@@ -311,6 +311,17 @@
protected JavaCompiler delegateCompiler;
/**
+ * SourceCompleter that delegates to the complete-method of this class.
+ */
+ protected final ClassReader.SourceCompleter thisCompleter =
+ new ClassReader.SourceCompleter() {
+ @Override
+ public void complete(ClassSymbol sym) throws CompletionFailure {
+ JavaCompiler.this.complete(sym);
+ }
+ };
+
+ /**
* Command line options.
*/
protected Options options;
@@ -374,7 +385,7 @@
types = Types.instance(context);
taskListener = MultiTaskListener.instance(context);
- reader.sourceCompleter = this;
+ reader.sourceCompleter = thisCompleter;
options = Options.instance(context);
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Sep 17 08:21:11 2013 -0700
@@ -742,11 +742,6 @@
compiler.misc.incompatible.arg.types.in.mref=\
incompatible parameter types in method reference
-# 0: list of type, 1: message segment
-compiler.misc.bad.arg.types.in.lambda=\
- cannot type-check lambda expression with inferred parameter types\n\
- inferred types: {0}
-
compiler.err.new.not.allowed.in.annotation=\
''new'' not allowed in an annotation
@@ -1397,6 +1392,10 @@
compiler.warn.missing.SVUID=\
serializable class {0} has no definition of serialVersionUID
+# 0: symbol, 1: symbol, 2: symbol, 3: symbol
+compiler.warn.potentially.ambiguous.overload=\
+ {0} in {1} is potentially ambiguous with {2} in {3}
+
# 0: message segment
compiler.warn.override.varargs.missing=\
{0}; overridden method has no ''...''
@@ -1916,10 +1915,6 @@
inferred: {0}\n\
equality constraints(s): {1}
-# 0: list of type
-compiler.misc.cyclic.inference=\
- Cannot instantiate inference variables {0} because of an inference loop
-
# 0: symbol
compiler.misc.diamond=\
{0}<>
@@ -1932,6 +1927,10 @@
compiler.misc.diamond.and.explicit.params=\
cannot use ''<>'' with explicit type parameters for constructor
+# 0: unused
+compiler.misc.mref.infer.and.explicit.params=\
+ cannot use raw constructor reference with explicit type parameters for constructor
+
# 0: type, 1: list of type
compiler.misc.explicit.param.do.not.conform.to.bounds=\
explicit type argument {0} does not conform to declared bound(s) {1}
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Tue Sep 17 08:21:11 2013 -0700
@@ -1596,7 +1596,6 @@
public List<JCVariableDecl> params;
public JCTree body;
public boolean canCompleteNormally = true;
- public List<Type> inferredThrownTypes;
public ParameterKind paramKind;
public JCLambda(List<JCVariableDecl> params,
@@ -1908,6 +1907,7 @@
* Selects a member expression.
*/
public static class JCMemberReference extends JCFunctionalExpression implements MemberReferenceTree {
+
public ReferenceMode mode;
public ReferenceKind kind;
public Name name;
@@ -1917,6 +1917,12 @@
public Type varargsElement;
public PolyKind refPolyKind;
public boolean ownerAccessible;
+ public OverloadKind overloadKind;
+
+ public enum OverloadKind {
+ OVERLOADED,
+ UNOVERLOADED;
+ }
/**
* Javac-dependent classification for member references, based
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Tue Sep 17 08:21:11 2013 -0700
@@ -890,7 +890,7 @@
/** Create a value parameter tree from its name, type, and owner.
*/
public JCVariableDecl Param(Name name, Type argtype, Symbol owner) {
- return VarDef(new VarSymbol(0, name, argtype, owner), null);
+ return VarDef(new VarSymbol(PARAMETER, name, argtype, owner), null);
}
/** Create a a list of value parameter trees x0, ..., xn from a list of
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Bits.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Bits.java Tue Sep 17 08:21:11 2013 -0700
@@ -27,8 +27,6 @@
import java.util.Arrays;
-import static com.sun.tools.javac.util.Bits.BitsOpKind.*;
-
/** A class for extensible, mutable bit sets.
*
* <p><b>This is NOT part of any supported API.
@@ -38,20 +36,6 @@
*/
public class Bits {
- public enum BitsOpKind {
- INIT,
- CLEAR,
- INCL_BIT,
- EXCL_BIT,
- ASSIGN,
- AND_SET,
- OR_SET,
- DIFF_SET,
- XOR_SET,
- INCL_RANGE,
- EXCL_RANGE,
- }
-
// ____________ reset _________
// / UNKNOWN \ <-------- / UNINIT \
// \____________/ | \_________/
@@ -64,11 +48,14 @@
// | |
// -----------
// any
- private enum BitsState {
+ protected enum BitsState {
/* A Bits instance is in UNKNOWN state if it has been explicitly reset.
* It is possible to get to this state from any other by calling the
* reset method. An instance in the UNKNOWN state can pass to the
* NORMAL state after being assigned another Bits instance.
+ *
+ * Bits instances are final fields in Flow so the UNKNOWN state models
+ * the null assignment.
*/
UNKNOWN,
/* A Bits instance is in UNINIT when it is created with the default
@@ -103,13 +90,9 @@
public int[] bits = null;
// This field will store last version of bits after every change.
- public int[] oldBits = null;
-
- public BitsOpKind lastOperation = null;
-
private static final int[] unassignedBits = new int[0];
- private BitsState currentState;
+ protected BitsState currentState;
/** Construct an initially empty set.
*/
@@ -127,27 +110,20 @@
/** Construct a set consisting initially of given bit vector.
*/
- private Bits(int[] bits, BitsState initState) {
+ protected Bits(int[] bits, BitsState initState) {
this.bits = bits;
this.currentState = initState;
switch (initState) {
case UNKNOWN:
- reset(); //this will also set current state;
+ this.bits = null;
break;
case NORMAL:
Assert.check(bits != unassignedBits);
- lastOperation = INIT;
break;
}
}
- /** This method will be called after any operation that causes a change to
- * the bits. Subclasses can thus override it in order to extract information
- * from the changes produced to the bits by the given operation.
- */
- public void changed() {}
-
- private void sizeTo(int len) {
+ protected void sizeTo(int len) {
if (bits.length < len) {
bits = Arrays.copyOf(bits, len);
}
@@ -157,16 +133,18 @@
*/
public void clear() {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = CLEAR;
- for (int i = 0; i < bits.length; i++) bits[i] = 0;
- changed();
+ for (int i = 0; i < bits.length; i++) {
+ bits[i] = 0;
+ }
currentState = BitsState.NORMAL;
}
public void reset() {
+ internalReset();
+ }
+
+ protected void internalReset() {
bits = null;
- oldBits = null;
currentState = BitsState.UNKNOWN;
}
@@ -175,40 +153,40 @@
}
public Bits assign(Bits someBits) {
- lastOperation = ASSIGN;
- oldBits = bits;
bits = someBits.dup().bits;
- changed();
currentState = BitsState.NORMAL;
return this;
}
/** Return a copy of this set.
*/
- private Bits dup() {
+ public Bits dup() {
Assert.check(currentState != BitsState.UNKNOWN);
Bits tmp = new Bits();
- if (currentState != BitsState.NORMAL) {
- tmp.bits = bits;
- } else {
- tmp.bits = new int[bits.length];
- System.arraycopy(bits, 0, tmp.bits, 0, bits.length);
- }
+ tmp.bits = dupBits();
currentState = BitsState.NORMAL;
return tmp;
}
+ protected int[] dupBits() {
+ int [] result;
+ if (currentState != BitsState.NORMAL) {
+ result = bits;
+ } else {
+ result = new int[bits.length];
+ System.arraycopy(bits, 0, result, 0, bits.length);
+ }
+ return result;
+ }
+
/** Include x in this set.
*/
public void incl(int x) {
Assert.check(currentState != BitsState.UNKNOWN);
- Assert.check(x >= 0);
- oldBits = bits;
- lastOperation = INCL_BIT;
+ Assert.check(x >= 0, "Value of x " + x);
sizeTo((x >>> wordshift) + 1);
bits[x >>> wordshift] = bits[x >>> wordshift] |
(1 << (x & wordmask));
- changed();
currentState = BitsState.NORMAL;
}
@@ -217,14 +195,11 @@
*/
public void inclRange(int start, int limit) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = INCL_RANGE;
sizeTo((limit >>> wordshift) + 1);
for (int x = start; x < limit; x++) {
bits[x >>> wordshift] = bits[x >>> wordshift] |
(1 << (x & wordmask));
}
- changed();
currentState = BitsState.NORMAL;
}
@@ -232,13 +207,10 @@
*/
public void excludeFrom(int start) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = EXCL_RANGE;
Bits temp = new Bits();
temp.sizeTo(bits.length);
temp.inclRange(0, start);
internalAndSet(temp);
- changed();
currentState = BitsState.NORMAL;
}
@@ -247,12 +219,9 @@
public void excl(int x) {
Assert.check(currentState != BitsState.UNKNOWN);
Assert.check(x >= 0);
- oldBits = bits;
- lastOperation = EXCL_BIT;
sizeTo((x >>> wordshift) + 1);
bits[x >>> wordshift] = bits[x >>> wordshift] &
~(1 << (x & wordmask));
- changed();
currentState = BitsState.NORMAL;
}
@@ -269,15 +238,12 @@
*/
public Bits andSet(Bits xs) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = AND_SET;
internalAndSet(xs);
- changed();
currentState = BitsState.NORMAL;
return this;
}
- private void internalAndSet(Bits xs) {
+ protected void internalAndSet(Bits xs) {
Assert.check(currentState != BitsState.UNKNOWN);
sizeTo(xs.bits.length);
for (int i = 0; i < xs.bits.length; i++) {
@@ -289,13 +255,10 @@
*/
public Bits orSet(Bits xs) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = OR_SET;
sizeTo(xs.bits.length);
for (int i = 0; i < xs.bits.length; i++) {
bits[i] = bits[i] | xs.bits[i];
}
- changed();
currentState = BitsState.NORMAL;
return this;
}
@@ -304,14 +267,11 @@
*/
public Bits diffSet(Bits xs) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = DIFF_SET;
for (int i = 0; i < bits.length; i++) {
if (i < xs.bits.length) {
bits[i] = bits[i] & ~xs.bits[i];
}
}
- changed();
currentState = BitsState.NORMAL;
return this;
}
@@ -320,13 +280,10 @@
*/
public Bits xorSet(Bits xs) {
Assert.check(currentState != BitsState.UNKNOWN);
- oldBits = bits;
- lastOperation = XOR_SET;
sizeTo(xs.bits.length);
for (int i = 0; i < xs.bits.length; i++) {
bits[i] = bits[i] ^ xs.bits[i];
}
- changed();
currentState = BitsState.NORMAL;
return this;
}
@@ -336,7 +293,9 @@
*/
private static int trailingZeroBits(int x) {
Assert.check(wordlen == 32);
- if (x == 0) return 32;
+ if (x == 0) {
+ return 32;
+ }
int n = 1;
if ((x & 0xffff) == 0) { n += 16; x >>>= 16; }
if ((x & 0x00ff) == 0) { n += 8; x >>>= 8; }
@@ -355,24 +314,31 @@
public int nextBit(int x) {
Assert.check(currentState != BitsState.UNKNOWN);
int windex = x >>> wordshift;
- if (windex >= bits.length) return -1;
+ if (windex >= bits.length) {
+ return -1;
+ }
int word = bits[windex] & ~((1 << (x & wordmask))-1);
while (true) {
- if (word != 0)
+ if (word != 0) {
return (windex << wordshift) + trailingZeroBits(word);
+ }
windex++;
- if (windex >= bits.length) return -1;
+ if (windex >= bits.length) {
+ return -1;
+ }
word = bits[windex];
}
}
/** a string representation of this set.
*/
+ @Override
public String toString() {
- if (bits.length > 0) {
+ if (bits != null && bits.length > 0) {
char[] digits = new char[bits.length * wordlen];
- for (int i = 0; i < bits.length * wordlen; i++)
+ for (int i = 0; i < bits.length * wordlen; i++) {
digits[i] = isMember(i) ? '1' : '0';
+ }
return new String(digits);
} else {
return "[]";
@@ -396,6 +362,8 @@
System.out.println("found " + i);
count ++;
}
- if (count != 125) throw new Error();
+ if (count != 125) {
+ throw new Error();
+ }
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java Tue Sep 17 08:21:11 2013 -0700
@@ -33,6 +33,18 @@
public class GraphUtils {
/**
+ * Basic interface for defining various dependency kinds. All dependency kinds
+ * must at least support basic capabilities to tell the DOT engine how to render them.
+ */
+ public interface DependencyKind {
+ /**
+ * Returns the DOT representation (to be used in a {@code style} attribute
+ * that's most suited for this dependency kind.
+ */
+ String getDotStyle();
+ }
+
+ /**
* This class is a basic abstract class for representing a node.
* A node is associated with a given data.
*/
@@ -43,9 +55,20 @@
this.data = data;
}
- public abstract Iterable<? extends Node<D>> getDependencies();
+ /**
+ * Get an array of the dependency kinds supported by this node.
+ */
+ public abstract DependencyKind[] getSupportedDependencyKinds();
- public abstract String printDependency(Node<D> to);
+ /**
+ * Get all dependencies, regardless of their kind.
+ */
+ public abstract Iterable<? extends Node<D>> getAllDependencies();
+
+ /**
+ * Get a name for the dependency (of given kind) linking this node to a given node
+ */
+ public abstract String getDependencyName(Node<D> to, DependencyKind dk);
@Override
public String toString() {
@@ -66,7 +89,9 @@
super(data);
}
- public abstract Iterable<? extends TarjanNode<D>> getDependencies();
+ public abstract Iterable<? extends TarjanNode<D>> getAllDependencies();
+
+ public abstract Iterable<? extends TarjanNode<D>> getDependenciesByKind(DependencyKind dk);
public int compareTo(TarjanNode<D> o) {
return (index < o.index) ? -1 : (index == o.index) ? 0 : 1;
@@ -95,7 +120,7 @@
index++;
stack.prepend(v);
v.active = true;
- for (TarjanNode<D> nd: v.getDependencies()) {
+ for (TarjanNode<D> nd: v.getAllDependencies()) {
@SuppressWarnings("unchecked")
N n = (N)nd;
if (n.index == -1) {
@@ -134,9 +159,11 @@
}
//dump arcs
for (TarjanNode<D> from : nodes) {
- for (TarjanNode<D> to : from.getDependencies()) {
- buf.append(String.format("%s -> %s [label = \" %s \"];\n",
- from.hashCode(), to.hashCode(), from.printDependency(to)));
+ for (DependencyKind dk : from.getSupportedDependencyKinds()) {
+ for (TarjanNode<D> to : from.getDependenciesByKind(dk)) {
+ buf.append(String.format("%s -> %s [label = \" %s \" style = %s ];\n",
+ from.hashCode(), to.hashCode(), from.getDependencyName(to, dk), dk.getDotStyle()));
+ }
}
}
buf.append("}\n");
--- a/langtools/src/share/classes/com/sun/tools/javac/util/List.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/List.java Tue Sep 17 08:21:11 2013 -0700
@@ -116,6 +116,19 @@
return buf.toList();
}
+ /**
+ * Create a new list from the first {@code n} elements of this list
+ */
+ public List<A> take(int n) {
+ ListBuffer<A> buf = ListBuffer.lb();
+ int count = 0;
+ for (A el : this) {
+ if (count++ == n) break;
+ buf.append(el);
+ }
+ return buf.toList();
+ }
+
/** Construct a list consisting of given element.
*/
public static <A> List<A> of(A x1) {
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java Tue Sep 17 08:21:11 2013 -0700
@@ -40,7 +40,7 @@
public class AnnotatedTypeImpl
extends AbstractTypeImpl implements AnnotatedType {
- AnnotatedTypeImpl(DocEnv env, com.sun.tools.javac.code.Type.AnnotatedType type) {
+ AnnotatedTypeImpl(DocEnv env, com.sun.tools.javac.code.Type type) {
super(env, type);
}
@@ -50,7 +50,7 @@
*/
@Override
public AnnotationDesc[] annotations() {
- List<TypeCompound> tas = ((com.sun.tools.javac.code.Type.AnnotatedType)type).typeAnnotations;
+ List<? extends TypeCompound> tas = type.getAnnotationMirrors();
if (tas == null ||
tas.isEmpty()) {
return new AnnotationDesc[0];
@@ -65,7 +65,7 @@
@Override
public com.sun.javadoc.Type underlyingType() {
- return TypeMaker.getType(env, ((com.sun.tools.javac.code.Type.AnnotatedType)type).underlyingType, true, false);
+ return TypeMaker.getType(env, type.unannotatedType(), true, false);
}
@Override
--- a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java Tue Sep 17 08:21:11 2013 -0700
@@ -289,7 +289,7 @@
}
public boolean isFunctionalInterface() {
- return env.types.isFunctionalInterface(tsym);
+ return env.types.isFunctionalInterface(tsym) && env.source.allowLambda();
}
/**
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Tue Sep 17 08:21:11 2013 -0700
@@ -124,6 +124,11 @@
private boolean silent = false;
/**
+ * The source language version.
+ */
+ protected Source source;
+
+ /**
* Constructor
*
* @param context Context for this javadoc instance.
@@ -144,6 +149,7 @@
// Default. Should normally be reset with setLocale.
this.doclocale = new DocLocale(this, "", breakiterator);
+ source = Source.instance(context);
}
public void setSilent(boolean silent) {
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -134,7 +134,7 @@
docenv.setEncoding(encoding);
docenv.docClasses = docClasses;
docenv.legacyDoclet = legacyDoclet;
- javadocReader.sourceCompleter = docClasses ? null : this;
+ javadocReader.sourceCompleter = docClasses ? null : thisCompleter;
ListBuffer<String> names = new ListBuffer<String>();
ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<JCCompilationUnit>();
--- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java Tue Sep 17 08:21:11 2013 -0700
@@ -63,10 +63,8 @@
t = env.types.erasure(t);
}
- if (considerAnnotations &&
- t.isAnnotated()) {
- Type.AnnotatedType at = (Type.AnnotatedType) t;
- return new AnnotatedTypeImpl(env, at);
+ if (considerAnnotations && t.isAnnotated()) {
+ return new AnnotatedTypeImpl(env, t);
}
switch (t.getTag()) {
@@ -143,8 +141,7 @@
static String getTypeString(DocEnv env, Type t, boolean full) {
// TODO: should annotations be included here?
if (t.isAnnotated()) {
- Type.AnnotatedType at = (Type.AnnotatedType)t;
- t = at.underlyingType;
+ t = t.unannotatedType();
}
switch (t.getTag()) {
case ARRAY:
--- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java Tue Sep 17 08:21:11 2013 -0700
@@ -140,7 +140,7 @@
if (!type.isAnnotated()) {
return new AnnotationDesc[0];
}
- List<TypeCompound> tas = ((com.sun.tools.javac.code.Type.AnnotatedType) type).typeAnnotations;
+ List<? extends TypeCompound> tas = type.getAnnotationMirrors();
AnnotationDesc res[] = new AnnotationDesc[tas.length()];
int i = 0;
for (Attribute.Compound a : tas) {
--- a/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/com/sun/javadoc/AccessSkipNav/AccessSkipNav.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4638136
+ * @bug 4638136 7198273
* @summary Add ability to skip over nav bar for accessibility
* @author dkramer
* @run main AccessSkipNav
@@ -42,7 +42,7 @@
*/
public class AccessSkipNav {
- private static final String BUGID = "4638136";
+ private static final String BUGID = "4638136 - 7198273";
private static final String BUGNAME = "AccessSkipNav";
private static final String FS = System.getProperty("file.separator");
private static final String PS = System.getProperty("path.separator");
@@ -86,7 +86,7 @@
// Testing only for the presence of the <a href> and <a name>
// Top navbar <a href>
- { "<a href=\"#skip-navbar_top\" title=\"Skip navigation links\"></a>",
+ { "<a href=\"#skip-navbar_top\" title=\"Skip navigation links\">Skip navigation links</a>",
TMPDEST_DIR1 + "p1" + FS + "C1.html" },
// Top navbar <a name>
@@ -95,7 +95,7 @@
TMPDEST_DIR1 + "p1" + FS + "C1.html" },
// Bottom navbar <a href>
- { "<a href=\"#skip-navbar_bottom\" title=\"Skip navigation links\"></a>",
+ { "<a href=\"#skip-navbar_bottom\" title=\"Skip navigation links\">Skip navigation links</a>",
TMPDEST_DIR1 + "p1" + FS + "C1.html" },
// Bottom navbar <a name>
--- a/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testGeneratedBy/TestGeneratedBy.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8000418
+ * @bug 8000418 8024288
* @summary Verify that files use a common Generated By string
* @library ../lib/
* @build JavadocTester TestGeneratedBy
@@ -50,32 +50,44 @@
"index.html"
};
- private static final String[] ARGS =
+ private static final String[] STD_ARGS =
new String[] {
"-d", OUTPUT_DIR,
"-sourcepath", SRC_DIR,
"pkg"
};
- private static final String BUG_ID = "8000418";
- private static String[][] getTests() {
+ private static final String[] NO_TIMESTAMP_ARGS =
+ new String[] {
+ "-notimestamp",
+ "-d", OUTPUT_DIR,
+ "-sourcepath", SRC_DIR,
+ "pkg"
+ };
+
+ private static final String BUG_ID = "8000418-8024288";
+
+ private static String[][] getTests(boolean timestamp) {
String version = System.getProperty("java.version");
String[][] tests = new String[FILES.length][];
for (int i = 0; i < FILES.length; i++) {
+ String genBy = "Generated by javadoc";
+ if (timestamp) genBy += " (" + version + ") on ";
tests[i] = new String[] {
- OUTPUT_DIR + FS + FILES[i],
- "Generated by javadoc (" + version + ") on "
+ OUTPUT_DIR + FS + FILES[i], genBy
};
}
return tests;
}
- private static String[][] getNegatedTests() {
+ private static String[][] getNegatedTests(boolean timestamp) {
String[][] tests = new String[FILES.length][];
for (int i = 0; i < FILES.length; i++) {
tests[i] = new String[] {
OUTPUT_DIR + FS + FILES[i],
- "Generated by javadoc (version",
+ (timestamp
+ ? "Generated by javadoc (version"
+ : "Generated by javadoc ("),
"Generated by javadoc on"
};
}
@@ -88,9 +100,10 @@
*/
public static void main(String[] args) {
TestGeneratedBy tester = new TestGeneratedBy();
- int exitCode = run(tester, ARGS, getTests(), getNegatedTests());
+ int ec1 = run(tester, STD_ARGS, getTests(true), getNegatedTests(true));
+ int ec2 = run(tester, NO_TIMESTAMP_ARGS, getTests(false), getNegatedTests(false));
tester.printSummary();
- if (exitCode != 0) {
+ if (ec1 != 0 || ec2 != 0) {
throw new Error("Error found while executing Javadoc");
}
}
--- a/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testLambdaFeature/TestLambdaFeature.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8004893
+ * @bug 8004893 8022738
* @summary Make sure that the lambda feature changes work fine in
* javadoc.
* @author bpatel
@@ -35,11 +35,15 @@
public class TestLambdaFeature extends JavadocTester {
//Test information.
- private static final String BUG_ID = "8004893";
+ private static final String BUG_ID = "8004893-8022738";
//Javadoc arguments.
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
+ "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "pkg1"
+ };
+
+ private static final String[] ARGS_1 = new String[] {
+ "-d", BUG_ID + "-2", "-sourcepath", SRC_DIR, "-source", "1.5", "pkg1"
};
//Input for string search tests.
@@ -63,6 +67,11 @@
"<dl>" + NL + "<dt>Functional Interface:</dt>" + NL +
"<dd>This is a functional interface and can therefore be used as " +
"the assignment target for a lambda expression or method " +
+ "reference.</dd>" + NL + "</dl>"},
+ {BUG_ID + FS + "pkg1" + FS + "FuncInf.html",
+ "<dl>" + NL + "<dt>Functional Interface:</dt>" + NL +
+ "<dd>This is a functional interface and can therefore be used as " +
+ "the assignment target for a lambda expression or method " +
"reference.</dd>" + NL + "</dl>"}
};
private static final String[][] NEGATED_TEST = {
@@ -75,6 +84,10 @@
{BUG_ID + FS + "pkg" + FS + "B.html",
"<dl>" + NL + "<dt>Functional Interface:</dt>"}
};
+ private static final String[][] NEGATED_TEST_1 = {
+ {BUG_ID + "-2" + FS + "pkg1" + FS + "FuncInf.html",
+ "<dl>" + NL + "<dt>Functional Interface:</dt>"}
+ };
/**
* The entry point of the test.
@@ -83,6 +96,7 @@
public static void main(String[] args) {
TestLambdaFeature tester = new TestLambdaFeature();
run(tester, ARGS, TEST, NEGATED_TEST);
+ run(tester, ARGS_1, NO_TEST, NEGATED_TEST_1);
tester.printSummary();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testLambdaFeature/pkg1/FuncInf.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+public interface FuncInf<V> {
+
+ V call() throws Exception;
+}
--- a/langtools/test/com/sun/javadoc/testLegacyTaglet/C.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testLegacyTaglet/C.java Tue Sep 17 08:21:11 2013 -0700
@@ -25,5 +25,13 @@
/**
* This is an {@underline underline}.
* @todo Finish this class.
+ * @check Check this.
*/
-public class C {}
+public class C {
+
+ /**
+ * @todo Tag in Method.
+ */
+ public void mtd() {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testLegacyTaglet/Check.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.tools.doclets.Taglet;
+import com.sun.javadoc.*;
+import java.util.Map;
+
+public class Check implements Taglet {
+
+ private static final String TAG_NAME = "check";
+ private static final String TAG_HEADER = "Check:";
+
+ /**
+ * Return true since the tag can be used in package documentation.
+ *
+ * @return true since the tag can be used in package documentation.
+ */
+ public boolean inPackage() {
+ return true;
+ }
+
+ /**
+ * Return true since the tag can be used in overview documentation.
+ *
+ * @return true since the tag can be used in overview documentation.
+ */
+ public boolean inOverview() {
+ return true;
+ }
+
+ /**
+ * Return true since the tag can be used in type (class/interface)
+ * documentation.
+ *
+ * @return true since the tag can be used in type (class/interface)
+ * documentation.
+ */
+ public boolean inType() {
+ return true;
+ }
+
+ /**
+ * Return true since the tag can be used in constructor documentation.
+ *
+ * @return true since the tag can be used in constructor documentation.
+ */
+ public boolean inConstructor() {
+ return true;
+ }
+
+ /**
+ * Return true since the tag can be used in field documentation.
+ *
+ * @return true since the tag can be used in field documentation.
+ */
+ public boolean inField() {
+ return true;
+ }
+
+ /**
+ * Return true since the tag can be used in method documentation.
+ *
+ * @return true since the tag can be used in method documentation.
+ */
+ public boolean inMethod() {
+ return true;
+ }
+
+ /**
+ * Return false since the tag is not an inline tag.
+ *
+ * @return false since the tag is not an inline tag.
+ */
+ public boolean isInlineTag() {
+ return false;
+ }
+
+ /**
+ * Register this taglet.
+ *
+ * @param tagletMap the map to register this tag to.
+ */
+ @SuppressWarnings("unchecked")
+ public static void register(Map tagletMap) {
+ Check tag = new Check();
+ Taglet t = (Taglet) tagletMap.get(tag.getName());
+ if (t != null) {
+ tagletMap.remove(tag.getName());
+ }
+ tagletMap.put(tag.getName(), tag);
+ }
+
+ /**
+ * Return the name of this custom tag.
+ *
+ * @return the name of this tag.
+ */
+ public String getName() {
+ return TAG_NAME;
+ }
+
+ /**
+ * Given the tag representation of this custom tag, return its string
+ * representation.
+ *
+ * @param tag the tag representation of this custom tag.
+ */
+ public String toString(Tag tag) {
+ return "<dt><span class=\"strong\">" + TAG_HEADER + ":</span></dt><dd>" + tag.text() +
+ "</dd>\n";
+ }
+
+ /**
+ * Given an array of tags representing this custom tag, return its string
+ * representation.
+ *
+ * @param tags the array of tags representing of this custom tag.
+ * @return null to test if the javadoc throws an exception or not.
+ */
+ public String toString(Tag[] tags) {
+ return null;
+ }
+}
--- a/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testLegacyTaglet/TestLegacyTaglet.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,32 +23,33 @@
/*
* @test
- * @bug 4638723
+ * @bug 4638723 8015882
* @summary Test to ensure that the refactored version of the standard
* doclet still works with Taglets that implement the 1.4.0 interface.
* @author jamieh
* @library ../lib/
- * @compile ../lib/JavadocTester.java
- * @compile TestLegacyTaglet.java
- * @compile ToDoTaglet.java
- * @compile UnderlineTaglet.java
+ * @compile ../lib/JavadocTester.java TestLegacyTaglet.java ToDoTaglet.java UnderlineTaglet.java Check.java
* @run main TestLegacyTaglet
*/
public class TestLegacyTaglet extends JavadocTester {
- private static final String BUG_ID = "4638723";
+ private static final String BUG_ID = "4638723-8015882";
private static final String[] ARGS =
new String[] {"-d", BUG_ID, "-sourcepath", SRC_DIR,
- "-tagletpath", SRC_DIR, "-taglet", "ToDoTaglet",
+ "-tagletpath", SRC_DIR, "-taglet", "ToDoTaglet", "-taglet", "Check",
"-taglet", "UnderlineTaglet", SRC_DIR + FS + "C.java"};
private static final String[][] TEST = new String[][] {
{BUG_ID + FS + "C.html", "This is an <u>underline</u>"},
{BUG_ID + FS + "C.html",
"<DT><B>To Do:</B><DD><table cellpadding=2 cellspacing=0><tr>" +
- "<td bgcolor=\"yellow\">Finish this class.</td></tr></table></DD>"}};
+ "<td bgcolor=\"yellow\">Finish this class.</td></tr></table></DD>"},
+ {BUG_ID + FS + "C.html",
+ "<DT><B>To Do:</B><DD><table cellpadding=2 cellspacing=0><tr>" +
+ "<td bgcolor=\"yellow\">Tag in Method.</td></tr></table></DD>"}
+ };
private static final String[][] NEGATED_TEST = NO_TEST;
@@ -59,6 +60,9 @@
public static void main(String[] args) {
TestLegacyTaglet tester = new TestLegacyTaglet();
run(tester, ARGS, TEST, NEGATED_TEST);
+ if (tester.getErrorOutput().contains("NullPointerException")) {
+ throw new AssertionError("javadoc threw NullPointerException");
+ }
tester.printSummary();
}
--- a/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java Tue Sep 17 08:21:11 2013 -0700
@@ -23,13 +23,12 @@
/*
* @test
- * @bug 4131628 4664607 7025314
+ * @bug 4131628 4664607 7025314 8023700 7198273
* @summary Make sure the Next/Prev Class links iterate through all types.
* Make sure the navagation is 2 columns, not 3.
* @author jamieh
* @library ../lib/
- * @build JavadocTester
- * @build TestNavigation
+ * @build JavadocTester TestNavigation
* @run main TestNavigation
*/
@@ -45,23 +44,23 @@
//Input for string search tests.
private static final String[][] TEST = {
- {BUG_ID + FS + "pkg" + FS + "A.html", "<li>Prev Class</li>"},
+ {BUG_ID + FS + "pkg" + FS + "A.html", "<li>Prev Class</li>"},
{BUG_ID + FS + "pkg" + FS + "A.html",
- "<a href=\"../pkg/C.html\" title=\"class in pkg\"><span class=\"strong\">Next Class</span></a>"},
+ "<a href=\"../pkg/C.html\" title=\"class in pkg\"><span class=\"strong\">Next Class</span></a>"},
{BUG_ID + FS + "pkg" + FS + "C.html",
- "<a href=\"../pkg/A.html\" title=\"annotation in pkg\"><span class=\"strong\">Prev Class</span></a>"},
+ "<a href=\"../pkg/A.html\" title=\"annotation in pkg\"><span class=\"strong\">Prev Class</span></a>"},
{BUG_ID + FS + "pkg" + FS + "C.html",
- "<a href=\"../pkg/E.html\" title=\"enum in pkg\"><span class=\"strong\">Next Class</span></a>"},
+ "<a href=\"../pkg/E.html\" title=\"enum in pkg\"><span class=\"strong\">Next Class</span></a>"},
{BUG_ID + FS + "pkg" + FS + "E.html",
- "<a href=\"../pkg/C.html\" title=\"class in pkg\"><span class=\"strong\">Prev Class</span></a>"},
+ "<a href=\"../pkg/C.html\" title=\"class in pkg\"><span class=\"strong\">Prev Class</span></a>"},
{BUG_ID + FS + "pkg" + FS + "E.html",
- "<a href=\"../pkg/I.html\" title=\"interface in pkg\"><span class=\"strong\">Next Class</span></a>"},
+ "<a href=\"../pkg/I.html\" title=\"interface in pkg\"><span class=\"strong\">Next Class</span></a>"},
{BUG_ID + FS + "pkg" + FS + "I.html",
- "<a href=\"../pkg/E.html\" title=\"enum in pkg\"><span class=\"strong\">Prev Class</span></a>"},
- {BUG_ID + FS + "pkg" + FS + "I.html", "<li>Next Class</li>"},
+ "<a href=\"../pkg/E.html\" title=\"enum in pkg\"><span class=\"strong\">Prev Class</span></a>"},
+ {BUG_ID + FS + "pkg" + FS + "I.html", "<li>Next Class</li>"},
// Test for 4664607
{BUG_ID + FS + "pkg" + FS + "I.html",
- "<a href=\"#skip-navbar_top\" title=\"Skip navigation links\"></a><a name=\"navbar_top_firstrow\">" + NL +
+ "<div class=\"skipNav\"><a href=\"#skip-navbar_top\" title=\"Skip navigation links\">Skip navigation links</a></div>" + NL + "<a name=\"navbar_top_firstrow\">" + NL +
"<!-- -->" + NL + "</a>"}
};
private static final String[][] NEGATED_TEST = NO_TEST;
--- a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java Tue Sep 17 08:21:11 2013 -0700
@@ -23,9 +23,9 @@
/*
* @test
- * @bug 8006124 8009684 8016921
+ * @bug 8006124 8009684 8016921 8023700
* @summary Test javadoc support for profiles.
- * @author Bhavesh Patel
+ * @author Bhavesh Patel, Evgeniya Stepanova
* @library ../lib/
* @build JavadocTester TestProfiles
* @run main TestProfiles
@@ -38,8 +38,9 @@
private static final String PACKAGE_BUG_ID = BUG_ID + "-2";
//Javadoc arguments.
private static final String[] ARGS1 = new String[]{
- "-d", PROFILE_BUG_ID, "-sourcepath", SRC_DIR, "-Xprofilespath", SRC_DIR + FS
- + "profile-rtjar-includes.txt", "pkg1", "pkg2", "pkg3", "pkg4", "pkg5"
+ "-d", PROFILE_BUG_ID, "-sourcepath", SRC_DIR, "-Xprofilespath",
+ SRC_DIR + FS + "profile-rtjar-includes.txt", "pkg1", "pkg2",
+ "pkg3", "pkg4", "pkg5", "pkgDeprecated"
};
private static final String[] ARGS2 = new String[]{
"-d", PACKAGE_BUG_ID, "-sourcepath", SRC_DIR, "pkg1", "pkg2", "pkg3", "pkg4", "pkg5"
@@ -49,7 +50,7 @@
// Tests for profile-overview-frame.html listing all profiles.
{PROFILE_BUG_ID + FS + "profile-overview-frame.html",
"<span><a href=\"overview-frame.html\" "
- + "target=\"packageListFrame\">All Packages</a></span>"
+ + "target=\"packageListFrame\">All Packages</a></span>"
},
{PROFILE_BUG_ID + FS + "profile-overview-frame.html",
"<li><a href=\"compact1-frame.html\" target=\"packageListFrame\">"
@@ -58,8 +59,8 @@
// Tests for profileName-frame.html listing all packages in a profile.
{PROFILE_BUG_ID + FS + "compact2-frame.html",
"<span><a href=\"overview-frame.html\" target=\"packageListFrame\">"
- + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" "
- + "target=\"packageListFrame\">All Profiles</a></span>"
+ + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" "
+ + "target=\"packageListFrame\">All Profiles</a></span>"
},
{PROFILE_BUG_ID + FS + "compact2-frame.html",
"<li><a href=\"pkg4/compact2-package-frame.html\" "
@@ -74,8 +75,8 @@
},
// Tests for profileName-summary.html listing the summary for a profile.
{PROFILE_BUG_ID + FS + "compact2-summary.html",
- "<li><a href=\"compact1-summary.html\">Prev Profile</a></li>" + NL
- + "<li><a href=\"compact3-summary.html\">Next Profile</a></li>"
+ "<li><a href=\"compact1-summary.html\">Prev Profile</a></li>" + NL
+ + "<li><a href=\"compact3-summary.html\">Next Profile</a></li>"
},
{PROFILE_BUG_ID + FS + "compact2-summary.html",
"<h1 title=\"Profile\" class=\"title\">Profile compact2</h1>"
@@ -87,7 +88,7 @@
// Tests for profileName-package-summary.html listing the summary for a
// package in a profile.
{PROFILE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html",
- "<li><a href=\"../pkg4/compact3-package-summary.html\">Prev Package"
+ "<li><a href=\"../pkg4/compact3-package-summary.html\">Prev Package"
+ "</a></li>"
},
{PROFILE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html",
@@ -96,7 +97,7 @@
//Test for "overview-frame.html" showing the "All Profiles" link.
{PROFILE_BUG_ID + FS + "overview-frame.html",
"<span><a href=\"profile-overview-frame.html\" "
- + "target=\"packageListFrame\">All Profiles</a></span>"
+ + "target=\"packageListFrame\">All Profiles</a></span>"
},
//Test for "className.html" showing the profile information for the type.
{PROFILE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html",
@@ -113,6 +114,49 @@
"target=\"classFrame\">compact2</a></li>" + NL + "<li><a href=\"" +
"compact3-summary.html\" target=\"classFrame\">compact3</a></li>" + NL +
"</ul>"
+ },
+ //Test deprecated class in profiles
+ {PROFILE_BUG_ID + FS + "compact1-summary.html","<td class=\"colFirst\">"
+ + "<a href=\"pkg2/Class1Pkg2.html\" title=\"class in pkg2\">Class1Pkg2</a></td>"
+ + NL + "<td class=\"colLast\">Deprecated"
+ },
+ {PROFILE_BUG_ID + FS + "deprecated-list.html","<td class=\"colOne\">"
+ + "<a href=\"pkg2/Class1Pkg2.html\" title=\"class in pkg2\">pkg2.Class1Pkg2</a>"
+ + NL +"<div class=\"block\"><span class=\"italic\">Class1Pkg2. This class is deprecated</span></div>"
+ },
+ //Test deprecated package in profile
+ {PROFILE_BUG_ID + FS + "deprecated-list.html","<td class=\"colOne\">"
+ + "<a href=\"pkgDeprecated/package-summary.html\">pkgDeprecated</a>"
+ + NL +"<div class=\"block\"><span class=\"italic\">This package is <b>Deprecated</b>."
+ + " Use pkg1.</span></div>"
+ },
+ {PROFILE_BUG_ID + FS + "pkgDeprecated" + FS + "package-summary.html",
+ "<div class=\"deprecatedContent\"><span class=\"strong\">Deprecated.</span>"
+ + NL + "<div class=\"block\"><span class=\"italic\">This package is <b>Deprecated</b>."
+ + " Use pkg1.</span></div>"
+ },
+ // need to add teststring when JDK-8015496 will be fixed
+ //Test exception in profiles
+ {PROFILE_BUG_ID + FS + "compact1-summary.html","<table class=\"packageSummary\" "
+ + "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" "
+ + "summary=\"Exception Summary table, listing exceptions, and an explanation\">"
+ + NL + "<caption><span>Exception Summary</span><span class=\"tabEnd\">"
+ + " </span></caption>" + NL + "<tr>" + NL + "<th class=\"colFirst\" "
+ + "scope=\"col\">Exception</th>" + NL + "<th class=\"colLast\" scope=\"col\">"
+ + "Description</th>" + NL + "</tr>" + NL + "<tbody>" + NL + "<tr class=\"altColor\">"
+ + NL + "<td class=\"colFirst\"><a href=\"pkg2/ClassException.html\""
+ + " title=\"class in pkg2\">ClassException</a></td>"
+ },
+ //Test errors in profiles
+ {PROFILE_BUG_ID + FS + "compact1-summary.html",
+ "<table class=\"packageSummary\" border=\"0\" cellpadding=\"3\" cellspacing=\"0\" "
+ + "summary=\"Error Summary table, listing errors, and an explanation\">"
+ + NL + "<caption><span>Error Summary</span><span class=\"tabEnd\"> "
+ + "</span></caption>" + NL + "<tr>" + NL + "<th class=\"colFirst\""
+ + " scope=\"col\">Error</th>" + NL + "<th class=\"colLast\" "
+ + "scope=\"col\">Description</th>" + NL + "</tr>" + NL + "<tbody>"
+ + NL + "<tr class=\"altColor\">" + NL + "<td class=\"colFirst\">"
+ + "<a href=\"pkg2/ClassError.html\" title=\"class in pkg2\">ClassError</a></td>"
}
};
private static final String[][] PROFILES_NEGATED_TEST = {
@@ -125,6 +169,8 @@
{PROFILE_BUG_ID + FS + "pkg4" + FS + "compact2-package-frame.html",
"<li><a href=\"Anno1Pkg4.html\" title=\"annotation in pkg4\" "
+ "target=\"classFrame\">Anno1Pkg4</a></li>"
+ },
+ {PROFILE_BUG_ID + FS + "compact1-summary.html","<li>Use</li>"
}
};
private static final String[][] PACKAGES_TEST = {
@@ -143,12 +189,12 @@
private static final String[][] PACKAGES_NEGATED_TEST = {
{PACKAGE_BUG_ID + FS + "profile-overview-frame.html",
"<span><a href=\"overview-frame.html\" "
- + "target=\"packageListFrame\">All Packages</a></span>"
+ + "target=\"packageListFrame\">All Packages</a></span>"
},
{PACKAGE_BUG_ID + FS + "compact2-frame.html",
"<span><a href=\"overview-frame.html\" target=\"packageListFrame\">"
- + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" "
- + "target=\"packageListFrame\">All Profiles</a></span>"
+ + "All Packages</a></span><span><a href=\"profile-overview-frame.html\" "
+ + "target=\"packageListFrame\">All Profiles</a></span>"
},
{PACKAGE_BUG_ID + FS + "pkg2" + FS + "compact2-package-frame.html",
"<a href=\"../compact2-summary.html\" target=\"classFrame\">"
@@ -163,7 +209,7 @@
},
{PACKAGE_BUG_ID + FS + "overview-frame.html",
"<span><a href=\"profile-overview-frame.html\" "
- + "target=\"packageListFrame\">All Profiles</a></span>"
+ + "target=\"packageListFrame\">All Profiles</a></span>"
},
{PACKAGE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html",
"<div class=\"subTitle\">compact1, compact2, compact3</div>"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfilesConfiguration.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006124 8009684 8015663 8015496
+ * @summary Test javadoc options support for profiles.
+ * @author Evgeniya Stepanova
+ * @library ../lib/
+ * @build JavadocTester TestProfilesConfiguration
+ * @run main TestProfilesConfiguration
+ */
+public class TestProfilesConfiguration extends JavadocTester {
+
+ //Test information.
+ private static final String BUG_ID = "8006124-8009684";
+ private static final String PROFILE_CONFIGURATION_BUG_ID = BUG_ID + "-3";
+ private static final String NODEPR_NOPKGS_BUG_ID = BUG_ID + "-4";
+ //Javadoc arguments.
+ private static final String[] ARGS3 = new String[]{
+ "-d", PROFILE_CONFIGURATION_BUG_ID, "-sourcepath", SRC_DIR, "-nocomment",
+ "-keywords", "-Xprofilespath", SRC_DIR + FS + "profile-rtjar-includes.txt",
+ "-doctitle", "Simple doctitle", "-use", "pkg3", "pkg1", "pkg2", "pkg4",
+ "pkg5", "-packagesheader", "Simple packages header","pkgDeprecated"
+ };
+ private static final String[] ARGS4 = new String[]{
+ "-d", NODEPR_NOPKGS_BUG_ID, "-sourcepath", SRC_DIR, "-nocomment", "-nodeprecated",
+ "-keywords", "-Xprofilespath", SRC_DIR + FS + "profile-rtjar-includes-nopkgs.txt",
+ "-doctitle", "Simple doctitle", "-use", "-packagesheader", "Simple packages header",
+ "pkg1", "pkg2", "pkg3", "pkg4", "pkg5", "pkgDeprecated"
+ };
+ private static final String[][] NODEPR_NOPKGS_TEST = {
+ {NODEPR_NOPKGS_BUG_ID + FS + "overview-summary.html",
+ "<ul>" + NL + "<li><a href=\"compact2-summary.html\" target=\"classFrame\">" +
+ "compact2</a></li>" + NL + "<li><a href=\"compact3-summary.html\" target=\"" +
+ "classFrame\">compact3</a></li>" + NL + "</ul>"
+ },
+ {NODEPR_NOPKGS_BUG_ID + FS + "profile-overview-frame.html",
+ "<ul title=\"Profiles\">" + NL + "<li><a href=\"compact2-frame.html\" target=\"packageListFrame\">" +
+ "compact2</a></li>" + NL + "<li><a href=\"compact3-frame.html\" target=\"" +
+ "packageListFrame\">compact3</a></li>" + NL + "</ul>"
+ }
+ };
+ private static final String[][] NODEPR_NOPKGS_NEGATED_TEST = {
+ {NODEPR_NOPKGS_BUG_ID + FS + "overview-summary.html",
+ "compact1"
+ }
+ };
+
+ private static final String[][] PROFILES_CONFIGURATION_TEST = {
+ //-use option test string fo profile view page
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html","<li>Use</li>"
+ },
+ //-doctitle option test string
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "overview-summary.html",
+ "<div class=\"header\">" + NL + "<h1 class=\"title\">Simple doctitle</h1>"
+ },
+ //-packagesheader option test string fo profiles
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "profile-overview-frame.html",
+ "<h1 title=\"Simple packages header\" class=\"bar\">Simple packages header</h1>"
+ },
+ //-keywords option test string for profiles
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html",
+ "<meta name=\"keywords\" content=\"compact1 profile\">"
+ },
+ //Deprecated information on a package
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html",
+ "<h3><a href=\"pkgDeprecated/compact1-package-summary.html\" target=\"" +
+ "classFrame\">pkgDeprecated</a></h3>" + NL + "<div class=\"deprecatedContent\">" +
+ "<span class=\"strong\">Deprecated.</span></div>"
+ }
+ };
+ private static final String[][] PROFILES_CONFIGURATION_NEGATED_TEST = {
+ //-nocomments option test string
+ {PROFILE_CONFIGURATION_BUG_ID + FS + "compact1-summary.html",
+ "<div class=\"block\"><i>Class1Pkg2.</i></div>"
+ }
+ };
+
+ /**
+ * The entry point of the test.
+ *
+ * @param args the array of command line arguments.
+ */
+ public static void main(String[] args) {
+ TestProfilesConfiguration tester = new TestProfilesConfiguration();
+ run(tester, ARGS3, PROFILES_CONFIGURATION_TEST,
+ PROFILES_CONFIGURATION_NEGATED_TEST);
+ run(tester, ARGS4, NODEPR_NOPKGS_TEST,
+ NODEPR_NOPKGS_NEGATED_TEST);
+ tester.printSummary();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getBugId() {
+ return BUG_ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getBugName() {
+ return getClass().getName();
+ }
+}
--- a/langtools/test/com/sun/javadoc/testProfiles/pkg2/Class1Pkg2.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/Class1Pkg2.java Tue Sep 17 08:21:11 2013 -0700
@@ -24,7 +24,7 @@
package pkg2;
/**
- * Another test class.
+ * @deprecated Class1Pkg2. This class is deprecated
*
* @author Bhavesh Patel
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassError.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg2;
+
+/**
+ * Simple error class.
+ *
+ * @author Evgeniya Stepanova
+ */
+public class ClassError extends Error {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkg2/ClassException.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg2;
+
+/**
+ * Simple exception class.
+ *
+ * @author Evgeniya Stepanova
+ */
+public class ClassException extends Exception {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/Class1PkgDeprecated.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkgDeprecated;
+
+/**
+ * Simple deprecated class of deprecated package.
+ *
+ * @author Evgeniya Stepanova
+ */
+public class Class1PkgDeprecated {
+
+ public void method(int t) {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/pkgDeprecated/package-info.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Deprecated package.
+ *
+ * @deprecated This package is <b>Deprecated</b>. Use pkg1.
+ */
+package pkgDeprecated;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes-nopkgs.txt Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,41 @@
+PROFILE_1_RTJAR_INCLUDE_PACKAGES :=
+
+PROFILE_1_RTJAR_INCLUDE_TYPES :=
+
+PROFILE_1_RTJAR_EXCLUDE_TYPES :=
+
+PROFILE_1_INCLUDE_METAINF_SERVICES :=
+
+
+PROFILE_2_RTJAR_INCLUDE_PACKAGES := \
+ pkg4 \
+ pkgDeprecated
+
+PROFILE_2_RTJAR_INCLUDE_TYPES :=
+
+PROFILE_2_RTJAR_EXCLUDE_TYPES := \
+ pkg4/Anno1Pkg4.class
+
+PROFILE_2_INCLUDE_METAINF_SERVICES :=
+
+
+PROFILE_3_RTJAR_INCLUDE_PACKAGES := \
+ pkg5
+
+PROFILE_3_RTJAR_INCLUDE_TYPES :=
+
+PROFILE_3_RTJAR_EXCLUDE_TYPES :=
+
+PROFILE_3_INCLUDE_METAINF_SERVICES :=
+
+
+PROFILE_4_RTJAR_INCLUDE_PACKAGES := \
+ pkg1
+
+PROFILE_4_RTJAR_INCLUDE_TYPES :=
+
+PROFILE_4_RTJAR_EXCLUDE_TYPES :=
+
+PROFILE_4_INCLUDE_METAINF_SERVICES :=
+
+
--- a/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes.txt Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testProfiles/profile-rtjar-includes.txt Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,6 @@
PROFILE_1_RTJAR_INCLUDE_PACKAGES := \
- pkg2
+ pkg2 \
+ pkgDeprecated
PROFILE_1_RTJAR_INCLUDE_TYPES := \
pkg3/Class1Pkg3.class
--- a/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java Tue Sep 17 08:21:11 2013 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4494033 7028815 7052425 8007338
+ * @bug 4494033 7028815 7052425 8007338 8023608
* @summary Run tests on doclet stylesheet.
* @author jamieh
* @library ../lib/
@@ -72,7 +72,46 @@
" overflow:hidden;" + NL +
" padding:0px;" + NL +
" margin:0px;" + NL +
- " white-space:pre;" + NL +
+ "}"},
+ {BUG_ID + FS + "stylesheet.css",
+ ".overviewSummary caption span, .packageSummary caption span, " +
+ ".contentContainer ul.blockList li.blockList caption span, " +
+ ".summary caption span, .classUseContainer caption span, " +
+ ".constantValuesContainer caption span {" + NL +
+ " white-space:nowrap;" + NL +
+ " padding-top:8px;" + NL +
+ " padding-left:8px;" + NL +
+ " display:inline-block;" + NL +
+ " float:left;" + NL +
+ " background-image:url(resources/titlebar.gif);" + NL +
+ "}"},
+ {BUG_ID + FS + "stylesheet.css",
+ ".contentContainer ul.blockList li.blockList caption " +
+ "span.activeTableTab span {" + NL +
+ " white-space:nowrap;" + NL +
+ " padding-top:8px;" + NL +
+ " padding-left:8px;" + NL +
+ " display:inline-block;" + NL +
+ " float:left;" + NL +
+ " background-image:url(resources/activetitlebar.gif);" + NL +
+ "}"},
+ {BUG_ID + FS + "stylesheet.css",
+ ".contentContainer ul.blockList li.blockList caption span.tableTab span {" + NL +
+ " white-space:nowrap;" + NL +
+ " padding-top:8px;" + NL +
+ " padding-left:8px;" + NL +
+ " display:inline-block;" + NL +
+ " float:left;" + NL +
+ " background-image:url(resources/titlebar.gif);" + NL +
+ "}"},
+ {BUG_ID + FS + "stylesheet.css",
+ ".contentContainer ul.blockList li.blockList caption span.tableTab, " +
+ ".contentContainer ul.blockList li.blockList caption span.activeTableTab {" + NL +
+ " padding-top:0px;" + NL +
+ " padding-left:0px;" + NL +
+ " background-image:none;" + NL +
+ " float:none;" + NL +
+ " display:inline-block;" + NL +
"}"},
// Test whether a link to the stylesheet file is inserted properly
// in the class documentation.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/lib/combo/TEST.properties Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,4 @@
+# This file identifies root(s) of the test-ng hierarchy.
+
+
+TestNG.dirs = .
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/lib/combo/tools/javac/combo/Diagnostics.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.stream.Collectors.toList;
+
+/**
+* A container for compiler diagnostics, separated into errors and warnings,
+ * used by JavacTemplateTestBase.
+ *
+ * @author Brian Goetz
+*/
+public class Diagnostics implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ protected List<Diagnostic<? extends JavaFileObject>> diags = new ArrayList<>();
+ protected boolean foundErrors = false;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ diags.add(diagnostic);
+ foundErrors = foundErrors || diagnostic.getKind() == Diagnostic.Kind.ERROR;
+ }
+
+ /** Were there any errors found? */
+ public boolean errorsFound() {
+ return foundErrors;
+ }
+
+ /** Get all diagnostic keys */
+ public List<String> keys() {
+ return diags.stream()
+ .map(Diagnostic::getCode)
+ .collect(toList());
+ }
+
+ /** Do the diagnostics contain the specified error key? */
+ public boolean containsErrorKey(String key) {
+ return diags.stream()
+ .filter(d -> d.getKind() == Diagnostic.Kind.ERROR)
+ .anyMatch(d -> d.getCode().equals(key));
+ }
+
+ /** Get the error keys */
+ public List<String> errorKeys() {
+ return diags.stream()
+ .filter(d -> d.getKind() == Diagnostic.Kind.ERROR)
+ .map(Diagnostic::getCode)
+ .collect(toList());
+ }
+
+ public String toString() { return keys().toString(); }
+
+ /** Clear all diagnostic state */
+ public void reset() {
+ diags.clear();
+ foundErrors = false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/lib/combo/tools/javac/combo/JavacTemplateTestBase.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.util.Pair;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.fail;
+
+/**
+ * Base class for template-driven TestNG javac tests that support on-the-fly
+ * source file generation, compilation, classloading, execution, and separate
+ * compilation.
+ *
+ * <p>Manages a set of templates (which have embedded tags of the form
+ * {@code #\{NAME\}}), source files (which are also templates), and compile
+ * options. Test cases can register templates and source files, cause them to
+ * be compiled, validate whether the set of diagnostic messages output by the
+ * compiler is correct, and optionally load and run the compiled classes.
+ *
+ * @author Brian Goetz
+ */
+@Test
+public abstract class JavacTemplateTestBase {
+ private static final Set<String> suiteErrors = Collections.synchronizedSet(new HashSet<>());
+ private static final AtomicInteger counter = new AtomicInteger();
+ private static final File root = new File("gen");
+ private static final File nullDir = new File("empty");
+
+ protected final Map<String, Template> templates = new HashMap<>();
+ protected final Diagnostics diags = new Diagnostics();
+ protected final List<Pair<String, Template>> sourceFiles = new ArrayList<>();
+ protected final List<String> compileOptions = new ArrayList<>();
+ protected final List<File> classpaths = new ArrayList<>();
+ protected final Template.Resolver defaultResolver = new MapResolver(templates);
+
+ private Template.Resolver currentResolver = defaultResolver;
+
+ /** Add a template with a specified name */
+ protected void addTemplate(String name, Template t) {
+ templates.put(name, t);
+ }
+
+ /** Add a template with a specified name */
+ protected void addTemplate(String name, String s) {
+ templates.put(name, new StringTemplate(s));
+ }
+
+ /** Add a source file */
+ protected void addSourceFile(String name, Template t) {
+ sourceFiles.add(new Pair<>(name, t));
+ }
+
+ /** Add a File to the class path to be used when loading classes; File values
+ * will generally be the result of a previous call to {@link #compile()}.
+ * This enables testing of separate compilation scenarios if the class path
+ * is set up properly.
+ */
+ protected void addClassPath(File path) {
+ classpaths.add(path);
+ }
+
+ /**
+ * Add a set of compilation command-line options
+ */
+ protected void addCompileOptions(String... opts) {
+ Collections.addAll(compileOptions, opts);
+ }
+
+ /** Reset the compile options to the default (empty) value */
+ protected void resetCompileOptions() { compileOptions.clear(); }
+
+ /** Remove all templates */
+ protected void resetTemplates() { templates.clear(); }
+
+ /** Remove accumulated diagnostics */
+ protected void resetDiagnostics() { diags.reset(); }
+
+ /** Remove all source files */
+ protected void resetSourceFiles() { sourceFiles.clear(); }
+
+ /** Remove registered class paths */
+ protected void resetClassPaths() { classpaths.clear(); }
+
+ // Before each test method, reset everything
+ @BeforeMethod
+ public void reset() {
+ resetCompileOptions();
+ resetDiagnostics();
+ resetSourceFiles();
+ resetTemplates();
+ resetClassPaths();
+ }
+
+ // After each test method, if the test failed, capture source files and diagnostics and put them in the log
+ @AfterMethod
+ public void copyErrors(ITestResult result) {
+ if (!result.isSuccess()) {
+ suiteErrors.addAll(diags.errorKeys());
+
+ List<Object> list = new ArrayList<>();
+ Collections.addAll(list, result.getParameters());
+ list.add("Test case: " + getTestCaseDescription());
+ for (Pair<String, Template> e : sourceFiles)
+ list.add("Source file " + e.fst + ": " + e.snd);
+ if (diags.errorsFound())
+ list.add("Compile diagnostics: " + diags.toString());
+ result.setParameters(list.toArray(new Object[list.size()]));
+ }
+ }
+
+ @AfterSuite
+ // After the suite is done, dump any errors to output
+ public void dumpErrors() {
+ if (!suiteErrors.isEmpty())
+ System.err.println("Errors found in test suite: " + suiteErrors);
+ }
+
+ /**
+ * Get a description of this test case; since test cases may be combinatorially
+ * generated, this should include all information needed to describe the test case
+ */
+ protected String getTestCaseDescription() {
+ return this.toString();
+ }
+
+ /** Assert that all previous calls to compile() succeeded */
+ protected void assertCompileSucceeded() {
+ if (diags.errorsFound())
+ fail("Expected successful compilation");
+ }
+
+ /**
+ * If the provided boolean is true, assert all previous compiles succeeded,
+ * otherwise assert that a compile failed.
+ * */
+ protected void assertCompileSucceededIff(boolean b) {
+ if (b)
+ assertCompileSucceeded();
+ else
+ assertCompileFailed();
+ }
+
+ /** Assert that a previous call to compile() failed */
+ protected void assertCompileFailed() {
+ if (!diags.errorsFound())
+ fail("Expected failed compilation");
+ }
+
+ /** Assert that a previous call to compile() failed with a specific error key */
+ protected void assertCompileFailed(String message) {
+ if (!diags.errorsFound())
+ fail("Expected failed compilation: " + message);
+ }
+
+ /** Assert that a previous call to compile() failed with all of the specified error keys */
+ protected void assertCompileErrors(String... keys) {
+ if (!diags.errorsFound())
+ fail("Expected failed compilation");
+ for (String k : keys)
+ if (!diags.containsErrorKey(k))
+ fail("Expected compilation error " + k);
+ }
+
+ /** Convert an object, which may be a Template or a String, into a Template */
+ protected Template asTemplate(Object o) {
+ if (o instanceof Template)
+ return (Template) o;
+ else if (o instanceof String)
+ return new StringTemplate((String) o);
+ else
+ return new StringTemplate(o.toString());
+ }
+
+ /** Compile all registered source files */
+ protected void compile() throws IOException {
+ compile(false);
+ }
+
+ /** Compile all registered source files, optionally generating class files
+ * and returning a File describing the directory to which they were written */
+ protected File compile(boolean generate) throws IOException {
+ List<JavaFileObject> files = new ArrayList<>();
+ for (Pair<String, Template> e : sourceFiles)
+ files.add(new FileAdapter(e.fst, asTemplate(e.snd)));
+ return compile(classpaths, files, generate);
+ }
+
+ /** Compile all registered source files, using the provided list of class paths
+ * for finding required classfiles, optionally generating class files
+ * and returning a File describing the directory to which they were written */
+ protected File compile(List<File> classpaths, boolean generate) throws IOException {
+ List<JavaFileObject> files = new ArrayList<>();
+ for (Pair<String, Template> e : sourceFiles)
+ files.add(new FileAdapter(e.fst, asTemplate(e.snd)));
+ return compile(classpaths, files, generate);
+ }
+
+ private File compile(List<File> classpaths, List<JavaFileObject> files, boolean generate) throws IOException {
+ JavaCompiler systemJavaCompiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = systemJavaCompiler.getStandardFileManager(null, null, null);
+ if (classpaths.size() > 0)
+ fm.setLocation(StandardLocation.CLASS_PATH, classpaths);
+ JavacTask ct = (JavacTask) systemJavaCompiler.getTask(null, fm, diags, compileOptions, null, files);
+ if (generate) {
+ File destDir = new File(root, Integer.toString(counter.incrementAndGet()));
+ // @@@ Assert that this directory didn't exist, or start counter at max+1
+ destDir.mkdirs();
+ fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
+ ct.generate();
+ return destDir;
+ }
+ else {
+ ct.analyze();
+ return nullDir;
+ }
+ }
+
+ /** Load the given class using the provided list of class paths */
+ protected Class<?> loadClass(String className, File... destDirs) {
+ try {
+ List<URL> list = new ArrayList<>();
+ for (File f : destDirs)
+ list.add(new URL("file:" + f.toString().replace("\\", "/") + "/"));
+ return Class.forName(className, true, new URLClassLoader(list.toArray(new URL[list.size()])));
+ } catch (ClassNotFoundException | MalformedURLException e) {
+ throw new RuntimeException("Error loading class " + className, e);
+ }
+ }
+
+ /** An implementation of Template which is backed by a String */
+ protected class StringTemplate implements Template {
+ protected final String template;
+
+ public StringTemplate(String template) {
+ this.template = template;
+ }
+
+ public String expand(String selector) {
+ return Behavior.expandTemplate(template, currentResolver);
+ }
+
+ public String toString() {
+ return expand("");
+ }
+
+ public StringTemplate with(final String key, final String value) {
+ return new StringTemplateWithResolver(template, new KeyResolver(key, value));
+ }
+
+ }
+
+ /** An implementation of Template which is backed by a String and which
+ * encapsulates a Resolver for resolving embedded tags. */
+ protected class StringTemplateWithResolver extends StringTemplate {
+ private final Resolver localResolver;
+
+ public StringTemplateWithResolver(String template, Resolver localResolver) {
+ super(template);
+ this.localResolver = localResolver;
+ }
+
+ @Override
+ public String expand(String selector) {
+ Resolver saved = currentResolver;
+ currentResolver = new ChainedResolver(currentResolver, localResolver);
+ try {
+ return super.expand(selector);
+ }
+ finally {
+ currentResolver = saved;
+ }
+ }
+
+ @Override
+ public StringTemplate with(String key, String value) {
+ return new StringTemplateWithResolver(template, new ChainedResolver(localResolver, new KeyResolver(key, value)));
+ }
+ }
+
+ /** A Resolver which uses a Map to resolve tags */
+ private class KeyResolver implements Template.Resolver {
+ private final String key;
+ private final String value;
+
+ public KeyResolver(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public Template lookup(String k) {
+ return key.equals(k) ? new StringTemplate(value) : null;
+ }
+ }
+
+ private class FileAdapter extends SimpleJavaFileObject {
+ private final String filename;
+ private final Template template;
+
+ public FileAdapter(String filename, Template template) {
+ super(URI.create("myfo:/" + filename), Kind.SOURCE);
+ this.template = template;
+ this.filename = filename;
+ }
+
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return toString();
+ }
+
+ public String toString() {
+ return Template.Behavior.expandTemplate(template.expand(filename), defaultResolver);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/lib/combo/tools/javac/combo/Template.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A template into which tags of the form {@code #\{KEY\}} or
+ * {@code #\{KEY.SUBKEY\}} can be expanded.
+ */
+public interface Template {
+ String expand(String selector);
+
+ interface Resolver {
+ public Template lookup(String key);
+ }
+
+ public static class Behavior {
+ /* Looks for expandable keys. An expandable key can take the form:
+ * #{MAJOR}
+ * #{MAJOR.}
+ * #{MAJOR.MINOR}
+ * where MAJOR can be IDENTIFIER or IDENTIFIER[NUMERIC_INDEX]
+ * and MINOR can be an identifier.
+ *
+ * The ability to have an empty minor is provided on the
+ * assumption that some tests that can be written with this
+ * will find it useful to make a distinction akin to
+ * distinguishing F from F(), where F is a function pointer,
+ * and also cases of #{FOO.#{BAR}}, where BAR expands to an
+ * empty string.
+ *
+ * However, this being a general-purpose framework, the exact
+ * use is left up to the test writers.
+ */
+ private static final Pattern pattern = Pattern.compile("#\\{([A-Z_][A-Z0-9_]*(?:\\[\\d+\\])?)(?:\\.([A-Z0-9_]*))?\\}");
+
+ public static String expandTemplate(String template, final Map<String, Template> vars) {
+ return expandTemplate(template, new MapResolver(vars));
+ }
+
+ public static String expandTemplate(String template, Resolver res) {
+ CharSequence in = template;
+ StringBuffer out = new StringBuffer();
+ while (true) {
+ boolean more = false;
+ Matcher m = pattern.matcher(in);
+ while (m.find()) {
+ String major = m.group(1);
+ String minor = m.group(2);
+ Template key = res.lookup(major);
+ if (key == null)
+ throw new IllegalStateException("Unknown major key " + major);
+
+ String replacement = key.expand(minor == null ? "" : minor);
+ more |= pattern.matcher(replacement).find();
+ m.appendReplacement(out, replacement);
+ }
+ m.appendTail(out);
+ if (!more)
+ return out.toString();
+ else {
+ in = out;
+ out = new StringBuffer();
+ }
+ }
+ }
+
+ }
+}
+
+class MapResolver implements Template.Resolver {
+ private final Map<String, Template> vars;
+
+ public MapResolver(Map<String, Template> vars) {this.vars = vars;}
+
+ public Template lookup(String key) {
+ return vars.get(key);
+ }
+}
+
+class ChainedResolver implements Template.Resolver {
+ private final Template.Resolver upstreamResolver, thisResolver;
+
+ public ChainedResolver(Template.Resolver upstreamResolver, Template.Resolver thisResolver) {
+ this.upstreamResolver = upstreamResolver;
+ this.thisResolver = thisResolver;
+ }
+
+ public Template.Resolver getUpstreamResolver() {
+ return upstreamResolver;
+ }
+
+ @Override
+ public Template lookup(String key) {
+ Template result = thisResolver.lookup(key);
+ if (result == null)
+ result = upstreamResolver.lookup(key);
+ return result;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/lib/combo/tools/javac/combo/TemplateTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package tools.javac.combo;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * TemplateTest
+ */
+@Test
+public class TemplateTest {
+ Map<String, Template> vars = new HashMap<>();
+
+ @BeforeTest
+ void before() { vars.clear(); }
+
+ private void assertTemplate(String expected, String template) {
+ String result = Template.Behavior.expandTemplate(template, vars);
+ assertEquals(result, expected, "for " + template);
+ }
+
+ private String dotIf(String s) {
+ return s == null || s.isEmpty() ? "" : "." + s;
+ }
+
+ public void testTemplateExpansion() {
+ vars.put("A", s -> "a" + dotIf(s));
+ vars.put("B", s -> "b" + dotIf(s));
+ vars.put("C", s -> "#{A}#{B}");
+ vars.put("D", s -> "#{A" + dotIf(s) + "}#{B" + dotIf(s) + "}");
+ vars.put("_D", s -> "d");
+
+ assertTemplate("", "");
+ assertTemplate("foo", "foo");
+ assertTemplate("a", "#{A}");
+ assertTemplate("a", "#{A.}");
+ assertTemplate("a.FOO", "#{A.FOO}");
+ assertTemplate("aa", "#{A}#{A}");
+ assertTemplate("ab", "#{C}");
+ assertTemplate("ab", "#{C.FOO}");
+ assertTemplate("ab", "#{C.}");
+ assertTemplate("a.FOOb.FOO", "#{D.FOO}");
+ assertTemplate("ab", "#{D}");
+ assertTemplate("d", "#{_D}");
+ assertTemplate("#{A", "#{A");
+ }
+
+ public void testIndexedTemplate() {
+ vars.put("A[0]", s -> "a" );
+ vars.put("A[1]", s -> "b" );
+ vars.put("A[2]", s -> "c" );
+ vars.put("X", s -> "0");
+ assertTemplate("a", "#{A[0]}");
+ assertTemplate("b", "#{A[1]}");
+ assertTemplate("c", "#{A[2]}");
+ }
+
+ public void testAngleBrackets() {
+ vars.put("X", s -> "xyz");
+ assertTemplate("List<String> ls = xyz;", "List<String> ls = #{X};");
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class )
+ public void testUnknownKey() {
+ assertTemplate("#{Q}", "#{Q}");
+ }
+}
--- a/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/Diagnostics/compressed/T8012003c.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,3 +1,2 @@
T8012003c.java:18:15: compiler.err.report.access: m(), private, P
-- compiler.note.compressed.diags
1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8022162/IncorrectSignatureDeterminationForInnerClassesTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8022162
+ * @summary Incorrect signature determination for certain inner class generics
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main IncorrectSignatureDeterminationForInnerClassesTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+public class IncorrectSignatureDeterminationForInnerClassesTest {
+
+ private static final String DSrc =
+ "package p1;\n" +
+
+ "public class D<T> {\n" +
+ "}\n" +
+
+ "abstract class Q<T> {\n" +
+ " protected void m(M.E e) {}\n" +
+
+ " public class M extends D<T> {\n" +
+ " public class E {}\n" +
+ " }\n" +
+ "}";
+
+ private static final String HSrc =
+ "package p1;\n" +
+
+ "public class H {\n" +
+ " static class EQ extends Q<Object> {\n" +
+ " private void m2(M.E item) {\n" +
+ " m(item);\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+
+ public static void main(String args[]) throws Exception {
+ new IncorrectSignatureDeterminationForInnerClassesTest().run();
+ }
+
+ void run() throws Exception {
+ compile();
+ }
+
+ void compile() throws Exception {
+ Files.createDirectory(Paths.get("classes"));
+
+ ToolBox.JavaToolArgs javacParams =
+ new ToolBox.JavaToolArgs()
+ .appendArgs("-d", "classes")
+ .setSources(DSrc);
+
+ ToolBox.javac(javacParams);
+
+ // compile class H against the class files for classes D and Q
+ javacParams =
+ new ToolBox.JavaToolArgs()
+ .appendArgs("-d", "classes", "-cp", "classes")
+ .setSources(HSrc);
+ ToolBox.javac(javacParams);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8023545
+ * @summary Misleading error message when using diamond operator with private constructor
+ * @compile/fail/ref=MisleadingErrorMsgDiamondPlusPrivateCtorTest.out -XDrawDiagnostics MisleadingErrorMsgDiamondPlusPrivateCtorTest.java
+ */
+
+public class MisleadingErrorMsgDiamondPlusPrivateCtorTest {
+ public void foo() {
+ MyClass<Object> foo = new MyClass<>();
+ }
+}
+
+class MyClass<E> {
+ private MyClass() {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8023545/MisleadingErrorMsgDiamondPlusPrivateCtorTest.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,2 @@
+MisleadingErrorMsgDiamondPlusPrivateCtorTest.java:10:31: compiler.err.report.access: <E>MyClass(), private, MyClass
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8024039
+ * @summary javac, previous solution for JDK-8022186 was incorrect
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main NoDeadCodeGenerationOnTrySmtTest
+ */
+
+import java.io.File;
+import java.nio.file.Paths;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.Code_attribute.Exception_data;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.javac.util.Assert;
+
+public class NoDeadCodeGenerationOnTrySmtTest {
+
+ static final String testSource =
+ "public class Test {\n" +
+ " void m1(int arg) {\n" +
+ " synchronized (new Integer(arg)) {\n" +
+ " {\n" +
+ " label0:\n" +
+ " do {\n" +
+ " break label0;\n" +
+ " } while (arg != 0);\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+
+ " void m2(int arg) {\n" +
+ " synchronized (new Integer(arg)) {\n" +
+ " {\n" +
+ " label0:\n" +
+ " {\n" +
+ " break label0;\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+
+ static final int[][] expectedExceptionTable = {
+ // {from, to, target, type},
+ {11, 13, 16, 0},
+ {16, 19, 16, 0}
+ };
+
+ static final String[] methodsToLookFor = {"m1", "m2"};
+
+ public static void main(String[] args) throws Exception {
+ new NoDeadCodeGenerationOnTrySmtTest().run();
+ }
+
+ void run() throws Exception {
+ compileTestClass();
+ checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
+ "Test.class").toUri()), methodsToLookFor);
+ }
+
+ void compileTestClass() throws Exception {
+ ToolBox.JavaToolArgs javacSuccessArgs =
+ new ToolBox.JavaToolArgs().setSources(testSource);
+ ToolBox.javac(javacSuccessArgs);
+ }
+
+ void checkClassFile(final File cfile, String[] methodsToFind) throws Exception {
+ ClassFile classFile = ClassFile.read(cfile);
+ int numberOfmethodsFound = 0;
+ for (String methodToFind : methodsToFind) {
+ for (Method method : classFile.methods) {
+ if (method.getName(classFile.constant_pool).equals(methodToFind)) {
+ numberOfmethodsFound++;
+ Code_attribute code = (Code_attribute) method.attributes.get("Code");
+ Assert.check(code.exception_table_langth == expectedExceptionTable.length,
+ "The ExceptionTable found has a length different to the expected one");
+ int i = 0;
+ for (Exception_data entry: code.exception_table) {
+ Assert.check(entry.start_pc == expectedExceptionTable[i][0] &&
+ entry.end_pc == expectedExceptionTable[i][1] &&
+ entry.handler_pc == expectedExceptionTable[i][2] &&
+ entry.catch_type == expectedExceptionTable[i][3],
+ "Exception table entry at pos " + i + " differ from expected.");
+ i++;
+ }
+ }
+ }
+ }
+ Assert.check(numberOfmethodsFound == 2, "Some seek methods were not found");
+ }
+
+ void error(String msg) {
+ throw new AssertionError(msg);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8024207/FlowCrashTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,23 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8024207
+ * @summary javac crash in Flow$AssignAnalyzer.visitIdent
+ * @compile/fail/ref=FlowCrashTest.out -XDrawDiagnostics FlowCrashTest.java
+ */
+
+import java.util.*;
+import java.util.stream.*;
+
+public class FlowCrashTest {
+ static class ViewId { }
+
+ public void crash() {
+
+ Map<ViewId,String> viewToProfile = null;
+ new TreeMap<>(viewToProfile.entrySet().stream()
+ .collect(Collectors.toMap((vid, prn) -> prn,
+ (vid, prn) -> Arrays.asList(vid),
+ (a, b) -> { a.addAll(b); return a; })));
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8024207/FlowCrashTest.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,2 @@
+FlowCrashTest.java:18:42: compiler.err.cant.apply.symbols: kindname.method, toMap, @475,@542,@624,{(compiler.misc.inapplicable.method: kindname.method, java.util.stream.Collectors, <T,K,U>toMap(java.util.function.Function<? super T,? extends K>,java.util.function.Function<? super T,? extends U>), (compiler.misc.infer.arg.length.mismatch: T,K,U)),(compiler.misc.inapplicable.method: kindname.method, java.util.stream.Collectors, <T,K,U>toMap(java.util.function.Function<? super T,? extends K>,java.util.function.Function<? super T,? extends U>,java.util.function.BinaryOperator<U>), (compiler.misc.infer.no.conforming.assignment.exists: T,K,U, (compiler.misc.incompatible.arg.types.in.lambda))),(compiler.misc.inapplicable.method: kindname.method, java.util.stream.Collectors, <T,K,U,M>toMap(java.util.function.Function<? super T,? extends K>,java.util.function.Function<? super T,? extends U>,java.util.function.BinaryOperator<U>,java.util.function.Supplier<M>), (compiler.misc.infer.arg.length.mismatch: T,K,U,M))}
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8024398/NPETryTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8024398
+ * @summary javac, compiler crashes with try with empty body
+ * @compile NPETryTest.java
+ */
+
+public class NPETryTest {
+ void m()
+ {
+ /* This is the statement provoking the error the rest are provided as
+ * additional tests
+ */
+ try {}
+ catch (Exception e) {}
+
+ try {}
+ catch (Exception e) {}
+ finally {}
+
+ try {}
+ finally {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoDefault.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,9 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8022322
+ * @summary Default methods are not allowed in an annotation.
+ * @compile/fail/ref=NoDefault.out -XDrawDiagnostics NoDefault.java
+ */
+@interface NoDefault {
+ default int m() {return 0;}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoDefault.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,3 @@
+NoDefault.java:8:17: compiler.err.mod.not.allowed.here: default
+NoDefault.java:8:21: compiler.err.intf.meth.cant.have.body
+2 errors
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,9 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8022322
+ * @summary Default methods are not allowed in an annotation.
+ * @compile/fail/ref=NoDefaultAbstract.out -XDrawDiagnostics NoDefaultAbstract.java
+ */
+@interface NoDefaultAbstract {
+ default int m();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoDefaultAbstract.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,2 @@
+NoDefaultAbstract.java:8:17: compiler.err.mod.not.allowed.here: default
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoStatic.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,10 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8022322
+ * @summary Static methods are not allowed in an annotation.
+ * @compile/fail/ref=NoStatic.out -XDrawDiagnostics NoStatic.java
+ */
+
+@interface NoStatic {
+ static int m() {return 0;}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoStatic.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,3 @@
+NoStatic.java:9:16: compiler.err.mod.not.allowed.here: static
+NoStatic.java:9:20: compiler.err.intf.meth.cant.have.body
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoStaticAbstract.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,10 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8022322
+ * @summary Static methods are not allowed in an annotation.
+ * @compile/fail/ref=NoStaticAbstract.out -XDrawDiagnostics NoStaticAbstract.java
+ */
+
+@interface NoStaticAbstract {
+ static int m();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/neg/NoStaticAbstract.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,2 @@
+NoStaticAbstract.java:9:16: compiler.err.mod.not.allowed.here: static
+1 error
--- a/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that default methods don't cause ClassReader to complete classes recursively
* @author Maurizio Cimadamore
* @compile pkg/Foo.java
--- a/langtools/test/tools/javac/defaultMethods/Neg01.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg01.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary negative test for ambiguous defaults
* @compile/fail/ref=Neg01.out -XDrawDiagnostics Neg01.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg02.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg02.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that ill-formed MI hierarchies do not compile
* @compile/fail/ref=Neg02.out -XDrawDiagnostics Neg02.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg03.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg03.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that re-abstraction works properly
* @compile/fail/ref=Neg03.out -XDrawDiagnostics Neg03.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg04.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg04.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default method must have most specific return type
* @compile/fail/ref=Neg04.out -XDrawDiagnostics Neg04.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg05.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg05.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that abstract methods are compatible with inherited defaults
* @compile/fail/ref=Neg05.out -XDrawDiagnostics Neg05.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg06.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg06.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary flow analysis is not run on inlined default bodies
* @compile/fail/ref=Neg06.out -XDrawDiagnostics Neg06.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg07.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg07.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default overrides are properly type-checked
* @compile/fail/ref=Neg07.out -XDrawDiagnostics Neg07.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg08.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg08.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default overrides are properly type-checked
* @compile/fail/ref=Neg08.out -XDrawDiagnostics Neg08.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg09.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg09.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default overrides are properly type-checked
* @compile/fail/ref=Neg09.out -Werror -Xlint:unchecked -XDrawDiagnostics Neg09.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg10.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg10.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default overrides are properly type-checked
* @compile/fail/ref=Neg10.out -Werror -Xlint:unchecked -XDrawDiagnostics Neg10.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg11.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg11.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default overrides are properly type-checked
* @compile/fail/ref=Neg11.out -XDrawDiagnostics Neg11.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg12.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg12.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that abstract methods are discarded in overload resolution diags
* @compile/fail/ref=Neg12.out -XDrawDiagnostics Neg12.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg13.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg13.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that default method overriding object members are flagged as error
* @compile/fail/ref=Neg13.out -XDrawDiagnostics Neg13.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg14.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg14.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that a class cannot have two sibling interfaces with a default and abstract method
* @compile/fail/ref=Neg14.out -XDrawDiagnostics Neg14.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg15.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg15.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that level skipping in default super calls is correctly rejected
* @compile/fail/ref=Neg15.out -XDrawDiagnostics Neg15.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Neg16.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Neg16.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
-/*
- * @test /nodynamiccopyright/
+/* @test /nodynamiccopyright/
+ * @bug 7192246
* @summary check that level skipping in default super calls is correctly rejected
* @compile/fail/ref=Neg16.out -XDrawDiagnostics Neg16.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos01.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos01.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary basic test for default methods
* @author Maurizio Cimadamore
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos02.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos02.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary test for explicit resolution of ambiguous default methods
* @author Maurizio Cimadamore
* @compile Pos02.java
--- a/langtools/test/tools/javac/defaultMethods/Pos04.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos04.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary test for overriding with default method
* @author Maurizio Cimadamore
* @compile Pos04.java
--- a/langtools/test/tools/javac/defaultMethods/Pos05.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos05.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that indirectly inherited default methods are discovered during resolution
* @author Maurizio Cimadamore
* @compile Pos05.java
--- a/langtools/test/tools/javac/defaultMethods/Pos06.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos06.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that well-formed MI hierarchies behaves well w.r.t. method resolution (i.e. no ambiguities)
* @author Maurizio Cimadamore
* @compile Pos06.java
--- a/langtools/test/tools/javac/defaultMethods/Pos07.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos07.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that compilation order does not matter
* @author Maurizio Cimadamore
* @compile Pos07.java
--- a/langtools/test/tools/javac/defaultMethods/Pos08.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos08.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that common overrider solves default method conflicts
* @author Maurizio Cimadamore
* @compile Pos08.java
--- a/langtools/test/tools/javac/defaultMethods/Pos10.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos10.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that type-variables in generic extension decl can be accessed from default impl
* @author Maurizio Cimadamore
* @compile Pos10.java
--- a/langtools/test/tools/javac/defaultMethods/Pos11.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos11.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary complex test with conflict resolution via overriding
* @author Brian Goetz
* @compile Pos11.java
--- a/langtools/test/tools/javac/defaultMethods/Pos12.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos12.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that 'this' can be used from within an extension method
* @compile Pos12.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos13.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos13.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary qualified 'this' inside default method causes StackOverflowException
* @compile Pos13.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos14.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos14.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that overload resolution selects most specific signature
* @compile Pos14.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos15.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos15.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that overload resolution selects most specific signature
* @compile Pos15.java
*/
--- a/langtools/test/tools/javac/defaultMethods/Pos16.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/Pos16.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary 'class wins' should not short-circuit overload resolution
* @compile Pos16.java
*/
--- a/langtools/test/tools/javac/defaultMethods/TestDefaultBody.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/TestDefaultBody.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that code attributed for default methods is correctly generated
*/
--- a/langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that javac does not generate bridge methods for defaults
*/
--- a/langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary check that clinit in interface doesn't cause spurious default method diagnostics
* @compile -source 1.4 -target 1.4 Clinit.java
* @compile CrossCompile.java
--- a/langtools/test/tools/javac/defaultMethods/separate/Separate.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/separate/Separate.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 7192246
* @summary smoke test for separate compilation of default methods
* @author Maurizio Cimadamore
* @compile pkg1/A.java
--- a/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java Tue Sep 17 08:21:11 2013 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8006694
+ * @bug 7192246 8006694
* @summary Automatic test for checking correctness of default super/this resolution
* temporarily workaround combo tests are causing time out in several platforms
* @library ../../lib
--- a/langtools/test/tools/javac/depDocComment/SuppressDeprecation.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/depDocComment/SuppressDeprecation.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,8 +1,8 @@
-SuppressDeprecation.java:130:17: compiler.warn.has.been.deprecated: X, compiler.misc.unnamed.package
SuppressDeprecation.java:82:10: compiler.warn.has.been.deprecated: g(), T
SuppressDeprecation.java:83:14: compiler.warn.has.been.deprecated: g(), T
SuppressDeprecation.java:84:9: compiler.warn.has.been.deprecated: var, T
SuppressDeprecation.java:87:9: compiler.warn.has.been.deprecated: T(), T
SuppressDeprecation.java:90:9: compiler.warn.has.been.deprecated: T(int), T
SuppressDeprecation.java:98:1: compiler.warn.has.been.deprecated: T(), T
+SuppressDeprecation.java:130:17: compiler.warn.has.been.deprecated: X, compiler.misc.unnamed.package
7 warnings
--- a/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/diags/examples/BadArgTypesInLambda.java Tue Sep 17 08:21:11 2013 -0700
@@ -21,9 +21,6 @@
* questions.
*/
-// key: compiler.err.cant.apply.symbol
-// key: compiler.misc.no.conforming.assignment.exists
-// key: compiler.misc.bad.arg.types.in.lambda
// key: compiler.err.prob.found.req
// key: compiler.misc.inconvertible.types
// options: -Xdiags:verbose
--- a/langtools/test/tools/javac/diags/examples/CyclicInference.java Thu Sep 12 11:09:20 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.prob.found.req
-// key: compiler.misc.cyclic.inference
-
-class CyclicInference {
- interface SAM<X> {
- void m(X x);
- }
-
- <Z> void g(SAM<Z> sz) { }
-
- void test() {
- g(x-> {});
- }
-}
--- a/langtools/test/tools/javac/diags/examples/IncompatibleArgTypesInMethodRef.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleArgTypesInMethodRef.java Tue Sep 17 08:21:11 2013 -0700
@@ -31,6 +31,7 @@
}
void g(String s, Integer i) { }
+ void g(Integer i, String s) { }
<Z> void m(SAM<Z> s) { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/MrefInferAndExplicitParams.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.mref
+// key: compiler.misc.mref.infer.and.explicit.params
+
+public class MrefInferAndExplicitParams {
+ static class Foo<X> {}
+
+ interface Supplier<X> {
+ X make();
+ }
+
+ Supplier<Foo<String>> sfs = Foo::<Number>new;
+}
--- a/langtools/test/tools/javac/diags/examples/MrefStat.java.rej Thu Sep 12 11:09:20 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
---- MrefStat.java
-+++ MrefStat.java
-@@ -0,0 +1,31 @@
-+/*
-+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * This code is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ */
-+
-+// key: compiler.note.mref.stat
-+// options: -XDdumpLambdaToMethodStats
-+
-+class MrefStat {
-+ Runnable r = MrefStat::m;
-+
-+ static void m() { }
-+}
--- a/langtools/test/tools/javac/diags/examples/MrefStat1.java.rej Thu Sep 12 11:09:20 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
---- MrefStat1.java
-+++ MrefStat1.java
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
-+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-+ *
-+ * This code is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 only, as
-+ * published by the Free Software Foundation.
-+ *
-+ * This code is distributed in the hope that it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ * version 2 for more details (a copy is included in the LICENSE file that
-+ * accompanied this code).
-+ *
-+ * You should have received a copy of the GNU General Public License version
-+ * 2 along with this work; if not, write to the Free Software Foundation,
-+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-+ * or visit www.oracle.com if you need additional information or have any
-+ * questions.
-+ */
-+
-+// key: compiler.note.mref.stat.1
-+// options: -XDdumpLambdaToMethodStats
-+
-+class MrefStat1 {
-+
-+ void m() { }
-+
-+ static class Sub extends MrefStat1 {
-+ Runnable r = super::m;
-+ }
-+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/PotentiallyAmbiguousOverload.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.warn.potentially.ambiguous.overload
+// options: -Xlint:overloads
+
+class PotentiallyAmbiguousOverload {
+ interface F1 {
+ void m(String s);
+ }
+
+ interface F2 {
+ void m(Integer s);
+ }
+
+ void m(F1 f1) { }
+ void m(F2 f2) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/AliveRanges.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.lang.annotation.*;
+
+@Repeatable(AliveRanges.class)
+@Target({ElementType.METHOD})
+@interface AliveRange {
+ String varName();
+ int bytecodeStart();
+ int bytecodeLength();
+}
+
+@Target({ElementType.METHOD})
+@interface AliveRanges {AliveRange[] value();}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/LVTHarness.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7047734
+ * @summary The LVT is not generated correctly during some try/catch scenarios
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor LVTHarness
+ * @run main LVTHarness
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.Set;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.ConstantPool.InvalidIndex;
+import com.sun.tools.classfile.ConstantPool.UnexpectedEntry;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
+import com.sun.tools.classfile.LocalVariableTable_attribute;
+import com.sun.tools.classfile.Method;
+
+import static javax.tools.StandardLocation.*;
+import static com.sun.tools.classfile.LocalVariableTable_attribute.Entry;
+
+public class LVTHarness {
+
+ static int nerrors = 0;
+
+ static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+ static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+ public static void main(String[] args) throws Exception {
+ fm.setLocation(SOURCE_PATH,
+ Arrays.asList(new File(System.getProperty("test.src"), "tests")));
+ for (JavaFileObject jfo : fm.list(SOURCE_PATH, "",
+ Collections.singleton(JavaFileObject.Kind.SOURCE), true)) {
+ new LVTHarness(jfo).check();
+ }
+ if (nerrors > 0) {
+ throw new AssertionError("Errors were found");
+ }
+ }
+
+
+ JavaFileObject jfo;
+ Map<ElementKey, AliveRanges> aliveRangeMap =
+ new HashMap<ElementKey, AliveRanges>();
+ Set<String> declaredKeys = new HashSet<>();
+ List<ElementKey> seenAliveRanges = new ArrayList<>();
+
+ protected LVTHarness(JavaFileObject jfo) {
+ this.jfo = jfo;
+ }
+
+ protected void check() throws Exception {
+ JavacTask ct = (JavacTask)comp.getTask(null, fm, null, Arrays.asList("-g"),
+ null, Arrays.asList(jfo));
+ System.err.println("compiling code " + jfo.toString());
+ ct.setProcessors(Collections.singleton(new AliveRangeFinder()));
+ if (!ct.call()) {
+ throw new AssertionError("Error during compilation");
+ }
+
+ checkClassFile(new File(jfo.getName().replace(".java", ".class")));
+
+ //check all candidates have been used up
+ for (Map.Entry<ElementKey, AliveRanges> entry : aliveRangeMap.entrySet()) {
+ if (!seenAliveRanges.contains(entry.getKey())) {
+ error("Redundant @AliveRanges annotation on method " +
+ entry.getKey().elem);
+ }
+ }
+ }
+
+ void checkClassFile(File file)
+ throws IOException, ConstantPoolException, InvalidDescriptor {
+ ClassFile classFile = ClassFile.read(file);
+ ConstantPool constantPool = classFile.constant_pool;
+
+ //lets get all the methods in the class file.
+ for (Method method : classFile.methods) {
+ for (ElementKey elementKey: aliveRangeMap.keySet()) {
+ String methodDesc = method.getName(constantPool) +
+ method.descriptor.getParameterTypes(constantPool);
+ if (methodDesc.equals(elementKey.elem.toString())) {
+ checkMethod(constantPool, method, aliveRangeMap.get(elementKey));
+ seenAliveRanges.add(elementKey);
+ }
+ }
+ }
+ }
+
+ void checkMethod(ConstantPool constantPool, Method method, AliveRanges ranges)
+ throws InvalidIndex, UnexpectedEntry {
+ Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code);
+ LocalVariableTable_attribute lvt =
+ (LocalVariableTable_attribute) (code.attributes.get(Attribute.LocalVariableTable));
+ List<String> infoFromRanges = convertToStringList(ranges);
+ List<String> infoFromLVT = convertToStringList(constantPool, lvt);
+
+ // infoFromRanges most be contained in infoFromLVT
+ int i = 0;
+ int j = 0;
+ while (i < infoFromRanges.size() && j < infoFromLVT.size()) {
+ int comparison = infoFromRanges.get(i).compareTo(infoFromLVT.get(j));
+ if (comparison == 0) {
+ i++; j++;
+ } else if (comparison > 0) {
+ j++;
+ } else {
+ break;
+ }
+ }
+
+ if (i < infoFromRanges.size()) {
+ error(infoFromLVT, infoFromRanges);
+ }
+ }
+
+ List<String> convertToStringList(AliveRanges ranges) {
+ List<String> result = new ArrayList<>();
+ for (Annotation anno : ranges.value()) {
+ AliveRange range = (AliveRange)anno;
+ String str = formatLocalVariableData(range.varName(),
+ range.bytecodeStart(), range.bytecodeLength());
+ result.add(str);
+ }
+ Collections.sort(result);
+ return result;
+ }
+
+ List<String> convertToStringList(ConstantPool constantPool,
+ LocalVariableTable_attribute lvt) throws InvalidIndex, UnexpectedEntry {
+ List<String> result = new ArrayList<>();
+ for (Entry entry : lvt.local_variable_table) {
+ String str = formatLocalVariableData(constantPool.getUTF8Value(entry.name_index),
+ entry.start_pc, entry.length);
+ result.add(str);
+ }
+ Collections.sort(result);
+ return result;
+ }
+
+ String formatLocalVariableData(String varName, int start, int length) {
+ StringBuilder sb = new StringBuilder()
+ .append("var name: ").append(varName)
+ .append(" start: ").append(start)
+ .append(" length: ").append(length);
+ return sb.toString();
+ }
+
+ protected void error(List<String> infoFromLVT, List<String> infoFromRanges) {
+ nerrors++;
+ System.err.printf("Error occurred while checking file: %s\n", jfo.getName());
+ System.err.println("The range info from the annotations is");
+ printStringListToErrOutput(infoFromRanges);
+ System.err.println();
+ System.err.println("And the range info from the class file is");
+ printStringListToErrOutput(infoFromLVT);
+ System.err.println();
+ }
+
+ void printStringListToErrOutput(List<String> list) {
+ for (String s : list) {
+ System.err.println("\t" + s);
+ }
+ }
+
+ protected void error(String msg) {
+ nerrors++;
+ System.err.printf("Error occurred while checking file: %s\nreason: %s\n",
+ jfo.getName(), msg);
+ }
+
+ class AliveRangeFinder extends JavacTestingAbstractProcessor {
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+ if (roundEnv.processingOver())
+ return true;
+
+ TypeElement aliveRangeAnno = elements.getTypeElement("AliveRanges");
+
+ if (!annotations.contains(aliveRangeAnno)) {
+ error("no @AliveRanges annotation found in test class");
+ }
+
+ for (Element elem: roundEnv.getElementsAnnotatedWith(aliveRangeAnno)) {
+ Annotation annotation = elem.getAnnotation(AliveRanges.class);
+ aliveRangeMap.put(new ElementKey(elem), (AliveRanges)annotation);
+ }
+ return true;
+ }
+ }
+
+ class ElementKey {
+
+ String key;
+ Element elem;
+
+ public ElementKey(Element elem) {
+ this.elem = elem;
+ this.key = computeKey(elem);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ElementKey) {
+ ElementKey other = (ElementKey)obj;
+ return other.key.equals(key);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return key.hashCode();
+ }
+
+ String computeKey(Element e) {
+ StringBuilder buf = new StringBuilder();
+ while (e != null) {
+ buf.append(e.toString());
+ e = e.getEnclosingElement();
+ }
+ buf.append(jfo.getName());
+ return buf.toString();
+ }
+
+ @Override
+ public String toString() {
+ return "Key{" + key + "}";
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseConditional.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,16 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseConditional {
+
+ @AliveRange(varName="o", bytecodeStart=5, bytecodeLength=33)
+ @AliveRange(varName="oo", bytecodeStart=23, bytecodeLength=15)
+ void m(String[] args) {
+ Boolean o;
+ Boolean oo = ((o = Boolean.TRUE).booleanValue()) ?
+ o = Boolean.TRUE :
+ Boolean.FALSE;
+ oo.hashCode();
+ o = Boolean.FALSE;
+ o.hashCode();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseDoLoop.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,15 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseDoLoop {
+
+ @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=15)
+ @AliveRange(varName="args", bytecodeStart=0, bytecodeLength=18)
+ void m(String[] args) {
+ Object o;
+ do {
+ o = "";
+ o.hashCode();
+ } while (args[0] != null);
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseFor.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,27 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseFor {
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=24, bytecodeLength=1)
+ void m1(String[] args) {
+ Object o;
+ for (int i = 0; i < 5; i++) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=24, bytecodeLength=1)
+ void m2(String[] args) {
+ Object o;
+ for (int i = 0; i < 5; i++) {
+ o = "";
+ o.hashCode();
+ continue;
+ }
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseForEach.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,15 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseForEach {
+
+ @AliveRange(varName="o", bytecodeStart=25, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=39, bytecodeLength=1)
+ void m(String[] args) {
+ Object o;
+ for (String s : args) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseIf.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,61 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseIf {
+
+ @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=17, bytecodeLength=1)
+ void m0(String[] args) {
+ Object o;
+ if (args[0] != null) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=18, bytecodeLength=1)
+ void m1() {
+ Object o;
+ int i = 5;
+ if (i == 5) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=18, bytecodeLength=1)
+ void m2() {
+ Object o;
+ int i = 5;
+ if (!(i == 5)) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=15, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=1)
+ void m3(String[] args) {
+ Object o;
+ if (args[0] != null && args[1] != null) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=15, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=1)
+ void m4(String[] args) {
+ Object o;
+ if (args[0] != null || args[1] != null) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseIfElse.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,48 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseIfElse {
+
+ @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=20, bytecodeLength=9)
+ void m0(String[] args) {
+ Object o;
+ if (args[0] != null) {
+ o = "then";
+ o.hashCode();
+ } else {
+ o = "else";
+ o.hashCode();
+ }
+ o = "finish";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9)
+ void m1() {
+ Object o;
+ int i = 5;
+ if (i == 5) {
+ o = "then";
+ o.hashCode();
+ } else {
+ o = "else";
+ o.hashCode();
+ }
+ o = "finish";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9)
+ void m2(String[] args) {
+ Object o;
+ int i = 5;
+ if (i != 5) {
+ o = "then";
+ o.hashCode();
+ } else {
+ o = "else";
+ o.hashCode();
+ }
+ o = "finish";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseSwitch.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,73 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseSwitch {
+
+ @AliveRange(varName="o", bytecodeStart=31, bytecodeLength=16)
+ @AliveRange(varName="o", bytecodeStart=50, bytecodeLength=15)
+ @AliveRange(varName="o", bytecodeStart=68, bytecodeLength=1)
+ @AliveRange(varName="oo", bytecodeStart=39, bytecodeLength=26)
+ @AliveRange(varName="uu", bytecodeStart=59, bytecodeLength=6)
+ void m1(String[] args) {
+ Object o;
+ switch (args.length) {
+ case 0:
+ o = "0";
+ o.hashCode();
+ Object oo = "oo";
+ oo.hashCode();
+ break;
+ case 1:
+ o = "1";
+ o.hashCode();
+ Object uu = "uu";
+ uu.hashCode();
+ break;
+ }
+ o = "return";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=95, bytecodeLength=18)
+ @AliveRange(varName="o", bytecodeStart=116, bytecodeLength=15)
+ @AliveRange(varName="o", bytecodeStart=134, bytecodeLength=1)
+ @AliveRange(varName="oo", bytecodeStart=104, bytecodeLength=27)
+ @AliveRange(varName="uu", bytecodeStart=125, bytecodeLength=6)
+ void m2(String[] args) {
+ Object o;
+ switch (args[0]) {
+ case "string0":
+ o = "0";
+ o.hashCode();
+ Object oo = "oo";
+ oo.hashCode();
+ break;
+ case "string1":
+ o = "1";
+ o.hashCode();
+ Object uu = "uu";
+ uu.hashCode();
+ break;
+ }
+ o = "return";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=31, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=42, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=53, bytecodeLength=9)
+ void m3(String[] args) {
+ Object o;
+ switch (args.length) {
+ case 0:
+ o = "0";
+ o.hashCode();
+ break;
+ case 1:
+ o = "1";
+ o.hashCode();
+ break;
+ default:
+ o = "default";
+ o.hashCode();
+ }
+ o = "finish";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseTry.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,76 @@
+/* /nodynamiccopyright/ */
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+
+public class TestCaseTry {
+
+ @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=8)
+ @AliveRange(varName="o", bytecodeStart=15, bytecodeLength=1)
+ void m0(String[] args) {
+ Object o;
+ try {
+ o = "";
+ o.hashCode();
+ } catch (RuntimeException e) {}
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=16)
+ @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=23)
+ void m1() {
+ Object o;
+ try {
+ o = "";
+ o.hashCode();
+ } catch (RuntimeException e) {
+ }
+ finally {
+ o = "finally";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=3, bytecodeLength=16)
+ @AliveRange(varName="o", bytecodeStart=23, bytecodeLength=31)
+ void m2() {
+ Object o;
+ try {
+ o = "";
+ o.hashCode();
+ } catch (RuntimeException e) {
+ o = "catch";
+ o.hashCode();
+ }
+ finally {
+ o = "finally";
+ o.hashCode();
+ }
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=22, bytecodeLength=38)
+ @AliveRange(varName="o", bytecodeStart=103, bytecodeLength=8)
+ void m3() {
+ Object o;
+ try (BufferedReader br =
+ new BufferedReader(new FileReader("aFile"))) {
+ o = "inside try";
+ o.hashCode();
+ } catch (Exception e) {}
+ o = "";
+ }
+
+ @AliveRange(varName="o", bytecodeStart=12, bytecodeLength=96)
+ @AliveRange(varName="o", bytecodeStart=112, bytecodeLength=1)
+ void m4() {
+ String o;
+ try (BufferedReader br =
+ new BufferedReader(new FileReader(o = "aFile"))) {
+ o = "inside try";
+ o.hashCode();
+ } catch (Exception e) {}
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/tests/TestCaseWhile.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,15 @@
+/* /nodynamiccopyright/ */
+
+public class TestCaseWhile {
+
+ @AliveRange(varName="o", bytecodeStart=9, bytecodeLength=5)
+ @AliveRange(varName="o", bytecodeStart=20, bytecodeLength=1)
+ void m(String[] args) {
+ Object o;
+ while (args[0] != null) {
+ o = "";
+ o.hashCode();
+ }
+ o = "";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/neg/OrderedIntersections.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6962494
+ * @summary The order of elements of intersection types shouldn't matter
+ * @compile/fail/ref=OrderedIntersections.out -XDrawDiagnostics OrderedIntersections.java
+ */
+
+interface i1 {}
+interface i2 {}
+
+public class OrderedIntersections {
+ static <t1 extends i1 & i2> Object smf(t1 x) {
+ System.out.println( " smf1 " );
+ return null;
+ }
+
+ static <t2 extends i2 & i1> Object smf(t2 x) {
+ System.out.println( " smf2 " );
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/neg/OrderedIntersections.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,2 @@
+OrderedIntersections.java:17:40: compiler.err.already.defined: kindname.method, <t1>smf(t1), kindname.class, OrderedIntersections
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177a.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8016177 8016178
+ * @summary structural most specific and stuckness
+ * @compile/fail/ref=T8016177a.out -XDrawDiagnostics T8016177a.java
+ */
+import java.util.List;
+
+class T8016177a {
+
+ interface ToIntFunction<X> {
+ int m(X x);
+ }
+
+ interface Function<X, Y> {
+ Y m(X x);
+ }
+
+ <T,R> void m1(List<T> s, Function<T,R> f) { }
+ <T,R> void m1(List<T> s, ToIntFunction<T> f) { }
+
+ <T,R> List<R> m2(List<T> s, Function<T,R> f) { return null; }
+ <T,R> List<R> m2(List<T> s, ToIntFunction<T> f) { return null; }
+
+ <T,R> List<T> m3(List<T> s, Function<T,R> f) { return null; }
+ <T,R> List<R> m3(List<T> s, ToIntFunction<T> f) { return null; }
+
+ <T,R> List<T> m4(List<T> s, Function<T,R> f) { return null; }
+ <T,R> List<T> m4(List<T> s, ToIntFunction<T> f) { return null; }
+
+ <T,R> List<R> m5(List<T> s, Function<T,R> f) { return null; }
+ <T,R> List<T> m5(List<T> s, ToIntFunction<T> f) { return null; }
+
+ <T extends R,R> List<R> m6(List<T> s, Function<T,R> f) { return null; }
+ <T extends R,R> List<T> m6(List<T> s, ToIntFunction<T> f) { return null; }
+
+ void test(List<String> ss) {
+ m1(ss, s->s.length()); //ambiguous
+ m2(ss, s->s.length()); //ambiguous
+ m3(ss, s->s.length()); //ambiguous
+ m4(ss, s->s.length()); //ambiguous
+ m5(ss, s->s.length()); //ambiguous
+ m6(ss, s->s.length()); //ambiguous
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177a.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,8 @@
+T8016177a.java:38:10: compiler.err.ref.ambiguous: m1, kindname.method, <T,R>m1(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m1(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:39:10: compiler.err.ref.ambiguous: m2, kindname.method, <T,R>m2(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m2(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:40:10: compiler.err.ref.ambiguous: m3, kindname.method, <T,R>m3(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m3(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:41:10: compiler.err.ref.ambiguous: m4, kindname.method, <T,R>m4(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m4(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:42:10: compiler.err.ref.ambiguous: m5, kindname.method, <T,R>m5(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m5(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:43:10: compiler.err.ref.ambiguous: m6, kindname.method, <T,R>m6(java.util.List<T>,T8016177a.Function<T,R>), T8016177a, kindname.method, <T,R>m6(java.util.List<T>,T8016177a.ToIntFunction<T>), T8016177a
+T8016177a.java:43:12: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: T,R, (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, java.lang.String)))
+7 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177b.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,34 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8016177 8016178
+ * @summary structural most specific and stuckness
+ * @compile/fail/ref=T8016177b.out -XDrawDiagnostics T8016177b.java
+ */
+class T8016177b {
+ interface ToIntFunction<X> {
+ int m(X x);
+ }
+
+ interface Function<X, Y> {
+ Y m(X x);
+ }
+
+ <U, V> Function<U, V> id(Function<U, V> arg) { return null; }
+
+ <U, V> Function<U, V> id2(Function<U, V> arg) { return null; }
+ <U> ToIntFunction<U> id2(ToIntFunction<U> arg) { return null; }
+
+
+ <X,Y,Z> X f(Y arg, Function<Y, Z> f) { return null; }
+
+ <X,Y,Z> X f2(Y arg, Function<Y, Z> f) { return null; }
+ <X,Y> X f2(Y arg, ToIntFunction<Y> f) { return null; }
+
+ <T> T g(T arg) { return null; }
+
+ void test() {
+ g(f("hi", id(x->1))); //ok
+ g(f("hi", id2(x->1))); //ambiguous
+ g(f2("hi", id(x->1))); //ok
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177b.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,2 @@
+T8016177b.java:31:19: compiler.err.ref.ambiguous: id2, kindname.method, <U,V>id2(T8016177b.Function<U,V>), T8016177b, kindname.method, <U>id2(T8016177b.ToIntFunction<U>), T8016177b
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177c.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,47 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8016081 8016178
+ * @summary structural most specific and stuckness
+ * @compile/fail/ref=T8016177c.out -XDrawDiagnostics T8016177c.java
+ */
+
+class T8016177c {
+
+ interface Function<X, Y> {
+ Y m(X x);
+ }
+
+ interface ExtFunction<X, Y> extends Function<X, Y> { }
+
+ <U, V> U m1(Function<U, V> f) { return null; }
+ <U, V> U m1(ExtFunction<U, V> f) { return null; }
+
+ void m2(Function<Integer, Integer> f) { }
+ void m2(ExtFunction<Integer, Integer> f) { }
+
+ void m3(Function<Integer, Integer> f) { }
+ void m3(ExtFunction<Object, Integer> f) { }
+
+ int g1(Object s) { return 1; }
+
+ int g2(Number s) { return 1; }
+ int g2(Object s) { return 1; }
+
+ void test() {
+ m1((Integer x)->x); //ok - explicit lambda - subtyping picks most specific
+ m2((Integer x)->x); //ok - explicit lambda - subtyping picks most specific
+ m3((Integer x)->x); //ok - explicit lambda (only one applicable)
+
+ m1(x->1); //ok - stuck lambda but nominal most specific wins
+ m2(x->1); //ok - stuck lambda but nominal most specific wins
+ m3(x->1); //ambiguous - implicit lambda & different params
+
+ m1(this::g1); //ok - unambiguous ref - subtyping picks most specific
+ m2(this::g1); //ok - unambiguous ref - subtyping picks most specific
+ m3(this::g1); //ambiguous - both applicable, neither most specific
+
+ m1(this::g2); //ok - stuck mref but nominal most specific wins
+ m2(this::g2); //ok - stuck mref but nominal most specific wins
+ m3(this::g2); //ambiguous - different params
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177c.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,4 @@
+T8016177c.java:37:9: compiler.err.ref.ambiguous: m3, kindname.method, m3(T8016177c.Function<java.lang.Integer,java.lang.Integer>), T8016177c, kindname.method, m3(T8016177c.ExtFunction<java.lang.Object,java.lang.Integer>), T8016177c
+T8016177c.java:41:9: compiler.err.ref.ambiguous: m3, kindname.method, m3(T8016177c.Function<java.lang.Integer,java.lang.Integer>), T8016177c, kindname.method, m3(T8016177c.ExtFunction<java.lang.Object,java.lang.Integer>), T8016177c
+T8016177c.java:45:9: compiler.err.ref.ambiguous: m3, kindname.method, m3(T8016177c.Function<java.lang.Integer,java.lang.Integer>), T8016177c, kindname.method, m3(T8016177c.ExtFunction<java.lang.Object,java.lang.Integer>), T8016177c
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177d.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8016081 8016178
+ * @summary structural most specific and stuckness
+ * @compile T8016177d.java
+ */
+import java.util.*;
+
+class T8016177d {
+
+ interface UnaryOperator<X> {
+ X m(X x);
+ }
+
+ interface IntStream {
+ IntStream sorted();
+ IntStream distinct();
+ IntStream limit(int i);
+ }
+
+ abstract class WrappingUnaryOperator<S> implements UnaryOperator<S> { }
+
+ <S1> WrappingUnaryOperator<S1> wrap1(UnaryOperator<S1> uo) { return null; }
+ <S2> WrappingUnaryOperator<S2> wrap2(UnaryOperator<S2> uo) { return null; }
+ <S3> WrappingUnaryOperator<S3> wrap3(UnaryOperator<S3> uo) { return null; }
+
+ <P> List<List<P>> perm(List<P> l) { return null; }
+
+ List<List<WrappingUnaryOperator<IntStream>>> intPermutationOfFunctions =
+ perm(Arrays.asList(
+ wrap1(s -> s.sorted()),
+ wrap2(s -> s.distinct()),
+ wrap3(s -> s.limit(5))
+ ));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177e.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8016081 8016178
+ * @summary structural most specific and stuckness
+ * @compile T8016177e.java
+ */
+import java.util.*;
+
+class T8016177e {
+
+ interface TerminalOp<X, Y> { }
+
+ interface Consumer<X> {
+ void m(X x);
+ }
+
+ <T> TerminalOp<T, Void> makeRef(Consumer<? super T> action) { return null; }
+
+ <T> void test() {
+ Map<T, Boolean> map = null;
+ TerminalOp<T, Void> forEachOp = makeRef(t -> { map.put(t, null); });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177f.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8016081 8016178
+ * @summary structural most specific and stuckness
+ * @compile T8016177f.java
+ */
+import java.util.*;
+
+class T8016177f {
+
+ interface Function<S, T> {
+ T apply(S s);
+ }
+
+ interface IntFunction<T> {
+ T apply(int s);
+ }
+
+
+ interface BiConsumer<X,Y> {
+ void m(X x, Y y);
+ }
+
+ interface Consumer<X> {
+ void m(X x);
+ }
+
+ interface Supplier<X> {
+ X make();
+ }
+
+ interface TestData<T, S extends BaseStream<T, S>> {
+ interface OfRef<T> extends TestData<T, Stream<T>> { }
+ interface OfDouble extends TestData<Double, DoubleStream> { }
+ }
+
+ interface BaseStream<T, S extends BaseStream<T, S>> { }
+
+ interface Stream<T> extends BaseStream<T, Stream<T>> {
+ <M> Stream<M> map(Function<T, M> s);
+ <R> R collect(Supplier<R> resultFactory, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);
+ <Z> Z[] toArray(IntFunction<Z[]> s);
+ }
+
+ interface DoubleStream extends BaseStream<Double, DoubleStream> {
+ DoubleStream filter(DoublePredicate dp);
+ double[] toArray();
+ }
+
+ interface DoublePredicate {
+ boolean p(double d);
+ }
+
+ <T, U, R, S_IN extends BaseStream<T, S_IN>, S_OUT extends BaseStream<U, S_OUT>>
+ R exerciseTerminalOps(TestData<T, S_IN> data,
+ Function<S_IN, S_OUT> streamF,
+ Function<S_OUT, R> terminalF) { return null; }
+
+ <O> TestData.OfRef<O> ofCollection(Collection<O> collection) { return null; }
+
+ void test1(TestData.OfDouble data, DoublePredicate dp) {
+ exerciseTerminalOps(data, s -> s.filter(dp), s -> s.toArray());
+ }
+
+ void test2(Function<Double, Integer> fdi, TestData.OfRef<Double> td, Stream<Integer> si) {
+ exerciseTerminalOps(
+ ofCollection((List<Double>)null),
+ s -> s.map(fdi),
+ s -> s.toArray(Integer[]::new));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177g.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,37 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8016081 8016178
+ * @summary structural most specific and stuckness
+ * @compile/fail/ref=T8016177g.out -XDrawDiagnostics T8016177g.java
+ */
+
+
+class Test {
+
+ interface Function<X, Y> {
+ Y m(X x);
+ }
+
+ interface Box<T> {
+ T get();
+ <R> R map(Function<T,R> f);
+ }
+
+ static class Person {
+ Person(String name) { }
+ }
+
+ void print(Object arg) { }
+ void print(String arg) { }
+
+ int abs(int a) { return 0; }
+ long abs(long a) { return 0; }
+ float abs(float a) { return 0; }
+ double abs(double a) { return 0; }
+
+ void test() {
+ Box<String> b = null;
+ print(b.map(s -> new Person(s)));
+ int i = abs(b.map(s -> Double.valueOf(s)));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8016177/T8016177g.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,2 @@
+T8016177g.java:35:20: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: double, int)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023389/T8023389.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8023389
+ * @summary Javac fails to infer type for lambda used with intersection type and wildcards
+ * @compile T8023389.java
+ */
+public class T8023389 {
+
+ static class U1 {}
+ static class X1 extends U1 {}
+
+ interface I { }
+
+ interface SAM<T> {
+ void m(T t);
+ }
+
+ /* Strictly speaking only the second of the following declarations provokes the bug.
+ * But the first line is also a useful test case.
+ */
+ SAM<? extends U1> sam1 = (SAM<? extends U1>) (X1 x) -> { };
+ SAM<? extends U1> sam2 = (SAM<? extends U1> & I) (X1 x) -> { };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023549/T8023549.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,27 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8023549
+ * @summary Compiler emitting spurious errors when constructor reference type is inferred and explicit type arguments are supplied
+ * @compile/fail/ref=T8023549.out -XDrawDiagnostics T8023549.java
+ */
+
+public class T8023549 {
+ static class Foo<X> { }
+
+ interface Supplier<X> {
+ X make();
+ }
+
+ interface ExtSupplier<X> extends Supplier<X> { }
+
+ void m1(Supplier<Foo<String>> sfs) { }
+
+ void m2(Supplier<Foo<String>> sfs) { }
+ void m2(ExtSupplier<Foo<Integer>> sfs) { }
+
+ void test() {
+ Supplier<Foo<String>> sfs = Foo::<Number>new;
+ m1(Foo::<Number>new);
+ m2(Foo::<Number>new);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023549/T8023549.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,5 @@
+T8023549.java:23:37: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.mref.infer.and.explicit.params)
+T8023549.java:24:12: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.mref.infer.and.explicit.params)
+T8023549.java:25:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(T8023549.Supplier<T8023549.Foo<java.lang.String>>), T8023549, kindname.method, m2(T8023549.ExtSupplier<T8023549.Foo<java.lang.Integer>>), T8023549
+T8023549.java:25:12: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.mref.infer.and.explicit.params)
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023558/T8023558a.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8023558
+ * @summary Javac creates invalid bootstrap methods for complex lambda/methodref case
+ */
+public class T8023558a {
+ interface SAM<T> {
+ T get();
+ }
+
+ public static void main(String[] args) {
+ SAM<SAM> sam = new SAM<SAM>() { public SAM get() { return null; } };
+ SAM temp = sam.get()::get;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023558/T8023558b.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8023558
+ * @summary Javac creates invalid bootstrap methods for complex lambda/methodref case
+ */
+public class T8023558b {
+
+ interface Supplier<X> {
+ X get();
+ }
+
+ static class A {
+ public A(Supplier<B> supplier) { }
+ }
+
+ static class B { }
+
+ static class C {
+ public B getB() {
+ return new B();
+ }
+ }
+
+ public static void main(String[] args) {
+ new T8023558b().test(T8023558b::getC);
+ }
+
+ private static C getC() {
+ return new C();
+ }
+
+ public void test(Supplier<C> supplier) {
+ new A(supplier.get()::getB);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8023558/T8023558c.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8023558
+ * @summary Javac creates invalid bootstrap methods for complex lambda/methodref case
+ */
+
+interface SAM<T> {
+ T get();
+}
+
+public class T8023558c {
+ public static void main(String[] args) {
+ SAM<SAM> sam = () -> Object::new;
+ SAM temp = sam.get()::get;
+ }
+}
--- a/langtools/test/tools/javac/lambda/BadRecovery.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/BadRecovery.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,2 +1,3 @@
+BadRecovery.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, BadRecovery.SAM1, @369, kindname.class, BadRecovery, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.lambda))
BadRecovery.java:17:77: compiler.err.cant.resolve.location: kindname.variable, f, , , (compiler.misc.location: kindname.class, BadRecovery, null)
-1 error
+2 errors
--- a/langtools/test/tools/javac/lambda/EffectivelyFinalTest.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/EffectivelyFinalTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,6 +1,6 @@
/*
* @test /nodynamiccopyright/
- * @bug 8003280
+ * @bug 7175538 8003280
* @summary Add lambda tests
* Integrate effectively final check with DA/DU analysis
* @compile/fail/ref=EffectivelyFinalTest01.out -XDrawDiagnostics EffectivelyFinalTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/EffectivelyFinalThrows.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8019521
+ * @summary Check that enhanced rethrow/effectivelly final works correctly inside lambdas
+ * @compile EffectivelyFinalThrows.java
+ */
+
+class EffectivelyFinalThrows {
+ interface SAM<E extends Throwable> {
+ public void t() throws E;
+ }
+ <E extends Throwable> void test(SAM<E> s) throws E {
+ s.t();
+ }
+ void test2(SAM<Checked> s) throws Checked {
+ test(() -> {
+ try {
+ s.t();
+ } catch (Throwable t) {
+ throw t;
+ }
+ });
+ }
+ static class Checked extends Exception {}
+}
--- a/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
* @bug 8003280
* @summary Add lambda tests
* stale state after speculative attribution round leads to missing classfiles
+ * @compile/fail/ref=ErroneousLambdaExpr.out -XDrawDiagnostics ErroneousLambdaExpr.java
*/
public class ErroneousLambdaExpr<T> {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,2 @@
+ErroneousLambdaExpr.java:63:13: compiler.err.ref.ambiguous: call, kindname.method, call(ErroneousLambdaExpr.SAM1<T>), ErroneousLambdaExpr, kindname.method, call(ErroneousLambdaExpr.SAM2), ErroneousLambdaExpr
+1 error
--- a/langtools/test/tools/javac/lambda/MethodReference22.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference22.out Tue Sep 17 08:21:11 2013 -0700
@@ -3,13 +3,17 @@
MethodReference22.java:46:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))
MethodReference22.java:47:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))
MethodReference22.java:51:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22))
-MethodReference22.java:52:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1401, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22)))
+MethodReference22.java:52:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1401, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22)))
MethodReference22.java:53:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22))
-MethodReference22.java:54:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1504, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22)))
+MethodReference22.java:54:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1504, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22)))
MethodReference22.java:55:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22))
-MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1607, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22)))
+MethodReference22.java:56:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1607, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22)))
MethodReference22.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))
-MethodReference22.java:58:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1710, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)))
+MethodReference22.java:58:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1710, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)))
+MethodReference22.java:62:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
MethodReference22.java:62:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String))
+MethodReference22.java:63:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
+MethodReference22.java:64:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
+MethodReference22.java:65:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
MethodReference22.java:65:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))
-14 errors
+18 errors
--- a/langtools/test/tools/javac/lambda/MethodReference23.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference23.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,6 +1,6 @@
MethodReference23.java:52:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23))
-MethodReference23.java:53:9: compiler.err.cant.apply.symbol: kindname.method, call11, MethodReference23.SAM11, @1140, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23)))
+MethodReference23.java:53:15: compiler.err.cant.apply.symbol: kindname.method, call11, MethodReference23.SAM11, @1140, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23)))
MethodReference23.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23))
-MethodReference23.java:58:9: compiler.err.cant.apply.symbol: kindname.method, call12, MethodReference23.SAM12, @1282, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23)))
+MethodReference23.java:58:15: compiler.err.cant.apply.symbol: kindname.method, call12, MethodReference23.SAM12, @1282, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23)))
MethodReference23.java:72:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference23.SAM21), MethodReference23, kindname.method, call3(MethodReference23.SAM22), MethodReference23
5 errors
--- a/langtools/test/tools/javac/lambda/MethodReference41.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference41.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that diamond inference is applied when using raw constructor reference qualifier
- * @run main MethodReference41
+ * @compile/fail/ref=MethodReference41.out -XDrawDiagnostics MethodReference41.java
*/
-public class MethodReference41 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference41 {
interface SAM1 {
void m(String s);
@@ -54,13 +24,20 @@
Foo(X x) { }
}
+ static void m1(SAM1 s) { }
- static void m(SAM1 s) { assertTrue(false); }
- static void m(SAM2 s) { assertTrue(true); }
- static void m(SAM3 s) { assertTrue(false); }
+ static void m2(SAM2 s) { }
+
+ static void m3(SAM3 s) { }
+
+ static void m4(SAM1 s) { }
+ static void m4(SAM2 s) { }
+ static void m4(SAM3 s) { }
public static void main(String[] args) {
- m(Foo::new);
- assertTrue(assertionCount == 1);
+ m1(Foo::new);
+ m2(Foo::new);
+ m3(Foo::new);
+ m4(Foo::new);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference41.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,4 @@
+MethodReference41.java:38:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference41.SAM1, @767, kindname.class, MethodReference41, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.String, kindname.class, MethodReference41.Foo<X>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number))))
+MethodReference41.java:40:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference41.SAM3, @811, kindname.class, MethodReference41, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference41.Foo<X>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number))))
+MethodReference41.java:41:9: compiler.err.ref.ambiguous: m4, kindname.method, m4(MethodReference41.SAM2), MethodReference41, kindname.method, m4(MethodReference41.SAM3), MethodReference41
+3 errors
--- a/langtools/test/tools/javac/lambda/MethodReference42.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference42.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that diamond inference is applied when using raw constructor reference qualifier
- * @run main MethodReference42
+ * @compile/fail/ref=MethodReference42.out -XDrawDiagnostics MethodReference42.java
*/
-public class MethodReference42 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference42 {
static class SuperFoo<X> { }
@@ -54,12 +24,20 @@
SuperFoo<Object> m();
}
- static void m(SAM1 s) { assertTrue(false); }
- static void m(SAM2 s) { assertTrue(true); }
- static void m(SAM3 s) { assertTrue(false); }
+ static void m1(SAM1 s) { }
+
+ static void m2(SAM2 s) { }
+
+ static void m3(SAM3 s) { }
+
+ static void m4(SAM1 s) { }
+ static void m4(SAM2 s) { }
+ static void m4(SAM3 s) { }
public static void main(String[] args) {
- m(Foo::new);
- assertTrue(assertionCount == 1);
+ m1(Foo::new);
+ m2(Foo::new);
+ m3(Foo::new);
+ m4(Foo::new);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference42.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,4 @@
+MethodReference42.java:38:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference42.SAM1, @811, kindname.class, MethodReference42, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number))
+MethodReference42.java:40:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference42.SAM3, @855, kindname.class, MethodReference42, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Number))
+MethodReference42.java:41:9: compiler.err.ref.ambiguous: m4, kindname.method, m4(MethodReference42.SAM2), MethodReference42, kindname.method, m4(MethodReference42.SAM3), MethodReference42
+3 errors
--- a/langtools/test/tools/javac/lambda/MethodReference43.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference43.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that diamond inference is applied when using raw constructor reference qualifier
- * @run main MethodReference43
+ * @compile/fail/ref=MethodReference43.out -XDrawDiagnostics MethodReference43.java
*/
-public class MethodReference43 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference43 {
interface SAM1 {
Foo<?> m(String s);
@@ -58,14 +28,24 @@
Foo(X x) { }
}
+ static void m1(SAM1 s) { }
- static void m(SAM1 s) { assertTrue(false); }
- static void m(SAM2 s) { assertTrue(false); }
- static void m(SAM3 s) { assertTrue(false); }
- static void m(SAM4 s) { assertTrue(true); }
+ static void m2(SAM2 s) { }
+
+ static void m3(SAM3 s) { }
+
+ static void m4(SAM4 s) { }
+
+ static void m5(SAM1 s) { }
+ static void m5(SAM2 s) { }
+ static void m5(SAM3 s) { }
+ static void m5(SAM4 s) { }
public static void main(String[] args) {
- m(Foo::new);
- assertTrue(assertionCount == 1);
+ m1(Foo::new);
+ m2(Foo::new);
+ m3(Foo::new);
+ m4(Foo::new);
+ m5(Foo::new);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference43.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,5 @@
+MethodReference43.java:45:11: compiler.err.cant.apply.symbol: kindname.method, m1, MethodReference43.SAM1, @897, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.String, kindname.class, MethodReference43.Foo<X>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number))))
+MethodReference43.java:47:11: compiler.err.cant.apply.symbol: kindname.method, m3, MethodReference43.SAM3, @941, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference43.Foo<X>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number))))
+MethodReference43.java:49:9: compiler.err.ref.ambiguous: m5, kindname.method, m5(MethodReference43.SAM3), MethodReference43, kindname.method, m5(MethodReference43.SAM4), MethodReference43
+MethodReference43.java:49:11: compiler.err.cant.apply.symbol: kindname.method, m5, MethodReference43.SAM3, @985, kindname.class, MethodReference43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Foo, java.lang.Number, java.lang.Object, kindname.class, MethodReference43.Foo<X>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number))))
+4 errors
--- a/langtools/test/tools/javac/lambda/MethodReference44.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference44.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that generic method reference is inferred when type parameters are omitted
- * @run main MethodReference44
+ * @compile/fail/ref=MethodReference44.out -XDrawDiagnostics MethodReference44.java
*/
-public class MethodReference44 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference44 {
static class SuperFoo<X> { }
@@ -56,12 +26,20 @@
static <X extends Number> Foo<X> m() { return null; }
- static void g(SAM1 s) { assertTrue(false); }
- static void g(SAM2 s) { assertTrue(true); }
- static void g(SAM3 s) { assertTrue(false); }
+ static void g1(SAM1 s) { }
+
+ static void g2(SAM2 s) { }
+
+ static void g3(SAM3 s) { }
+
+ static void g4(SAM1 s) { }
+ static void g4(SAM2 s) { }
+ static void g4(SAM3 s) { }
public static void main(String[] args) {
- g(MethodReference44::m);
- assertTrue(assertionCount == 1);
+ g1(MethodReference44::m);
+ g2(MethodReference44::m);
+ g3(MethodReference44::m);
+ g4(MethodReference44::m);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference44.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,4 @@
+MethodReference44.java:40:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference44.SAM1, @864, kindname.class, MethodReference44, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number))
+MethodReference44.java:42:11: compiler.err.cant.apply.symbol: kindname.method, g3, MethodReference44.SAM3, @932, kindname.class, MethodReference44, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Number))
+MethodReference44.java:43:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference44.SAM2), MethodReference44, kindname.method, g4(MethodReference44.SAM3), MethodReference44
+3 errors
--- a/langtools/test/tools/javac/lambda/MethodReference46.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference46.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that generic method reference is inferred when type parameters are omitted
- * @run main MethodReference46
+ * @compile/fail/ref=MethodReference46.out -XDrawDiagnostics MethodReference46.java
*/
-public class MethodReference46 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference46 {
interface SAM1 {
void m(String s);
@@ -56,12 +26,20 @@
static <X extends Number> void m(X fx) { }
- static void g(SAM1 s) { assertTrue(false); }
- static void g(SAM2 s) { assertTrue(true); }
- static void g(SAM3 s) { assertTrue(false); }
+ static void g1(SAM1 s) { }
+
+ static void g2(SAM2 s) { }
+
+ static void g3(SAM3 s) { }
+
+ static void g4(SAM1 s) { }
+ static void g4(SAM2 s) { }
+ static void g4(SAM3 s) { }
public static void main(String[] args) {
- g(MethodReference46::m);
- assertTrue(assertionCount == 1);
+ g1(MethodReference46::m);
+ g2(MethodReference46::m);
+ g3(MethodReference46::m);
+ g4(MethodReference46::m);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference46.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,4 @@
+MethodReference46.java:40:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference46.SAM1, @809, kindname.class, MethodReference46, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m, X, java.lang.String, kindname.class, MethodReference46, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number))))
+MethodReference46.java:42:11: compiler.err.cant.apply.symbol: kindname.method, g3, MethodReference46.SAM3, @877, kindname.class, MethodReference46, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m, X, java.lang.Object, kindname.class, MethodReference46, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Number))))
+MethodReference46.java:43:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference46.SAM2), MethodReference46, kindname.method, g4(MethodReference46.SAM3), MethodReference46
+3 errors
--- a/langtools/test/tools/javac/lambda/MethodReference47.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference47.java Tue Sep 17 08:21:11 2013 -0700
@@ -7,14 +7,6 @@
*/
public class MethodReference47 {
- static int assertionCount = 0;
-
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
-
interface SAM1 {
void m(Integer s);
}
@@ -34,7 +26,7 @@
static void g2(SAM2 s) { }
public static void main(String[] args) {
- g1(MethodReference46::m);
- g2(MethodReference46::m);
+ g1(MethodReference47::m);
+ g2(MethodReference47::m);
}
}
--- a/langtools/test/tools/javac/lambda/MethodReference47.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference47.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,2 +1,2 @@
-MethodReference47.java:38:9: compiler.err.ref.ambiguous: g2, kindname.method, g2(MethodReference47.SAM1), MethodReference47, kindname.method, g2(MethodReference47.SAM2), MethodReference47
+MethodReference47.java:30:9: compiler.err.ref.ambiguous: g2, kindname.method, g2(MethodReference47.SAM1), MethodReference47, kindname.method, g2(MethodReference47.SAM2), MethodReference47
1 error
--- a/langtools/test/tools/javac/lambda/MethodReference48.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference48.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,42 +1,12 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 8003280
* @summary Add lambda tests
* check that raw qualifier in unbound method reference is inferred from descriptor
- * @run main MethodReference48
+ * @compile/fail/ref=MethodReference48.out -XDrawDiagnostics MethodReference48.java
*/
-public class MethodReference48 {
-
- static int assertionCount = 0;
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
+public class MethodReference48 {
static class Foo<X> {
X m() { return null; };
@@ -54,12 +24,20 @@
Object m(Foo<Integer> fi);
}
- static void g(SAM1 s) { assertTrue(false); } //return type not compatible
- static void g(SAM2 s) { assertTrue(true); } //ok
- static void g(SAM3 s) { assertTrue(false); } //ok but less specific
+ static void g1(SAM1 s) { } //return type not compatible
+
+ static void g2(SAM2 s) { } //ok
+
+ static void g3(SAM3 s) { } //ok
+
+ static void g4(SAM1 s) { } //return type not compatible
+ static void g4(SAM2 s) { } //ok
+ static void g4(SAM3 s) { } //ok
public static void main(String[] args) {
- g(Foo::m);
- assertTrue(assertionCount == 1);
+ g1(Foo::m);
+ g2(Foo::m);
+ g3(Foo::m);
+ g4(Foo::m);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference48.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,3 @@
+MethodReference48.java:38:11: compiler.err.cant.apply.symbol: kindname.method, g1, MethodReference48.SAM1, @869, kindname.class, MethodReference48, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: java.lang.String, MethodReference48.Foo<java.lang.Object>)))
+MethodReference48.java:41:9: compiler.err.ref.ambiguous: g4, kindname.method, g4(MethodReference48.SAM2), MethodReference48, kindname.method, g4(MethodReference48.SAM3), MethodReference48
+2 errors
--- a/langtools/test/tools/javac/lambda/MethodReference70.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference70.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,3 +1,3 @@
MethodReference70.java:26:10: compiler.err.ref.ambiguous: g, kindname.method, <Z>g(MethodReference70.F<Z>), MethodReference70, kindname.method, <Z>g(MethodReference70.G<Z>), MethodReference70
-MethodReference70.java:26:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z)
+MethodReference70.java:26:11: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, m2, java.lang.Object,{(compiler.misc.inapplicable.method: kindname.method, MethodReference70, m2(java.lang.Integer), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.Integer))),(compiler.misc.inapplicable.method: kindname.method, MethodReference70, m2(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.String)))})))
2 errors
--- a/langtools/test/tools/javac/lambda/MethodReference71.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MethodReference71.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,3 +1,3 @@
MethodReference71.java:24:10: compiler.err.ref.ambiguous: g, kindname.method, <Z>g(MethodReference71.F<Z>), MethodReference71, kindname.method, <Z>g(MethodReference71.G<Z>), MethodReference71
-MethodReference71.java:24:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z)
+MethodReference71.java:24:11: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m2, java.lang.Integer[], java.lang.Object, kindname.class, MethodReference71, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.Integer)))))
2 errors
--- a/langtools/test/tools/javac/lambda/MostSpecific04.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MostSpecific04.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,17 +26,10 @@
* @bug 8003280
* @summary Add lambda tests
* Structural most specific doesn't handle cases with wildcards in functional interfaces
+ * @compile/fail/ref=MostSpecific04.out -XDrawDiagnostics MostSpecific04.java
*/
public class MostSpecific04 {
- static int assertionCount = 0;
-
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
-
interface DoubleMapper<T> {
double map(T t);
}
@@ -46,13 +39,13 @@
}
static class MyList<E> {
- void map(DoubleMapper<? super E> m) { assertTrue(false); }
- void map(LongMapper<? super E> m) { assertTrue(true); }
+ void map(DoubleMapper<? super E> m) { }
+ void map(LongMapper<? super E> m) { }
}
public static void main(String[] args) {
MyList<String> ls = new MyList<String>();
- ls.map(e->e.length());
- assertTrue(assertionCount == 1);
+ ls.map(e->e.length()); //ambiguous - implicit
+ ls.map((String e)->e.length()); //ok
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific04.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,2 @@
+MostSpecific04.java:48:11: compiler.err.ref.ambiguous: map, kindname.method, map(MostSpecific04.DoubleMapper<? super E>), MostSpecific04.MyList, kindname.method, map(MostSpecific04.LongMapper<? super E>), MostSpecific04.MyList
+1 error
--- a/langtools/test/tools/javac/lambda/MostSpecific05.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MostSpecific05.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,17 +26,10 @@
* @bug 8003280
* @summary Add lambda tests
* Structural most specific doesn't handle cases with wildcards in functional interfaces
+ * @compile/fail/ref=MostSpecific05.out -XDrawDiagnostics MostSpecific05.java
*/
public class MostSpecific05 {
- static int assertionCount = 0;
-
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
-
interface ObjectConverter<T extends Object> {
T map(Object o);
}
@@ -46,13 +39,13 @@
}
static class MyMapper<A extends Object, B extends Number> {
- void map(ObjectConverter<? extends A> m) { assertTrue(false); }
- void map(NumberConverter<? extends B> m) { assertTrue(true); }
+ void map(ObjectConverter<? extends A> m) { }
+ void map(NumberConverter<? extends B> m) { }
}
public static void main(String[] args) {
MyMapper<Number, Double> mm = new MyMapper<Number, Double>();
- mm.map(e->1.0);
- assertTrue(assertionCount == 1);
+ mm.map(e->1.0); //ambiguous - implicit
+ mm.map((Object e)->1.0); //ok
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific05.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,2 @@
+MostSpecific05.java:48:11: compiler.err.ref.ambiguous: map, kindname.method, map(MostSpecific05.ObjectConverter<? extends A>), MostSpecific05.MyMapper, kindname.method, map(MostSpecific05.NumberConverter<? extends B>), MostSpecific05.MyMapper
+1 error
--- a/langtools/test/tools/javac/lambda/MostSpecific08.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/MostSpecific08.java Tue Sep 17 08:21:11 2013 -0700
@@ -25,7 +25,7 @@
* @test
* @bug 8008813
* @summary Structural most specific fails when method reference is passed to overloaded method
- * @compile MostSpecific08.java
+ * @compile/fail/ref=MostSpecific08.out -XDrawDiagnostics MostSpecific08.java
*/
class MostSpecific08 {
@@ -51,12 +51,14 @@
}
void testMref(Tester t) {
- IntResult pr = t.apply(C::getInt);
- ReferenceResult<Integer> rr = t.apply(C::getInteger);
+ IntResult pr = t.apply(C::getInt); //ok - unoverloaded mref
+ ReferenceResult<Integer> rr = t.apply(C::getInteger); //ok - unoverloaded mref
}
void testLambda(Tester t) {
- IntResult pr = t.apply(c->c.getInt());
- ReferenceResult<Integer> rr = t.apply(c->c.getInteger());
+ IntResult pr1 = t.apply(c->c.getInt()); //ambiguous - implicit
+ IntResult pr2 = t.apply((C c)->c.getInt()); //ok
+ ReferenceResult<Integer> rr1 = t.apply(c->c.getInteger()); //ambiguous - implicit
+ ReferenceResult<Integer> rr2 = t.apply((C c)->c.getInteger()); //ok
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific08.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,4 @@
+MostSpecific08.java:59:26: compiler.err.ref.ambiguous: apply, kindname.method, apply(MostSpecific08.PrimitiveFunction), MostSpecific08.Tester, kindname.method, <Z>apply(MostSpecific08.ReferenceFunction<Z>), MostSpecific08.Tester
+MostSpecific08.java:61:41: compiler.err.ref.ambiguous: apply, kindname.method, apply(MostSpecific08.PrimitiveFunction), MostSpecific08.Tester, kindname.method, <Z>apply(MostSpecific08.ReferenceFunction<Z>), MostSpecific08.Tester
+MostSpecific08.java:61:47: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: MostSpecific08.IntResult, MostSpecific08.ReferenceResult<java.lang.Integer>)
+3 errors
--- a/langtools/test/tools/javac/lambda/TargetType01.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType01.java Tue Sep 17 08:21:11 2013 -0700
@@ -26,7 +26,7 @@
* @bug 8003280 8009131
* @summary Add lambda tests
* check nested case of overload resolution and lambda parameter inference
- * @compile TargetType01.java
+ * @compile/fail/ref=TargetType01.out -XDrawDiagnostics TargetType01.java
*/
class TargetType01 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType01.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,3 @@
+TargetType01.java:45:9: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
+TargetType01.java:45:26: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
+2 errors
--- a/langtools/test/tools/javac/lambda/TargetType02.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType02.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,19 +27,11 @@
* @summary Add lambda tests
* check overload resolution and target type inference w.r.t. generic methods
* @author Maurizio Cimadamore
- * @run main TargetType02
+ * @compile/fail/ref=TargetType02.out -XDrawDiagnostics TargetType02.java
*/
public class TargetType02 {
- static int assertionCount = 0;
-
- static void assertTrue(boolean cond) {
- assertionCount++;
- if (!cond)
- throw new AssertionError();
- }
-
interface S1<X extends Number> {
X m(Integer x);
}
@@ -48,15 +40,16 @@
abstract X m(Integer x);
}
- static <Z extends Number> void call(S1<Z> s) { s.m(1); assertTrue(true); }
- static <Z extends String> void call(S2<Z> s) { s.m(2); assertTrue(false); }
+ static <Z extends Number> void call1(S1<Z> s) { }
+
+ static <Z extends String> void call2(S2<Z> s) { }
+
+ static <Z extends Number> void call3(S1<Z> s) { }
+ static <Z extends String> void call3(S2<Z> s) { }
void test() {
- call(i -> { toString(); return i; });
- }
-
- public static void main(String[] args) {
- new TargetType02().test();
- assertTrue(assertionCount == 1);
+ call1(i -> { toString(); return i; });
+ call2(i -> { toString(); return i; });
+ call3(i -> { toString(); return i; });
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType02.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,3 @@
+TargetType02.java:52:14: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String)
+TargetType02.java:53:9: compiler.err.ref.ambiguous: call3, kindname.method, <Z>call3(TargetType02.S1<Z>), TargetType02, kindname.method, <Z>call3(TargetType02.S2<Z>), TargetType02
+2 errors
--- a/langtools/test/tools/javac/lambda/TargetType10.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType10.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,10 +1,10 @@
/*
* @test /nodynamiccopyright/
- * @bug 8003280
+ * @bug 8003280 8016177
* @summary Add lambda tests
* check that wildcards in the target method of a lambda conversion is handled correctly
* @author Maurizio Cimadamore
- * @compile/fail/ref=TargetType10.out -XDrawDiagnostics TargetType10.java
+ * @compile TargetType10.java
*/
class TargetType10 {
--- a/langtools/test/tools/javac/lambda/TargetType10.out Thu Sep 12 11:09:20 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-TargetType10.java:17:18: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: B,A)
-1 error
--- a/langtools/test/tools/javac/lambda/TargetType21.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType21.java Tue Sep 17 08:21:11 2013 -0700
@@ -26,8 +26,10 @@
void test() {
call(x -> { throw new Exception(); }); //ambiguous
+ call((Integer x) -> { System.out.println(""); }); //ok (only one is void)
+ call((Integer x) -> { return (Object) null; }); //ok (only one returns Object)
call(x -> { System.out.println(""); }); //ambiguous
- call(x -> { return (Object) null; }); //cyclic inference
+ call(x -> { return (Object) null; }); //ambiguous
call(x -> { return null; }); //ambiguous
}
}
--- a/langtools/test/tools/javac/lambda/TargetType21.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType21.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,7 @@
TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
-TargetType21.java:29:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
-TargetType21.java:30:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: A)
-TargetType21.java:31:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
-4 errors
+TargetType21.java:31:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+TargetType21.java:32:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+TargetType21.java:32:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM2, @888, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val)))
+TargetType21.java:33:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
+TargetType21.java:33:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM2, @946, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val)))
+6 errors
--- a/langtools/test/tools/javac/lambda/TargetType24.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType24.java Tue Sep 17 08:21:11 2013 -0700
@@ -29,11 +29,14 @@
}
void test(Array<String> as, final Array<Character> ac) {
- final boolean b1 = as.forAll(s -> ac.forAll(c -> false)); //ok
+ final boolean b1 = as.forAll((String s) -> ac.forAll((Character c) -> false)); //ok
+ final boolean b2 = as.forAll(s -> ac.forAll(c -> false)); //ambiguous
+ final boolean b3 = as.forAll((String s) -> ac.forAll(c -> false)); //ambiguous
+ final boolean b4 = as.forAll(s -> ac.forAll((Character c) -> false)); //ambiguous
final String s1 = as.forAll2(s -> ac.forAll2(c -> "")); //ok
- final boolean b2 = as.forAll(s -> ac.forAll(c -> "" )); //fail
+ final boolean b5 = as.forAll(s -> ac.forAll(c -> "" )); //fail
final String s2 = as.forAll2(s -> ac.forAll2(c -> false)); //fail
- final boolean b3 = as.forAll((F<String, Boolean>)s -> ac.forAll((F<Character, Boolean>)c -> "")); //fail
+ final boolean b6 = as.forAll((F<String, Boolean>)s -> ac.forAll((F<Character, Boolean>)c -> "")); //fail
final String s3 = as.forAll((FSub<String, String>)s -> ac.forAll((FSub<Character, String>)c -> false)); //fail
}
}
--- a/langtools/test/tools/javac/lambda/TargetType24.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType24.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,11 @@
-TargetType24.java:34:37: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, boolean)
-TargetType24.java:35:45: compiler.err.cant.apply.symbol: kindname.method, forAll2, TargetType24.FSub<java.lang.Character,java.lang.String>, @945, kindname.class, TargetType24.Array<A>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String)))
-TargetType24.java:36:101: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Boolean))
-TargetType24.java:37:104: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String))
-4 errors
+TargetType24.java:33:30: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:33:45: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:34:54: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:35:30: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:37:30: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:37:45: compiler.err.ref.ambiguous: forAll, kindname.method, forAll(TargetType24.F<A,java.lang.Boolean>), TargetType24.Array, kindname.method, forAll(TargetType24.FSub<A,java.lang.String>), TargetType24.Array
+TargetType24.java:37:52: compiler.err.cant.apply.symbol: kindname.method, forAll, TargetType24.F<java.lang.Character,java.lang.Boolean>, @1149, kindname.class, TargetType24.Array<A>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Boolean)))
+TargetType24.java:38:53: compiler.err.cant.apply.symbol: kindname.method, forAll2, TargetType24.FSub<java.lang.Character,java.lang.String>, @1221, kindname.class, TargetType24.Array<A>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String)))
+TargetType24.java:39:101: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Boolean))
+TargetType24.java:40:104: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String))
+10 errors
--- a/langtools/test/tools/javac/lambda/TargetType26.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType26.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,2 +1,2 @@
-TargetType26.java:16:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z)
+TargetType26.java:16:11: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.not.a.functional.intf: java.lang.Object))
1 error
--- a/langtools/test/tools/javac/lambda/TargetType27.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType27.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,2 +1,2 @@
-TargetType27.java:18:10: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: R)
+TargetType27.java:18:10: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: A,R, (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.not.a.functional.intf: java.lang.Object)))
1 error
--- a/langtools/test/tools/javac/lambda/TargetType39.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType39.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,3 +1,3 @@
-TargetType39.java:19:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: U)
-TargetType39.java:20:13: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: V)
+TargetType39.java:19:13: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: U,V, (compiler.misc.incompatible.type.in.conditional: (compiler.misc.inconvertible.types: TargetType39.SAM<java.lang.String,java.lang.Void>, TargetType39.SAM<java.lang.Object,V>)))
+TargetType39.java:20:13: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: U,V, (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.incompatible.type.in.conditional: (compiler.misc.not.a.functional.intf: java.lang.Object))))
2 errors
--- a/langtools/test/tools/javac/lambda/TargetType43.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType43.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,4 +1,5 @@
TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
TargetType43.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
+TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
-3 errors
+4 errors
--- a/langtools/test/tools/javac/lambda/TargetType66.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType66.java Tue Sep 17 08:21:11 2013 -0700
@@ -17,8 +17,8 @@
void g(SAM2 s2) { }
void test() {
- g(x->{ String s = x; }); //g(SAM1)
- g(x->{ Integer i = x; }); //g(SAM2)
+ g(x->{ String s = x; }); //ambiguous
+ g(x->{ Integer i = x; }); //ambiguous
g(x->{ Object o = x; }); //ambiguous
g(x->{ Character c = x; }); //error: inapplicable methods
g(x->{ Character c = ""; }); //error: incompatible types
--- a/langtools/test/tools/javac/lambda/TargetType66.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/TargetType66.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,4 +1,9 @@
+TargetType66.java:20:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
+TargetType66.java:21:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
+TargetType66.java:21:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)
TargetType66.java:22:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
-TargetType66.java:23:9: compiler.err.cant.apply.symbols: kindname.method, g, @578,{(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.String, (compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character))))),(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.Integer, (compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Integer, java.lang.Character)))))}
+TargetType66.java:23:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
+TargetType66.java:23:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character)
+TargetType66.java:24:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
TargetType66.java:24:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character)
-3 errors
+8 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodTestCase.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringJoiner;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import tools.javac.combo.*;
+
+import static org.testng.Assert.fail;
+
+/**
+ * BridgeMethodTestCase -- used for asserting linkage to bridges under separate compilation.
+ *
+ * Example test case:
+ * public void test1() throws IOException, ReflectiveOperationException {
+ * compileSpec("C(Bc1(A))");
+ * assertLinkage("C", LINKAGE_ERROR, "B1");
+ * recompileSpec("C(Bc1(Ac0))", "A");
+ * assertLinkage("C", "A0", "B1");
+ * }
+ *
+ * This compiles A, B, and C, asserts that C.m()Object does not exist, asserts
+ * that C.m()Number eventually invokes B.m()Number, recompiles B, and then asserts
+ * that the result of calling C.m()Object now arrives at A.
+ *
+ * @author Brian Goetz
+ */
+
+@Test
+public abstract class BridgeMethodTestCase extends JavacTemplateTestBase {
+
+ private static final String TYPE_LETTERS = "ABCDIJK";
+
+ private static final String BASE_INDEX_CLASS = "class C0 {\n" +
+ " int val;\n" +
+ " C0(int val) { this.val = val; }\n" +
+ " public int getVal() { return val; }\n" +
+ "}\n";
+ private static final String INDEX_CLASS_TEMPLATE = "class C#ID extends C#PREV {\n" +
+ " C#ID(int val) { super(val); }\n" +
+ "}\n";
+
+
+
+ protected static String LINKAGE_ERROR = "-1";
+
+ private List<File> compileDirs = new ArrayList<>();
+
+ /**
+ * Compile all the classes in a class spec, and put them on the classpath.
+ *
+ * The spec is the specification for a nest of classes, using the following notation
+ * A, B represent abstract classes
+ * C represents a concrete class
+ * I, J, K represent interfaces
+ * Lowercase 'c' following a class means that the method m() is concrete
+ * Lowercase 'a' following a class or interface means that the method m() is abstract
+ * Lowercase 'd' following an interface means that the method m() is default
+ * A number 0, 1, or 2 following the lowercase letter indicates the return type of that method
+ * 0 = Object, 1 = Number, 2 = Integer (these form an inheritance chain so bridges are generated)
+ * A classes supertypes follow its method spec, in parentheses
+ * Examples:
+ * C(Ia0, Jd0) -- C extends I and J, I has abstract m()Object, J has default m()Object
+ * Cc1(Ia0) -- C has concrete m()Number, extends I with abstract m()Object
+ * If a type must appear multiple times, its full spec must be in the first occurrence
+ * Example:
+ * C(I(Kd0), J(K))
+ */
+ protected void compileSpec(String spec) throws IOException {
+ compileSpec(spec, false);
+ }
+
+ /**
+ * Compile all the classes in a class spec, and assert that there were compilation errors.
+ */
+ protected void compileSpec(String spec, String... errorKeys) throws IOException {
+ compileSpec(spec, false, errorKeys);
+ }
+
+ protected void compileSpec(String spec, boolean debug, String... errorKeys) throws IOException {
+ ClassModel cm = new Parser(spec).parseClassModel();
+ for (int i = 0; i <= cm.maxIndex() ; i++) {
+ if (debug) System.out.println(indexClass(i));
+ addSourceFile(String.format("C%d.java", i), new StringTemplate(indexClass(i)));
+ }
+ for (Map.Entry<String, ClassModel> e : classes(cm).entrySet()) {
+ if (debug) System.out.println(e.getValue().toSource());
+ addSourceFile(e.getKey() + ".java", new StringTemplate(e.getValue().toSource()));
+ }
+ compileDirs.add(compile(true));
+ resetSourceFiles();
+ if (errorKeys.length == 0)
+ assertCompileSucceeded();
+ else
+ assertCompileErrors(errorKeys);
+ }
+
+ /**
+ * Recompile only a subset of classes in the class spec, as named by names,
+ * and put them on the classpath such that they shadow earlier versions of that class.
+ */
+ protected void recompileSpec(String spec, String... names) throws IOException {
+ List<String> nameList = Arrays.asList(names);
+ ClassModel cm = new Parser(spec).parseClassModel();
+ for (int i = 0; i <= cm.maxIndex() ; i++) {
+ addSourceFile(String.format("C%d.java", i), new StringTemplate(indexClass(i)));
+ }
+ for (Map.Entry<String, ClassModel> e : classes(cm).entrySet())
+ if (nameList.contains(e.getKey()))
+ addSourceFile(e.getKey() + ".java", new StringTemplate(e.getValue().toSource()));
+ compileDirs.add(compile(Arrays.asList(classPaths()), true));
+ resetSourceFiles();
+ assertCompileSucceeded();
+ }
+
+ protected void assertLinkage(String name, String... expected) throws ReflectiveOperationException {
+ for (int i=0; i<expected.length; i++) {
+ String e = expected[i];
+ if (e.equals(LINKAGE_ERROR)) {
+ try {
+ int actual = invoke(name, i);
+ fail("Expected linkage error, got" + fromNum(actual));
+ }
+ catch (LinkageError x) {
+ // success
+ }
+ }
+ else {
+ if (e.length() == 1)
+ e += "0";
+ int expectedInt = toNum(e);
+ int actual = invoke(name, i);
+ if (expectedInt != actual)
+ fail(String.format("Expected %s but found %s for %s.m()%d", fromNum(expectedInt), fromNum(actual), name, i));
+ }
+ }
+ }
+
+ private Map<String, ClassModel> classes(ClassModel cm) {
+ HashMap<String, ClassModel> m = new HashMap<>();
+ classesHelper(cm, m);
+ return m;
+ }
+
+ private String indexClass(int index) {
+ if (index == 0) {
+ return BASE_INDEX_CLASS;
+ } else {
+ return INDEX_CLASS_TEMPLATE
+ .replace("#ID", String.valueOf(index))
+ .replace("#PREV", String.valueOf(index - 1));
+ }
+ }
+
+ private static String overrideName(int index) {
+ return "C" + index;
+ }
+
+ private void classesHelper(ClassModel cm, Map<String, ClassModel> m) {
+ if (!m.containsKey(cm.name))
+ m.put(cm.name, cm);
+ for (ClassModel s : cm.supertypes)
+ classesHelper(s, m);
+ }
+
+ private static String fromNum(int num) {
+ return String.format("%c%d", TYPE_LETTERS.charAt(num / 10), num % 10);
+ }
+
+ private static int toNum(String name, int index) {
+ return 10*(TYPE_LETTERS.indexOf(name.charAt(0))) + index;
+ }
+
+ private static int toNum(String string) {
+ return 10*(TYPE_LETTERS.indexOf(string.charAt(0))) + Integer.parseInt(string.substring(1, 2));
+ }
+
+ private int invoke(String name, int index) throws ReflectiveOperationException {
+ File[] files = classPaths();
+ Class clazz = loadClass(name, files);
+ Method[] ms = clazz.getMethods();
+ for (Method m : ms) {
+ if (m.getName().equals("m") && m.getReturnType().getName().equals(overrideName(index))) {
+ m.setAccessible(true);
+ Object instance = clazz.newInstance();
+ Object c0 = m.invoke(instance);
+ Method getVal = c0.getClass().getMethod("getVal");
+ getVal.setAccessible(true);
+ return (int)getVal.invoke(c0);
+ }
+ }
+ throw new NoSuchMethodError("cannot find method m()" + index + " in class " + name);
+ }
+
+ private File[] classPaths() {
+ File[] files = new File[compileDirs.size()];
+ for (int i=0; i<files.length; i++)
+ files[files.length - i - 1] = compileDirs.get(i);
+ return files;
+ }
+
+ @BeforeMethod
+ @Override
+ public void reset() {
+ compileDirs.clear();
+ super.reset();
+ }
+
+ private static class ClassModel {
+
+ enum MethodType {
+ ABSTRACT('a'), CONCRETE('c'), DEFAULT('d');
+
+ public final char designator;
+
+ MethodType(char designator) {
+ this.designator = designator;
+ }
+
+ public static MethodType find(char c) {
+ for (MethodType m : values())
+ if (m.designator == c)
+ return m;
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private final String name;
+ private final boolean isInterface;
+ private final List<ClassModel> supertypes;
+ private final MethodType methodType;
+ private final int methodIndex;
+
+ private ClassModel(String name,
+ boolean anInterface,
+ List<ClassModel> supertypes,
+ MethodType methodType,
+ int methodIndex) {
+ this.name = name;
+ isInterface = anInterface;
+ this.supertypes = supertypes;
+ this.methodType = methodType;
+ this.methodIndex = methodIndex;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(name);
+ if (methodType != null) {
+ sb.append(methodType.designator);
+ sb.append(methodIndex);
+ }
+ if (!supertypes.isEmpty()) {
+ sb.append("(");
+ for (int i=0; i<supertypes.size(); i++) {
+ if (i > 0)
+ sb.append(",");
+ sb.append(supertypes.get(i).toString());
+ }
+ sb.append(")");
+ }
+ return sb.toString();
+ }
+
+ int maxIndex() {
+ int maxSoFar = methodIndex;
+ for (ClassModel cm : supertypes) {
+ maxSoFar = Math.max(cm.maxIndex(), maxSoFar);
+ }
+ return maxSoFar;
+ }
+
+ public String toSource() {
+ String extendsClause = "";
+ String implementsClause = "";
+ String methodBody = "";
+ boolean isAbstract = "AB".contains(name);
+
+ for (ClassModel s : supertypes) {
+ if (!s.isInterface) {
+ extendsClause = String.format("extends %s", s.name);
+ break;
+ }
+ }
+
+ StringJoiner sj = new StringJoiner(", ");
+ for (ClassModel s : supertypes)
+ if (s.isInterface)
+ sj.add(s.name);
+ if (sj.length() > 0) {
+ if (isInterface)
+ implementsClause = "extends " + sj.toString();
+ else
+ implementsClause = "implements " + sj.toString();
+ }
+ if (methodType != null) {
+ switch (methodType) {
+ case ABSTRACT:
+ methodBody = String.format("public abstract %s m();", overrideName(methodIndex));
+ break;
+ case CONCRETE:
+ methodBody = String.format("public %s m() { return new %s(%d); };",
+ overrideName(methodIndex), overrideName(methodIndex), toNum(name, methodIndex));
+ break;
+ case DEFAULT:
+ methodBody = String.format("public default %s m() { return new %s(%d); };",
+ overrideName(methodIndex), overrideName(methodIndex), toNum(name, methodIndex));
+ break;
+
+ }
+ }
+
+ return String.format("public %s %s %s %s %s { %s }", isAbstract ? "abstract" : "",
+ isInterface ? "interface" : "class",
+ name, extendsClause, implementsClause, methodBody);
+ }
+ }
+
+ private static class Parser {
+ private final String input;
+ private final char[] chars;
+ private int index;
+
+ private Parser(String s) {
+ input = s;
+ chars = s.toCharArray();
+ }
+
+ private char peek() {
+ return index < chars.length ? chars[index] : 0;
+ }
+
+ private boolean peek(String validChars) {
+ return validChars.indexOf(peek()) >= 0;
+ }
+
+ private char advanceIf(String validChars) {
+ if (peek(validChars))
+ return chars[index++];
+ else
+ return 0;
+ }
+
+ private char advanceIfDigit() {
+ return advanceIf("0123456789");
+ }
+
+ private int index() {
+ StringBuilder buf = new StringBuilder();
+ char c = advanceIfDigit();
+ while (c != 0) {
+ buf.append(c);
+ c = advanceIfDigit();
+ }
+ return Integer.valueOf(buf.toString());
+ }
+
+ private char advance() {
+ return chars[index++];
+ }
+
+ private char expect(String validChars) {
+ char c = advanceIf(validChars);
+ if (c == 0)
+ throw new IllegalArgumentException(String.format("Expecting %s at position %d of %s", validChars, index, input));
+ return c;
+ }
+
+ public ClassModel parseClassModel() {
+ List<ClassModel> supers = new ArrayList<>();
+ char name = expect(TYPE_LETTERS);
+ boolean isInterface = "IJK".indexOf(name) >= 0;
+ ClassModel.MethodType methodType = peek(isInterface ? "ad" : "ac") ? ClassModel.MethodType.find(advance()) : null;
+ int methodIndex = 0;
+ if (methodType != null) {
+ methodIndex = index();
+ }
+ if (peek() == '(') {
+ advance();
+ supers.add(parseClassModel());
+ while (peek() == ',') {
+ advance();
+ supers.add(parseClassModel());
+ }
+ expect(")");
+ }
+ return new ClassModel(new String(new char[]{ name }), isInterface, supers, methodType, methodIndex);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/bridge/template_tests/BridgeMethodsTemplateTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,1082 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+import java.io.IOException;
+
+import org.testng.annotations.Test;
+
+/**
+ * BridgeMethodsTemplateTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class BridgeMethodsTemplateTest extends BridgeMethodTestCase {
+
+ /*
+ * Cc1(A) -> Cc1(Ac0)
+ *
+ * 0*: Inherited from A
+ * 1: Declared in C
+ */
+ public void test1() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(A)");
+ assertLinkage("C", LINKAGE_ERROR, "C1");
+ recompileSpec("Cc1(Ac0)", "A");
+ assertLinkage("C", "A0", "C1");
+ }
+
+ /*
+ * Cc1(I) -> Cc1(Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Declared in C
+ */
+ public void test2() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(I)");
+ assertLinkage("C", LINKAGE_ERROR, "C1");
+ recompileSpec("Cc1(Id0)", "I");
+ assertLinkage("C", "I0", "C1");
+ }
+
+ /*
+ * C(Bc1(A)) -> C(Bc1(Ac0))
+ *
+ * 0*: Inherited from A
+ * 1: Inherited from B
+ */
+ public void test3() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Bc1(A))");
+ assertLinkage("C", LINKAGE_ERROR, "B1");
+ recompileSpec("C(Bc1(Ac0))", "A");
+ assertLinkage("C", "A0", "B1");
+ }
+
+ /*
+ * C(B(Ac0)) -> C(Bc1(Ac0))
+ *
+ * 0: Inherited from B (through bridge)
+ * 1: Inherited from B
+ */
+ public void test4() throws IOException, ReflectiveOperationException {
+ compileSpec("C(B(Ac0))");
+ assertLinkage("C", "A0", LINKAGE_ERROR);
+ recompileSpec("C(Bc1(Ac0))", "B");
+ assertLinkage("C", "B1", "B1");
+ }
+
+ /*
+ * C(B(A)) -> C(Bc1(Ac0))
+ *
+ * 0: Inherited from B (through bridge)
+ * 1: Inherited from B
+ */
+ public void test5() throws IOException, ReflectiveOperationException {
+ compileSpec("C(B(A))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+ recompileSpec("C(Bc1(Ac0))", "A", "B");
+ assertLinkage("C", "B1", "B1");
+ }
+
+ /*
+ * C(Ac1(I)) -> C(Ac1(Id0))
+ *
+ * 0*: Inherited default from I
+ * 1: Inherited from A
+ */
+ public void test6() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac1(I))");
+ assertLinkage("C", LINKAGE_ERROR, "A1");
+ recompileSpec("C(Ac1(Id0))", "I");
+ assertLinkage("C", "I0", "A1");
+ }
+
+ /*
+ * C(A(Id0)) -> C(Ac1(Id0))
+ *
+ * 0: Inherited from A (through bridge)
+ * 1: Inherited from A
+ */
+ public void test7() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0))");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(Ac1(Id0))", "A");
+ assertLinkage("C", "A1", "A1");
+ }
+
+ /*
+ * C(A(I)) -> C(Ac1(Id0))
+ *
+ * 0*: Inherited from A (through bridge)
+ * 1*: Inherited from A
+ */
+ public void test8() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(I))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+ recompileSpec("C(Ac1(Id0))", "A", "I");
+ assertLinkage("C", "A1", "A1");
+ }
+
+ /*
+ * C(Id1(J)) -> C(Id1(Jd0))
+ *
+ * 0*: Inherited default from J
+ * 1: Inherited default from I
+ */
+ public void test9() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Id1(J))");
+ assertLinkage("C", LINKAGE_ERROR, "I1");
+ recompileSpec("C(Id1(Jd0))", "J");
+ assertLinkage("C", "J0", "I1");
+ }
+
+ /*
+ * C(I(Jd0)) -> C(Id1(Jd0))
+ *
+ * 0: Inherited default from I (through bridge)
+ * 1: Inherited default from I
+ */
+ public void test10() throws IOException, ReflectiveOperationException {
+ compileSpec("C(I(Jd0))");
+ assertLinkage("C", "J0", LINKAGE_ERROR);
+ recompileSpec("C(Id1(Jd0))", "I");
+ assertLinkage("C", "I1", "I1");
+ }
+
+ /*
+ * C(I(J)) -> C(Id1(Jd0))
+ *
+ * 0: Inherited default from I (through bridge)
+ * 1: Inherited default from I
+ */
+ public void test11() throws IOException, ReflectiveOperationException {
+ compileSpec("C(I(J))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+ recompileSpec("C(Id1(Jd0))", "I", "J");
+ assertLinkage("C", "I1", "I1");
+ }
+
+ /*
+ * Cc2(B(Ac0)) -> Cc2(Bc1(Ac0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from B
+ * 2: Declared in C
+ */
+ public void test12() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(B(Ac0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Bc1(Ac0))", "B");
+ assertLinkage("C", "C2", "B1", "C2");
+ }
+
+ /*
+ * Cc2(B(Aa0)) -> Cc2(Bc1(Aa0))
+ *
+ * 0: Bridge in C (through bridge)
+ * 1*: Inherited from B
+ * 2: Declared in C
+ */
+ public void test13() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(B(Aa0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Bc1(Aa0))", "B");
+ assertLinkage("C", "C2", "B1", "C2");
+ }
+
+ /*
+ * Cc2(Bc1(A)) -> Cc2(Bc1(Ac0))
+ *
+ * 0*: Inherited from A
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test14() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Bc1(A))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Bc1(Ac0))", "A");
+ assertLinkage("C", "A0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(Ba1(A)) -> Cc2(Ba1(Ac0))
+ *
+ * 0*: Inherited from A
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test15() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Ba1(A))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Ba1(Ac0))", "A");
+ assertLinkage("C", "A0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(B(A)) -> Cc2(Bc1(Ac0))
+ *
+ * 0*: Inherited from B (through bridge)
+ * 1*: Inherited from B
+ * 2: Declared in C
+ */
+ public void test16() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(B(A))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Bc1(Ac0))", "B", "A");
+ assertLinkage("C", "B1", "B1", "C2");
+ }
+
+ /*
+ * Cc2(A(Id0)) -> Cc2(Ac1(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test17() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Id0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1(Id0))", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(A(Ia0)) -> Cc2(Ac1(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test18() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Ia0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1(Ia0))", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(Ac1(I)) -> Cc2(Ac1(Id0))
+ *
+ * 0*: Inherited from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test19() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Ac1(I))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Ac1(Id0))", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(Aa1(I)) -> Cc2(Aa1(Id0))
+ *
+ * 0*: Inherited from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test20() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Aa1(I))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Aa1(Id0))", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(A(I)) -> Cc2(Ac1(Id0))
+ *
+ * 0*: Inherited from A (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test21() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(I))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1(Id0))", "A", "I");
+ assertLinkage("C", "A1", "A1", "C2");
+ }
+
+ /*
+ * Cc2(J(Id0)) -> Cc2(Jd1(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test22() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(J(Id0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Jd1(Id0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(J(Ia0)) -> Cc2(Jd1(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test23() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(J(Ia0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Jd1(Ia0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(Jd1(I)) -> Cc2(Jd1(Id0))
+ *
+ * 0*: Inherited default from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test24() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Jd1(I))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Jd1(Id0))", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(Ja1(I)) -> Cc2(Ja1(Id0))
+ *
+ * 0*: Inherited default from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test25() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Ja1(I))");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Ja1(Id0))", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(J(I)) -> Cc2(Jd1(Id0))
+ *
+ * 0*: Inherited default from J (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test26() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(J(I))");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Jd1(Id0))", "J", "I");
+ assertLinkage("C", "J1", "J1", "C2");
+ }
+
+ /*
+ * C(Ac1, I) -> C(Ac1, Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Inherited from A
+ */
+ public void test27() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac1,I)");
+ assertLinkage("C", LINKAGE_ERROR, "A1");
+ recompileSpec("C(Ac1,Id0)", "I");
+ assertLinkage("C", "I0", "A1");
+ }
+
+ /*
+ * C(A, Id0) -> C(Ac1, Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Inherited from A
+ */
+ public void test28() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A,Id0)");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(Ac1,Id0)", "A");
+ assertLinkage("C", "I0", "A1");
+ }
+
+ /*
+ * C(A, I) -> C(Ac1, Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Inherited from A
+ */
+ public void test29() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A,I)");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+ recompileSpec("C(Ac1,Id0)", "A", "I");
+ assertLinkage("C", "I0", "A1");
+ }
+
+ /*
+ * Cc2(Ac1, I) -> Cc2(Ac1, Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test30() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Ac1,I)");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Ac1,Id0)", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(Aa1, I) -> Cc2(Aa1, Id0)
+ *
+ * 0*: Inherited default from I
+ * 1: Declared in C (through bridge)
+ * 2: Declared in C
+ */
+ public void test31() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Aa1,I)");
+ assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+ recompileSpec("Cc2(Aa1,Id0)", "I");
+ assertLinkage("C", "I0", "C2", "C2");
+ }
+
+ /*
+ * Cc2(A, Id0) -> Cc2(Ac1, Id0)
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test32() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A,Id0)");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1,Id0)", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(A, Ia0) -> Cc2(Ac1, Ia0)
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test33() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A,Ia0)");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1,Ia0)", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(A, I) -> Cc2(Ac1, Id0)
+ *
+ * 0*: Inherited from A
+ * 1*: Inherited default from I
+ * 2: Declared in C
+ */
+ public void test34() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A,I)");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1,Id0)", "A", "I");
+ assertLinkage("C", "I0", "A1", "C2");
+ }
+
+ /*
+ * Cc2(Id0, J) -> Cc2(Id0, Jd1)
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test35() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Id0,J)");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Id0,Jd1)", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(Ia0, J) -> Cc2(Ia0, Jd1)
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test36() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(Ia0,J)");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ia0,Jd1)", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(I, J) -> Cc2(Id0, Jd1)
+ *
+ * 0*: Inherited default from I
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test37() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(I,J)");
+ assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Id0,Jd1)", "I", "J");
+ assertLinkage("C", "I0", "J1", "C2");
+ }
+
+ /*
+ * C(A(Id0), J(Id0)) -> C(Ac1(Id0), J(Id0))
+ *
+ * 0: Inherited default from I
+ * 0*: Inherited from A (through bridge)
+ * 1*: Inherited from A
+ */
+ public void test38() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),J(Id0))");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(Ac1(Id0),J(Id0))", "A");
+ assertLinkage("C", "A1", "A1");
+ }
+
+ /*
+ * C(A(Id0), J(Id0)) -> C(A(Id0), Jd1(Id0))
+ *
+ * 0: Inherited default from I
+ * 0: Inherited default from J (through bridge)
+ * 1*: Inherited default from J
+ */
+ public void test39() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),J(Id0))");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(A(Id0),Jd1(Id0))", "J");
+ assertLinkage("C", "J1", "J1");
+ }
+
+ /*
+ * C(A(Id0), J(Id0)) -> C(Ac2(Id0), Jd1(Id0))
+ *
+ * 0: Inherited default from I
+ * 0*: Inherited from A (new bridge in A beats new bridge in J)
+ * 1*: Inherited default from J
+ * 2: Inherited from A
+ */
+ public void test40() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),J(Id0))");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(Ac2(Id0),Jd1(Id0))", "A", "J");
+ assertLinkage("C", "A2", "J1", "A2");
+ }
+
+ /*
+ * C(J(Id0), K(Id0)) -> C(Jd1(Id0), K(Id0))
+ *
+ * 0: Inherited from I
+ * 0*: Inherited default from J (through bridge)
+ * 1: Inherited default from J
+ */
+ public void test41() throws IOException, ReflectiveOperationException {
+ compileSpec("C(J(Id0),K(Id0))");
+ assertLinkage("C", "I0", LINKAGE_ERROR);
+ recompileSpec("C(Jd1(Id0),K(Id0))", "J");
+ assertLinkage("C", "J1", "J1");
+ }
+
+ /*
+ * C(Ac2(Id0), J(Id0)) -> C(Ac2(Id0), Jd1(Id0))
+ *
+ * 0: Inherited from A (bridge in A beats new bridge in J)
+ * 1*: Inherited default from J
+ * 2: Inherited from A
+ */
+ public void test42() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac2(Id0),J(Id0))");
+ assertLinkage("C", "A2", LINKAGE_ERROR, "A2");
+ recompileSpec("C(Ac2(Id0),Jd1(Id0))", "J");
+ assertLinkage("C", "A2", "J1", "A2");
+ }
+
+ /*
+ * C(Ac2(Ia0), J(Ia0)) -> C(Ac2(Ia0), Jd1(Ia0))
+ *
+ * 0: Inherited from A (bridge in A beats new bridge in J)
+ * 1*: Inherited default from J
+ * 2: Inherited from A
+ */
+ public void test43() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac2(Ia0),J(Ia0))");
+ assertLinkage("C", "A2", LINKAGE_ERROR, "A2");
+ recompileSpec("C(Ac2(Ia0),Jd1(Ia0))", "J");
+ assertLinkage("C", "A2", "J1", "A2");
+ }
+
+ /*
+ * C(A(Id0), Jd1(Id0)) -> C(Ac2(Id0), Jd1(Id0))
+ *
+ * 0: Inherited from J
+ * 0*: Inherited from A (new bridge in A beats bridge in J)
+ * 1: Inherited default from J
+ * 2*: Inherited from A
+ */
+ public void test44() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),Jd1(Id0))");
+ assertLinkage("C", "J1", "J1", LINKAGE_ERROR);
+ recompileSpec("C(Ac2(Id0),Jd1(Id0))", "A");
+ assertLinkage("C", "A2", "J1", "A2");
+ }
+
+ /*
+ * C(A(Ia0), Jd1(Ia0)) -> C(Ac2(Ia0), Jd1(Ia0))
+ *
+ * 0: Inherited from J
+ * 0*: Inherited from A (new bridge in A beats bridge in J)
+ * 1: Inherited default from J
+ * 2*: Inherited from A
+ */
+ public void test45() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Ia0),Jd1(Ia0))");
+ assertLinkage("C", "J1", "J1", LINKAGE_ERROR);
+ recompileSpec("C(Ac2(Ia0),Jd1(Ia0))", "A");
+ assertLinkage("C", "A2", "J1", "A2");
+ }
+
+ /*
+ * Cc2(A(Id0), J(Id0)) -> Cc2(Ac1(Id0), J(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test46() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Id0),J(Id0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1(Id0),J(Id0))", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(A(Ia0), J(Ia0)) -> Cc2(Ac1(Ia0), J(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C
+ */
+ public void test47() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Ia0),J(Ia0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Ac1(Ia0),J(Ia0))", "A");
+ assertLinkage("C", "C2", "A1", "C2");
+ }
+
+ /*
+ * Cc2(A(Id0), J(Id0)) -> Cc2(A(Id0), Jd1(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test48() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Id0),J(Id0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(A(Id0),Jd1(Id0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(A(Ia0), J(Ia0)) -> Cc2(A(Ia0), Jd1(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test49() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(A(Ia0),J(Ia0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(A(Ia0),Jd1(Ia0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+
+ /*
+ * Cc3(A(Id0), J(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0))
+ *
+ * 0: Bridge in C
+ * 1*: Inherited from A
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test50() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Id0),J(Id0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "A", "J");
+ assertLinkage("C", "C3", "A1", "J2", "C3");
+ }
+
+ /*
+ * Cc3(A(Ia0), J(Ia0)) -> Cc3(Ac1(Ia0), Jd2(Ia0))
+ *
+ * 0: Bridge in C
+ * 1*: Inherited from A
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test51() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Ia0),J(Ia0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "A", "J");
+ assertLinkage("C", "C3", "A1", "J2", "C3");
+ }
+
+ /*
+ * Cc2(J(Id0), K(Id0)) -> Cc2(Jd1(Id0), K(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test52() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(J(Id0),K(Id0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Jd1(Id0),K(Id0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc2(J(Ia0), K(Ia0)) -> Cc2(Jd1(Ia0), K(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2: Declared in C
+ */
+ public void test53() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc2(J(Ia0),K(Ia0))");
+ assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+ recompileSpec("Cc2(Jd1(Ia0),K(Ia0))", "J");
+ assertLinkage("C", "C2", "J1", "C2");
+ }
+
+ /*
+ * Cc3(J(Id0), K(Id0)) -> Cc3(Jd1(Id0), Kd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test54() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(J(Id0),K(Id0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "J", "K");
+ assertLinkage("C", "C3", "J1", "K2", "C3");
+ }
+
+ /*
+ * Cc3(J(Ia0), K(Ia0)) -> Cc3(Jd1(Ia0), Kd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited default from J
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test55() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(J(Ia0),K(Ia0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "J", "K");
+ assertLinkage("C", "C3", "J1", "K2", "C3");
+ }
+
+ /*
+ * Cc3(Ac1(Id0), J(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test56() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Ac1(Id0),J(Id0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "J");
+ assertLinkage("C", "C3", "C3", "J2", "C3");
+ }
+
+ /*
+ * Cc3(Ac1(Ia0), J(Ia0)) -> Cc3(Ac1(Ia0), Jd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test57() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Ac1(Ia0),J(Ia0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "J");
+ assertLinkage("C", "C3", "C3", "J2", "C3");
+ }
+
+ /*
+ * Cc3(Aa1(Id0), J(Id0)) -> Cc3(Aa1(Id0), Jd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test58() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Aa1(Id0),J(Id0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Aa1(Id0),Jd2(Id0))", "J");
+ assertLinkage("C", "C3", "C3", "J2", "C3");
+ }
+
+ /*
+ * Cc3(Aa1(Ia0), J(Ia0)) -> Cc3(Aa1(Ia0), Jd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from J
+ * 3: Declared in C
+ */
+ public void test59() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Aa1(Ia0),J(Ia0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Aa1(Ia0),Jd2(Ia0))", "J");
+ assertLinkage("C", "C3", "C3", "J2", "C3");
+ }
+
+ /*
+ * Cc3(A(Id0), Jd2(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C (through bridge)
+ * 3: Declared in C
+ */
+ public void test60() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Id0),Jd2(Id0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+ recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "A");
+ assertLinkage("C", "C3", "A1", "C3", "C3");
+ }
+
+ /*
+ * Cc3(A(Im0), Jd2(Ia0)) -> Cc3(Ac1(Im0), Jd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C (through bridge)
+ * 3: Declared in C
+ */
+ public void test61() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Ia0),Jd2(Ia0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+ recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "A");
+ assertLinkage("C", "C3", "A1", "C3", "C3");
+ }
+
+ /*
+ * Cc3(A(Im0), Ja2(Id0)) -> Cc3(Ac1(Id0), Ja2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C (through bridge)
+ * 3: Declared in C
+ */
+ public void test62() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Id0),Ja2(Id0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+ recompileSpec("Cc3(Ac1(Id0),Ja2(Id0))", "A");
+ assertLinkage("C", "C3", "A1", "C3", "C3");
+ }
+
+ /*
+ * Cc3(A(Im0), Ja2(Ia0)) -> Cc3(Ac1(Ia0), Ja2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1*: Inherited from A
+ * 2: Declared in C (through bridge)
+ * 3: Declared in C
+ */
+ public void test63() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(A(Ia0),Ja2(Ia0))");
+ assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+ recompileSpec("Cc3(Ac1(Ia0),Ja2(Ia0))", "A");
+ assertLinkage("C", "C3", "A1", "C3", "C3");
+ }
+
+ /*
+ * Cc3(Jd1(Id0), K(Id0)) -> Cc3(Jd1(Id0), Kd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test64() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Jd1(Id0),K(Id0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "K");
+ assertLinkage("C", "C3", "C3", "K2", "C3");
+ }
+
+ /*
+ * Cc3(Jd1(Ia0), K(Ia0)) -> Cc3(Jd1(Ia0), Kd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test65() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Jd1(Ia0),K(Ia0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "K");
+ assertLinkage("C", "C3", "C3", "K2", "C3");
+ }
+
+ /*
+ * Cc3(Ja1(Id0), K(Id0)) -> Cc3(Ja1(Id0), Kd2(Id0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test66() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Jd1(Id0),K(Id0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "K");
+ assertLinkage("C", "C3", "C3", "K2", "C3");
+ }
+
+ /*
+ * Cc3(Ja1(Ia0), K(Ia0)) -> Cc3(Ja1(Ia0), Kd2(Ia0))
+ *
+ * 0: Declared in C (through bridge)
+ * 1: Declared in C (through bridge)
+ * 2*: Inherited default from K
+ * 3: Declared in C
+ */
+ public void test67() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc3(Jd1(Ia0),K(Ia0))");
+ assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+ recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "K");
+ assertLinkage("C", "C3", "C3", "K2", "C3");
+ }
+
+ // Dan's set A
+ public void testA1() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Id0)");
+ assertLinkage("C", "I0");
+ }
+
+ public void testA2() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0))");
+ assertLinkage("C", "I0");
+ }
+
+ public void testA3() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),J)");
+ assertLinkage("C", "I0");
+ }
+
+ public void testA4() throws IOException, ReflectiveOperationException {
+ compileSpec("D(C(Id0),Jd0(Id0))");
+ assertLinkage("D", "J0");
+ assertLinkage("C", "I0");
+ }
+
+ public void testA5() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0),Jd0)",
+ "compiler.err.types.incompatible.unrelated.defaults");
+ }
+
+ public void testA6() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Ia0,Jd0))",
+ "compiler.err.does.not.override.abstract",
+ "compiler.err.types.incompatible.abstract.default");
+ }
+
+ public void testA7() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Id0,Jd0))",
+ "compiler.err.types.incompatible.unrelated.defaults");
+ }
+
+ public void testA8() throws IOException, ReflectiveOperationException {
+ compileSpec("C(A(Ia0),J)", "compiler.err.does.not.override.abstract");
+ }
+
+ public void testA9() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac0(Id0))");
+ assertLinkage("C", "A0");
+ }
+
+ public void testA10() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Aa0,I)", "compiler.err.does.not.override.abstract");
+ }
+
+ public void testA11() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac0,Id0)");
+ assertLinkage("C", "A0");
+ }
+
+ // Dan's set B
+
+ /* B1 can't be done, needs a second concrete class D
+ public void testB1() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(Dc0)");
+ assertLinkage("C", "C1", "C1");
+ assertLinkage("D", "A0", LINKAGE_ERROR);
+ }
+ */
+
+ public void testB2() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(Ac0)");
+ assertLinkage("C", "C1", "C1");
+ }
+
+ //??? B3 seems to suggest that we should create an abstract class
+ //public void testB3() throws IOException, ReflectiveOperationException {
+ // compileSpec("Ba1(Cc0)");
+ // assertLinkage("B", "C0", "A1");
+ //}
+
+ // B4 needs too many classes
+
+ public void testB5() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(Aa1(Id0))");
+ assertLinkage("C", "C1", "C1");
+ }
+
+ public void testB6() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Ac1(Id0))");
+ assertLinkage("C", "A1", "A1");
+ }
+
+ public void testB7() throws IOException, ReflectiveOperationException {
+ compileSpec("Cc1(Id0)");
+ assertLinkage("C", "C1", "C1");
+ }
+
+ public void testB8() throws IOException, ReflectiveOperationException {
+ compileSpec("C(Jd1(Id0))");
+ assertLinkage("C", "J1", "J1");
+ }
+
+ // B9 needs too many classes
+
+ // The rest of Dan's tests need generics
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/bridge/template_tests/TEST.properties Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,7 @@
+# This file identifies root(s) of the test-ng hierarchy.
+
+
+
+TestNG.dirs = .
+
+lib.dirs = /lib/combo
--- a/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -197,7 +197,7 @@
"class Test {\n" +
" void m(SAM1 s) { }\n" +
" void m(SAM2 s) { }\n" +
- " { m(x->{ #LR }); }\n" +
+ " { m((#A1 x)->{ #LR }); }\n" +
"}\n";
String source;
@@ -236,14 +236,17 @@
void check() {
checkCount.incrementAndGet();
+ if (ak1 != ak2)
+ return;
+
if (!lrk.compatibleWith(rt1) || !lrk.compatibleWith(rt2))
return;
if (lrk.needsConversion(rt1) != lrk.needsConversion(rt2))
return;
- boolean m1MoreSpecific = moreSpecific(rt1, rt2, ek1, ek2, ak1, ak2);
- boolean m2MoreSpecific = moreSpecific(rt2, rt1, ek2, ek1, ak2, ak1);
+ boolean m1MoreSpecific = rt1.moreSpecificThan(rt2);
+ boolean m2MoreSpecific = rt2.moreSpecificThan(rt1);
boolean ambiguous = (m1MoreSpecific == m2MoreSpecific);
@@ -268,17 +271,6 @@
}
}
- boolean moreSpecific(RetTypeKind rk1, RetTypeKind rk2, ExceptionKind ek1,
- ExceptionKind ek2, ArgTypeKind ak1, ArgTypeKind ak2) {
- if (!rk1.moreSpecificThan(rk2))
- return false;
-
- if (ak1 != ak2)
- return false;
-
- return true;
- }
-
static class DiagnosticChecker
implements javax.tools.DiagnosticListener<JavaFileObject> {
--- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest5.java Thu Sep 12 11:09:20 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @bug 8003280
- * @summary Add lambda tests
- * This test is for overloaded methods, verify that the specific method is
- selected when type inference occurs
- * @compile InferenceTest5.java
- * @run main InferenceTest5
- */
-
-import java.util.List;
-import java.io.File;
-
-public class InferenceTest5 {
-
- private static void assertTrue(boolean b) {
- if(!b)
- throw new AssertionError();
- }
-
- public static void main(String[] args) {
- InferenceTest5 test = new InferenceTest5();
- int n = test.method1((a, b) -> {} );
- assertTrue(n == 1);
-
- n = test.method1(() -> null);
- assertTrue(n == 2);
-
- n = test.method1(a -> null);
- assertTrue(n == 3);
-
- n = test.method1(a -> {});
- assertTrue(n == 4);
-
- n = test.method1(() -> {});
- assertTrue(n == 5);
-
- n = test.method1((a, b) -> 0);
- assertTrue(n == 6);
-
- n = test.method1((a, b) -> null);
- assertTrue(n == 6);
-
- n = test.method1((a, b) -> null, (a, b) -> null);
- assertTrue(n == 7);
- }
-
- int method1(SAM1<String> s) {
- return 1;
- }
-
- int method1(SAM2 s) {
- return 2;
- }
-
- int method1(SAM3 s) {
- return 3;
- }
-
- int method1(SAM4 s) {
- return 4;
- }
-
- int method1(SAM5 s) {
- return 5;
- }
-
- int method1(SAM6<?, ? super Integer> s) {
- return 6;
- }
-
- int method1(SAM6<?, ?>... s) {
- return 7;
- }
-
- static interface SAM1<T> {
- void foo(List<T> a, List<T> b);
- }
-
- static interface SAM2 {
- List<String> foo();
- }
-
- static interface SAM3 {
- String foo(int a);
- }
-
- static interface SAM4 {
- void foo(List<File> a);
- }
-
- static interface SAM5 {
- void foo();
- }
-
- static interface SAM6<T, V> {
- V get(T t, T t2);
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest6.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280 8016177
+ * @summary Add lambda tests
+ * Missing cast to SAM type that causes type inference to not work.
+ * @compile -XDrawDiagnostics InferenceTest6.java
+ */
+
+import java.util.*;
+
+public class InferenceTest6 {
+ public static void main(String[] args) {
+ InferenceTest6 test = new InferenceTest6();
+ test.method1(n -> {});
+ test.method1((SAM1<String>)n -> {});
+ test.method1((SAM1<Integer>)n -> {n++;});
+ test.method1((SAM1<Comparator<String>>)n -> {List<String> list = Arrays.asList("string1", "string2"); Collections.sort(list,n);});
+ test.method1((SAM1<Thread>)n -> {n.start();});
+ }
+
+ interface SAM1<X> {
+ void m1(X arg);
+ }
+
+ <X> void method1(SAM1<X> s) {}
+}
--- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg1_2.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg1_2.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,4 +1,5 @@
InferenceTest_neg1_2.java:14:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5<java.lang.Integer>), InferenceTest_neg1_2
-InferenceTest_neg1_2.java:15:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM2), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>), InferenceTest_neg1_2
-InferenceTest_neg1_2.java:16:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM3<java.lang.Integer>), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5<java.lang.Integer>), InferenceTest_neg1_2
-3 errors
+InferenceTest_neg1_2.java:15:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5<java.lang.Integer>), InferenceTest_neg1_2
+InferenceTest_neg1_2.java:16:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5<java.lang.Integer>), InferenceTest_neg1_2
+InferenceTest_neg1_2.java:16:20: compiler.err.cant.apply.symbol: kindname.method, method, InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>, @597, kindname.class, InferenceTest_neg1_2, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, java.lang.String)))
+4 errors
--- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.java Thu Sep 12 11:09:20 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 8003280
- * @summary Add lambda tests
- * Missing cast to SAM type that causes type inference to not work.
- * @compile/fail/ref=InferenceTest_neg5.out -XDrawDiagnostics InferenceTest_neg5.java
- */
-
-import java.util.*;
-
-public class InferenceTest_neg5 {
- public static void main(String[] args) {
- InferenceTest_neg5 test = new InferenceTest_neg5();
- test.method1(n -> {});
- test.method1((SAM1<String>)n -> {});
- test.method1((SAM1<Integer>)n -> {n++;});
- test.method1((SAM1<Comparator<String>>)n -> {List<String> list = Arrays.asList("string1", "string2"); Collections.sort(list,n);});
- test.method1((SAM1<Thread>)n -> {n.start();});
- }
-
- interface SAM1<X> {
- void m1(X arg);
- }
-
- <X> void method1(SAM1<X> s) {}
-}
--- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.out Thu Sep 12 11:09:20 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-InferenceTest_neg5.java:14:21: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: X)
-1 error
--- a/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -227,12 +227,7 @@
}
else if (lambdaBodyType != LambdaBody.RETURN_ARG)
return false;
- if ( genericDeclKind == GenericDeclKind.GENERIC_NOBOUND ||
- genericDeclKind == GenericDeclKind.GENERIC_BOUND ) {
- if ( parameterType == TypeKind.GENERIC &&
- parameterKind == ParameterKind.IMPLICIT) //cyclic inference
- return false;
- }
+
return true;
}
--- a/langtools/test/tools/javac/lib/DPrinter.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/lib/DPrinter.java Tue Sep 17 08:21:11 2013 -0700
@@ -49,7 +49,7 @@
import com.sun.source.util.TaskListener;
import com.sun.source.util.Trees;
import com.sun.tools.javac.api.JavacTrees;
-import com.sun.tools.javac.code.Annotations;
+import com.sun.tools.javac.code.SymbolMetadata;
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Kinds;
@@ -186,21 +186,21 @@
FULL
};
- public void printAnnotations(String label, Annotations annotations) {
+ public void printAnnotations(String label, SymbolMetadata annotations) {
printAnnotations(label, annotations, Details.FULL);
}
- protected void printAnnotations(String label, Annotations annotations, Details details) {
+ protected void printAnnotations(String label, SymbolMetadata annotations, Details details) {
if (annotations == null) {
printNull(label);
} else {
// no SUMMARY format currently available to use
// use reflection to get at private fields
- Object DECL_NOT_STARTED = getField(null, Annotations.class, "DECL_NOT_STARTED");
- Object DECL_IN_PROGRESS = getField(null, Annotations.class, "DECL_IN_PROGRESS");
- Object attributes = getField(annotations, Annotations.class, "attributes");
- Object type_attributes = getField(annotations, Annotations.class, "type_attributes");
+ Object DECL_NOT_STARTED = getField(null, SymbolMetadata.class, "DECL_NOT_STARTED");
+ Object DECL_IN_PROGRESS = getField(null, SymbolMetadata.class, "DECL_IN_PROGRESS");
+ Object attributes = getField(annotations, SymbolMetadata.class, "attributes");
+ Object type_attributes = getField(annotations, SymbolMetadata.class, "type_attributes");
if (!showEmptyItems) {
if (attributes instanceof List && ((List) attributes).isEmpty()
--- a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java Tue Sep 17 08:21:11 2013 -0700
@@ -31,6 +31,7 @@
* @compile/fail/ref=TestMissingElement.ref -proc:only -XprintRounds -XDrawDiagnostics -processor TestMissingElement InvalidSource.java
*/
+import java.io.PrintWriter;
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.element.*;
@@ -38,7 +39,18 @@
import javax.lang.model.util.*;
import static javax.tools.Diagnostic.Kind.*;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.util.Log;
+
public class TestMissingElement extends JavacTestingAbstractProcessor {
+ private PrintWriter out;
+
+ @Override
+ public void init(ProcessingEnvironment env) {
+ super.init(env);
+ out = ((JavacProcessingEnvironment) env).getContext().get(Log.outKey);
+ }
+
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement te: ElementFilter.typesIn(roundEnv.getRootElements())) {
@@ -70,13 +82,13 @@
}
private void checkInterfaces(TypeElement te, String expect) {
- System.err.println("check interfaces: " + te + " -- " + expect);
+ out.println("check interfaces: " + te + " -- " + expect);
String found = asString(te.getInterfaces(), ", ");
checkEqual("interfaces", te, found, expect);
}
private void checkSupertype(TypeElement te, String expect) {
- System.err.println("check supertype: " + te + " -- " + expect);
+ out.println("check supertype: " + te + " -- " + expect);
String found = asString(te.getSuperclass());
checkEqual("supertype", te, found, expect);
}
@@ -85,7 +97,7 @@
if (found.equals(expect)) {
// messager.printMessage(NOTE, "expected " + label + " found: " + expect, te);
} else {
- System.err.println("unexpected " + label + ": " + te + "\n"
+ out.println("unexpected " + label + ": " + te + "\n"
+ " found: " + found + "\n"
+ "expect: " + expect);
messager.printMessage(ERROR, "unexpected " + label + " found: " + found + "; expected: " + expect, te);
--- a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref Tue Sep 17 08:21:11 2013 -0700
@@ -2,6 +2,24 @@
input files: {ExpectInterfaces, ExpectSupertype, OK, InvalidSource}
annotations: [ExpectSupertype, ExpectInterfaces]
last round: false
+check supertype: InvalidSource.TestClassMissingClassA -- !:empty clss A!
+check supertype: InvalidSource.TestClassMissingClassAB -- !:empty clss (pkg A).B!
+check supertype: InvalidSource.TestClassMissingClass_juA -- !:empty clss (pkg java.util).A!
+check supertype: InvalidSource.TestClassTMissingClassAT -- !:empty clss A!<tvar T>
+check interfaces: InvalidSource.TestClassMissingIntfA -- !:empty intf A!
+check interfaces: InvalidSource.TestClassMissingIntfAB -- !:empty intf (pkg A).B!
+check interfaces: InvalidSource.TestClassMissingIntfAOK -- !:empty intf A!, intf OK
+check interfaces: InvalidSource.TestClassOKMissingIntfA -- intf OK, !:empty intf A!
+check interfaces: InvalidSource.TestClassMissingIntfA_B -- !:empty intf A!, !:empty intf B!
+check interfaces: InvalidSource.TestIntfMissingIntfA -- !:empty intf A!
+check interfaces: InvalidSource.TestIntfMissingIntfAOK -- !:empty intf A!, intf OK
+check interfaces: InvalidSource.TestIntfOKMissingIntfA -- intf OK, !:empty intf A!
+check interfaces: InvalidSource.TestIntfMissingIntfAB -- !:empty intf A!, !:empty intf B!
+check interfaces: InvalidSource.TestClassTMissingIntfAT -- !:empty intf A!<tvar T>
+check interfaces: InvalidSource.TestClassTMissingIntfAT_B -- !:empty intf A!<tvar T>, !:empty intf B!
+check interfaces: InvalidSource.TestIntfTMissingIntfAT -- !:empty intf A!<tvar T>
+check interfaces: InvalidSource.TestIntfTMissingIntfAT_B -- !:empty intf A!<tvar T>, !:empty intf B!
+check interfaces: InvalidSource.TestClassListMissingX -- intf (pkg java.util).List<!:empty clss X!>
Round 2:
input files: {}
annotations: []
@@ -28,22 +46,4 @@
InvalidSource.java:103:51: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null)
InvalidSource.java:103:57: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, InvalidSource, null)
InvalidSource.java:106:58: compiler.err.cant.resolve.location: kindname.class, X, , , (compiler.misc.location: kindname.class, InvalidSource, null)
-22 errors
-check supertype: InvalidSource.TestClassMissingClassA -- !:empty clss A!
-check supertype: InvalidSource.TestClassMissingClassAB -- !:empty clss (pkg A).B!
-check supertype: InvalidSource.TestClassMissingClass_juA -- !:empty clss (pkg java.util).A!
-check supertype: InvalidSource.TestClassTMissingClassAT -- !:empty clss A!<tvar T>
-check interfaces: InvalidSource.TestClassMissingIntfA -- !:empty intf A!
-check interfaces: InvalidSource.TestClassMissingIntfAB -- !:empty intf (pkg A).B!
-check interfaces: InvalidSource.TestClassMissingIntfAOK -- !:empty intf A!, intf OK
-check interfaces: InvalidSource.TestClassOKMissingIntfA -- intf OK, !:empty intf A!
-check interfaces: InvalidSource.TestClassMissingIntfA_B -- !:empty intf A!, !:empty intf B!
-check interfaces: InvalidSource.TestIntfMissingIntfA -- !:empty intf A!
-check interfaces: InvalidSource.TestIntfMissingIntfAOK -- !:empty intf A!, intf OK
-check interfaces: InvalidSource.TestIntfOKMissingIntfA -- intf OK, !:empty intf A!
-check interfaces: InvalidSource.TestIntfMissingIntfAB -- !:empty intf A!, !:empty intf B!
-check interfaces: InvalidSource.TestClassTMissingIntfAT -- !:empty intf A!<tvar T>
-check interfaces: InvalidSource.TestClassTMissingIntfAT_B -- !:empty intf A!<tvar T>, !:empty intf B!
-check interfaces: InvalidSource.TestIntfTMissingIntfAT -- !:empty intf A!<tvar T>
-check interfaces: InvalidSource.TestIntfTMissingIntfAT_B -- !:empty intf A!<tvar T>, !:empty intf B!
-check interfaces: InvalidSource.TestClassListMissingX -- intf (pkg java.util).List<!:empty clss X!>
\ No newline at end of file
+22 errors
\ No newline at end of file
--- a/langtools/test/tools/javac/warnings/6594914/T6594914a.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/warnings/6594914/T6594914a.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,7 +1,7 @@
T6594914a.java:11:5: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6594914a.java:16:16: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
-T6594914a.java:16:52: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6594914a.java:16:33: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6594914a.java:17:20: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6594914a.java:16:52: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
T6594914a.java:24:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
6 warnings
--- a/langtools/test/tools/javac/warnings/6594914/T6594914b.out Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javac/warnings/6594914/T6594914b.out Tue Sep 17 08:21:11 2013 -0700
@@ -1,7 +1,7 @@
T6594914b.java:11:13: compiler.warn.sun.proprietary: sun.misc.Lock
T6594914b.java:16:24: compiler.warn.sun.proprietary: sun.misc.Lock
-T6594914b.java:16:56: compiler.warn.sun.proprietary: sun.misc.Lock
T6594914b.java:16:39: compiler.warn.sun.proprietary: sun.misc.Lock
T6594914b.java:17:28: compiler.warn.sun.proprietary: sun.misc.CEFormatException
+T6594914b.java:16:56: compiler.warn.sun.proprietary: sun.misc.Lock
T6594914b.java:24:17: compiler.warn.sun.proprietary: sun.misc.Lock
6 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/ImplicitTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8021112
+ * @summary Verify that deprecated warning is printed correctly for import
+ * statement when processing a file on demand while attributing another file.
+ * @clean pack.ImplicitUse pack.ImplicitMain pack.Dep
+ * @compile/ref=ImplicitTest.out -XDrawDiagnostics -Xlint:deprecation pack/ImplicitMain.java
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/ImplicitTest.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,2 @@
+ImplicitUse.java:4:12: compiler.warn.has.been.deprecated: pack.Dep, pack
+1 warning
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/PackageInfo.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8021112
+ * @summary Verify that deprecated warnings are printed correctly for package-info.java
+ * @clean pack.package-info pack.DeprecatedClass
+ * @compile/ref=PackageInfo.out -XDrawDiagnostics -Xlint:deprecation pack/package-info.java pack/DeprecatedClass.java
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/PackageInfo.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,3 @@
+package-info.java:5:12: compiler.warn.has.been.deprecated: pack.DeprecatedClass, pack
+package-info.java:2:2: compiler.warn.has.been.deprecated: pack.DeprecatedClass, pack
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T6480588.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,36 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 6470588
+ * @summary Verify that \\@SuppressWarnings("deprecation") works OK for all parts
+ * of class/method/field "header", including (declaration) annotations
+ * @build VerifySuppressWarnings
+ * @compile/ref=T6480588.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast T6480588.java
+ * @run main VerifySuppressWarnings T6480588.java
+ */
+
+@DeprecatedAnnotation
+class T6480588 extends DeprecatedClass implements DeprecatedInterface {
+ @DeprecatedAnnotation
+ public DeprecatedClass method(DeprecatedClass param) throws DeprecatedClass {
+ DeprecatedClass lv = new DeprecatedClass();
+ @Deprecated
+ DeprecatedClass lvd = new DeprecatedClass();
+ return null;
+ }
+
+ @Deprecated
+ public void methodD() {
+ }
+
+ @DeprecatedAnnotation
+ DeprecatedClass field = new DeprecatedClass();
+
+ @DeprecatedAnnotation
+ class Inner extends DeprecatedClass implements DeprecatedInterface {
+ }
+
+}
+
+@Deprecated class DeprecatedClass extends Throwable { }
+@Deprecated interface DeprecatedInterface { }
+@Deprecated @interface DeprecatedAnnotation { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T6480588.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,18 @@
+T6480588.java:12:24: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:12:51: compiler.warn.has.been.deprecated: DeprecatedInterface, compiler.misc.unnamed.package
+T6480588.java:11:2: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
+T6480588.java:14:12: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:14:65: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:13:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
+T6480588.java:14:35: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:15:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:15:34: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:17:9: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:17:35: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:26:5: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:25:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
+T6480588.java:26:33: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:29:25: compiler.warn.has.been.deprecated: DeprecatedClass, compiler.misc.unnamed.package
+T6480588.java:29:52: compiler.warn.has.been.deprecated: DeprecatedInterface, compiler.misc.unnamed.package
+T6480588.java:28:6: compiler.warn.has.been.deprecated: DeprecatedAnnotation, compiler.misc.unnamed.package
+17 warnings
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T8021112a.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test;
+
+/**
+ * @test
+ * @bug 8021112
+ * @summary Verify that \\@SuppressWarnings work even if the value is defined
+ * inside the suppressed class itself, and verify that "unnecessary cast"
+ * lint can be properly suppressed.
+ * @compile -Xlint:cast -Werror T8021112a.java
+ */
+
+import static test.T8021112a.D;
+
+@SuppressWarnings(D)
+public class T8021112a {
+ public static final String D = (String) "cast";
+}
+
+class Other {
+ public static final String D = "cast";
+ @SuppressWarnings(D)
+ public static final String D2 = (String) "cast";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T8021112b.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,22 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 8021112
+ * @summary Verify that \\@SuppressWarnings("unchecked") works correctly for lazy attrib values
+ * @build VerifySuppressWarnings
+ * @compile/ref=T8021112b.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast T8021112b.java
+ * @run main VerifySuppressWarnings T8021112b.java
+ */
+
+public class T8021112b {
+ public static final String D1 = Dep.D;
+ public static final String D2 = "";
+ public static final Object[] o = {
+ new Object() {
+ Dep d;
+ }
+ };
+}
+
+@Deprecated class Dep {
+ public static final String D = T8021112b.D2;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T8021112b.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,3 @@
+T8021112b.java:11:37: compiler.warn.has.been.deprecated: Dep, compiler.misc.unnamed.package
+T8021112b.java:15:13: compiler.warn.has.been.deprecated: Dep, compiler.misc.unnamed.package
+2 warnings
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,51 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 8021112
+ * @summary Verify that \\@SuppressWarnings("unchecked") works for type annotations
+ * @build VerifySuppressWarnings
+ * @compile/ref=TypeAnnotations.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast TypeAnnotations.java
+ * @run main VerifySuppressWarnings TypeAnnotations.java
+ */
+
+import java.lang.annotation.*;
+
+public class TypeAnnotations extends @TA Object implements @TA Runnable {
+
+ public @TA String @TA [] m(@TA String @TA [] p) throws @TA Throwable {
+ Runnable r = () -> {
+ @TA Object tested = null;
+ @TA boolean isAnnotated = tested instanceof @TA String;
+ };
+
+ @TA Object tested = null;
+ @TA boolean isAnnotated = tested instanceof @TA String;
+
+ return (@TA String @TA []) null;
+ }
+
+ {
+ Runnable r = () -> {
+ @TA Object tested = null;
+ @TA boolean isAnnotated = tested instanceof @TA String;
+ };
+
+ @TA Object tested = null;
+ @TA boolean isAnnotated = tested instanceof @TA String;
+
+ @TA String @TA [] ret = (@TA String @TA []) null;
+ }
+
+ @TA String @TA [] f = new @TA String @TA[0];
+
+ @Override public void run() { }
+
+ public static class Inner extends @TA Object implements @TA Runnable {
+ @Override public void run() { }
+ }
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE})
+@Deprecated
+@interface TA {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/TypeAnnotations.out Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,41 @@
+TypeAnnotations.java:12:39: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:12:61: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:14:24: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:14:61: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:14:13: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:14:44: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:14:33: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:23:29: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:23:18: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:16:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:17:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:17:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:17:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:20:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:21:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:21:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:21:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:23:18: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:23:29: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:28:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:29:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:29:14: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:29:58: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:32:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:33:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:33:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:33:54: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:46: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:35: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:21: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:10: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:35: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:35:46: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:38:17: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:38:6: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:38:43: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:38:32: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:38:32: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:42:40: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+TypeAnnotations.java:42:62: compiler.warn.has.been.deprecated: TA, compiler.misc.unnamed.package
+40 warnings
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/VerifySuppressWarnings.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.NewClassTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TreeScanner;
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.FileObject;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+
+/**Takes a source file, parses it once to get the warnings inside the file and
+ * then for each and every declaration in the file, it tries to place
+ * the @SuppressWarnings annotation on the declaration and verifies than no
+ * warnings are produced inside the declaration, but all are produced outside it.
+ *
+ * Currently only works with <code>unchecked,deprecation,cast</code> warnings.
+ */
+public class VerifySuppressWarnings {
+
+ private static final List<String> STANDARD_PARAMS = Arrays.asList("-Xlint:unchecked,deprecation,cast", "-Xjcov");
+
+ public static void main(String... args) throws IOException, URISyntaxException {
+ if (args.length != 1) throw new IllegalStateException("Must provide class name!");
+ String testContent = null;
+ List<File> sourcePath = new ArrayList<>();
+ for (String sourcePaths : System.getProperty("test.src.path").split(":")) {
+ sourcePath.add(new File(sourcePaths));
+ }
+ JavacFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
+ for (File sp : sourcePath) {
+ File inp = new File(sp, args[0]);
+
+ if (inp.canRead()) {
+ testContent = fm.getRegularFile(inp).getCharContent(true).toString();
+ }
+ }
+ if (testContent == null) throw new IllegalStateException();
+ final List<Diagnostic<?>> diagnostics = new ArrayList<>();
+ DiagnosticListener<JavaFileObject> collectDiagnostics = new DiagnosticListener<JavaFileObject>() {
+ @Override public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ diagnostics.add(diagnostic);
+ }
+ };
+ JavaFileObject testFile = new TestFO(new URI("mem://" + args[0]), testContent);
+ JavacTask task = JavacTool.create().getTask(null,
+ new TestFM(fm),
+ collectDiagnostics,
+ STANDARD_PARAMS,
+ null,
+ Arrays.asList(testFile));
+ final Trees trees = Trees.instance(task);
+ final CompilationUnitTree cut = task.parse().iterator().next();
+ task.analyze();
+
+ final List<int[]> declarationSpans = new ArrayList<>();
+
+ new TreeScanner<Void, Void>() {
+ @Override public Void visitClass(ClassTree node, Void p) {
+ handleDeclaration(node);
+ return super.visitClass(node, p);
+ }
+ @Override public Void visitMethod(MethodTree node, Void p) {
+ handleDeclaration(node);
+ return super.visitMethod(node, p);
+ }
+ @Override public Void visitVariable(VariableTree node, Void p) {
+ handleDeclaration(node);
+ return super.visitVariable(node, p);
+ }
+
+ @Override
+ public Void visitNewClass(NewClassTree node, Void p) {
+ if (node.getClassBody() != null) {
+ scan(node.getClassBody().getMembers(), null);
+ }
+ return null;
+ }
+
+ private void handleDeclaration(Tree node) {
+ int endPos = (int) trees.getSourcePositions().getEndPosition(cut, node);
+
+ if (endPos == (-1)) {
+ if (node.getKind() == Tree.Kind.METHOD && (((JCMethodDecl) node).getModifiers().flags & Flags.GENERATEDCONSTR) != 0) {
+ return ;
+ }
+ throw new IllegalStateException();
+ }
+
+ declarationSpans.add(new int[] {(int) trees.getSourcePositions().getStartPosition(cut, node), endPos});
+ }
+ }.scan(cut, null);
+
+ for (final int[] declarationSpan : declarationSpans) {
+ final String suppressWarnings = "@SuppressWarnings({\"deprecation\", \"unchecked\", \"serial\"})";
+ final String updatedContent = testContent.substring(0, declarationSpan[0]) + suppressWarnings + testContent.substring(declarationSpan[0]);
+ final List<Diagnostic<?>> foundErrors = new ArrayList<>(diagnostics);
+ DiagnosticListener<JavaFileObject> verifyDiagnostics = new DiagnosticListener<JavaFileObject>() {
+ @Override public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ long adjustedPos = diagnostic.getPosition();
+
+ if (adjustedPos >= declarationSpan[0]) adjustedPos -= suppressWarnings.length();
+
+ if (declarationSpan[0] <= adjustedPos && adjustedPos <= declarationSpan[1]) {
+ throw new IllegalStateException("unsuppressed: " + diagnostic.getMessage(null));
+ }
+
+ boolean found = false;
+
+ for (Iterator<Diagnostic<?>> it = foundErrors.iterator(); it.hasNext();) {
+ Diagnostic<?> d = it.next();
+ if (d.getPosition() == adjustedPos && d.getCode().equals(diagnostic.getCode())) {
+ it.remove();
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ throw new IllegalStateException("diagnostic not originally reported: " + diagnostic.getMessage(null));
+ }
+ }
+ };
+
+ JavaFileObject updatedFile = new TestFO(new URI("mem://" + args[0]), updatedContent);
+ JavacTask testTask = JavacTool.create().getTask(null,
+ new TestFM(fm),
+ verifyDiagnostics,
+ STANDARD_PARAMS,
+ null,
+ Arrays.asList(updatedFile));
+
+ testTask.analyze();
+
+ for (Diagnostic<?> d : foundErrors) {
+ if (d.getPosition() < declarationSpan[0] || declarationSpan[1] < d.getPosition()) {
+ throw new IllegalStateException("missing: " + d.getMessage(null));
+ }
+ }
+ }
+ }
+
+ private static final class TestFO extends SimpleJavaFileObject {
+ private final String content;
+ public TestFO(URI uri, String content) {
+ super(uri, Kind.SOURCE);
+ this.content = content;
+ }
+
+ @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return content;
+ }
+
+ @Override public boolean isNameCompatible(String simpleName, Kind kind) {
+ return true;
+ }
+ }
+
+ private static final class TestFM extends ForwardingJavaFileManager<JavaFileManager> {
+
+ public TestFM(JavaFileManager fileManager) {
+ super(fileManager);
+ }
+
+ @Override
+ public boolean isSameFile(FileObject a, FileObject b) {
+ return a.equals(b);
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/pack/DeprecatedClass.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,5 @@
+/* /nodynamiccopyright/ */
+package pack;
+@Deprecated
+@interface DeprecatedClass {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/pack/ImplicitMain.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,14 @@
+/* /nodynamiccopyright/ */
+package pack;
+
+@SuppressWarnings("deprecation")
+public class ImplicitMain {
+ private Object test() {
+ return new ImplicitUse();
+ }
+}
+
+@Deprecated
+class Dep {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/pack/ImplicitUse.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,7 @@
+/* /nodynamiccopyright/ */
+package pack;
+
+import pack.Dep;
+
+public class ImplicitUse {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/pack/package-info.java Tue Sep 17 08:21:11 2013 -0700
@@ -0,0 +1,5 @@
+/* /nodynamiccopyright/ */
+@DeprecatedClass
+package pack;
+
+import pack.DeprecatedClass;
--- a/langtools/test/tools/javadoc/api/basic/APITest.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javadoc/api/basic/APITest.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
+import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
@@ -164,11 +165,13 @@
}
private void listFiles(Path dir, Set<Path> files) throws IOException {
- for (Path f: Files.newDirectoryStream(dir)) {
- if (Files.isDirectory(f))
- listFiles(f, files);
- else if (Files.isRegularFile(f))
- files.add(f);
+ try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir)) {
+ for (Path f: ds) {
+ if (Files.isDirectory(f))
+ listFiles(f, files);
+ else if (Files.isRegularFile(f))
+ files.add(f);
+ }
}
}
--- a/langtools/test/tools/javadoc/api/basic/GetTask_FileManagerTest.java Thu Sep 12 11:09:20 2013 -0700
+++ b/langtools/test/tools/javadoc/api/basic/GetTask_FileManagerTest.java Tue Sep 17 08:21:11 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6493690
+ * @bug 6493690 8024434
* @summary javadoc should have a javax.tools.Tool service provider
* @build APITest
* @run main GetTask_FileManagerTest