This commit is contained in:
Lana Steuck 2014-05-01 14:21:15 -07:00
commit 5e30be8573
82 changed files with 3630 additions and 533 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2014, 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
@ -49,9 +49,9 @@ import com.sun.tools.doclets.internal.toolkit.util.DocPath;
public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
/**
* Array of Packages to be documented.
* A Set of Packages to be documented.
*/
protected PackageDoc[] packages;
protected SortedSet<PackageDoc> packages;
/**
* Constructor. Also initializes the packages variable.
@ -89,12 +89,12 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
/**
* Adds the packages list to the documentation tree.
*
* @param packages an array of packagedoc objects
* @param packages a collection of packagedoc objects
* @param text caption for the table
* @param tableSummary summary for the table
* @param body the document tree to which the packages list will be added
*/
protected abstract void addPackagesList(PackageDoc[] packages, String text,
protected abstract void addPackagesList(Collection<PackageDoc> packages, String text,
String tableSummary, Content body);
/**
@ -141,15 +141,14 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
* Adds package index contents. Call appropriate methods from
* the sub-classes. Adds it to the body HtmlTree
*
* @param packages array of packages to be documented
* @param packages a collection of packages to be documented
* @param text string which will be used as the heading
* @param tableSummary summary for the table
* @param body the document tree to which the index contents will be added
*/
protected void addIndexContents(PackageDoc[] packages, String text,
protected void addIndexContents(Collection<PackageDoc> packages, String text,
String tableSummary, Content body) {
if (packages.length > 0) {
Arrays.sort(packages);
if (!packages.isEmpty()) {
HtmlTree div = new HtmlTree(HtmlTag.DIV);
div.addStyle(HtmlStyle.indexHeader);
addAllClassesLink(div);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2014, 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
@ -180,7 +180,7 @@ public class ClassUseWriter extends SubWriterHolderWriter {
Map<String,List<ProgramElementDoc>> map = new HashMap<>();
List<? extends ProgramElementDoc> list= classMap.get(classdoc.qualifiedName());
if (list != null) {
Collections.sort(list);
list.sort(Util.makeComparatorForClassUse());
for (ProgramElementDoc doc : list) {
PackageDoc pkg = doc.containingPackage();
pkgSet.add(pkg);
@ -245,7 +245,7 @@ public class ClassUseWriter extends SubWriterHolderWriter {
protected void addClassUse(Content contentTree) throws IOException {
HtmlTree ul = new HtmlTree(HtmlTag.UL);
ul.addStyle(HtmlStyle.blockList);
if (configuration.packages.length > 1) {
if (configuration.packages.size() > 1) {
addPackageList(ul);
addPackageAnnotationList(ul);
}

View File

@ -495,15 +495,15 @@ public class ConfigurationImpl extends Configuration {
if (createoverview) {
topFile = DocPaths.OVERVIEW_SUMMARY;
} else {
if (packages.length == 1 && packages[0].name().equals("")) {
if (packages.size() == 1 && packages.first().name().equals("")) {
if (root.classes().length > 0) {
ClassDoc[] classarr = root.classes();
Arrays.sort(classarr);
ClassDoc cd = getValidClass(classarr);
topFile = DocPath.forClass(cd);
}
} else {
topFile = DocPath.forPackage(packages[0]).resolve(DocPaths.PACKAGE_SUMMARY);
} else if (!packages.isEmpty()) {
topFile = DocPath.forPackage(packages.first()).resolve(DocPaths.PACKAGE_SUMMARY);
}
}
}
@ -534,7 +534,7 @@ public class ConfigurationImpl extends Configuration {
* packages is more than one. Sets {@link #createoverview} field to true.
*/
protected void setCreateOverview() {
if ((overview || packages.length > 1) && !nooverview) {
if ((overview || packages.size() > 1) && !nooverview) {
createoverview = true;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2014, 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
@ -65,7 +65,7 @@ public class FrameOutputWriter extends HtmlDocletWriter {
public FrameOutputWriter(ConfigurationImpl configuration,
DocPath filename) throws IOException {
super(configuration, filename);
noOfPackages = configuration.packages.length;
noOfPackages = configuration.packages.size();
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2014, 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
@ -215,22 +215,22 @@ public class HtmlDoclet extends AbstractDoclet {
if (!configuration.shouldDocumentProfile(profileName))
continue;
ProfilePackageIndexFrameWriter.generate(configuration, profileName);
PackageDoc[] packages = configuration.profilePackages.get(
List<PackageDoc> packages = configuration.profilePackages.get(
profileName);
PackageDoc prev = null, next;
for (int j = 0; j < packages.length; j++) {
for (int j = 0; j < packages.size(); j++) {
// if -nodeprecated option is set and the package is marked as
// deprecated, do not generate the profilename-package-summary.html
// and profilename-package-frame.html pages for that package.
if (!(configuration.nodeprecated && Util.isDeprecated(packages[j]))) {
ProfilePackageFrameWriter.generate(configuration, packages[j], i);
next = (j + 1 < packages.length
&& packages[j + 1].name().length() > 0) ? packages[j + 1] : null;
PackageDoc pkg = packages.get(j);
if (!(configuration.nodeprecated && Util.isDeprecated(pkg))) {
ProfilePackageFrameWriter.generate(configuration, pkg, i);
next = getNamedPackage(packages, j + 1);
AbstractBuilder profilePackageSummaryBuilder =
configuration.getBuilderFactory().getProfilePackageSummaryBuilder(
packages[j], prev, next, Profile.lookup(i));
pkg, prev, next, Profile.lookup(i));
profilePackageSummaryBuilder.build();
prev = packages[j];
prev = pkg;
}
}
nextProfile = (i + 1 < configuration.profiles.getProfileCount()) ?
@ -244,35 +244,47 @@ public class HtmlDoclet extends AbstractDoclet {
}
}
PackageDoc getNamedPackage(List<PackageDoc> list, int idx) {
if (idx < list.size()) {
PackageDoc pkg = list.get(idx);
if (!pkg.name().isEmpty()) {
return pkg;
}
}
return null;
}
/**
* {@inheritDoc}
*/
protected void generatePackageFiles(ClassTree classtree) throws Exception {
PackageDoc[] packages = configuration.packages;
if (packages.length > 1) {
Set<PackageDoc> packages = configuration.packages;
if (packages.size() > 1) {
PackageIndexFrameWriter.generate(configuration);
}
List<PackageDoc> pList = new ArrayList<>(configuration.packages);
PackageDoc prev = null, next;
for (int i = 0; i < packages.length; i++) {
for (int i = 0; i < pList.size(); i++) {
// if -nodeprecated option is set and the package is marked as
// deprecated, do not generate the package-summary.html, package-frame.html
// and package-tree.html pages for that package.
if (!(configuration.nodeprecated && Util.isDeprecated(packages[i]))) {
PackageFrameWriter.generate(configuration, packages[i]);
next = (i + 1 < packages.length &&
packages[i + 1].name().length() > 0) ? packages[i + 1] : null;
PackageDoc pkg = pList.get(i);
if (!(configuration.nodeprecated && Util.isDeprecated(pkg))) {
PackageFrameWriter.generate(configuration, pkg);
next = getNamedPackage(pList, i + 1);
//If the next package is unnamed package, skip 2 ahead if possible
next = (i + 2 < packages.length && next == null) ? packages[i + 2] : next;
if (next == null)
next = getNamedPackage(pList, i + 2);
AbstractBuilder packageSummaryBuilder =
configuration.getBuilderFactory().getPackageSummaryBuilder(
packages[i], prev, next);
pkg, prev, next);
packageSummaryBuilder.build();
if (configuration.createtree) {
PackageTreeWriter.generate(configuration,
packages[i], prev, next,
pkg, prev, next,
configuration.nodeprecated);
}
prev = packages[i];
prev = pkg;
}
}
}

View File

@ -524,9 +524,9 @@ public class HtmlDocletWriter extends HtmlDocWriter {
if (configuration.createoverview) {
navList.addContent(getNavLinkContents());
}
if (configuration.packages.length == 1) {
navList.addContent(getNavLinkPackage(configuration.packages[0]));
} else if (configuration.packages.length > 1) {
if (configuration.packages.size() == 1) {
navList.addContent(getNavLinkPackage(configuration.packages.first()));
} else if (configuration.packages.size() > 1) {
navList.addContent(getNavLinkPackage());
}
navList.addContent(getNavLinkClass());
@ -916,7 +916,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @return package name content
*/
public Content getPackageName(PackageDoc packageDoc) {
return packageDoc == null || packageDoc.name().length() == 0 ?
return packageDoc == null || packageDoc.name().isEmpty() ?
defaultPackageLabel :
getPackageLabel(packageDoc.name());
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2014, 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
@ -25,7 +25,8 @@
package com.sun.tools.doclets.formats.html;
import java.io.*;
import java.io.IOException;
import java.util.Collection;
import com.sun.javadoc.*;
import com.sun.tools.doclets.formats.html.markup.*;
@ -78,7 +79,7 @@ public class PackageIndexFrameWriter extends AbstractPackageIndexWriter {
/**
* {@inheritDoc}
*/
protected void addPackagesList(PackageDoc[] packages, String text,
protected void addPackagesList(Collection<PackageDoc> packages, String text,
String tableSummary, Content body) {
Content heading = HtmlTree.HEADING(HtmlConstants.PACKAGE_HEADING, true,
packagesLabel);
@ -106,7 +107,7 @@ public class PackageIndexFrameWriter extends AbstractPackageIndexWriter {
protected Content getPackage(PackageDoc pd) {
Content packageLinkContent;
Content packageLabel;
if (pd.name().length() > 0) {
if (!pd.name().isEmpty()) {
packageLabel = getPackageLabel(pd.name());
packageLinkContent = getHyperLink(pathString(pd,
DocPaths.PACKAGE_FRAME), packageLabel, "",

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2014, 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
@ -111,8 +111,8 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
protected void addIndex(Content body) {
for (String groupname : groupList) {
List<PackageDoc> list = groupPackageMap.get(groupname);
if (list != null && list.size() > 0) {
addIndexContents(list.toArray(new PackageDoc[list.size()]),
if (list != null && !list.isEmpty()) {
addIndexContents(list,
groupname, configuration.getText("doclet.Member_Table_Summary",
groupname, configuration.getText("doclet.packages")), body);
}
@ -146,7 +146,7 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
/**
* {@inheritDoc}
*/
protected void addPackagesList(PackageDoc[] packages, String text,
protected void addPackagesList(Collection<PackageDoc> packages, String text,
String tableSummary, Content body) {
Content table = HtmlTree.TABLE(HtmlStyle.overviewSummary, 0, 3, 0, tableSummary,
getTableCaption(new RawHtml(text)));
@ -164,25 +164,23 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
* @param packages Packages to which link is to be generated
* @param tbody the documentation tree to which the list will be added
*/
protected void addPackagesList(PackageDoc[] packages, Content tbody) {
for (int i = 0; i < packages.length; i++) {
if (packages[i] != null && packages[i].name().length() > 0) {
if (configuration.nodeprecated && Util.isDeprecated(packages[i]))
continue;
Content packageLinkContent = getPackageLink(packages[i],
getPackageName(packages[i]));
Content tdPackage = HtmlTree.TD(HtmlStyle.colFirst, packageLinkContent);
HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
tdSummary.addStyle(HtmlStyle.colLast);
addSummaryComment(packages[i], tdSummary);
HtmlTree tr = HtmlTree.TR(tdPackage);
tr.addContent(tdSummary);
if (i%2 == 0)
tr.addStyle(HtmlStyle.altColor);
else
tr.addStyle(HtmlStyle.rowColor);
tbody.addContent(tr);
protected void addPackagesList(Collection<PackageDoc> packages, Content tbody) {
boolean altColor = true;
for (PackageDoc pkg : packages) {
if (pkg != null && !pkg.name().isEmpty()) {
if (!(configuration.nodeprecated && Util.isDeprecated(pkg))) {
Content packageLinkContent = getPackageLink(pkg, getPackageName(pkg));
Content tdPackage = HtmlTree.TD(HtmlStyle.colFirst, packageLinkContent);
HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
tdSummary.addStyle(HtmlStyle.colLast);
addSummaryComment(pkg, tdSummary);
HtmlTree tr = HtmlTree.TR(tdPackage);
tr.addContent(tdSummary);
tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
tbody.addContent(tr);
}
}
altColor = !altColor;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2014, 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
@ -119,7 +119,7 @@ public class PackageTreeWriter extends AbstractTreeWriter {
Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, false,
HtmlStyle.title, headContent);
Content div = HtmlTree.DIV(HtmlStyle.header, heading);
if (configuration.packages.length > 1) {
if (configuration.packages.size() > 1) {
addLinkToMainTree(div);
}
body.addContent(div);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2014, 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
@ -135,7 +135,7 @@ public class PackageUseWriter extends SubWriterHolderWriter {
protected void addPackageUse(Content contentTree) throws IOException {
HtmlTree ul = new HtmlTree(HtmlTag.UL);
ul.addStyle(HtmlStyle.blockList);
if (configuration.packages.length > 1) {
if (configuration.packages.size() > 1) {
addPackageList(ul);
}
addClassList(ul);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2014, 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
@ -25,7 +25,8 @@
package com.sun.tools.doclets.formats.html;
import java.io.*;
import java.io.IOException;
import java.util.List;
import com.sun.javadoc.*;
import com.sun.tools.javac.sym.Profiles;
@ -92,7 +93,7 @@ public class ProfilePackageIndexFrameWriter extends AbstractProfileIndexWriter {
Content div = HtmlTree.DIV(HtmlStyle.indexContainer, heading);
HtmlTree ul = new HtmlTree(HtmlTag.UL);
ul.setTitle(packagesLabel);
PackageDoc[] packages = configuration.profilePackages.get(profileName);
List<PackageDoc> packages = configuration.profilePackages.get(profileName);
for (PackageDoc packageDoc : packages) {
if ((!(configuration.nodeprecated && Util.isDeprecated(packageDoc)))) {
ul.addContent(getPackage(packageDoc, profileName));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2014, 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
@ -25,7 +25,8 @@
package com.sun.tools.doclets.formats.html;
import java.io.*;
import java.io.IOException;
import java.util.SortedSet;
import com.sun.javadoc.*;
import com.sun.tools.doclets.formats.html.markup.*;
@ -51,7 +52,7 @@ public class TreeWriter extends AbstractTreeWriter {
/**
* Packages in this run.
*/
private PackageDoc[] packages;
SortedSet<PackageDoc> packages;
/**
* True if there are no packages specified on the command line,
@ -67,11 +68,10 @@ public class TreeWriter extends AbstractTreeWriter {
* @param classtree the tree being built.
*/
public TreeWriter(ConfigurationImpl configuration,
DocPath filename, ClassTree classtree)
throws IOException {
DocPath filename, ClassTree classtree) throws IOException {
super(configuration, filename, classtree);
packages = configuration.packages;
classesonly = packages.length == 0;
classesonly = packages.isEmpty();
}
/**
@ -127,7 +127,7 @@ public class TreeWriter extends AbstractTreeWriter {
*/
protected void addPackageTreeLinks(Content contentTree) {
//Do nothing if only unnamed package is used
if (packages.length == 1 && packages[0].name().length() == 0) {
if (isUnnamedPackage()) {
return;
}
if (!classesonly) {
@ -136,21 +136,24 @@ public class TreeWriter extends AbstractTreeWriter {
contentTree.addContent(span);
HtmlTree ul = new HtmlTree(HtmlTag.UL);
ul.addStyle(HtmlStyle.horizontal);
for (int i = 0; i < packages.length; i++) {
int i = 0;
for (PackageDoc pkg : packages) {
// If the package name length is 0 or if -nodeprecated option
// is set and the package is marked as deprecated, do not include
// the page in the list of package hierarchies.
if (packages[i].name().length() == 0 ||
(configuration.nodeprecated && Util.isDeprecated(packages[i]))) {
if (pkg.name().isEmpty() ||
(configuration.nodeprecated && Util.isDeprecated(pkg))) {
i++;
continue;
}
DocPath link = pathString(packages[i], DocPaths.PACKAGE_TREE);
DocPath link = pathString(pkg, DocPaths.PACKAGE_TREE);
Content li = HtmlTree.LI(getHyperLink(
link, new StringContent(packages[i].name())));
if (i < packages.length - 1) {
link, new StringContent(pkg.name())));
if (i < packages.size() - 1) {
li.addContent(", ");
}
ul.addContent(li);
i++;
}
contentTree.addContent(ul);
}
@ -168,4 +171,8 @@ public class TreeWriter extends AbstractTreeWriter {
addNavLinks(true, bodyTree);
return bodyTree;
}
private boolean isUnnamedPackage() {
return packages.size() == 1 && packages.first().name().isEmpty();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2014, 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
@ -289,16 +289,16 @@ public abstract class Configuration {
public Profiles profiles;
/**
* An map of the profiles to packages.
* A map of the profiles to packages.
*/
public Map<String,PackageDoc[]> profilePackages;
public Map<String, List<PackageDoc>> profilePackages;
/**
* An array of the packages specified on the command-line merged
* with the array of packages that contain the classes specified on the
* command-line. The array is sorted.
* A sorted set of packages specified on the command-line merged with a
* collection of packages that contain the classes specified on the
* command-line.
*/
public PackageDoc[] packages;
public SortedSet<PackageDoc> packages;
/**
* Constructor. Constructs the message retriever with resource file.
@ -423,7 +423,7 @@ public abstract class Configuration {
// 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()]));
profilePackages.put(p.name, pkgs);
prev = pkgs;
}
@ -432,14 +432,11 @@ public abstract class Configuration {
showProfiles = !prev.isEmpty();
}
private void initPackageArray() {
Set<PackageDoc> set = new HashSet<>(Arrays.asList(root.specifiedPackages()));
private void initPackages() {
packages = new TreeSet<>(Arrays.asList(root.specifiedPackages()));
for (ClassDoc aClass : root.specifiedClasses()) {
set.add(aClass.containingPackage());
packages.add(aClass.containingPackage());
}
ArrayList<PackageDoc> results = new ArrayList<>(set);
Collections.sort(results);
packages = results.toArray(new PackageDoc[] {});
}
/**
@ -547,7 +544,7 @@ public abstract class Configuration {
* @throws DocletAbortException
*/
public void setOptions() throws Fault {
initPackageArray();
initPackages();
setOptions(root.options());
try {
initProfiles();

View File

@ -29,6 +29,7 @@ import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import com.sun.javadoc.PackageDoc;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
@ -63,7 +64,7 @@ public abstract class AbstractBuilder {
* efficiency purposes. We don't want to copy the
* doc files multiple times for a single package.
*/
final Set<String> containingPackagesSeen;
final Set<PackageDoc> containingPackagesSeen;
/**
* Shared parser for the builder XML file
@ -71,7 +72,7 @@ public abstract class AbstractBuilder {
final LayoutParser layoutParser;
Context(Configuration configuration,
Set<String> containingPackagesSeen,
Set<PackageDoc> containingPackagesSeen,
LayoutParser layoutParser) {
this.configuration = configuration;
this.containingPackagesSeen = containingPackagesSeen;
@ -89,7 +90,7 @@ public abstract class AbstractBuilder {
* efficiency purposes. We don't want to copy the
* doc files multiple times for a single package.
*/
protected final Set<String> containingPackagesSeen;
protected final Set<PackageDoc> containingPackagesSeen;
protected final LayoutParser layoutParser;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2014, 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
@ -133,14 +133,13 @@ public class AnnotationTypeBuilder extends AbstractBuilder {
private void copyDocFiles() {
PackageDoc containingPackage = annotationTypeDoc.containingPackage();
if((configuration.packages == null ||
Arrays.binarySearch(configuration.packages,
containingPackage) < 0) &&
! containingPackagesSeen.contains(containingPackage.name())){
!configuration.packages.contains(containingPackage) &&
!containingPackagesSeen.contains(containingPackage))){
//Only copy doc files dir if the containing package is not
//documented AND if we have not documented a class from the same
//package already. Otherwise, we are making duplicate copies.
Util.copyDocFiles(configuration, containingPackage);
containingPackagesSeen.add(containingPackage.name());
containingPackagesSeen.add(containingPackage);
}
}

View File

@ -68,7 +68,7 @@ public class BuilderFactory {
this.configuration = configuration;
this.writerFactory = configuration.getWriterFactory();
Set<String> containingPackagesSeen = new HashSet<>();
Set<PackageDoc> containingPackagesSeen = new HashSet<>();
context = new AbstractBuilder.Context(configuration, containingPackagesSeen,
LayoutParser.getInstance(configuration));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2014, 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
@ -271,14 +271,13 @@ public class ClassBuilder extends AbstractBuilder {
private void copyDocFiles() {
PackageDoc containingPackage = classDoc.containingPackage();
if((configuration.packages == null ||
Arrays.binarySearch(configuration.packages,
containingPackage) < 0) &&
! containingPackagesSeen.contains(containingPackage.name())){
!configuration.packages.contains(containingPackage)) &&
! containingPackagesSeen.contains(containingPackage)){
//Only copy doc files dir if the containing package is not
//documented AND if we have not documented a class from the same
//package already. Otherwise, we are making duplicate copies.
Util.copyDocFiles(configuration, containingPackage);
containingPackagesSeen.add(containingPackage.name());
containingPackagesSeen.add(containingPackage);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2014, 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
@ -25,7 +25,8 @@
package com.sun.tools.doclets.internal.toolkit.builders;
import java.io.*;
import java.io.IOException;
import java.util.List;
import com.sun.javadoc.*;
import com.sun.tools.javac.jvm.Profile;
@ -165,7 +166,7 @@ public class ProfileSummaryBuilder extends AbstractBuilder {
* be added
*/
public void buildPackageSummary(XMLNode node, Content summaryContentTree) {
PackageDoc[] packages = configuration.profilePackages.get(profile.name);
List<PackageDoc> packages = configuration.profilePackages.get(profile.name);
for (PackageDoc aPackage : packages) {
this.pkg = aPackage;
Content packageSummaryContentTree = profileWriter.getPackageSummaryHeader(this.pkg);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2014, 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
@ -84,7 +84,7 @@ public class DeprecatedAPIListBuilder {
* @param configuration the current configuration of the doclet.
*/
private void buildDeprecatedAPIInfo(Configuration configuration) {
PackageDoc[] packages = configuration.packages;
Set<PackageDoc> packages = configuration.packages;
for (PackageDoc pkg : packages) {
if (Util.isDeprecated(pkg)) {
getList(PACKAGE).add(pkg);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2014, 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
@ -175,7 +175,7 @@ public class Group {
*
* @param packages Packages specified on the command line.
*/
public Map<String,List<PackageDoc>> groupPackages(PackageDoc[] packages) {
public Map<String, List<PackageDoc>> groupPackages(Set<PackageDoc> packages) {
Map<String,List<PackageDoc>> groupPackageMap = new HashMap<>();
String defaultGroupName =
(pkgNameGroupMap.isEmpty() && regExpGroupMap.isEmpty())?

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2014, 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
@ -71,27 +71,6 @@ public class IndexBuilder {
// make ProgramElementDoc[] when new toArray is available
protected final Object[] elements;
/**
* A comparator used to sort classes and members.
* Note: Maybe this compare code belongs in the tool?
*/
private class DocComparator implements Comparator<Doc> {
public int compare(Doc d1, Doc d2) {
String doc1 = d1.name();
String doc2 = d2.name();
int compareResult;
if ((compareResult = doc1.compareToIgnoreCase(doc2)) != 0) {
return compareResult;
} else if (d1 instanceof ProgramElementDoc && d2 instanceof ProgramElementDoc) {
doc1 = (((ProgramElementDoc) d1).qualifiedName());
doc2 = (((ProgramElementDoc) d2).qualifiedName());
return doc1.compareToIgnoreCase(doc2);
} else {
return 0;
}
}
}
/**
* Constructor. Build the index map.
*
@ -133,7 +112,7 @@ public class IndexBuilder {
*/
protected void sortIndexMap() {
for (List<Doc> docs : indexmap.values()) {
Collections.sort(docs, new DocComparator());
docs.sort(Util.makeComparatorForIndexUse());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2014, 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.io.*;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.text.Collator;
import java.util.*;
import javax.tools.StandardLocation;
@ -49,7 +50,6 @@ import com.sun.tools.javac.util.StringUtils;
* @author Jamie Ho
*/
public class Util {
/**
* Return array of class members whose documentation is to be generated.
* If the member is deprecated do not include such a member in the
@ -781,4 +781,163 @@ public class Util {
elt.name().contentEquals(ElementType.PARAMETER.name()) ||
elt.name().contentEquals(ElementType.TYPE.name());
}
/**
* A general purpose String comparator, which compares two Strings using a Collator
* strength of "SECONDARY", thus providing optimum case insensitive comparisons in
* most Locales.
*
* @param s1 first String to compare.
* @param s2 second String to compare.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
public static int compareStrings(String s1, String s2) {
Collator collator = Collator.getInstance();
collator.setStrength(Collator.SECONDARY);
return collator.compare(s1, s2);
}
/**
* A comparator for index file uses, this sorts first on names, then on
* parameter types and finally on the fully qualified name.
* @return a comparator for index file use
*/
public static Comparator<Doc> makeComparatorForIndexUse() {
return new Util.DocComparator<Doc>() {
/**
* compare two given Doc entities, first sort on name, if
* applicable on the method's parameter types, and finally on the
* fully qualified name of the entity.
*
* @param d1 - a Doc element.
* @param d2 - a Doc element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
public int compare(Doc d1, Doc d2) {
int result = compareStrings(d1.name(), d2.name());
if (result != 0) {
return result;
}
if (d1 instanceof ExecutableMemberDoc && d2 instanceof ExecutableMemberDoc) {
result = compareExecutableMembers(
(ExecutableMemberDoc) d1,
(ExecutableMemberDoc) d2);
if (result != 0) {
return result;
}
}
if (d1 instanceof ProgramElementDoc && d2 instanceof ProgramElementDoc) {
return compareProgramElementDoc((ProgramElementDoc)d1, (ProgramElementDoc)d2);
}
return 0;
}
};
}
/**
* Comparator for ClassUse representations, this sorts on member names,
* fully qualified member names and then the parameter types if applicable.
* @return a comparator to sort classes and members for class use
*/
public static Comparator<Doc> makeComparatorForClassUse() {
return new Util.DocComparator<Doc>() {
/**
* compare two given Doc entities, first sort on name, and if
* applicable on the fully qualified name, and finally if applicable
* on the parameter types.
* @param d1 - a Doc element.
* @param d2 - a Doc element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
public int compare(Doc d1, Doc d2) {
int result = compareStrings(d1.name(), d2.name());
if (result != 0) {
return result;
}
if (d1 instanceof ProgramElementDoc && d2 instanceof ProgramElementDoc) {
result = compareProgramElementDoc((ProgramElementDoc) d1, (ProgramElementDoc) d2);
if (result != 0) {
return result;
}
}
if (d1 instanceof ExecutableMemberDoc && d2 instanceof ExecutableMemberDoc) {
return compareExecutableMembers((ExecutableMemberDoc)d1, (ExecutableMemberDoc)d2);
}
return 0;
}
};
}
/**
* A general purpose comparator to sort Doc entities, basically provides the building blocks
* for creating specific comparators for an use-case.
* @param <T> a Doc entity
*/
static abstract class DocComparator<T extends Doc> implements Comparator<Doc> {
/**
* compares two parameter arrays by first comparing the length of the arrays, and
* then each Type of the parameter in the array.
* @param params1 the first parameter array.
* @param params2 the first parameter array.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareParameters(Parameter[] params1, Parameter[] params2) {
if (params1.length == 0 && params2.length == 0) {
return 0;
}
int result = Integer.compare(params1.length, params2.length);
if (result != 0) {
return result;
}
for (int i = 0; i < params1.length; i++) {
result = compareStrings(params1[i].typeName(), params2[i].typeName());
if (result != 0) {
return result;
}
}
return 0;
}
/**
* Compares two MemberDocs, typically the name of a method,
* field or constructor.
* @param e1 the first MemberDoc.
* @param e2 the second MemberDoc.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareMembers(MemberDoc e1, MemberDoc e2) {
return compareStrings(e1.name(), e2.name());
}
/**
* Compares two ExecutableMemberDocs such as methods and constructors,
* as well as the parameters the entity might take.
* @param m1 the first ExecutableMemberDoc.
* @param m2 the second ExecutableMemberDoc.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareExecutableMembers(ExecutableMemberDoc m1, ExecutableMemberDoc m2) {
int result = compareMembers(m1, m2);
if (result == 0)
result = compareParameters(m1.parameters(), m2.parameters());
return result;
}
/**
* Compares the fully qualified names of the entities
* @param p1 the first ProgramElementDoc.
* @param p2 the first ProgramElementDoc.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareProgramElementDoc(ProgramElementDoc p1, ProgramElementDoc p2) {
return compareStrings(p1.qualifiedName(), p2.qualifiedName());
}
}
}

View File

@ -195,6 +195,9 @@ public enum Source {
public boolean allowObjectToPrimitiveCast() {
return compareTo(JDK1_7) >= 0;
}
public boolean enforceThisDotInit() {
return compareTo(JDK1_7) >= 0;
}
public boolean allowPoly() {
return compareTo(JDK1_8) >= 0;
}

View File

@ -383,7 +383,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
/** A class is an inner class if it it has an enclosing instance class.
*/
public boolean isInner() {
return type.getEnclosingType().hasTag(CLASS);
return kind == TYP && type.getEnclosingType().hasTag(CLASS);
}
/** An inner class has an outer instance if it is not an interface

View File

@ -43,6 +43,7 @@ import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.jvm.ClassReader;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.*;
import static com.sun.tools.javac.code.BoundKind.*;
import static com.sun.tools.javac.code.Flags.*;
@ -304,8 +305,8 @@ public class Types {
}
/**
* Is t a subtype of or convertiable via boxing/unboxing
* convertions to s?
* Is t a subtype of or convertible via boxing/unboxing
* conversions to s?
*/
public boolean isConvertible(Type t, Type s) {
return isConvertible(t, s, noWarnings);
@ -1933,6 +1934,17 @@ public class Types {
* @param sym a symbol
*/
public Type asSuper(Type t, Symbol sym) {
/* Some examples:
*
* (Enum<E>, Comparable) => Comparable<E>
* (c.s.s.d.AttributeTree.ValueKind, Enum) => Enum<c.s.s.d.AttributeTree.ValueKind>
* (c.s.s.t.ExpressionTree, c.s.s.t.Tree) => c.s.s.t.Tree
* (j.u.List<capture#160 of ? extends c.s.s.d.DocTree>, Iterable) =>
* Iterable<capture#160 of ? extends c.s.s.d.DocTree>
*/
if (sym.type == syms.objectType) { //optimization
return syms.objectType;
}
return asSuper.visit(t, sym);
}
// where
@ -3867,9 +3879,11 @@ public class Types {
}
return buf.reverse();
}
public Type capture(Type t) {
if (!t.hasTag(CLASS))
if (!t.hasTag(CLASS)) {
return t;
}
if (t.getEnclosingType() != Type.noType) {
Type capturedEncl = capture(t.getEnclosingType());
if (capturedEncl != t.getEnclosingType()) {

View File

@ -2141,6 +2141,11 @@ public class Attr extends JCTree.Visitor {
cdef.extending = clazz;
}
if (resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
isSerializable(clazztype)) {
localEnv.info.isSerializable = true;
}
attribStat(cdef, localEnv);
checkLambdaCandidate(tree, cdef.sym, clazztype);
@ -2296,6 +2301,9 @@ public class Attr extends JCTree.Visitor {
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
try {
Type currentTarget = pt();
if (needsRecovery && isSerializable(currentTarget)) {
localEnv.info.isSerializable = true;
}
List<Type> explicitParamTypes = null;
if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
//attribute lambda parameters
@ -2700,17 +2708,20 @@ public class Attr extends JCTree.Visitor {
typeargtypes = attribTypes(that.typeargs, localEnv);
}
Type target;
Type desc;
if (pt() != Type.recoveryType) {
target = targetChecker.visit(pt(), that);
desc = types.findDescriptorType(target);
Type currentTarget = pt();
boolean isTargetSerializable =
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
isSerializable(currentTarget);
if (currentTarget != Type.recoveryType) {
currentTarget = targetChecker.visit(currentTarget, that);
desc = types.findDescriptorType(currentTarget);
} else {
target = Type.recoveryType;
currentTarget = Type.recoveryType;
desc = fallbackDescriptorType(that);
}
setFunctionalInfo(localEnv, that, pt(), desc, target, resultInfo.checkContext);
setFunctionalInfo(localEnv, that, pt(), desc, currentTarget, resultInfo.checkContext);
List<Type> argtypes = desc.getParameterTypes();
Resolve.MethodCheck referenceCheck = rs.resolveMethodCheck;
@ -2761,10 +2772,10 @@ public class Attr extends JCTree.Visitor {
JCDiagnostic diag = diags.create(diagKind, log.currentSource(), that,
"invalid.mref", Kinds.kindName(that.getMode()), detailsDiag);
if (targetError && target == Type.recoveryType) {
if (targetError && currentTarget == Type.recoveryType) {
//a target error doesn't make sense during recovery stage
//as we don't know what actual parameter types are
result = that.type = target;
result = that.type = currentTarget;
return;
} else {
if (targetError) {
@ -2772,7 +2783,7 @@ public class Attr extends JCTree.Visitor {
} else {
log.report(diag);
}
result = that.type = types.createErrorType(target);
result = that.type = types.createErrorType(currentTarget);
return;
}
}
@ -2783,7 +2794,7 @@ public class Attr extends JCTree.Visitor {
if (desc.getReturnType() == Type.recoveryType) {
// stop here
result = that.type = target;
result = that.type = currentTarget;
return;
}
@ -2801,7 +2812,7 @@ public class Attr extends JCTree.Visitor {
//static ref with class type-args
log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
diags.fragment("static.mref.with.targs"));
result = that.type = types.createErrorType(target);
result = that.type = types.createErrorType(currentTarget);
return;
}
@ -2810,7 +2821,7 @@ public class Attr extends JCTree.Visitor {
//no static bound mrefs
log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
diags.fragment("static.bound.mref"));
result = that.type = types.createErrorType(target);
result = that.type = types.createErrorType(currentTarget);
return;
}
@ -2818,6 +2829,10 @@ public class Attr extends JCTree.Visitor {
// Check that super-qualified symbols are not abstract (JLS)
rs.checkNonAbstract(that.pos(), that.sym);
}
if (isTargetSerializable) {
chk.checkElemAccessFromSerializableLambda(that);
}
}
ResultInfo checkInfo =
@ -2849,9 +2864,9 @@ public class Attr extends JCTree.Visitor {
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
checkReferenceCompatible(that, desc, refType, resultInfo.checkContext, isSpeculativeRound);
if (!isSpeculativeRound) {
checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, target);
checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, 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);
@ -3191,6 +3206,11 @@ public class Attr extends JCTree.Visitor {
while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym))
env1 = env1.outer;
}
if (env.info.isSerializable) {
chk.checkElemAccessFromSerializableLambda(tree);
}
result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo);
}
@ -3315,6 +3335,10 @@ public class Attr extends JCTree.Visitor {
}
}
if (env.info.isSerializable) {
chk.checkElemAccessFromSerializableLambda(tree);
}
env.info.selectSuper = selectSuperPrev;
result = checkId(tree, site, sym, env, resultInfo);
}
@ -4181,6 +4205,11 @@ public class Attr extends JCTree.Visitor {
((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
log.error(env.tree.pos(), "enum.types.not.extensible");
}
if (isSerializable(c.type)) {
env.info.isSerializable = true;
}
attribClassBody(env, c);
chk.checkDeprecatedAnnotation(env.tree.pos(), c);
@ -4294,7 +4323,7 @@ public class Attr extends JCTree.Visitor {
// Check for proper use of serialVersionUID
if (env.info.lint.isEnabled(LintCategory.SERIAL) &&
isSerializable(c) &&
isSerializable(c.type) &&
(c.flags() & Flags.ENUM) == 0 &&
checkForSerial(c)) {
checkSerialVersionUID(tree, c);
@ -4334,15 +4363,15 @@ public class Attr extends JCTree.Visitor {
return null;
}
/** check if a class is a subtype of Serializable, if that is available. */
private boolean isSerializable(ClassSymbol c) {
/** check if a type is a subtype of Serializable, if that is available. */
boolean isSerializable(Type t) {
try {
syms.serializableType.complete();
}
catch (CompletionFailure e) {
return false;
}
return types.isSubtype(c.type, syms.serializableType);
return types.isSubtype(t, syms.serializableType);
}
/** Check that an appropriate serialVersionUID member is defined. */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2014, 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
@ -54,6 +54,10 @@ public class AttrContext {
*/
boolean selectSuper = false;
/** Is the current target of lambda expression or method reference serializable?
*/
boolean isSerializable = false;
/** Are arguments to current function applications boxed into an array for varargs?
*/
Resolve.MethodResolutionPhase pendingResolutionPhase = null;
@ -89,6 +93,7 @@ public class AttrContext {
info.enclVar = enclVar;
info.returnResult = returnResult;
info.defaultSuperCallSite = defaultSuperCallSite;
info.isSerializable = isSerializable;
return info;
}

View File

@ -81,6 +81,7 @@ public class Check {
private final TreeInfo treeinfo;
private final JavaFileManager fileManager;
private final Profile profile;
private final boolean warnOnAccessToSensitiveMembers;
// The set of lint options currently in effect. It is initialized
// from the context, and then is set/reset as needed by Attr as it
@ -130,6 +131,7 @@ public class Check {
warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
enableSunApiLintControl = options.isSet("enableSunApiLintControl");
warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers");
Target target = Target.instance(context);
syntheticNameChar = target.syntheticNameChar();
@ -513,6 +515,11 @@ public class Check {
public DeferredAttrContext deferredAttrContext() {
return deferredAttr.emptyDeferredAttrContext;
}
@Override
public String toString() {
return "CheckContext: basicHandler";
}
};
/** Check that a given type is assignable to a given proto-type.
@ -2588,6 +2595,44 @@ public class Check {
}
}
void checkElemAccessFromSerializableLambda(final JCTree tree) {
if (warnOnAccessToSensitiveMembers) {
Symbol sym = TreeInfo.symbol(tree);
if ((sym.kind & (VAR | MTH)) == 0) {
return;
}
if (sym.kind == VAR) {
if ((sym.flags() & PARAMETER) != 0 ||
sym.isLocal() ||
sym.name == names._this ||
sym.name == names._super) {
return;
}
}
if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
isEffectivelyNonPublic(sym)) {
log.warning(tree.pos(),
"access.to.sensitive.member.from.serializable.element", sym);
}
}
}
private boolean isEffectivelyNonPublic(Symbol sym) {
if (sym.packge() == syms.rootPackage) {
return false;
}
while (sym.kind != Kinds.PCK) {
if ((sym.flags() & PUBLIC) == 0) {
return true;
}
sym = sym.owner;
}
return false;
}
/** Report a conflict between a user symbol and a synthetic symbol.
*/
private void syntheticError(DiagnosticPosition pos, Symbol sym) {

View File

@ -109,6 +109,11 @@ public class DeferredAttr extends JCTree.Visitor {
void complete() {
Assert.error("Empty deferred context!");
}
@Override
public String toString() {
return "Empty deferred context!";
}
};
}

View File

@ -196,6 +196,7 @@ public class Flow {
private final boolean allowImprovedRethrowAnalysis;
private final boolean allowImprovedCatchAnalysis;
private final boolean allowEffectivelyFinalInInnerClasses;
private final boolean enforceThisDotInit;
public static Flow instance(Context context) {
Flow instance = context.get(flowKey);
@ -206,7 +207,7 @@ public class Flow {
public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
new AliveAnalyzer().analyzeTree(env, make);
new AssignAnalyzer(log, syms, lint, names).analyzeTree(env);
new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env);
new FlowAnalyzer().analyzeTree(env, make);
new CaptureAnalyzer().analyzeTree(env, make);
}
@ -238,7 +239,7 @@ public class Flow {
//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);
new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env);
LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
flowAnalyzer.analyzeTree(env, that, make);
return flowAnalyzer.inferredThrownTypes;
@ -288,6 +289,7 @@ public class Flow {
allowImprovedRethrowAnalysis = source.allowImprovedRethrowAnalysis();
allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis();
allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses();
enforceThisDotInit = source.enforceThisDotInit();
}
/**
@ -1422,6 +1424,8 @@ public class Flow {
protected Names names;
final boolean enforceThisDotInit;
public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
final Bits inits;
@ -1444,7 +1448,7 @@ public class Flow {
}
}
public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names) {
public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names, boolean enforceThisDotInit) {
this.inits = inits;
uninits = new Bits();
uninitsTry = new Bits();
@ -1454,6 +1458,7 @@ public class Flow {
uninitsWhenFalse = new Bits(true);
this.syms = syms;
this.names = names;
this.enforceThisDotInit = enforceThisDotInit;
}
private boolean isInitialConstructor = false;
@ -2275,12 +2280,34 @@ public class Flow {
public void visitAssign(JCAssign tree) {
JCTree lhs = TreeInfo.skipParens(tree.lhs);
if (!(lhs instanceof JCIdent)) {
if (!isIdentOrThisDotIdent(lhs))
scanExpr(lhs);
}
scanExpr(tree.rhs);
letInit(lhs);
}
private boolean isIdentOrThisDotIdent(JCTree lhs) {
if (lhs.hasTag(IDENT))
return true;
if (!lhs.hasTag(SELECT))
return false;
JCFieldAccess fa = (JCFieldAccess)lhs;
return fa.selected.hasTag(IDENT) &&
((JCIdent)fa.selected).name == names._this;
}
// check fields accessed through this.<field> are definitely
// assigned before reading their value
public void visitSelect(JCFieldAccess tree) {
super.visitSelect(tree);
if (enforceThisDotInit &&
tree.selected.hasTag(IDENT) &&
((JCIdent)tree.selected).name == names._this &&
tree.sym.kind == VAR)
{
checkInit(tree.pos(), (VarSymbol)tree.sym);
}
}
public void visitAssignop(JCAssignOp tree) {
scanExpr(tree.lhs);
@ -2410,8 +2437,8 @@ public class Flow {
}
}
public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names) {
super(new Bits(), syms, names);
public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names, boolean enforceThisDotInit) {
super(new Bits(), syms, names, enforceThisDotInit);
this.log = log;
this.lint = lint;
}

View File

@ -141,24 +141,24 @@ public class Infer {
* Main inference entry point - instantiate a generic method type
* using given argument types and (possibly) an expected target-type.
*/
public Type instantiateMethod(Env<AttrContext> env,
List<Type> tvars,
MethodType mt,
Attr.ResultInfo resultInfo,
Symbol msym,
List<Type> argtypes,
boolean allowBoxing,
boolean useVarargs,
Resolve.MethodResolutionContext resolveContext,
Warner warn) throws InferenceException {
Type instantiateMethod( Env<AttrContext> env,
List<Type> tvars,
MethodType mt,
Attr.ResultInfo resultInfo,
MethodSymbol msym,
List<Type> argtypes,
boolean allowBoxing,
boolean useVarargs,
Resolve.MethodResolutionContext resolveContext,
Warner warn) throws InferenceException {
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
final InferenceContext inferenceContext = new InferenceContext(tvars);
final InferenceContext inferenceContext = new InferenceContext(tvars); //B0
inferenceException.clear();
try {
DeferredAttr.DeferredAttrContext deferredAttrContext =
resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn);
resolveContext.methodCheck.argumentsAcceptable(env, deferredAttrContext,
resolveContext.methodCheck.argumentsAcceptable(env, deferredAttrContext, //B2
argtypes, mt.getParameterTypes(), warn);
if (allowGraphInference &&
@ -166,7 +166,8 @@ public class Infer {
!warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
//inject return constraints earlier
checkWithinBounds(inferenceContext, warn); //propagation
Type newRestype = generateReturnConstraints(resultInfo, mt, inferenceContext);
Type newRestype = generateReturnConstraints(env.tree, resultInfo, //B3
mt, inferenceContext);
mt = (MethodType)types.createMethodTypeWithReturn(mt, newRestype);
//propagate outwards if needed
if (resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
@ -192,7 +193,7 @@ public class Infer {
inferenceContext.restvars().nonEmpty() &&
resultInfo != null &&
!warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
generateReturnConstraints(resultInfo, mt, inferenceContext);
generateReturnConstraints(env.tree, resultInfo, mt, inferenceContext);
inferenceContext.solveLegacy(false, warn, LegacyInferenceSteps.EQ_UPPER.steps); //maximizeInst
mt = (MethodType)inferenceContext.asInstType(mt);
}
@ -209,6 +210,12 @@ public class Infer {
} else {
inferenceContext.notifyChange(inferenceContext.boundedVars());
}
if (resultInfo == null) {
/* if the is no result info then we can clear the capture types
* cache without affecting any result info check
*/
inferenceContext.captureTypeCache.clear();
}
}
}
@ -217,7 +224,7 @@ public class Infer {
* call occurs in a context where a type T is expected, use the expected
* type to derive more constraints on the generic method inference variables.
*/
Type generateReturnConstraints(Attr.ResultInfo resultInfo,
Type generateReturnConstraints(JCTree tree, Attr.ResultInfo resultInfo,
MethodType mt, InferenceContext inferenceContext) {
InferenceContext rsInfoInfContext = resultInfo.checkContext.inferenceContext();
Type from = mt.getReturnType();
@ -231,13 +238,29 @@ public class Infer {
}
}
}
Type qtype1 = inferenceContext.asUndetVar(from);
Type to = returnConstraintTarget(qtype1, resultInfo.pt);
Type qtype = inferenceContext.asUndetVar(from);
Type to = resultInfo.pt;
if (qtype.hasTag(VOID)) {
to = syms.voidType;
} else if (to.hasTag(NONE)) {
to = from.isPrimitive() ? from : syms.objectType;
} else if (qtype.hasTag(UNDETVAR)) {
if (resultInfo.pt.isReference()) {
to = generateReturnConstraintsUndetVarToReference(
tree, (UndetVar)qtype, to, resultInfo, inferenceContext);
} else {
if (to.isPrimitive()) {
to = generateReturnConstraintsPrimitive(tree, (UndetVar)qtype, to,
resultInfo, inferenceContext);
}
}
}
Assert.check(allowGraphInference || !rsInfoInfContext.free(to),
"legacy inference engine cannot handle constraints on both sides of a subtyping assertion");
//we need to skip capture?
Warner retWarn = new Warner();
if (!resultInfo.checkContext.compatible(qtype1, rsInfoInfContext.asUndetVar(to), retWarn) ||
if (!resultInfo.checkContext.compatible(qtype, rsInfoInfContext.asUndetVar(to), retWarn) ||
//unchecked conversion is not allowed in source 7 mode
(!allowGraphInference && retWarn.hasLint(Lint.LintCategory.UNCHECKED))) {
throw inferenceException
@ -247,30 +270,96 @@ public class Infer {
return from;
}
Type returnConstraintTarget(Type from, Type to) {
if (from.hasTag(VOID)) {
return syms.voidType;
} else if (to.hasTag(NONE)) {
return from.isPrimitive() ? from : syms.objectType;
} else if (from.hasTag(UNDETVAR) && to.isPrimitive()) {
if (!allowGraphInference) {
//if legacy, just return boxed type
return types.boxedClass(to).type;
private Type generateReturnConstraintsPrimitive(JCTree tree, UndetVar from,
Type to, Attr.ResultInfo resultInfo, InferenceContext inferenceContext) {
if (!allowGraphInference) {
//if legacy, just return boxed type
return types.boxedClass(to).type;
}
//if graph inference we need to skip conflicting boxed bounds...
for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.UPPER,
InferenceBound.LOWER)) {
Type boundAsPrimitive = types.unboxedType(t);
if (boundAsPrimitive == null || boundAsPrimitive.hasTag(NONE)) {
continue;
}
//if graph inference we need to skip conflicting boxed bounds...
UndetVar uv = (UndetVar)from;
for (Type t : uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
Type boundAsPrimitive = types.unboxedType(t);
if (boundAsPrimitive == null) continue;
if (types.isConvertible(boundAsPrimitive, to)) {
//effectively skip return-type constraint generation (compatibility)
return syms.objectType;
return generateReferenceToTargetConstraint(tree, from, to,
resultInfo, inferenceContext);
}
return types.boxedClass(to).type;
}
private Type generateReturnConstraintsUndetVarToReference(JCTree tree,
UndetVar from, Type to, Attr.ResultInfo resultInfo,
InferenceContext inferenceContext) {
Type captureOfTo = types.capture(to);
/* T is a reference type, but is not a wildcard-parameterized type, and either
*/
if (captureOfTo == to) { //not a wildcard parameterized type
/* i) B2 contains a bound of one of the forms alpha = S or S <: alpha,
* where S is a wildcard-parameterized type, or
*/
for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
Type captureOfBound = types.capture(t);
if (captureOfBound != t) {
return generateReferenceToTargetConstraint(tree, from, to,
resultInfo, inferenceContext);
}
}
/* ii) B2 contains two bounds of the forms S1 <: alpha and S2 <: alpha,
* where S1 and S2 have supertypes that are two different
* parameterizations of the same generic class or interface.
*/
for (Type aLowerBound : from.getBounds(InferenceBound.LOWER)) {
for (Type anotherLowerBound : from.getBounds(InferenceBound.LOWER)) {
if (aLowerBound != anotherLowerBound &&
commonSuperWithDiffParameterization(aLowerBound, anotherLowerBound)) {
/* self comment check if any lower bound may be and undetVar,
* in that case the result of this call may be a false positive.
* Should this be restricted to non free types?
*/
return generateReferenceToTargetConstraint(tree, from, to,
resultInfo, inferenceContext);
}
}
}
return types.boxedClass(to).type;
} else {
return to;
}
/* T is a parameterization of a generic class or interface, G,
* and B2 contains a bound of one of the forms alpha = S or S <: alpha,
* where there exists no type of the form G<...> that is a
* supertype of S, but the raw type G is a supertype of S
*/
if (to.isParameterized()) {
for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
Type sup = types.asSuper(t, to.tsym);
if (sup != null && sup.isRaw()) {
return generateReferenceToTargetConstraint(tree, from, to,
resultInfo, inferenceContext);
}
}
}
return to;
}
private boolean commonSuperWithDiffParameterization(Type t, Type s) {
Pair<Type, Type> supers = getParameterizedSupers(t, s);
return (supers != null && !types.isSameType(supers.fst, supers.snd));
}
private Type generateReferenceToTargetConstraint(JCTree tree, UndetVar from,
Type to, Attr.ResultInfo resultInfo,
InferenceContext inferenceContext) {
inferenceContext.solve(List.of(from.qtype), new Warner());
Type capturedType = resultInfo.checkContext.inferenceContext()
.cachedCapture(tree, from.inst, false);
if (types.isConvertible(capturedType,
resultInfo.checkContext.inferenceContext().asUndetVar(to))) {
//effectively skip additional return-type constraint generation (compatibility)
return syms.objectType;
}
return to;
}
/**
@ -2132,8 +2221,10 @@ public class Infer {
* Copy variable in this inference context to the given context
*/
void dupTo(final InferenceContext that) {
that.inferencevars = that.inferencevars.appendList(inferencevars);
that.undetvars = that.undetvars.appendList(undetvars);
that.inferencevars = that.inferencevars.appendList(
inferencevars.diff(that.inferencevars));
that.undetvars = that.undetvars.appendList(
undetvars.diff(that.undetvars));
//set up listeners to notify original inference contexts as
//propagated vars are inferred in new context
for (Type t : inferencevars) {
@ -2252,6 +2343,30 @@ public class Infer {
return "Inference vars: " + inferencevars + '\n' +
"Undet vars: " + undetvars;
}
/* Method Types.capture() generates a new type every time it's applied
* to a wildcard parameterized type. This is intended functionality but
* there are some cases when what you need is not to generate a new
* captured type but to check that a previously generated captured type
* is correct. There are cases when caching a captured type for later
* reuse is sound. In general two captures from the same AST are equal.
* This is why the tree is used as the key of the map below. This map
* stores a Type per AST.
*/
Map<JCTree, Type> captureTypeCache = new HashMap<>();
Type cachedCapture(JCTree tree, Type t, boolean readOnly) {
Type captured = captureTypeCache.get(tree);
if (captured != null) {
return captured;
}
Type result = types.capture(t);
if (result != t && !readOnly) { // then t is a wildcard parameterized type
captureTypeCache.put(tree, result);
}
return result;
}
}
final InferenceContext emptyContext = new InferenceContext(List.<Type>nil());

View File

@ -36,6 +36,7 @@ import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type;
@ -50,8 +51,10 @@ import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import static com.sun.tools.javac.comp.LambdaToMethod.LambdaSymbolKind.*;
import static com.sun.tools.javac.code.Flags.*;
@ -437,13 +440,9 @@ public class LambdaToMethod extends TreeTranslator {
public void visitVarDef(JCVariableDecl tree) {
LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context;
if (context != null && lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) {
JCExpression init = translate(tree.init);
int prevPos = make.pos;
try {
result = make.at(tree).VarDef((VarSymbol)lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym), init);
} finally {
make.at(prevPos);
}
tree.init = translate(tree.init);
tree.sym = (VarSymbol) lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym);
result = tree;
} else if (context != null && lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) {
JCExpression init = translate(tree.init);
VarSymbol xsym = (VarSymbol)lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym);
@ -1284,7 +1283,10 @@ public class LambdaToMethod extends TreeTranslator {
@Override
public void visitNewClass(JCNewClass tree) {
if (lambdaNewClassFilter(context(), tree)) {
TypeSymbol def = tree.type.tsym;
boolean inReferencedClass = currentlyInClass(def);
boolean isLocal = def.isLocal();
if ((inReferencedClass && isLocal || lambdaNewClassFilter(context(), tree))) {
TranslationContext<?> localContext = context();
while (localContext != null) {
if (localContext.tree.getTag() == LAMBDA) {
@ -1294,16 +1296,16 @@ public class LambdaToMethod extends TreeTranslator {
localContext = localContext.prev;
}
}
if (context() != null && tree.type.tsym.owner.kind == MTH) {
if (context() != null && !inReferencedClass && isLocal) {
LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context();
captureLocalClassDefs(tree.type.tsym, lambdaContext);
captureLocalClassDefs(def, lambdaContext);
}
super.visitNewClass(tree);
}
//where
void captureLocalClassDefs(Symbol csym, final LambdaTranslationContext lambdaContext) {
JCClassDecl localCDef = localClassDefs.get(csym);
if (localCDef != null && localCDef.pos < lambdaContext.tree.pos) {
if (localCDef != null && lambdaContext.freeVarProcessedLocalClasses.add(csym)) {
BasicFreeVarCollector fvc = lower.new BasicFreeVarCollector() {
@Override
void addFreeVars(ClassSymbol c) {
@ -1329,6 +1331,18 @@ public class LambdaToMethod extends TreeTranslator {
fvc.scan(localCDef);
}
}
//where
boolean currentlyInClass(Symbol csym) {
for (Frame frame : frameStack) {
if (frame.tree.hasTag(JCTree.Tag.CLASSDEF)) {
JCClassDecl cdef = (JCClassDecl) frame.tree;
if (cdef.sym == csym) {
return true;
}
}
}
return false;
}
/**
* Method references to local class constructors, may, if the local
@ -1754,6 +1768,11 @@ public class LambdaToMethod extends TreeTranslator {
List<JCVariableDecl> syntheticParams;
/**
* to prevent recursion, track local classes processed
*/
final Set<Symbol> freeVarProcessedLocalClasses;
LambdaTranslationContext(JCLambda tree) {
super(tree);
Frame frame = frameStack.head;
@ -1783,6 +1802,8 @@ public class LambdaToMethod extends TreeTranslator {
translatedSymbols.put(CAPTURED_VAR, new LinkedHashMap<Symbol, Symbol>());
translatedSymbols.put(CAPTURED_THIS, new LinkedHashMap<Symbol, Symbol>());
translatedSymbols.put(TYPE_VAR, new LinkedHashMap<Symbol, Symbol>());
freeVarProcessedLocalClasses = new HashSet<>();
}
/**
@ -1893,7 +1914,7 @@ public class LambdaToMethod extends TreeTranslator {
};
break;
case LOCAL_VAR:
ret = new VarSymbol(sym.flags() & FINAL, name, types.erasure(sym.type), translatedSym);
ret = new VarSymbol(sym.flags() & FINAL, name, sym.type, translatedSym);
((VarSymbol) ret).pos = ((VarSymbol) sym).pos;
break;
case PARAM:

View File

@ -564,7 +564,7 @@ public class Resolve {
tvars,
(MethodType)mt,
resultInfo,
m,
(MethodSymbol)m,
argtypes,
allowBoxing,
useVarargs,
@ -772,6 +772,7 @@ public class Resolve {
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
return nilMethodCheck;
}
}
/**
@ -783,6 +784,11 @@ public class Resolve {
void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
//do nothing - actual always compatible to formals
}
@Override
public String toString() {
return "arityMethodCheck";
}
};
List<Type> dummyArgs(int length) {
@ -868,6 +874,11 @@ public class Resolve {
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
return new MostSpecificCheck(strict, actuals);
}
@Override
public String toString() {
return "resolveMethodCheck";
}
};
/**
@ -899,7 +910,9 @@ public class Resolve {
@Override
public boolean compatible(Type found, Type req, Warner warn) {
found = pendingInferenceContext.asUndetVar(found);
req = infer.returnConstraintTarget(found, req);
if (found.hasTag(UNDETVAR) && req.isPrimitive()) {
req = types.boxedClass(req).type;
}
return super.compatible(found, req, warn);
}
@ -915,6 +928,11 @@ public class Resolve {
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
return new MostSpecificCheck(strict, actuals);
}
@Override
public String toString() {
return "MethodReferenceCheck";
}
}
/**
@ -954,6 +972,11 @@ public class Resolve {
public DeferredAttrContext deferredAttrContext() {
return deferredAttrContext;
}
@Override
public String toString() {
return "MethodCheckContext";
}
}
/**
@ -972,7 +995,12 @@ public class Resolve {
DeferredType dt = (DeferredType)found;
return dt.check(this);
} else {
return super.check(pos, chk.checkNonVoid(pos, types.capture(U(found.baseType()))));
Type uResult = U(found.baseType());
Type capturedType = pos == null || pos.getTree() == null ?
types.capture(uResult) :
checkContext.inferenceContext()
.cachedCapture(pos.getTree(), uResult, true);
return super.check(pos, chk.checkNonVoid(pos, capturedType));
}
}

View File

@ -82,8 +82,10 @@ public class FSInfo {
for (StringTokenizer st = new StringTokenizer(path);
st.hasMoreTokens(); ) {
String elt = st.nextToken();
File f = (parent == null ? new File(elt) : new File(parent, elt));
list.add(f);
try {
File f = parent == null ? new File(elt): new File(file.toURI().resolve(elt));
list.add(f);
} catch (IllegalArgumentException ex) {}
}
return list;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2014, 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
@ -2812,7 +2812,7 @@ public class Gen extends JCTree.Visitor {
}
private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) {
super(new LVTBits(), syms, names);
super(new LVTBits(), syms, names, false);
lvtInits = (LVTBits)inits;
this.lvtRanges = lvtRanges;
}

View File

@ -1627,6 +1627,10 @@ compiler.warn.diamond.redundant.args.1=\
compiler.warn.varargs.redundant.trustme.anno=\
Redundant {0} annotation. {1}
# 0: symbol
compiler.warn.access.to.sensitive.member.from.serializable.element=\
access to sensitive member {0} from serializable element can be publicly accessible to untrusted code
#####
## The following are tokens which are non-terminals in the language. They should

View File

@ -851,6 +851,8 @@ public class TreeInfo {
return symbol(((JCTypeApply) tree).clazz);
case ANNOTATED_TYPE:
return symbol(((JCAnnotatedType) tree).underlyingType);
case REFERENCE:
return ((JCMemberReference) tree).sym;
default:
return null;
}

View File

@ -113,6 +113,46 @@ public abstract class JavadocTester {
*/
private File outputDir;
/**
* Alternatives for checking the contents of a directory.
*/
enum DirectoryCheck {
/**
* Check that the directory is empty.
*/
EMPTY((file, name) -> true),
/**
* Check that the directory does not contain any HTML files,
* such as may have been generated by a prior run of javadoc
* using this directory.
* For now, the check is only performed on the top level directory.
*/
NO_HTML_FILES((file, name) -> name.endsWith(".html")),
/**
* No check is performed on the directory contents.
*/
NONE(null) { @Override void check(File dir) { } };
/** The filter used to detect that files should <i>not</i> be present. */
FilenameFilter filter;
DirectoryCheck(FilenameFilter f) {
filter = f;
}
void check(File dir) {
if (dir.isDirectory()) {
String[] contents = dir.list(filter);
if (contents == null)
throw new Error("cannot list directory: " + dir);
if (contents.length > 0)
throw new Error("directory has unexpected content: " + dir);
}
}
}
private DirectoryCheck outputDirectoryCheck = DirectoryCheck.EMPTY;
/**
* The current subtest number.
*/
@ -206,6 +246,8 @@ public abstract class JavadocTester {
}
}
outputDirectoryCheck.check(outputDir);
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
PrintStream prevOut = System.out;
System.setOut(new PrintStream(stdout));
@ -231,6 +273,15 @@ public abstract class JavadocTester {
return returnCode;
}
/**
* Set a filter to check the initial contents of the output directory
* before javadoc is run.
* The filter should return true for files that should <b>not</b> appear.
*/
public void setCheckOutputDirectoryCheck(DirectoryCheck c) {
outputDirectoryCheck = c;
}
/**
* Create new string writer buffers
*/

View File

@ -86,10 +86,12 @@ public class TestDocFileDir extends JavadocTester {
*/
public static void main(String[] args) {
TestDocFileDir tester = new TestDocFileDir();
tester.setCheckOutputDirectoryCheck(DirectoryCheck.NO_HTML_FILES);
copyDir(SRC_DIR + "/pkg", ".");
tester.run(ARGS0, TEST0, NO_TEST);
copyDir(SRC_DIR + "/pkg", OUTPUT_DIR + "-1");
tester.run(ARGS1, TEST1, NO_TEST);
tester.setCheckOutputDirectoryCheck(DirectoryCheck.NONE);
tester.run(ARGS2, NO_TEST, NO_TEST, FILE_TEST2, FILE_NEGATED_TEST2);
tester.printSummary();
}

View File

@ -58,7 +58,7 @@ public class TestGeneratedBy extends JavadocTester {
private static final String[] NO_TIMESTAMP_ARGS =
new String[] {
"-notimestamp",
"-d", OUTPUT_DIR,
"-d", OUTPUT_DIR + "-1",
"-sourcepath", SRC_DIR,
"pkg"
};

View File

@ -45,7 +45,7 @@ public class TestGroupOption extends JavadocTester {
};
private static final String[] ARGS2 = new String[] {
"-d", OUTPUT_DIR, "-sourcepath", SRC_DIR,
"-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR,
"-group", "Package One", "pkg1",
"-group", "Package One", "pkg2",
"-group", "Package One", "pkg3",

View File

@ -40,127 +40,134 @@ public class TestHtmlDefinitionListTag extends JavadocTester {
// Optional Element should print properly nested definition list tags
// for default value.
private static final String[][] TEST_ALL = {
{ "pkg1/C1.html", "<pre>public class " +
"<span class=\"typeNameLabel\">C1</span>\n" +
"extends java.lang.Object\n" +
"implements java.io.Serializable</pre>"},
{ "pkg1/C4.html", "<dl>\n" +
"<dt>Default:</dt>\n" +
"<dd>true</dd>\n" +
"</dl>"}};
{ "pkg1/C1.html",
"<pre>public class <span class=\"typeNameLabel\">C1</span>\n" +
"extends java.lang.Object\n" +
"implements java.io.Serializable</pre>"},
{ "pkg1/C4.html",
"<dl>\n" +
"<dt>Default:</dt>\n" +
"<dd>true</dd>\n" +
"</dl>"}};
// Test for normal run of javadoc in which various ClassDocs and
// serialized form should have properly nested definition list tags
// enclosing comments, tags and deprecated information.
private static final String[][] TEST_CMNT_DEPR = {
{ "pkg1/package-summary.html", "<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>JDK1.0</dd>\n" +
"</dl>"},
{ "pkg1/C1.html", "<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>JDK1.0</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span></dt>\n" +
"<dd><a href=\"../pkg1/C2.html\" title=\"class in pkg1\"><code>" +
"C2</code></a>, \n" +
"<a href=\"../serialized-form.html#pkg1.C1\">" +
"Serialized Form</a></dd>\n" +
"</dl>"},
{ "pkg1/C1.html", "<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>1.4</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span></dt>\n" +
"<dd>" +
"<a href=\"../pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "pkg1/C1.html", "<dl>\n" +
"<dt><span class=\"paramLabel\">Parameters:</span></dt>\n" +
"<dd><code>title" +
"</code> - the title</dd>\n" +
"<dd><code>test</code> - boolean value" +
"</dd>\n" +
"<dt><span class=\"throwsLabel\">Throws:</span></dt>\n" +
"<dd><code>java.lang.IllegalArgumentException</code> - if the " +
"<code>owner</code>'s\n" +
" <code>GraphicsConfiguration</code> is not from a screen " +
"device</dd>\n" +
"<dd><code>HeadlessException</code></dd>\n" +
"</dl>"},
{ "pkg1/C1.html", "<dl>\n" +
"<dt><span class=\"paramLabel\">Parameters:</span></dt>\n" +
"<dd><code>undecorated" +
"</code> - <code>true</code> if no decorations are\n" +
" to be enabled;\n" +
" <code>false</code> " +
"if decorations are to be enabled.</dd>\n" +
"<dt><span class=\"simpleTagLabel\">Since:" +
"</span></dt>\n" +
"<dd>1.4</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span></dt>\n" +
"<dd>" +
"<a href=\"../pkg1/C1.html#readObject--\"><code>readObject()" +
"</code></a></dd>\n" +
"</dl>"},
{ "pkg1/C1.html", "<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:</span></dt>\n" +
"<dd><code>java.io.IOException</code></dd>\n" +
"<dt><span class=\"seeLabel\">See Also:" +
"</span></dt>\n" +
"<dd><a href=\"../pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "pkg1/C2.html", "<dl>\n" +
"<dt><span class=\"paramLabel\">Parameters:" +
"</span></dt>\n" +
"<dd><code>set</code> - boolean</dd>\n" +
"<dt><span class=\"simpleTagLabel\">" +
"Since:</span></dt>\n" +
"<dd>1.4</dd>\n" +
"</dl>"},
{ "serialized-form.html", "<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:</span>" +
"</dt>\n" +
"<dd><code>" +
"java.io.IOException</code></dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span>" +
"</dt>\n" +
"<dd><a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>C1.setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "pkg1/package-summary.html",
"<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>JDK1.0</dd>\n" +
"</dl>"},
{ "pkg1/C1.html",
"<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>JDK1.0</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span></dt>\n" +
"<dd><a href=\"../pkg1/C2.html\" title=\"class in pkg1\"><code>" +
"C2</code></a>, \n" +
"<a href=\"../serialized-form.html#pkg1.C1\">" +
"Serialized Form</a></dd>\n" +
"</dl>"},
{ "pkg1/C1.html",
"<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>1.4</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span></dt>\n" +
"<dd><a href=\"../pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "pkg1/C1.html",
"<dl>\n" +
"<dt><span class=\"paramLabel\">Parameters:</span></dt>\n" +
"<dd><code>title</code> - the title</dd>\n" +
"<dd><code>test</code> - boolean value" +
"</dd>\n" +
"<dt><span class=\"throwsLabel\">Throws:</span></dt>\n" +
"<dd><code>java.lang.IllegalArgumentException</code> - if the " +
"<code>owner</code>'s\n" +
" <code>GraphicsConfiguration</code> is not from a screen " +
"device</dd>\n" +
"<dd><code>HeadlessException</code></dd>\n" +
"</dl>"},
{ "pkg1/C1.html",
"<dl>\n" +
"<dt><span class=\"paramLabel\">Parameters:</span></dt>\n" +
"<dd><code>undecorated" +
"</code> - <code>true</code> if no decorations are\n" +
" to be enabled;\n" +
" <code>false</code> " +
"if decorations are to be enabled.</dd>\n" +
"<dt><span class=\"simpleTagLabel\">Since:" +
"</span></dt>\n" +
"<dd>1.4</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span></dt>\n" +
"<dd>" +
"<a href=\"../pkg1/C1.html#readObject--\"><code>readObject()" +
"</code></a></dd>\n" +
"</dl>"},
{ "pkg1/C1.html",
"<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:</span></dt>\n" +
"<dd><code>java.io.IOException</code></dd>\n" +
"<dt><span class=\"seeLabel\">See Also:" +
"</span></dt>\n" +
"<dd><a href=\"../pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "pkg1/C2.html",
"<dl>\n" +
"<dt><span class=\"paramLabel\">Parameters:" +
"</span></dt>\n" +
"<dd><code>set</code> - boolean</dd>\n" +
"<dt><span class=\"simpleTagLabel\">" +
"Since:</span></dt>\n" +
"<dd>1.4</dd>\n" +
"</dl>"},
{ "serialized-form.html",
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;<span class=\"deprecationComment\">As of JDK version 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a>.</span></div>\n" +
"<div class=\"block\">This field indicates whether the C1 is " +
"undecorated.</div>\n" +
"&nbsp;\n" +
"<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>1.4</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span>" +
"</dt>\n" +
"<dd><a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>C1.setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
"<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:</span>" +
"</dt>\n" +
"<dd><code>" +
"java.io.IOException</code></dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span>" +
"</dt>\n" +
"<dd><a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>C1.setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "serialized-form.html",
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;<span class=\"deprecationComment\">As of JDK version 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a>.</span></div>\n" +
"<div class=\"block\">Reads the object stream.</div>\n" +
"<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:" +
"</span></dt>\n" +
"<dd><code><code>" +
"IOException</code></code></dd>\n" +
"<dd><code>java.io.IOException</code></dd>\n" +
"</dl>"},
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;<span class=\"deprecationComment\">As of JDK version 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a>.</span></div>\n" +
"<div class=\"block\">This field indicates whether the C1 is " +
"undecorated.</div>\n" +
"&nbsp;\n" +
"<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>1.4</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span>" +
"</dt>\n" +
"<dd><a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>C1.setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "serialized-form.html",
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;</div>\n" +
"<div class=\"block\">The name for this class.</div>"}};
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;<span class=\"deprecationComment\">As of JDK version 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a>.</span></div>\n" +
"<div class=\"block\">Reads the object stream.</div>\n" +
"<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:" +
"</span></dt>\n" +
"<dd><code><code>" +
"IOException</code></code></dd>\n" +
"<dd><code>java.io.IOException</code></dd>\n" +
"</dl>"},
{ "serialized-form.html",
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;</div>\n" +
"<div class=\"block\">The name for this class.</div>"}};
// Test with -nodeprecated option. The ClassDocs should have properly nested
// definition list tags enclosing comments and tags. The ClassDocs should not
@ -168,183 +175,210 @@ public class TestHtmlDefinitionListTag extends JavadocTester {
// should display properly nested definition list tags for comments, tags
// and deprecated information.
private static final String[][] TEST_NODEPR = {
{ "pkg1/package-summary.html", "<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>JDK1.0</dd>\n" +
"</dl>"},
{ "pkg1/C1.html", "<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span>" +
"</dt>\n" +
"<dd>JDK1.0</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:" +
"</span></dt>\n" +
"<dd><a href=\"../pkg1/C2.html\" title=\"class in pkg1\">" +
"<code>C2</code></a>, \n" +
"<a href=\"../serialized-form.html#pkg1.C1\">" +
"Serialized Form</a></dd>\n" +
"</dl>"},
{ "pkg1/C1.html", "<dl>\n" +
"<dt><span class=\"paramLabel\">Parameters:" +
"</span></dt>\n" +
"<dd><code>title</code> - the title</dd>\n" +
"<dd><code>" +
"test</code> - boolean value</dd>\n" +
"<dt><span class=\"throwsLabel\">Throws:" +
"</span></dt>\n" +
"<dd><code>java.lang.IllegalArgumentException" +
"</code> - if the <code>owner</code>'s\n" +
" <code>GraphicsConfiguration" +
"</code> is not from a screen device</dd>\n" +
"<dd><code>" +
"HeadlessException</code></dd>\n" +
"</dl>"},
{ "pkg1/C1.html", "<dl>\n" +
"<dt><span class=\"paramLabel\">Parameters:" +
"</span></dt>\n" +
"<dd><code>undecorated</code> - <code>true</code>" +
" if no decorations are\n" +
" to be enabled;\n" +
" <code>false</code> if decorations are to be enabled." +
"</dd>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>1.4</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span></dt>\n" +
"<dd><a href=\"../pkg1/C1.html#readObject--\">" +
"<code>readObject()</code></a></dd>\n" +
"</dl>"},
{ "pkg1/C1.html", "<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:</span>" +
"</dt>\n" +
"<dd><code>java.io.IOException</code></dd>\n" +
"<dt>" +
"<span class=\"seeLabel\">See Also:</span></dt>\n" +
"<dd><a href=\"../pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "serialized-form.html", "<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:</span>" +
"</dt>\n" +
"<dd><code>" +
"java.io.IOException</code></dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span>" +
"</dt>\n" +
"<dd><a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>C1.setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "pkg1/package-summary.html",
"<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>JDK1.0</dd>\n" +
"</dl>"},
{ "pkg1/C1.html",
"<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span>" +
"</dt>\n" +
"<dd>JDK1.0</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:" +
"</span></dt>\n" +
"<dd><a href=\"../pkg1/C2.html\" title=\"class in pkg1\">" +
"<code>C2</code></a>, \n" +
"<a href=\"../serialized-form.html#pkg1.C1\">" +
"Serialized Form</a></dd>\n" +
"</dl>"},
{ "pkg1/C1.html",
"<dl>\n" +
"<dt><span class=\"paramLabel\">Parameters:" +
"</span></dt>\n" +
"<dd><code>title</code> - the title</dd>\n" +
"<dd><code>" +
"test</code> - boolean value</dd>\n" +
"<dt><span class=\"throwsLabel\">Throws:" +
"</span></dt>\n" +
"<dd><code>java.lang.IllegalArgumentException" +
"</code> - if the <code>owner</code>'s\n" +
" <code>GraphicsConfiguration" +
"</code> is not from a screen device</dd>\n" +
"<dd><code>" +
"HeadlessException</code></dd>\n" +
"</dl>"},
{ "pkg1/C1.html",
"<dl>\n" +
"<dt><span class=\"paramLabel\">Parameters:" +
"</span></dt>\n" +
"<dd><code>undecorated</code> - <code>true</code>" +
" if no decorations are\n" +
" to be enabled;\n" +
" <code>false</code> if decorations are to be enabled." +
"</dd>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>1.4</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span></dt>\n" +
"<dd><a href=\"../pkg1/C1.html#readObject--\">" +
"<code>readObject()</code></a></dd>\n" +
"</dl>"},
{ "pkg1/C1.html",
"<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:</span>" +
"</dt>\n" +
"<dd><code>java.io.IOException</code></dd>\n" +
"<dt>" +
"<span class=\"seeLabel\">See Also:</span></dt>\n" +
"<dd><a href=\"../pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "serialized-form.html",
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;<span class=\"deprecationComment\">As of JDK version 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a>.</span></div>\n" +
"<div class=\"block\">This field indicates whether the C1 is " +
"undecorated.</div>\n" +
"&nbsp;\n" +
"<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>1.4</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span>" +
"</dt>\n" +
"<dd><a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>C1.setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
"<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:</span>" +
"</dt>\n" +
"<dd><code>" +
"java.io.IOException</code></dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span>" +
"</dt>\n" +
"<dd><a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>C1.setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "serialized-form.html",
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;<span class=\"deprecationComment\">As of JDK version 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a>.</span></div>\n" +
"<div class=\"block\">Reads the object stream.</div>\n" +
"<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:" +
"</span></dt>\n" +
"<dd><code><code>" +
"IOException</code></code></dd>\n" +
"<dd><code>java.io.IOException</code></dd>\n" +
"</dl>"},
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;<span class=\"deprecationComment\">As of JDK version 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a>.</span></div>\n" +
"<div class=\"block\">This field indicates whether the C1 is " +
"undecorated.</div>\n" +
"&nbsp;\n" +
"<dl>\n" +
"<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n" +
"<dd>1.4</dd>\n" +
"<dt><span class=\"seeLabel\">See Also:</span>" +
"</dt>\n" +
"<dd><a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>C1.setUndecorated(boolean)</code></a></dd>\n" +
"</dl>"},
{ "serialized-form.html",
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;</div>\n" +
"<div class=\"block\">" +
"The name for this class.</div>"}};
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;<span class=\"deprecationComment\">As of JDK version 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a>.</span></div>\n" +
"<div class=\"block\">Reads the object stream.</div>\n" +
"<dl>\n" +
"<dt><span class=\"throwsLabel\">Throws:" +
"</span></dt>\n" +
"<dd><code><code>" +
"IOException</code></code></dd>\n" +
"<dd><code>java.io.IOException</code></dd>\n" +
"</dl>"},
{ "serialized-form.html",
"<span class=\"deprecatedLabel\">Deprecated.</span>" +
"&nbsp;</div>\n" +
"<div class=\"block\">" +
"The name for this class.</div>"}};
// Test with -nocomment and -nodeprecated options. The ClassDocs whould
// not display definition lists for any member details.
private static final String[][] TEST_NOCMNT_NODEPR = {
{ "pkg1/C1.html",
"<pre>public&nbsp;void&nbsp;readObject()\n" +
" throws java.io.IOException</pre>\n" +
"</li>"},
"<pre>public&nbsp;void&nbsp;readObject()\n" +
" throws java.io.IOException</pre>\n" +
"</li>"},
{ "pkg1/C2.html", "<pre>public&nbsp;C2()</pre>\n" +
"</li>"},
"</li>"},
{ "pkg1/C1.ModalExclusionType.html", "<pre>public " +
"static final&nbsp;<a href=\"../pkg1/C1.ModalExclusionType.html\" " +
"title=\"enum in pkg1\">C1.ModalExclusionType</a> " +
"APPLICATION_EXCLUDE</pre>\n" +
"</li>"},
"static final&nbsp;<a href=\"../pkg1/C1.ModalExclusionType.html\" " +
"title=\"enum in pkg1\">C1.ModalExclusionType</a> " +
"APPLICATION_EXCLUDE</pre>\n" +
"</li>"},
{ "serialized-form.html", "<pre>boolean " +
"undecorated</pre>\n" +
"<div class=\"block\"><span class=\"deprecatedLabel\">" +
"Deprecated.</span>&nbsp;<span class=\"deprecationComment\">As of JDK version 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\"><code>" +
"setUndecorated(boolean)</code></a>.</span></div>\n" +
"</li>"},
"undecorated</pre>\n" +
"<div class=\"block\"><span class=\"deprecatedLabel\">" +
"Deprecated.</span>&nbsp;<span class=\"deprecationComment\">As of JDK version 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\"><code>" +
"setUndecorated(boolean)</code></a>.</span></div>\n" +
"</li>"},
{ "serialized-form.html", "<span class=\"deprecatedLabel\">" +
"Deprecated.</span>&nbsp;<span class=\"deprecationComment\">As of JDK version" +
" 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a>.</span></div>\n" +
"</li>"}};
"Deprecated.</span>&nbsp;<span class=\"deprecationComment\">As of JDK version" +
" 1.5, replaced by\n" +
" <a href=\"pkg1/C1.html#setUndecorated-boolean-\">" +
"<code>setUndecorated(boolean)</code></a>.</span></div>\n" +
"</li>"}};
// Test for valid HTML generation which should not comprise of empty
// definition list tags.
private static final String[][] NEGATED_TEST = {
{ "pkg1/package-summary.html", "<dl></dl>"},
{ "pkg1/package-summary.html", "<dl>\n" +
"</dl>"},
{ "pkg1/C1.html", "<dl></dl>"},
{ "pkg1/C1.html", "<dl>\n" +
"</dl>"},
{ "pkg1/C1.ModalExclusionType.html", "<dl></dl>"},
{ "pkg1/C1.ModalExclusionType.html", "<dl>\n" +
"</dl>"},
{ "pkg1/C2.html", "<dl></dl>"},
{ "pkg1/C2.html", "<dl>\n" +
"</dl>"},
{ "pkg1/C2.ModalType.html", "<dl></dl>"},
{ "pkg1/C2.ModalType.html", "<dl>\n" +
"</dl>"},
{ "pkg1/C3.html", "<dl></dl>"},
{ "pkg1/C3.html", "<dl>\n" +
"</dl>"},
{ "pkg1/C4.html", "<dl></dl>"},
{ "pkg1/C4.html", "<dl>\n" +
"</dl>"},
{ "pkg1/C5.html", "<dl></dl>"},
{ "pkg1/C5.html", "<dl>\n" +
"</dl>"},
{ "overview-tree.html", "<dl></dl>"},
{ "overview-tree.html", "<dl>\n" +
"</dl>"},
{ "serialized-form.html", "<dl></dl>"},
{ "serialized-form.html", "<dl>\n" +
"</dl>"}};
private static final String[][] NEGATED_TEST_NO_C5 = {
{ "pkg1/package-summary.html",
"<dl></dl>"},
{ "pkg1/package-summary.html",
"<dl>\n" +
"</dl>"},
{ "pkg1/C1.html",
"<dl></dl>"},
{ "pkg1/C1.html",
"<dl>\n" +
"</dl>"},
{ "pkg1/C1.ModalExclusionType.html",
"<dl></dl>"},
{ "pkg1/C1.ModalExclusionType.html",
"<dl>\n" +
"</dl>"},
{ "pkg1/C2.html",
"<dl></dl>"},
{ "pkg1/C2.html",
"<dl>\n" +
"</dl>"},
{ "pkg1/C2.ModalType.html",
"<dl></dl>"},
{ "pkg1/C2.ModalType.html",
"<dl>\n" +
"</dl>"},
{ "pkg1/C3.html",
"<dl></dl>"},
{ "pkg1/C3.html",
"<dl>\n" +
"</dl>"},
{ "pkg1/C4.html",
"<dl></dl>"},
{ "pkg1/C4.html",
"<dl>\n" +
"</dl>"},
{ "overview-tree.html",
"<dl></dl>"},
{ "overview-tree.html",
"<dl>\n" +
"</dl>"},
{ "serialized-form.html",
"<dl></dl>"},
{ "serialized-form.html",
"<dl>\n" +
"</dl>"}};
private static final String[][] NEGATED_TEST_C5 = {
{ "pkg1/C5.html",
"<dl></dl>"},
{ "pkg1/C5.html",
"<dl>\n" +
"</dl>"}};
private static final String[] ARGS1 =
new String[] {
"-Xdoclint:none", "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1"};
"-Xdoclint:none", "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS2 =
new String[] {
"-Xdoclint:none", "-d", OUTPUT_DIR, "-nocomment", "-sourcepath",
"-Xdoclint:none", "-d", OUTPUT_DIR + "-2", "-nocomment", "-sourcepath",
SRC_DIR, "pkg1"};
private static final String[] ARGS3 =
new String[] {
"-Xdoclint:none", "-d", OUTPUT_DIR, "-nodeprecated", "-sourcepath",
"-Xdoclint:none", "-d", OUTPUT_DIR + "-3", "-nodeprecated", "-sourcepath",
SRC_DIR, "pkg1"};
private static final String[] ARGS4 =
new String[] {
"-Xdoclint:none", "-d", OUTPUT_DIR, "-nocomment", "-nodeprecated",
"-Xdoclint:none", "-d", OUTPUT_DIR + "-4", "-nocomment", "-nodeprecated",
"-sourcepath", SRC_DIR, "pkg1"};
/**
@ -353,14 +387,20 @@ public class TestHtmlDefinitionListTag extends JavadocTester {
*/
public static void main(String[] args) {
TestHtmlDefinitionListTag tester = new TestHtmlDefinitionListTag();
tester.run(ARGS1, TEST_ALL, NEGATED_TEST);
tester.run(ARGS1, TEST_CMNT_DEPR, NEGATED_TEST);
tester.run(ARGS2, TEST_ALL, NEGATED_TEST);
tester.run(ARGS2, NO_TEST, TEST_CMNT_DEPR);
tester.run(ARGS3, TEST_ALL, NEGATED_TEST);
tester.run(ARGS3, TEST_NODEPR, TEST_NOCMNT_NODEPR);
tester.run(ARGS4, TEST_ALL, NEGATED_TEST);
tester.run(ARGS4, TEST_NOCMNT_NODEPR, TEST_CMNT_DEPR);
tester.run(ARGS1, TEST_ALL, NEGATED_TEST_NO_C5);
tester.runTestsOnHTML(NO_TEST, NEGATED_TEST_C5);
tester.runTestsOnHTML(TEST_CMNT_DEPR, NO_TEST);
tester.run(ARGS2, TEST_ALL, NEGATED_TEST_NO_C5);
tester.runTestsOnHTML(NO_TEST, NEGATED_TEST_C5);
tester.runTestsOnHTML(NO_TEST, TEST_CMNT_DEPR);
tester.run(ARGS3, TEST_ALL, NEGATED_TEST_NO_C5);
tester.runTestsOnHTML(TEST_NODEPR, TEST_NOCMNT_NODEPR);
tester.run(ARGS4, TEST_ALL, NEGATED_TEST_NO_C5);
tester.runTestsOnHTML(TEST_NOCMNT_NODEPR, TEST_CMNT_DEPR);
tester.printSummary();
}
}

View File

@ -47,16 +47,14 @@ public class TestHtmlStrongTag extends JavadocTester {
private static final String[][] TEST2 = {
{ "pkg2/C2.html", "<B>Comments:</B>"}};
private static final String[][] NEGATED_TEST2 = {
{ "pkg2/C2.html", "<STRONG>Method Summary</STRONG>"},
{ "pkg1/package-summary.html",
"<STRONG>Class Summary</STRONG>"}};
{ "pkg2/C2.html", "<STRONG>Method Summary</STRONG>"}};
private static final String[] ARGS1 =
new String[] {
"-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1"};
"-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS2 =
new String[] {
"-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg2"};
"-d", OUTPUT_DIR + "-2", "-sourcepath", SRC_DIR, "pkg2"};
/**
* The entry point of the test.

View File

@ -58,13 +58,13 @@ public class TestHtmlTag extends JavadocTester {
private static final String[] ARGS1 =
new String[] {
"-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1"};
"-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS2 =
new String[] {
"-locale", "ja", "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg2"};
"-locale", "ja", "-d", OUTPUT_DIR + "-2", "-sourcepath", SRC_DIR, "pkg2"};
private static final String[] ARGS3 =
new String[] {
"-locale", "en_US", "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1"};
"-locale", "en_US", "-d", OUTPUT_DIR + "-3", "-sourcepath", SRC_DIR, "pkg1"};
/**
* The entry point of the test.

View File

@ -79,8 +79,8 @@ public class TestLinkOption extends JavadocTester {
private static final String[][] TEST2 = {
{ "pkg2/C2.html",
"This is a link to <a href=\"../../" + OUTPUT_DIR +
"-1/pkg/C.html?is-external=true\" " +
"This is a link to <a href=\"../../" +
OUTPUT_DIR + "-1/pkg/C.html?is-external=true\" " +
"title=\"class or interface in pkg\"><code>Class C</code></a>."
}
};
@ -119,7 +119,6 @@ public class TestLinkOption extends JavadocTester {
public static void main(String[] args) {
TestLinkOption tester = new TestLinkOption();
tester.run(ARGS1, TEST1, NEGATED_TEST1);
tester.run(ARGS1, TEST1, NEGATED_TEST1);
tester.run(ARGS2, TEST2, NO_TEST);
tester.runJavadoc(createArguments(true)); // with trailing slash
tester.runJavadoc(createArguments(false)); // without trailing slash

View File

@ -67,7 +67,9 @@ public class TestNotifications extends JavadocTester {
tester.run(ARGS, TEST, NO_TEST);
// No need to notify that the destination must be created because
// it already exists.
tester.setCheckOutputDirectoryCheck(DirectoryCheck.NONE);
tester.run(ARGS, NO_TEST, NEGATED_TEST);
tester.setCheckOutputDirectoryCheck(DirectoryCheck.NO_HTML_FILES);
//Make sure classname is not include in javadoc usage message.
tester.run(ARGS2, NO_TEST, NEGATED_TEST2);
tester.printSummary();

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2014, 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.
*/
/**
* Class in an unnamed package.
*/
public class C {
/**
* A ctor
* @param c a param
*/
public C(UsedInC c){}
/**
* another ctor
* @param c a param
* @param s a param
*/
public C(UsedInC c, String s) {}
/**
* yet another ctor
* @param c a param
* @param i a param
*/
public C(UsedInC c, int i) {}
/**
* Field in C.
*/
public UsedInC fieldInC;
/**
* Method in C.
* @param p a param
* @return UsedInC
*/
public UsedInC methodInC(UsedInC p) { return p;}
/**
* A static method
* @param s a param
* @return UsedInC
*/
public static UsedInC ymethod(String s) {return null;}
/**
* Another static method variant
* @param value a param
* @return UsedInC
*/
public static UsedInC ymethod(int value) {return -1;}
}

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2014, 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 8039410
* @summary test to determine if members are ordered correctly
* @author ksrini
* @library ../lib/
* @build JavadocTester
* @build TestOrdering
* @run main TestOrdering
*/
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestOrdering extends JavadocTester {
/**
* The entry point of the test.
* @param args the array of command line arguments.
*/
public static void main(String[] args) throws Exception {
TestOrdering tester = new TestOrdering();
// test unnamed packages
String[] ARGS = {
"-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-use",
SRC_DIR + "/C.java", SRC_DIR + "/UsedInC.java"
};
tester.runJavadoc(ARGS);
checkExecutableMemberOrdering(tester.readFileToString("class-use/UsedInC.html"));
// next test using packages
String[] ARGS1 = {
"-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "-use",
"pkg1"
};
tester.runJavadoc(ARGS1);
checkClassUseOrdering(tester.readFileToString("pkg1/class-use/UsedClass.html"));
checkIndexPathOrdering(tester.readFileToString("index-all.html"));
}
static void checkExecutableMemberOrdering(String usePage) {
// check constructors
int idx1 = usePage.indexOf("C.html#C-UsedInC");
int idx2 = usePage.indexOf("C.html#C-UsedInC-int");
int idx3 = usePage.indexOf("C.html#C-UsedInC-java.lang.String");
if (idx1 == -1 || idx2 == -1 || idx3 == -1) {
throw new Error("ctor strings not found");
}
if (idx1 > idx2 || idx2 > idx3 || idx1 > idx3) {
throw new Error("ctor strings are out of order");
}
// check methods
idx1 = usePage.indexOf("C.html#ymethod-int");
idx2 = usePage.indexOf("C.html#ymethod-java.lang.String");
if (idx1 == -1 || idx2 == -1) {
throw new Error("#ymethod strings not found");
}
if (idx1 > idx2) {
throw new Error("#ymethod strings are out of order");
}
System.out.println("Executable Member Ordering: OK");
}
static void checkClassUseOrdering(String usePage) {
checkClassUseOrdering(usePage, "pkg1/C#ITERATION#.html#zfield");
checkClassUseOrdering(usePage, "pkg1/C#ITERATION#.html#fieldInC#ITERATION#");
checkClassUseOrdering(usePage, "pkg1/C#ITERATION#.html#zmethod-pkg1.UsedClass");
checkClassUseOrdering(usePage, "pkg1/C#ITERATION#.html#methodInC#ITERATION#");
}
static void checkClassUseOrdering(String usePage, String searchString) {
int lastidx = 0;
System.out.println("testing for " + searchString);
for (int i = 1; i < 5; i++) {
String s = searchString.replaceAll("#ITERATION#", Integer.toString(i));
System.out.println(s);
int idx = usePage.indexOf(s);
if (idx < lastidx) {
throw new Error(s + ", member ordering error, last:" + lastidx + ", got:" + idx);
}
System.out.println("\tlast: " + lastidx + " got:" + idx);
lastidx = idx;
}
}
static void checkIndexPathOrdering(String indexPage) {
String[] OrderedExpectedStrings = {
"pkg1/UsedClass.html#add-java.lang.Double",
"pkg1/ZZTop.html#add-double",
"pkg1/ZZTop.html#add-java.lang.Double",
"pkg1/UsedClass.html#add-float",
"pkg1/ZZTop.html#add-float",
"pkg1/UsedClass.html#add-int",
"pkg1/ZZTop.html#add-int",
"pkg1/UsedClass.html#add-java.lang.Integer",
"pkg1/ZZTop.html#add-java.lang.Integer",
"pkg1/UsedClass.html#add-double-double",
"pkg1/UsedClass.html#add-double-java.lang.Double",
"pkg1/ZZTop.html#add-double-double",
"pkg1/ZZTop.html#add-double-java.lang.Double"
};
int lastidx = 0;
for (String x : OrderedExpectedStrings) {
int idx = indexPage.indexOf(x);
if (idx < lastidx) {
throw new Error(x + ", index is out of order, last:" + lastidx + ", got:" + idx);
}
System.out.println(x + ": OK");
lastidx = idx;
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2014, 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.
*/
/**
* An empty class
*/
public class UsedInC {}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2014, 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;
/**
* C1
*/
public class C1 {
/**
* Field in C1.
*/
public UsedClass fieldInC1;
/**
* A duplicated field
*/
public UsedClass zfield;
/**
* Method in C1.
* @param p a param
* @return UsedClass
*/
public UsedClass methodInC1(UsedClass p) {return p;}
/**
* A duplicated method to test ordering
* @param p a param
* @return UsedClass
*/
public UsedClass zmethod(UsedClass p) {return p;}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2014, 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 class C2 {
/**
* Field in C2.
*/
public UsedClass fieldInC2;
/**
* another field
*/
public C1 field = null;
/**
* A duplicated field
*/
public UsedClass zfield;
/**
* Method in C2.
* @return C1
*/
public C1 methodInC2() {return null;}
/**
* @param c1 a param
*/
public void method(pkg1.C1 c1) {}
/**
* Method in C2.
* @param p a param
* @return UsedClass
*/
public UsedClass methodInC2(UsedClass p) {return p;}
/**
* A duplicated method to test ordering
* @param p a param
* @return UsedClass
*/
public UsedClass zmethod(UsedClass p) {
return p;
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2014, 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 class C3 {
/**
* Field in C3.
*/
public UsedClass fieldInC3;
/**
* A duplicated field
*/
public UsedClass zfield;
/**
* Method in C3.
* @param p a param
* @return UsedClass
*/
public UsedClass methodInC3(UsedClass p) {return p;}
/**
* A duplicated method to test ordering
* @param p a param
* @return UsedClass
*/
public UsedClass zmethod(UsedClass p) {return p;}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2014, 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 class C4 {
/**
* Field in C4.
*/
public UsedClass fieldInC4;
/**
* A duplicated field
*/
public UsedClass zfield;
/**
* Method in C4.
* @param p a param
* @return UsedClass
*/
public UsedClass methodInC4(UsedClass p) {return p;}
/**
* A duplicated method to test ordering
* @param p a param
* @return UsedClass
*/
public UsedClass zmethod(UsedClass p) {return p;}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2014, 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;
/**
* For index and class-use testing
*/
public class UsedClass {
// This is the exact order we expect to see
/**
* @param i param
*/
public void add(int i){}
/**
* @param i param
* @return double
*/
public int add(Integer i) {return 0;}
/**
* @param d param
*/
public void add(double d){}
/**
* @param d param
* @return Double
*/
public Double add(Double d) {return (double) 22/7;}
/**
* @param f param
* @return Float
*/
public Float add(float f) {return (float) 22/7;}
/**
* @param d1 param
* @param d2 param
* @return double
*/
public double add(double d1, double d2) {return d1 + d2;}
/**
* @param d1 param
* @param d2 param
* @return double
*/
public double add(double d1, Double d2) {return d1 + d2;}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2014, 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;
/**
* For index testing only
*/
public class ZZTop {
// This is the exact order we expect to see
/**
* @param i param
*/
public void add(int i){}
/**
* @param i param
* @return double
*/
public int add(Integer i) {return 0;}
/**
* @param d param
*/
public void add(double d){}
/**
* @param d param
* @return Double
*/
public Double add(Double d) {return (double) 22/7;}
/**
* @param f param
* @return Float
*/
public Float add(float f) {return (float) 22/7;}
/**
* @param d1 param
* @param d2 param
* @return double
*/
public double add(double d1, double d2) {return d1 + d2;}
/**
* @param d1 param
* @param d2 param
* @return double
*/
public double add(double d1, Double d2) {return d1 + d2;}
}

View File

@ -115,19 +115,19 @@ public class TestSerializedFormDeprecationInfo extends JavadocTester {
private static final String[] ARGS1 =
new String[] {
"-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1"};
"-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS2 =
new String[] {
"-d", OUTPUT_DIR, "-nocomment", "-sourcepath", SRC_DIR, "pkg1"};
"-d", OUTPUT_DIR + "-2", "-nocomment", "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS3 =
new String[] {
"-d", OUTPUT_DIR, "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
"-d", OUTPUT_DIR + "-3", "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS4 =
new String[] {
"-d", OUTPUT_DIR, "-nocomment", "-nodeprecated", "-sourcepath",
"-d", OUTPUT_DIR + "-4", "-nocomment", "-nodeprecated", "-sourcepath",
SRC_DIR, "pkg1"};
/**

View File

@ -35,11 +35,11 @@ public class TestSinceTag extends JavadocTester {
//Javadoc arguments.
private static final String[] ARGS1 = new String[] {
"-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg1"
"-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg1"
};
private static final String[] ARGS2 = new String[] {
"-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "-nosince", "pkg1"
"-d", OUTPUT_DIR + "-2", "-sourcepath", SRC_DIR, "-nosince", "pkg1"
};
//Input for string search tests.

View File

@ -39,11 +39,11 @@ public class TestTypeParameters extends JavadocTester {
//Javadoc arguments.
private static final String[] ARGS1 = new String[]{
"-d", OUTPUT_DIR, "-use", "-sourcepath", SRC_DIR,
"-d", OUTPUT_DIR + "-1", "-use", "-sourcepath", SRC_DIR,
"pkg"
};
private static final String[] ARGS2 = new String[]{
"-d", OUTPUT_DIR, "-linksource", "-sourcepath", SRC_DIR,
"-d", OUTPUT_DIR + "-2", "-linksource", "-sourcepath", SRC_DIR,
"pkg"
};

View File

@ -40,11 +40,11 @@ public class TestWarnings extends JavadocTester {
//Javadoc arguments.
private static final String[] ARGS = new String[] {
"-Xdoclint:none", "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg"
"-Xdoclint:none", "-d", OUTPUT_DIR + "-1", "-sourcepath", SRC_DIR, "pkg"
};
private static final String[] ARGS2 = new String[] {
"-Xdoclint:none", "-d", OUTPUT_DIR, "-private", "-sourcepath", SRC_DIR,
"-Xdoclint:none", "-d", OUTPUT_DIR + "-2", "-private", "-sourcepath", SRC_DIR,
"pkg"
};
@ -78,7 +78,6 @@ public class TestWarnings extends JavadocTester {
public static void main(String[] args) {
TestWarnings tester = new TestWarnings();
tester.run(ARGS, TEST, NEGATED_TEST);
tester.run(ARGS, TEST, NEGATED_TEST);
tester.run(ARGS2, TEST2, NO_TEST);
tester.printSummary();
}

View File

@ -0,0 +1,21 @@
/*
* @test /nodynamiccopyright/
* @bug 8039026
* @summary Definitely unassigned field can be accessed
* @compile/fail/ref=T8039026.out -XDrawDiagnostics T8039026.java
*/
public class T8039026 {
final int x,y,z;
final int a = this.y; // <- error
{
int b = true ? this.x : 0; // <- error
System.out.println(this.x); // <- error
this.y = 1;
}
T8039026() {
this.x = 1; // <- no error!
this.y = 1; // <- error
this.z = this.x; // <- no error
}
}

View File

@ -0,0 +1,4 @@
T8039026.java:10:23: compiler.err.var.might.not.have.been.initialized: y
T8039026.java:12:28: compiler.err.var.might.not.have.been.initialized: x
T8039026.java:18:13: compiler.err.var.might.already.be.assigned: y
3 errors

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2014, 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 8030046
* @summary javac incorrectly handles absolute paths in manifest classpath
* @author govereau
* @library /tools/javac/lib
* @build ToolBox
* @run main AbsolutePathTest
*/
import java.io.File;
public class AbsolutePathTest {
public static void main(String... cmdline) throws Exception {
// compile test.Test
ToolBox.JavaToolArgs args = new ToolBox.JavaToolArgs();
args.appendArgs("-d", "."); // this is needed to get the classfiles in test
ToolBox.javac(args.setSources("package test; public class Test{}"));
// build test.jar containing test.Test
// we need the jars in a directory different from the working
// directory to trigger the bug. I will reuse test/
ToolBox.jar("cf", "test/test.jar", "test/Test.class");
// build second jar in test directory using
// an absolute path reference to the first jar
String path = new File("test/test.jar").getAbsolutePath();
ToolBox.mkManifestWithClassPath(null, path);
ToolBox.jar("cfm", "test/test2.jar", "MANIFEST.MF");
// this should not fail
args.appendArgs("-cp", ".");
ToolBox.javac(args.setSources("import test.Test; class Test2 {}"));
}
}

View File

@ -0,0 +1,241 @@
/*
* @test /nodynamiccopyright/
* @bug 8029102
* @summary Enhance compiler warnings for Lambda
* Checks that the warning for accessing non public members of a class is
* fired correctly.
* @compile/fail/ref=WarnSerializableLambdaTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTest.java
*/
import java.io.Serializable;
public class WarnSerializableLambdaTest {
void warnLambda() throws Exception {
SAM t3 = (SAM & Serializable)WarnSerializableLambdaTest::packageClassMethod;
SAM t4 = (SAM & Serializable)WarnSerializableLambdaTest::protectedClassMethod;
SAM t5 = (SAM & Serializable)WarnSerializableLambdaTest::privateClassMethod;
WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
SAM t6 = (SAM & Serializable)test::packageInstanceMethod;
SAM t7 = (SAM & Serializable)test::protectedInstanceMethod;
SAM t8 = (SAM & Serializable)test::privateInstanceMethod;
SAM t9 = (SAM & Serializable) c -> {
WarnSerializableLambdaTest.staticPackageField = "";
WarnSerializableLambdaTest.staticProtectedField = "";
WarnSerializableLambdaTest.staticPrivateField = "";
packageField = "";
protectedField = "";
privateField = "";
WarnSerializableLambdaTest.packageClassMethod(null);
WarnSerializableLambdaTest.protectedClassMethod(null);
WarnSerializableLambdaTest.privateClassMethod(null);
packageInstanceMethod(null);
protectedInstanceMethod(null);
privateInstanceMethod(null);
PrivateClass.effectivelyNonPublicStaticField = "";
PrivateClass.effectivelyNonPublicClassMethod();
PrivateClass p = new PrivateClass();
p.effectivelyNonPublicInstanceField = "";
p.effectivelyNonPublicInstanceMethod();
return null;
};
}
private void warnAnoInnerClass() throws Exception {
new SerializableDesc() {
public void m(Object param) throws Exception {
WarnSerializableLambdaTest.staticPackageField = "";
WarnSerializableLambdaTest.staticProtectedField = "";
WarnSerializableLambdaTest.staticPrivateField = "";
packageField = "";
protectedField = "";
privateField = "";
WarnSerializableLambdaTest.packageClassMethod(null);
WarnSerializableLambdaTest.protectedClassMethod(null);
WarnSerializableLambdaTest.privateClassMethod(null);
packageInstanceMethod(null);
protectedInstanceMethod(null);
privateInstanceMethod(null);
PrivateClass.effectivelyNonPublicStaticField = "";
PrivateClass.effectivelyNonPublicClassMethod();
PrivateClass p = new PrivateClass();
p.effectivelyNonPublicInstanceField = "";
p.effectivelyNonPublicInstanceMethod();
}
};
}
void dontWarnLambda() throws Exception {
SAM t1 = (SAM & Serializable)WarnSerializableLambdaTest::publicClassMethod;
WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
SAM t2 = (SAM & Serializable)test::publicInstanceMethod;
int[] buffer = {0};
SAM t3 = (SAM & Serializable) param -> {
Object localVar;
localVar = null;
param = null;
WarnSerializableLambdaTest.staticPublicField = "";
publicField = "";
WarnSerializableLambdaTest.publicClassMethod(null);
publicInstanceMethod(null);
PublicClass.effectivelyPublicStaticField = "";
PublicClass.effectivelyPublicClassMethod();
PublicClass p = new PublicClass();
p.effectivelyPublicInstanceField = "";
p.effectivelyPublicInstanceMethod();
int l = buffer.length;
return null;
};
}
private void dontWarnAnoInnerClass() throws Exception {
final int[] buffer = {0};
new SerializableDesc() {
public void m(Object param) throws Exception {
Object localVar;
localVar = null;
param = null;
WarnSerializableLambdaTest.staticPublicField = "";
publicField = "";
WarnSerializableLambdaTest.publicClassMethod(null);
publicInstanceMethod(null);
PublicClass.effectivelyPublicStaticField = "";
PublicClass.effectivelyPublicClassMethod();
PublicClass p = new PublicClass();
p.effectivelyPublicInstanceField = "";
p.effectivelyPublicInstanceMethod();
int l = buffer.length;
}
};
}
enum WarnEnum {
A {
public void m() throws Exception {
WarnSerializableLambdaTest.staticPackageField = "";
WarnSerializableLambdaTest.staticProtectedField = "";
WarnSerializableLambdaTest.staticPrivateField = "";
WarnSerializableLambdaTest test =
new WarnSerializableLambdaTest();
test.packageField = "";
test.protectedField = "";
test.privateField = "";
WarnSerializableLambdaTest.packageClassMethod(null);
WarnSerializableLambdaTest.protectedClassMethod(null);
WarnSerializableLambdaTest.privateClassMethod(null);
test.packageInstanceMethod(null);
test.protectedInstanceMethod(null);
test.privateInstanceMethod(null);
PrivateClass.effectivelyNonPublicStaticField = "";
PrivateClass.effectivelyNonPublicClassMethod();
PrivateClass p = new PrivateClass();
p.effectivelyNonPublicInstanceField = "";
p.effectivelyNonPublicInstanceMethod();
}
};
public void m() throws Exception {}
}
static String staticPackageField;
static private String staticPrivateField;
static protected String staticProtectedField;
static public String staticPublicField;
String packageField;
private String privateField;
protected String protectedField;
public String publicField;
static Object packageClassMethod(String s) {
return null;
}
static private Object privateClassMethod(String s) {
return null;
}
static protected Object protectedClassMethod(String s) {
return null;
}
static public Object publicClassMethod(String s) {
return null;
}
Object packageInstanceMethod(String s) {
return null;
}
protected Object protectedInstanceMethod(String s) {
return null;
}
private Object privateInstanceMethod(String s) {
return null;
}
public Object publicInstanceMethod(String s) {
return null;
}
interface SAM {
Object apply(String s) throws Exception;
}
interface SAM2 {
Object apply(String arg1, String arg2);
}
class SerializableDesc implements Serializable {
public void m(Object param) throws Exception {}
}
static private class PrivateClass {
static public String effectivelyNonPublicStaticField;
public String effectivelyNonPublicInstanceField;
static public void effectivelyNonPublicClassMethod() {}
public void effectivelyNonPublicInstanceMethod() {}
}
static public class PublicClass {
static public String effectivelyPublicStaticField;
public String effectivelyPublicInstanceField;
static public void effectivelyPublicClassMethod() {}
public void effectivelyPublicInstanceMethod() {}
}
}

View File

@ -0,0 +1,57 @@
WarnSerializableLambdaTest.java:15:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:16:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:17:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:20:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:21:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:22:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:26:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
WarnSerializableLambdaTest.java:27:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
WarnSerializableLambdaTest.java:28:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
WarnSerializableLambdaTest.java:30:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
WarnSerializableLambdaTest.java:31:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
WarnSerializableLambdaTest.java:32:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
WarnSerializableLambdaTest.java:34:39: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:35:39: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:36:39: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:38:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:39:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:40:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:42:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
WarnSerializableLambdaTest.java:43:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
WarnSerializableLambdaTest.java:46:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
WarnSerializableLambdaTest.java:47:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
WarnSerializableLambdaTest.java:56:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
WarnSerializableLambdaTest.java:57:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
WarnSerializableLambdaTest.java:58:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
WarnSerializableLambdaTest.java:60:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
WarnSerializableLambdaTest.java:61:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
WarnSerializableLambdaTest.java:62:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
WarnSerializableLambdaTest.java:64:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:65:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:66:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:68:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:69:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:70:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:72:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
WarnSerializableLambdaTest.java:73:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
WarnSerializableLambdaTest.java:76:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
WarnSerializableLambdaTest.java:77:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
WarnSerializableLambdaTest.java:141:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
WarnSerializableLambdaTest.java:142:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
WarnSerializableLambdaTest.java:143:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
WarnSerializableLambdaTest.java:148:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
WarnSerializableLambdaTest.java:149:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
WarnSerializableLambdaTest.java:150:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
WarnSerializableLambdaTest.java:152:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:153:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:154:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
WarnSerializableLambdaTest.java:156:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:157:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:158:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
WarnSerializableLambdaTest.java:160:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
WarnSerializableLambdaTest.java:161:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
WarnSerializableLambdaTest.java:164:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
WarnSerializableLambdaTest.java:165:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
- compiler.err.warnings.and.werror
1 error
54 warnings

View File

@ -0,0 +1,56 @@
/*
* @test /nodynamiccopyright/
* @bug 8029102
* @summary Enhance compiler warnings for Lambda
* Checks that the warning for accessing non public members of a class is
* fired correctly.
* @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTestb.java
*/
import java.io.Serializable;
public class WarnSerializableLambdaTestb {
public void foo(Secret1 secret) {
Object o = (Runnable & java.io.Serializable) () -> { secret.test(); };
}
public void bar(Secret2 secret) {
Object o = (Runnable & java.io.Serializable) () -> { secret.test(); };
}
private class Secret1 {
public void test() {}
}
static private class Secret2 {
public void test() {}
}
class TestInner {
private int j = 0;
void m() {
Serializable s = new Serializable() {
int i;
void m() {
i = 0; // don't warn
System.out.println(j); //warn
}
};
}
}
class TestInner2 {
class W implements Serializable {
public int p = 0;
class I {
public int r = 0;
class K implements Serializable {
void m() {
p = 1; // don't warn owner is serializable
r = 2; // warn owner is not serializable
}
}
}
}
}
}

View File

@ -0,0 +1,7 @@
WarnSerializableLambdaTestb.java:14:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
WarnSerializableLambdaTestb.java:18:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.sensitive.member.from.serializable.element: j
WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.sensitive.member.from.serializable.element: r
- compiler.err.warnings.and.werror
1 error
4 warnings

View File

@ -0,0 +1,255 @@
/*
* Copyright (c) 2014, 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
* @summary local variable table attribute test.
* @bug 8040097
* @library /tools/javac/lib ../lib
* @build LocalVariableTestBase TestBase InMemoryFileManager ToolBox
* @compile -g LocalVariableTableTest.java
* @run main LocalVariableTableTest
*/
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.LocalVariableTable_attribute;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
public class LocalVariableTableTest extends LocalVariableTestBase {
public LocalVariableTableTest(Class<?> clazz) {
super(clazz);
}
public static void main(String[] args) throws IOException {
new LocalVariableTableTest(LocalVariableTableTest.class).test();
}
@ExpectedLocals(name = "l", type = "D")
@ExpectedLocals(name = "i", type = "J")
public static void onlyTwoCellParameters(double l, long i) {
}
@ExpectedLocals(name = "l", type = "D")
@ExpectedLocals(name = "dl", type = "D")
@ExpectedLocals(name = "i", type = "J")
@ExpectedLocals(name = "il", type = "J")
@ExpectedLocals(name = "d", type = "J")
@ExpectedLocals(name = "ll", type = "J")
public static void onlyTwoCellLocals(double l, long i, long d) {
double dl = 1.1;
long il = 1;
long ll = 1;
}
@Override
protected List<VariableTable> getVariableTables(Code_attribute codeAttribute) {
return Stream.of(codeAttribute.attributes.attrs)
.filter(at -> at instanceof LocalVariableTable_attribute)
.map(at -> (LocalVariableTable_attribute) at)
.map((t) -> new LocalVariableTable(t)).collect(toList());
}
@ExpectedLocals(name = "l", type = "J")
@ExpectedLocals(name = "i", type = "I")
@ExpectedLocals(name = "d", type = "D")
@ExpectedLocals(name = "ll", type = "J")
@ExpectedLocals(name = "obj", type = "Ljava/lang/Object;")
@ExpectedLocals(name = "dd", type = "D")
@ExpectedLocals(name = "bb", type = "B")
@ExpectedLocals(name = "this", type = "LLocalVariableTableTest;")
public double longDoubleOverlap(long l, int i, double d) {
long ll = 1L;
Object obj = 2;
double dd = 3.0;
byte bb = 0;
return l + i + d + ll + Integer.valueOf(obj.toString()) + dd + bb;
}
@ExpectedLocals(name = "bool", type = "Z")
@ExpectedLocals(name = "b", type = "B")
@ExpectedLocals(name = "ch", type = "C")
@ExpectedLocals(name = "sh", type = "S")
@ExpectedLocals(name = "i", type = "I")
@ExpectedLocals(name = "l", type = "J")
@ExpectedLocals(name = "d", type = "D")
@ExpectedLocals(name = "f", type = "F")
@ExpectedLocals(name = "ref", type = "Ljava/lang/Integer;")
@ExpectedLocals(name = "arr", type = "[Ljava/lang/Integer;")
@ExpectedLocals(name = "this", type = "LLocalVariableTableTest;")
public void allTypesWithoutParameters() {
boolean bool = true;
byte b = 0x1;
char ch = 'a';
short sh = 1_1;
int i = -2;
long l = 1L;
float f = 1.1f;
double d = 0.1;
Integer ref = 2;
Integer[] arr = null;
}
@ExpectedLocals(name = "bool", type = "Z")
@ExpectedLocals(name = "b", type = "B")
@ExpectedLocals(name = "ch", type = "C")
@ExpectedLocals(name = "sh", type = "S")
@ExpectedLocals(name = "i", type = "I")
@ExpectedLocals(name = "l", type = "J")
@ExpectedLocals(name = "d", type = "D")
@ExpectedLocals(name = "f", type = "F")
@ExpectedLocals(name = "ref", type = "Ljava/lang/Integer;")
@ExpectedLocals(name = "this", type = "LLocalVariableTableTest;")
public void allTypesWithParameters(boolean bool, byte b, char ch) {
short sh = 1_1;
int i = -2;
long l = 1L;
float f = 1.1f;
double d = 0.1;
Integer ref = 2;
}
@ExpectedLocals(name = "list", type = "Ljava/util/List;")
@ExpectedLocals(name = "list2", type = "[Ljava/util/List;")
@ExpectedLocals(name = "p", type = "Ljava/lang/Object;")
@ExpectedLocals(name = "k", type = "Ljava/lang/Integer;")
@ExpectedLocals(name = "i", type = "I")
@ExpectedLocals(name = "this", type = "LLocalVariableTableTest;")
public <T extends List<Integer>, P, K extends Integer> void genericType(K k) {
T list = null;
int i = 0;
P p = null;
List<T>[] list2 = null;
}
@ExpectedLocals(name = "this", type = "LLocalVariableTableTest;")
@ExpectedLocals(name = "inWhile", type = "I")
@ExpectedLocals(name = "inTry", type = "D")
@ExpectedLocals(name = "inSync", type = "F")
@ExpectedLocals(name = "inDo", type = "B")
@ExpectedLocals(name = "inSwitch", type = "S")
@ExpectedLocals(name = "inFor", type = "J")
@ExpectedLocals(name = "s", type = "Ljava/util/stream/Stream;")
public void deepScope() {
{
while (true) {
int inWhile = 0;
for (long inFor : Arrays.asList(0)) {
try (Stream<? extends Integer> s = Stream.of(0)) {
double inTry = 0.0;
synchronized (this) {
float inSync = -1.0f;
do {
byte inDo = 0;
switch (1) {
default:
short inSwitch = 100;
}
} while (true);
}
}
}
}
}
}
@ExpectedLocals(name = "i", type = "I", scope = 0)
@ExpectedLocals(name = "i", type = "J", scope = 1)
public void reuseByLong() {
{
int i = 0;
}
{
long i = 1;
}
}
class LocalVariableTable implements VariableTable {
final LocalVariableTable_attribute att;
public LocalVariableTable(LocalVariableTable_attribute att) {
this.att = att;
}
@Override
public int localVariableTableLength() {
return att.local_variable_table_length;
}
@Override
public List<Entry> entries() {
return Stream.of(att.local_variable_table).map(LocalVariableTableEntry::new).collect(toList());
}
@Override
public int attributeLength() {
return att.attribute_length;
}
private class LocalVariableTableEntry implements Entry {
final LocalVariableTable_attribute.Entry entry;
private LocalVariableTableEntry(LocalVariableTable_attribute.Entry entry) {
this.entry = entry;
}
@Override
public int index() {
return entry.index;
}
@Override
public int startPC() {
return entry.start_pc;
}
@Override
public int length() {
return entry.length;
}
@Override
public String name() {
return getString(entry.name_index);
}
@Override
public String type() {
return getString(entry.descriptor_index);
}
@Override
public String toString() {
return dump();
}
}
}
}

View File

@ -0,0 +1,249 @@
/*
* Copyright (c) 2014, 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.classfile.*;
import java.io.IOException;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import static java.lang.String.format;
import static java.util.stream.Collectors.*;
public abstract class LocalVariableTestBase extends TestBase {
public static final int DEFAULT_SCOPE = 0;
private final ClassFile classFile;
private final Class<?> clazz;
protected abstract List<VariableTable> getVariableTables(Code_attribute codeAttribute);
public LocalVariableTestBase(Class<?> clazz) {
this.clazz = clazz;
try {
this.classFile = ClassFile.read(getClassFile(clazz));
} catch (IOException | ConstantPoolException e) {
throw new IllegalArgumentException("Can't read classfile for specified class", e);
}
}
//info in the LocalVariableTable attribute is compared against expected info stored in annotations
public void test() throws IOException {
List<java.lang.reflect.Method> testMethods = Stream.of(clazz.getDeclaredMethods())
.filter(m -> m.getAnnotationsByType(ExpectedLocals.class).length > 0)
.collect(toList());
int failed = 0;
for (java.lang.reflect.Method method : testMethods) {
try {
Map<String, String> expectedLocals2Types = new HashMap<>();
Map<String, Integer> sig2scope = new HashMap<>();
for (ExpectedLocals anno : method.getDeclaredAnnotationsByType(ExpectedLocals.class)) {
expectedLocals2Types.put(anno.name(), anno.type());
sig2scope.put(anno.name() + "&" + anno.type(), anno.scope());
}
test(method.getName(), expectedLocals2Types, sig2scope);
} catch (AssertionFailedException ex) {
System.err.printf("Test %s failed.%n", method.getName());
ex.printStackTrace();
failed++;
}
}
if (failed > 0)
throw new RuntimeException(format("Failed %d out of %d. See logs.", failed, testMethods.size()));
}
public void test(String methodName, Map<String, String> expectedLocals2Types, Map<String, Integer> sig2scope)
throws IOException {
for (Method m : classFile.methods) {
String mName = getString(m.name_index);
if (methodName.equals(mName)) {
System.out.println("Testing local variable table in method " + mName);
Code_attribute code_attribute = (Code_attribute) m.attributes.get(Attribute.Code);
List<? extends VariableTable> variableTables = getVariableTables(code_attribute);
generalLocalVariableTableCheck(variableTables);
List<VariableTable.Entry> entries = variableTables.stream()
.flatMap(table -> table.entries().stream())
.collect(toList());
generalEntriesCheck(entries, code_attribute);
assertIndexesAreUnique(entries, sig2scope);
checkNamesAndTypes(entries, expectedLocals2Types);
checkDoubleAndLongIndexes(entries, sig2scope, code_attribute.max_locals);
}
}
}
private void generalLocalVariableTableCheck(List<? extends VariableTable> variableTables) {
for (VariableTable localTable : variableTables) {
//only one per variable.
assertEquals(localTable.localVariableTableLength(),
localTable.entries().size(), "Incorrect local variable table length");
//attribute length is offset(line_number_table_length) + element_size*element_count
assertEquals(localTable.attributeLength(),
2 + (5 * 2) * localTable.localVariableTableLength(), "Incorrect attribute length");
}
}
private void generalEntriesCheck(List<VariableTable.Entry> entries, Code_attribute code_attribute) {
for (VariableTable.Entry e : entries) {
assertTrue(e.index() >= 0 && e.index() < code_attribute.max_locals,
"Index " + e.index() + " out of variable array. Size of array is " + code_attribute.max_locals);
assertTrue(e.startPC() >= 0, "StartPC is less then 0. StartPC = " + e.startPC());
assertTrue(e.length() >= 0, "Length is less then 0. Length = " + e.length());
assertTrue(e.startPC() + e.length() <= code_attribute.code_length,
format("StartPC+Length > code length.%n" +
"%s%n" +
"code_length = %s"
, e, code_attribute.code_length));
}
}
private void checkNamesAndTypes(List<LocalVariableTableTest.LocalVariableTable.Entry> entries,
Map<String, String> expectedLocals2Types) {
Map<String, List<String>> actualNames2Types = entries.stream()
.collect(
groupingBy(VariableTable.Entry::name,
mapping(VariableTable.Entry::type, toList())));
for (Map.Entry<String, String> name2type : expectedLocals2Types.entrySet()) {
String name = name2type.getKey();
String type = name2type.getValue();
assertTrue(actualNames2Types.containsKey(name),
format("There is no record for local variable %s%nEntries: %s", name, entries));
assertTrue(actualNames2Types.get(name).contains(type),
format("Types are different for local variable %s%nExpected type: %s%nActual type: %s",
name, type, actualNames2Types.get(name)));
}
}
private void assertIndexesAreUnique(Collection<VariableTable.Entry> entries, Map<String, Integer> scopes) {
//check every scope separately
Map<Object, List<VariableTable.Entry>> entriesByScope = groupByScope(entries, scopes);
for (Map.Entry<Object, List<VariableTable.Entry>> mapEntry : entriesByScope.entrySet()) {
mapEntry.getValue().stream()
.collect(groupingBy(VariableTable.Entry::index))
.entrySet()
.forEach(e ->
assertTrue(e.getValue().size() == 1,
"Multiple variables point to the same index in common scope. " + e.getValue()));
}
}
private void checkDoubleAndLongIndexes(Collection<LocalVariableTableTest.LocalVariableTable.Entry> entries,
Map<String, Integer> scopes, int maxLocals) {
//check every scope separately
Map<Object, List<VariableTable.Entry>> entriesByScope = groupByScope(entries, scopes);
for (List<VariableTable.Entry> entryList : entriesByScope.values()) {
Map<Integer, VariableTable.Entry> index2Entry = entryList.stream()
.collect(toMap(VariableTable.Entry::index, e -> e));
entryList.stream()
.filter(e -> "J".equals(e.type()) || "D".equals(e.type()))
.forEach(e -> {
assertTrue(e.index() + 1 < maxLocals,
format("Index %s is out of variable array. Long and double occupy 2 cells." +
" Size of array is %d", e.index() + 1, maxLocals));
assertTrue(!index2Entry.containsKey(e.index() + 1),
format("An entry points to the second cell of long/double entry.%n%s%n%s", e,
index2Entry.get(e.index() + 1)));
});
}
}
private Map<Object, List<VariableTable.Entry>> groupByScope(
Collection<LocalVariableTableTest.LocalVariableTable.Entry> entries, Map<String, Integer> scopes) {
return entries.stream().collect(groupingBy(e -> scopes.getOrDefault(e.name() + "&" + e.type(), DEFAULT_SCOPE)));
}
protected String getString(int i) {
try {
return classFile.constant_pool.getUTF8Info(i).value;
} catch (ConstantPool.InvalidIndex | ConstantPool.UnexpectedEntry ex) {
ex.printStackTrace();
throw new AssertionFailedException("Issue while reading constant pool");
}
}
interface VariableTable {
int localVariableTableLength();
List<LocalVariableTableTest.VariableTable.Entry> entries();
int attributeLength();
interface Entry {
int index();
int startPC();
int length();
String name();
String type();
default String dump() {
return format("Entry{" +
"%n name = %s" +
"%n type = %s" +
"%n index = %d" +
"%n startPC = %d" +
"%n length = %d" +
"%n}", name(), type(), index(), startPC(), length());
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Container.class)
@interface ExpectedLocals {
String name();
String type();
//variables from different scopes can share local variable table index and/or name.
int scope() default DEFAULT_SCOPE;
}
@Retention(RetentionPolicy.RUNTIME)
@interface Container {
ExpectedLocals[] value();
}
}

View File

@ -0,0 +1,207 @@
/*
* Copyright (c) 2014, 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
* @summary local variable type table attribute test.
* @bug 8040097
* @library /tools/javac/lib ../lib
* @build LocalVariableTestBase TestBase InMemoryFileManager ToolBox
* @compile -g LocalVariableTypeTableTest.java
* @run main LocalVariableTypeTableTest
*/
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
public class LocalVariableTypeTableTest<THIS> extends LocalVariableTestBase {
public LocalVariableTypeTableTest(Class<?> clazz) {
super(clazz);
}
public static void main(String[] args) throws IOException {
new LocalVariableTypeTableTest(LocalVariableTypeTableTest.class).test();
}
@Override
protected List<VariableTable> getVariableTables(Code_attribute codeAttribute) {
return Stream.of(codeAttribute.attributes.attrs)
.filter(at -> at instanceof LocalVariableTypeTable_attribute)
.map(at -> (LocalVariableTypeTable_attribute) at)
.map(LocalVariableTypeTable::new).collect(toList());
}
@ExpectedLocals(name = "list", type = "TT;")
@ExpectedLocals(name = "p", type = "[TP;")
@ExpectedLocals(name = "k", type = "TK;")
@ExpectedLocals(name = "c1", type = "Ljava/util/Collection<-Ljava/lang/Integer;>;")
@ExpectedLocals(name = "c2", type = "Ljava/util/Collection<*>;")
@ExpectedLocals(name = "c3", type = "Ljava/util/Collection<+TE;>;")
public <T extends List<Integer>, P, K extends Integer, E extends Supplier & Runnable>
void genericTypeWithParametersOnly(K k, T list, P[] p,
Collection<? super Integer> c1,
Collection<?> c2, Collection<? extends E> c3) {
}
@ExpectedLocals(name = "list", type = "TT;")
@ExpectedLocals(name = "p", type = "[TP;")
@ExpectedLocals(name = "k", type = "TK;")
@ExpectedLocals(name = "c1", type = "Ljava/util/Collection<-Ljava/lang/Integer;>;")
@ExpectedLocals(name = "c2", type = "Ljava/util/Collection<*>;")
@ExpectedLocals(name = "c3", type = "Ljava/util/Collection<+TE;>;")
public <T extends List<Integer>, P, K extends Integer, E extends Supplier & Runnable>
void genericType(K k, T list, P[] p) {
Collection<? super Integer> c1 = null;
Collection<?> c2 = null;
Collection<? extends E> c3 = null;
}
@ExpectedLocals(name = "list", type = "TT;")
@ExpectedLocals(name = "p", type = "[[TP;")
public <T extends List<Integer>, P, K extends Integer> void genericTypeWithoutParameters() {
T list = null;
list.add(1);
int i = 0;
P[][] p = null;
}
@ExpectedLocals(name = "this", type = "LLocalVariableTypeTableTest<TTHIS;>;")
public void genericThis() {
}
@ExpectedLocals(name = "this", type = "LLocalVariableTypeTableTest<TTHIS;>;")
@ExpectedLocals(name = "inWhile", type = "TTHIS;")
@ExpectedLocals(name = "inTry", type = "TTHIS;")
@ExpectedLocals(name = "inSync", type = "TTHIS;")
@ExpectedLocals(name = "inDo", type = "TTHIS;")
@ExpectedLocals(name = "inSwitch", type = "TTHIS;")
@ExpectedLocals(name = "inFor", type = "LLocalVariableTypeTableTest<-TTHIS;>;")
@ExpectedLocals(name = "s", type = "Ljava/util/stream/Stream<+Ljava/lang/Integer;>;")
public void deepScope() {
{
while (true) {
THIS inWhile = null;
for (LocalVariableTypeTableTest<? super THIS> inFor : Arrays.asList(this)) {
try (Stream<? extends Integer> s = Stream.of(0)) {
THIS inTry = null;
synchronized (this) {
THIS inSync = null;
do {
THIS inDo = null;
switch (1) {
default:
THIS inSwitch = null;
}
} while (true);
}
}
}
}
}
}
@ExpectedLocals(name = "i", type = "TTHIS;", scope = 0)
@ExpectedLocals(name = "i", type = "Ljava/util/List<TTHIS;>;", scope = 1)
public void reuseByLong() {
{
THIS i = null;
}
{
List<THIS> i = null;
}
}
class LocalVariableTypeTable implements VariableTable {
final LocalVariableTypeTable_attribute att;
public LocalVariableTypeTable(LocalVariableTypeTable_attribute att) {
this.att = att;
}
@Override
public int localVariableTableLength() {
return att.local_variable_table_length;
}
@Override
public List<Entry> entries() {
return Stream.of(att.local_variable_table).map(LocalVariableTypeTableEntry::new).collect(toList());
}
@Override
public int attributeLength() {
return att.attribute_length;
}
private class LocalVariableTypeTableEntry implements Entry {
final LocalVariableTypeTable_attribute.Entry entry;
private LocalVariableTypeTableEntry(LocalVariableTypeTable_attribute.Entry entry) {
this.entry = entry;
}
@Override
public int index() {
return entry.index;
}
@Override
public int startPC() {
return entry.start_pc;
}
@Override
public int length() {
return entry.length;
}
@Override
public String name() {
return getString(entry.name_index);
}
@Override
public String type() {
return getString(entry.signature_index);
}
@Override
public String toString() {
return dump();
}
}
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2014, 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.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
public class TestBase {
public Map<String, ? extends JavaFileObject> compile(String... sources) throws IOException,
CompilationException {
return compile(emptyList(), sources);
}
/**
* @param options - compiler options
* @param sources
* @return map where key is className, value is corresponding ClassFile.
* @throws IOException
*/
public Map<String, ? extends JavaFileObject> compile(List<String> options, String... sources) throws IOException,
CompilationException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<? extends JavaFileObject> src = Stream.of(sources).map(ToolBox.JavaSource::new).collect(toList());
try (InMemoryFileManager fileManager = new InMemoryFileManager(compiler.getStandardFileManager(null, null, null))) {
boolean success = compiler.getTask(null, fileManager, null, options, null, src).call();
if (!success) throw new CompilationException("Compilation Error");
return fileManager.getClasses();
}
}
public void assertEquals(Object actual, Object expected, String message) {
if (!Objects.equals(actual, expected))
throw new AssertionFailedException(format("%s%nGot: %s, Expected: ", message, actual, expected));
}
public void assertNull(Object actual, String message) {
assertEquals(actual, null, message);
}
public void assertNotNull(Object actual, String message) {
if (Objects.isNull(actual)) {
throw new AssertionFailedException(message + " : Expected not null value");
}
}
public void assertTrue(boolean actual, String message) {
assertEquals(actual, true, message);
}
public File getSourceFile(String fileName) {
return new File(System.getProperty("test.src", "."), fileName);
}
public File getClassFile(String fileName) {
return new File(System.getProperty("test.classes", TestBase.class.getResource(".").getPath()), fileName);
}
public File getClassFile(Class clazz) {
return getClassFile(clazz.getName().replace(".", "/") + ".class");
}
public static class CompilationException extends Exception {
public CompilationException(String message) {
super(message);
}
}
public static class AssertionFailedException extends RuntimeException {
public AssertionFailedException(String message) {
super(message);
}
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2014, 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.access.to.sensitive.member.from.serializable.element
// options: -XDwarnOnAccessToSensitiveMembers
import java.io.Serializable;
public class WarnSerializableLambda {
interface SAM {
void apply(String s);
}
private void m1() {
SAM s = (SAM & Serializable) c -> {
packageField = "";
};
}
String packageField;
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2014, 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 8030741
* @summary Inference: implement eager resolution of return types, consistent with JDK-8028800
* @compile EagerReturnTypeResolutionTesta.java
*/
public class EagerReturnTypeResolutionTesta {
abstract class Test1<T>{
abstract <S> S foo(S x, S y);
<S extends Number & Comparable<? extends Number>> void baz(Test1<S> a){}
void bar(Test1<Long> x, Test1<Integer> y){
baz(foo(x, y));
}
}
abstract class Test2<T>{
abstract <S> S foo(S x, S y);
abstract <S1> void baz(Test2<S1> a);
void bar(Test2<Integer> y, Test2<Long> x){
baz(foo(x, y));
}
}
abstract class Test3<T>{
abstract <S> S foo(S x, S y);
<T extends Number & Comparable<?>,
S extends Number & Comparable<? extends T>> void baz(Test3<S> a){}
void bar(Test3<Long> x, Test3<Integer> y){
baz(foo(x, y));
}
}
abstract class Test4 {
abstract class A0<T> {}
abstract class A1<T> extends A0<T> {}
abstract class A2<T> extends A0<T> {}
abstract <S> S foo(S x, S y);
abstract <S1> void baz(A0<S1> a);
void bar(A2<Integer> y, A1<Long> x){
baz(foo(x, y));
}
}
}

View File

@ -0,0 +1,182 @@
/*
* @test /nodynamiccopyright/
* @bug 8030741
* @summary Inference: implement eager resolution of return types, consistent with JDK-8028800
* @compile/fail/ref=EagerReturnTypeResolutionTestb.out -XDrawDiagnostics EagerReturnTypeResolutionTestb.java
* @author Dan Smith
*/
import java.util.List;
public class EagerReturnTypeResolutionTestb {
interface I<S> {}
interface J<S> extends I<S> {}
interface K extends I<String> {}
interface L<S> extends I {}
<T> T lower(List<? extends T> l) { return null; }
<T> T lower2(List<? extends T> l1, List<? extends T> l2) { return null; }
<T> T upper(List<? super T> l) { return null; }
<T> T upper2(List<? super T> l1, List<? super T> l2) { return null; }
<T> T eq(List<T> l) { return null; }
<T> T eq2(List<T> l1, List<T> l2) { return null; }
<X> void takeI(I<X> i) {}
void takeIString(I<String> i) {}
I<String> iStringField;
void takeLong(long arg) {}
long longField;
void testSimpleCaptureOK(List<I<?>> i1) {
takeI(lower(i1)); // ok*
takeI(eq(i1)); // ok*
takeI(upper(i1)); // ok, no capture
takeIString(upper(i1)); // ok
iStringField = upper(i1); // ok
}
void testSimpleCaptureKO(List<I<?>> i1) {
takeIString(lower(i1)); // ERROR
takeIString(eq(i1)); // ERROR
iStringField = lower(i1); // ERROR
iStringField = eq(i1); // ERROR
}
void testMultiCaptureOK(List<I<String>> i1, List<I<Integer>> i2, List<I<?>> i3,
List<J<String>> j1, List<J<Integer>> j2, List<K> k1) {
/* Lines marked with JDK-8029002 should be uncommented once this bug is
* fixed
*/
takeI(lower2(i1, i2)); // ok*
takeI(lower2(i1, i3)); // ok*
takeI(upper2(i1, i3)); // ok, no capture* JDK-8029002
takeIString(upper2(i1, i3)); // ok, no capture
iStringField = upper2(i1, i3); // ok, no capture
takeI(lower2(j1, j2)); // ok*
takeI(lower2(j1, k1)); // ok, no capture
takeI(upper2(j1, k1)); // ok, no capture* JDK-8029002
takeIString(lower2(j1, k1)); // ok, no capture
takeIString(upper2(j1, k1)); // ok, no capture
iStringField = lower2(j1, k1); // ok, no capture
iStringField = upper2(j1, k1); // ok, no capture
takeI(lower2(j2, k1)); // ok*
}
void testMultiCaptureKO(List<I<String>> i1, List<I<Integer>> i2, List<I<?>> i3,
List<J<String>> j1, List<J<Integer>> j2, List<K> k1) {
takeI(eq2(i1, i2)); // ERROR, bad bounds
takeI(upper2(i1, i2)); // ERROR, bad bounds
takeIString(lower2(i1, i2)); // ERROR
takeIString(eq2(i1, i2)); // ERROR, bad bounds
takeIString(upper2(i1, i2)); // ERROR, bad bounds
iStringField = lower2(i1, i2); // ERROR
iStringField = eq2(i1, i2); // ERROR, bad bounds
iStringField = upper2(i1, i2); // ERROR, bad bounds
takeI(eq2(i1, i3)); // ERROR, bad bounds
takeIString(lower2(i1, i3)); // ERROR
takeIString(eq2(i1, i3)); // ERROR, bad bounds
iStringField = lower2(i1, i3); // ERROR
iStringField = eq2(i1, i3); // ERROR, bad bounds
takeI(eq2(j1, j2)); // ERROR, bad bounds
takeI(upper2(j1, j2)); // ERROR, bad bounds
takeIString(lower2(j1, j2)); // ERROR
takeIString(eq2(j1, j2)); // ERROR, bad bounds
takeIString(upper2(j1, j2)); // ERROR, bad bounds
iStringField = lower2(j1, j2); // ERROR
iStringField = eq2(j1, j2); // ERROR, bad bounds
iStringField = upper2(j1, j2); // ERROR, bad bounds
takeI(eq2(j1, k1)); // ERROR, bad bounds
takeIString(eq2(j1, k1)); // ERROR, bad bounds
iStringField = eq2(j1, k1); // ERROR, bad bounds
takeI(eq2(j2, k1)); // ERROR, bad bounds
takeI(upper2(j2, k1)); // ERROR, bad bounds; actual: no error, see JDK-8037474
takeIString(lower2(j2, k1)); // ERROR
takeIString(eq2(j2, k1)); // ERROR, bad bounds
takeIString(upper2(j2, k1)); // ERROR, bad bounds
iStringField = lower2(j2, k1); // ERROR
iStringField = eq2(j2, k1); // ERROR, bad bounds
iStringField = upper2(j2, k1); // ERROR, bad bounds
}
void testRawOK(List<I> i1, List<J> j1, List<L<String>> l1) {
takeI(lower(i1)); // ok, unchecked
takeI(eq(i1)); // ok, unchecked
takeI(upper(i1)); // ok, no capture, not unchecked
takeIString(lower(i1)); // ok, unchecked
takeIString(eq(i1)); // ok, unchecked
takeIString(upper(i1)); // ok, no capture, not unchecked
iStringField = lower(i1); // ok, unchecked
iStringField = eq(i1); // ok, unchecked
iStringField = upper(i1); // ok, no capture, not unchecked
takeI(lower(j1)); // ok, unchecked
takeI(eq(j1)); // ok, unchecked
takeI(upper(j1)); // bad bounds? -- spec is unclear
takeIString(lower(j1)); // ok, unchecked
takeIString(eq(j1)); // ok, unchecked
takeIString(upper(j1)); // bad bounds? -- spec is unclear
iStringField = lower(j1); // ok, unchecked
iStringField = eq(j1); // ok, unchecked
iStringField = upper(j1); // bad bounds? -- spec is unclear
takeI(lower(l1)); // ok, unchecked
takeI(eq(l1)); // ok, unchecked
takeI(upper(l1)); // bad bounds? -- spec is unclear
takeIString(lower(l1)); // ok, unchecked
takeIString(eq(l1)); // ok, unchecked
takeIString(upper(l1)); // bad bounds? -- spec is unclear
iStringField = lower(l1); // ok, unchecked
iStringField = eq(l1); // ok, unchecked
iStringField = upper(l1); // bad bounds? -- spec is unclear
}
void testPrimOK(List<Integer> i1, List<Long> l1, List<Double> d1) {
takeLong(lower(i1)); // ok
takeLong(eq(i1)); // ok
takeLong(upper(i1)); // ok*
longField = lower(i1); // ok
longField = eq(i1); // ok
longField = upper(i1); // ok*
takeLong(lower(l1)); // ok
takeLong(eq(l1)); // ok
takeLong(upper(l1)); // ok
longField = lower(l1); // ok
longField = eq(l1); // ok
longField = upper(l1); // ok
}
void testPrimKO(List<Integer> i1, List<Long> l1, List<Double> d1) {
takeLong(lower(d1)); // ERROR
takeLong(eq(d1)); // ERROR
takeLong(upper(d1)); // ERROR
longField = lower(d1); // ERROR
longField = eq(d1); // ERROR
longField = upper(d1); // ERROR
}
}

View File

@ -0,0 +1,45 @@
EagerReturnTypeResolutionTestb.java:42:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ?>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:43:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ?>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:44:29: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:45:26: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:74:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:75:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:77:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:78:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:79:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:81:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:82:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:83:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:85:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<?>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<?>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:86:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ?>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:87:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<?>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<?>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:89:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:90:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<?>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<?>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:91:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:92:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:94:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.J<compiler.misc.type.captureof: 1, ? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:95:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:96:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:98:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:99:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:100:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:102:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:103:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:104:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:105:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>)
EagerReturnTypeResolutionTestb.java:106:9: compiler.err.cant.apply.symbol: kindname.method, takeI, EagerReturnTypeResolutionTestb.I<X>, java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Integer, java.lang.Integer,java.lang.String)
EagerReturnTypeResolutionTestb.java:108:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:109:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>)
EagerReturnTypeResolutionTestb.java:110:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.I<java.lang.String>,EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:112:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:113:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>)
EagerReturnTypeResolutionTestb.java:114:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.I<java.lang.String>,EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:174:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long))
EagerReturnTypeResolutionTestb.java:175:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long))
EagerReturnTypeResolutionTestb.java:176:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long))
EagerReturnTypeResolutionTestb.java:178:26: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long)
EagerReturnTypeResolutionTestb.java:179:23: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long)
EagerReturnTypeResolutionTestb.java:180:26: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long)
- compiler.note.unchecked.filename: EagerReturnTypeResolutionTestb.java
- compiler.note.unchecked.recompile
42 errors

View File

@ -0,0 +1,25 @@
/*
* @test /nodynamiccopyright/
* @bug 8030741
* @summary Inference: implement eager resolution of return types, consistent with JDK-8028800
* @compile/fail/ref=PrimitiveTypeBoxingTest.out -XDrawDiagnostics PrimitiveTypeBoxingTest.java
*/
public class PrimitiveTypeBoxingTest {
static void foo(long arg) {}
static void bar(int arg) {}
interface F<X> { void get(X arg); }
<Z> void m1(F<Z> f, Z arg) {}
<Z> void m2(Z arg, F<Z> f) {}
void test() {
m1(PrimitiveTypeBoxingTest::foo, 23); // expected: error
m2(23, PrimitiveTypeBoxingTest::foo); // expected: error
m1(PrimitiveTypeBoxingTest::bar, 23); // expected: success
m2(23, PrimitiveTypeBoxingTest::bar); // expected: success
}
}

View File

@ -0,0 +1,3 @@
PrimitiveTypeBoxingTest.java:19:9: compiler.err.cant.apply.symbol: kindname.method, m1, PrimitiveTypeBoxingTest.F<Z>,Z, @490,int, kindname.class, PrimitiveTypeBoxingTest, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.Long,java.lang.Object)
PrimitiveTypeBoxingTest.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m2, Z,PrimitiveTypeBoxingTest.F<Z>, int,@559, kindname.class, PrimitiveTypeBoxingTest, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.Long,java.lang.Object)
2 errors

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2014, 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 8029725
* @summary Lambda reference to containing local class causes javac infinite recursion
* @author Robert Field
* @run main LambdaLocalTest
*/
public class LambdaLocalTest {
interface F {void f();}
static F f;
static StringBuffer sb = new StringBuffer();
static void assertEquals(Object val, Object expected) {
if (!val.equals(expected)) {
throw new AssertionError("expected '" + expected + "' got '" + val + "'");
}
}
public static void main(String[] args) {
class Local {
public Local() {
f = () -> new Local();
sb.append("+");
}
}
new Local();
f.f();
assertEquals(sb.toString(), "++");
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2014, 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 8036942
* @summary javac generates incorrect exception table for multi-catch statements inside a lambda
* @run main LambdaMultiCatchTest
*/
import java.io.IOException;
import java.util.function.Function;
public class LambdaMultiCatchTest {
public static void main(String[] args) {
Function<String,String> fi = x -> {
String result = "nada";
try {
switch (x) {
case "IO": throw new IOException();
case "Illegal": throw new IllegalArgumentException();
case "Run": throw new RuntimeException();
}
} catch (IOException|IllegalArgumentException ex) {
result = "IO/Illegal";
} catch (Exception ex) {
result = "Any";
};
return result;
};
String val = fi.apply("Run");
if (!val.equals("Any")) {
throw new AssertionError("Fail: Expected 'Any' but got '" + val + "'");
}
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2014, 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 8029725
* @summary Lambda reference to containing local class causes javac infinite recursion
* @author Robert Field
* @run main LambdaOuterLocalTest
*/
public class LambdaOuterLocalTest {
interface F {void f();}
static F f;
static StringBuffer sb = new StringBuffer();
static void assertEquals(Object val, Object expected) {
if (!val.equals(expected)) {
throw new AssertionError("expected '" + expected + "' got '" + val + "'");
}
}
public static void main(String[] args) {
class Local1 {
public Local1() {
class Local2 {
public Local2() {
f = () -> new Local1();
sb.append("2");
}
}
sb.append("1");
new Local2();
}
}
new Local1();
f.f();
assertEquals(sb.toString(), "1212");
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2014, 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 8029852
* @summary Bad code generated (VerifyError) when lambda instantiates
* enclosing local class and has captured variables
*/
public class SingleLocalTest {
interface F {void f();}
static F f;
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
class Local1 {
public Local1() {
f = () -> new Local1();
sb.append("1");
}
}
new Local1();
f.f();
String s = sb.toString();
if (!s.equals("11")) {
throw new AssertionError("Expected '11' got '" + s + "'");
}
}
}

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2014, 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.*;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import javax.tools.*;
import static java.util.Collections.unmodifiableMap;
/**
* class for storing source/byte code in memory.
*/
public class InMemoryFileManager extends ForwardingJavaFileManager {
private final Map<String, InMemoryJavaFile> classes = new HashMap<>();
public InMemoryFileManager(JavaFileManager fileManager) {
super(fileManager);
}
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
InMemoryJavaFile javaFile = new InMemoryJavaFile(className);
classes.put(className, javaFile);
return javaFile;
}
@Override
public ClassLoader getClassLoader(Location location) {
return new ClassLoader(this.getClass().getClassLoader()) {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
InMemoryJavaFile classData = classes.get(name);
if (classData == null) throw new ClassNotFoundException(name);
byte[] byteCode = classData.bos.toByteArray();
return defineClass(name, byteCode, 0, byteCode.length);
}
};
}
public Map<String, ? extends JavaFileObject> getClasses() {
return unmodifiableMap(classes);
}
private static class InMemoryJavaFile extends SimpleJavaFileObject {
private final ByteArrayOutputStream bos =
new ByteArrayOutputStream();
protected InMemoryJavaFile(String name) {
super(URI.create("mfm:///" + name.replace('.', '/') + Kind.CLASS.extension), Kind.CLASS);
}
@Override
public OutputStream openOutputStream() throws IOException {
return bos;
}
@Override
public InputStream openInputStream() throws IOException {
return new ByteArrayInputStream(bos.toByteArray());
}
}
}

View File

@ -851,7 +851,7 @@ public class ToolBox {
* This method is intended for simple files and uses regular expressions,
* so comments matching the pattern can make the method fail.
*/
private static String getJavaFileNameFromSource(String source) {
static String getJavaFileNameFromSource(String source) {
String className = null;
Matcher matcher = publicClassPattern.matcher(source);
if (matcher.find()) {
@ -902,7 +902,9 @@ public class ToolBox {
.append("Main-Class: ")
.append(mainClass).toString());
}
Files.write(Paths.get("MANIFEST.MF"), lines, null);
Files.write(Paths.get("MANIFEST.MF"), lines,
StandardOpenOption.CREATE, StandardOpenOption.WRITE,
StandardOpenOption.TRUNCATE_EXISTING);
}
/**