This commit is contained in:
Lana Steuck 2015-03-05 15:24:15 -08:00
commit e9a801f0ef
72 changed files with 744 additions and 155 deletions

View File

@ -28,6 +28,10 @@
</sequential>
</macrodef>
<target name="crules" depends="build-all-tools,-def-jtreg">
<jtreg-tool name="all" tests="tools/all/RunCodingRules.java"/>
</target>
<target name="post-make" depends="clean, build-all-tools"/>
<target name="jtreg-debug" depends="build-all-tools,-def-jtreg">

View File

@ -156,7 +156,7 @@
<filter targetName="clean" isVisible="true" />
<filter targetName="jtreg" isVisible="true" />
<filter targetName="jtreg-debug" isVisible="true" />
<filter targetName="checkstyle" isVisible="true" />
<filter targetName="crules" isVisible="true" />
</targetFilters>
<viewClosedWhenNoErrors value="true" />
<expanded value="false" />

View File

@ -5,7 +5,31 @@
import com.sun.tools.javac.util.Assert;
public class Test {
public void check(String value) {
Assert.check(value.trim().length() > 0, "value=" + value);
String v;
public void check1(String value) {
Assert.check(value.trim().length() > 0, "value=" + value); //fail
}
public void check2(String value) {
Assert.check(value.trim().length() > 0, "value=" + "value"); //ok
}
public void check3(String value) {
Assert.check(value.trim().length() > 0, () -> "value=" + value); //ok
}
public void check4(String value) {
Assert.check(value.trim().length() > 0, value); //ok
}
public void check5(String value) {
Assert.check(value.trim().length() > 0, v); //ok
}
public void check6(String value) {
Assert.check(value.trim().length() > 0, () -> "value=" + "value"); //fail
}
public void check7(String value) {
Assert.check(value.trim().length() > 0, () -> value); //fail
}
public void check8(String value) {
Assert.check(value.trim().length() > 0, () -> v); //fail
}
}

View File

@ -1,2 +1,5 @@
Test.java:9:21: compiler.err.proc.messager: compiler.misc.crules.should.not.use.string.concatenation
1 error
Test.java:12:58: compiler.err.proc.messager: compiler.misc.crules.should.not.use.eager.string.evaluation
Test.java:27:49: compiler.err.proc.messager: compiler.misc.crules.should.not.use.lazy.string.evaluation
Test.java:30:49: compiler.err.proc.messager: compiler.misc.crules.should.not.use.lazy.string.evaluation
Test.java:33:49: compiler.err.proc.messager: compiler.misc.crules.should.not.use.lazy.string.evaluation
4 errors

View File

@ -23,10 +23,14 @@
package crules;
import com.sun.source.tree.LambdaExpressionTree.BodyKind;
import com.sun.source.util.JavacTask;
import com.sun.source.util.TaskEvent.Kind;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCLambda;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.Tag;
import com.sun.tools.javac.tree.TreeInfo;
@ -35,6 +39,22 @@ import com.sun.tools.javac.util.Assert;
public class AssertCheckAnalyzer extends AbstractCodingRulesAnalyzer {
enum AssertOverloadKind {
EAGER("crules.should.not.use.eager.string.evaluation"),
LAZY("crules.should.not.use.lazy.string.evaluation"),
NONE(null);
String errKey;
AssertOverloadKind(String errKey) {
this.errKey = errKey;
}
boolean simpleArgExpected() {
return this == AssertOverloadKind.EAGER;
}
}
public AssertCheckAnalyzer(JavacTask task) {
super(task);
treeVisitor = new AssertCheckVisitor();
@ -45,20 +65,46 @@ public class AssertCheckAnalyzer extends AbstractCodingRulesAnalyzer {
@Override
public void visitApply(JCMethodInvocation tree) {
Symbol method = TreeInfo.symbolFor(tree);
if (method != null &&
method.owner.getQualifiedName().contentEquals(Assert.class.getName()) &&
!method.name.contentEquals("error")) {
Symbol m = TreeInfo.symbolFor(tree);
AssertOverloadKind ak = assertOverloadKind(m);
if (ak != AssertOverloadKind.NONE &&
!m.name.contentEquals("error")) {
JCExpression lastParam = tree.args.last();
if (lastParam != null &&
lastParam.type.tsym == syms.stringType.tsym &&
lastParam.hasTag(Tag.PLUS)) {
messages.error(tree, "crules.should.not.use.string.concatenation");
if (isSimpleStringArg(lastParam) != ak.simpleArgExpected()) {
messages.error(lastParam, ak.errKey);
}
}
super.visitApply(tree);
}
AssertOverloadKind assertOverloadKind(Symbol method) {
if (method == null ||
!method.owner.getQualifiedName().contentEquals(Assert.class.getName()) ||
method.type.getParameterTypes().tail == null) {
return AssertOverloadKind.NONE;
}
Type formal = method.type.getParameterTypes().last();
if (types.isSameType(formal, syms.stringType)) {
return AssertOverloadKind.EAGER;
} else if (types.isSameType(types.erasure(formal), types.erasure(syms.supplierType))) {
return AssertOverloadKind.LAZY;
} else {
return AssertOverloadKind.NONE;
}
}
boolean isSimpleStringArg(JCExpression e) {
switch (e.getTag()) {
case LAMBDA:
JCLambda lambda = (JCLambda)e;
return (lambda.getBodyKind() == BodyKind.EXPRESSION) &&
isSimpleStringArg((JCExpression)lambda.body);
default:
Symbol argSym = TreeInfo.symbolFor(e);
return (e.type.constValue() != null ||
(argSym != null && argSym.kind == Kinds.Kind.VAR));
}
}
}
}

View File

@ -26,8 +26,10 @@
# 0: symbol
crules.err.var.must.be.final=\
Static variable {0} must be final
crules.should.not.use.string.concatenation=\
Should not use string concatenation.
crules.should.not.use.eager.string.evaluation=\
Should not use eager string evaluation. Use lazy version instead.
crules.should.not.use.lazy.string.evaluation=\
Should not use eager lazy evaluation. Use eager version instead.
crules.no.defined.by=\
This method implements a public API method, and should be marked with @DefinedBy.
crules.wrong.defined.by=\

View File

@ -28,6 +28,7 @@ package javax.tools;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* Provides an easy way to collect diagnostics in a list.
@ -43,7 +44,7 @@ public final class DiagnosticCollector<S> implements DiagnosticListener<S> {
Collections.synchronizedList(new ArrayList<Diagnostic<? extends S>>());
public void report(Diagnostic<? extends S> diagnostic) {
diagnostic.getClass(); // null check
Objects.requireNonNull(diagnostic);
diagnostics.add(diagnostic);
}

View File

@ -31,6 +31,7 @@ import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.URI;
import java.util.Objects;
/**
* Forwards calls to a given file object. Subclasses of this class
@ -53,8 +54,7 @@ public class ForwardingFileObject<F extends FileObject> implements FileObject {
* @param fileObject delegate to this file object
*/
protected ForwardingFileObject(F fileObject) {
fileObject.getClass(); // null check
this.fileObject = fileObject;
this.fileObject = Objects.requireNonNull(fileObject);
}
public URI toUri() {

View File

@ -27,6 +27,7 @@ package javax.tools;
import java.io.IOException;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
import javax.tools.JavaFileObject.Kind;
@ -51,8 +52,7 @@ public class ForwardingJavaFileManager<M extends JavaFileManager> implements Jav
* @param fileManager delegate to this file manager
*/
protected ForwardingJavaFileManager(M fileManager) {
fileManager.getClass(); // null check
this.fileManager = fileManager;
this.fileManager = Objects.requireNonNull(fileManager);
}
/**

View File

@ -27,6 +27,7 @@ package javax.tools;
import javax.lang.model.element.NestingKind;
import javax.lang.model.element.Modifier;
import java.util.Objects;
/**
* File abstraction for tools operating on Java&trade; programming language
@ -78,8 +79,7 @@ public interface JavaFileObject extends FileObject {
*/
public final String extension;
private Kind(String extension) {
extension.getClass(); // null check
this.extension = extension;
this.extension = Objects.requireNonNull(extension);
}
}

View File

@ -28,6 +28,7 @@ package javax.tools;
import java.io.*;
import java.net.URI;
import java.nio.CharBuffer;
import java.util.Objects;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.tools.JavaFileObject.Kind;
@ -61,9 +62,8 @@ public class SimpleJavaFileObject implements JavaFileObject {
* @param kind the kind of this file object
*/
protected SimpleJavaFileObject(URI uri, Kind kind) {
// null checks
uri.getClass();
kind.getClass();
Objects.requireNonNull(uri);
Objects.requireNonNull(kind);
if (uri.getPath() == null)
throw new IllegalArgumentException("URI must have a path: " + uri);
this.uri = uri;

View File

@ -27,7 +27,9 @@ package com.sun.source.util;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
import java.util.Iterator;
import java.util.Objects;
/**
* A path of tree nodes, typically used to represent the sequence of ancestor
@ -57,8 +59,8 @@ public class DocTreePath implements Iterable<DocTree> {
* @return a path identifying the target node
*/
public static DocTreePath getPath(DocTreePath path, DocTree target) {
path.getClass();
target.getClass();
Objects.requireNonNull(path); //null check
Objects.requireNonNull(target); //null check
class Result extends Error {
static final long serialVersionUID = -5942088234594905625L;
@ -96,11 +98,8 @@ public class DocTreePath implements Iterable<DocTree> {
* @param t the DocCommentTree to create the path for.
*/
public DocTreePath(TreePath treePath, DocCommentTree t) {
treePath.getClass();
t.getClass();
this.treePath = treePath;
this.docComment = t;
this.treePath = Objects.requireNonNull(treePath);
this.docComment = Objects.requireNonNull(t);
this.parent = null;
this.leaf = t;
}

View File

@ -26,6 +26,7 @@
package com.sun.source.util;
import java.util.Iterator;
import java.util.Objects;
import com.sun.source.tree.*;
@ -57,8 +58,8 @@ public class TreePath implements Iterable<Tree> {
* @return the tree path of the target node
*/
public static TreePath getPath(TreePath path, Tree target) {
path.getClass();
target.getClass();
Objects.requireNonNull(path);
Objects.requireNonNull(target);
class Result extends Error {
static final long serialVersionUID = -5942088234594905625L;

View File

@ -30,6 +30,7 @@ import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
/**
* <p><b>This is NOT part of any supported API.
@ -39,13 +40,9 @@ import java.io.InputStream;
*/
public class ClassReader {
ClassReader(ClassFile classFile, InputStream in, Attribute.Factory attributeFactory) throws IOException {
// null checks
classFile.getClass();
attributeFactory.getClass();
this.classFile = classFile;
this.classFile = Objects.requireNonNull(classFile);
this.attributeFactory = Objects.requireNonNull(attributeFactory);
this.in = new DataInputStream(new BufferedInputStream(in));
this.attributeFactory = attributeFactory;
}
ClassFile getClassFile() {

View File

@ -30,6 +30,7 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
@ -43,6 +44,7 @@ import com.sun.tools.classfile.Type.MethodType;
import com.sun.tools.classfile.Type.SimpleType;
import com.sun.tools.classfile.Type.TypeParamType;
import com.sun.tools.classfile.Type.WildcardType;
import static com.sun.tools.classfile.ConstantPool.*;
/**
@ -165,8 +167,7 @@ public class Dependencies {
* @param f the finder
*/
public void setFinder(Finder f) {
f.getClass(); // null check
finder = f;
finder = Objects.requireNonNull(f);
}
/**
@ -220,8 +221,7 @@ public class Dependencies {
* @param f the filter
*/
public void setFilter(Filter f) {
f.getClass(); // null check
filter = f;
filter = Objects.requireNonNull(f);
}
/**

View File

@ -81,6 +81,7 @@ import com.sun.source.util.DocTreePathScanner;
import com.sun.source.util.TreePath;
import com.sun.tools.doclint.HtmlTag.AttrKind;
import com.sun.tools.javac.tree.DocPretty;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.StringUtils;
@ -137,8 +138,7 @@ public class Checker extends DocTreePathScanner<Void, Void> {
// <editor-fold defaultstate="collapsed" desc="Top level">
Checker(Env env) {
env.getClass();
this.env = env;
this.env = Assert.checkNonNull(env);
tagStack = new LinkedList<>();
implicitHeaderLevel = env.implicitHeaderLevel;
}

View File

@ -45,6 +45,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.lang.model.element.Modifier;
@ -211,8 +212,7 @@ public class ClientCodeWrapper {
protected class WrappedJavaFileManager implements JavaFileManager {
protected JavaFileManager clientJavaFileManager;
WrappedJavaFileManager(JavaFileManager clientJavaFileManager) {
clientJavaFileManager.getClass(); // null check
this.clientJavaFileManager = clientJavaFileManager;
this.clientJavaFileManager = Objects.requireNonNull(clientJavaFileManager);
}
@Override @DefinedBy(Api.COMPILER)
@ -440,8 +440,7 @@ public class ClientCodeWrapper {
protected class WrappedFileObject implements FileObject {
protected FileObject clientFileObject;
WrappedFileObject(FileObject clientFileObject) {
clientFileObject.getClass(); // null check
this.clientFileObject = clientFileObject;
this.clientFileObject = Objects.requireNonNull(clientFileObject);
}
@Override @DefinedBy(Api.COMPILER)
@ -607,8 +606,7 @@ public class ClientCodeWrapper {
protected class WrappedDiagnosticListener<T /*super JavaFileObject*/> implements DiagnosticListener<T> {
protected DiagnosticListener<T> clientDiagnosticListener;
WrappedDiagnosticListener(DiagnosticListener<T> clientDiagnosticListener) {
clientDiagnosticListener.getClass(); // null check
this.clientDiagnosticListener = clientDiagnosticListener;
this.clientDiagnosticListener = Objects.requireNonNull(clientDiagnosticListener);
}
@Override @DefinedBy(Api.COMPILER)
@ -689,8 +687,7 @@ public class ClientCodeWrapper {
protected class WrappedTaskListener implements TaskListener {
protected TaskListener clientTaskListener;
WrappedTaskListener(TaskListener clientTaskListener) {
clientTaskListener.getClass(); // null check
this.clientTaskListener = clientTaskListener;
this.clientTaskListener = Objects.requireNonNull(clientTaskListener);
}
@Override @DefinedBy(Api.COMPILER_TREE)

View File

@ -34,8 +34,7 @@ import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.Assert;
/**
* Provides an implementation of Scope.
@ -67,8 +66,7 @@ public class JavacScope implements com.sun.source.tree.Scope {
protected final Env<AttrContext> env;
private JavacScope(Env<AttrContext> env) {
env.getClass(); // null-check
this.env = env;
this.env = Assert.checkNonNull(env);
}
@DefinedBy(Api.COMPILER_TREE)

View File

@ -108,7 +108,7 @@ public class JavacTaskImpl extends BasicJavacTask {
@Override @DefinedBy(Api.COMPILER)
public void setProcessors(Iterable<? extends Processor> processors) {
processors.getClass(); // null check
Objects.requireNonNull(processors);
// not mt-safe
if (used.get())
throw new IllegalStateException();

View File

@ -34,6 +34,7 @@ import java.nio.charset.Charset;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import javax.lang.model.SourceVersion;
@ -124,7 +125,7 @@ public final class JavacTool implements JavaCompiler {
if (options != null) {
for (String option : options)
option.getClass(); // null check
Objects.requireNonNull(option);
}
if (classes != null) {
@ -177,7 +178,7 @@ public final class JavacTool implements JavaCompiler {
if (err == null)
err = System.err;
for (String argument : arguments)
argument.getClass(); // null check
Objects.requireNonNull(argument);
return com.sun.tools.javac.Main.compile(arguments, new PrintWriter(err, true));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2015, 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
@ -299,7 +299,7 @@ public class Flags {
public static final long
ExtendedStandardFlags = (long)StandardFlags | DEFAULT,
ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT,
InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT,
InterfaceMethodMask = ABSTRACT | PRIVATE | STATIC | PUBLIC | STRICTFP | DEFAULT,
AnnotationTypeElementMask = ABSTRACT | PUBLIC,
LocalVarFlags = FINAL | PARAMETER,
ReceiverParamFlags = PARAMETER;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2015, 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
@ -212,6 +212,7 @@ public enum Source {
public boolean allowUnderscoreIdentifier() {
return compareTo(JDK1_8) <= 0;
}
public boolean allowPrivateInterfaceMethods() { return compareTo(JDK1_9) >= 0; }
public static SourceVersion toSourceVersion(Source source) {
switch(source) {
case JDK1_2:

View File

@ -147,6 +147,7 @@ public class Symtab {
/** Predefined types.
*/
public final Type objectType;
public final Type objectsType;
public final Type classType;
public final Type classLoaderType;
public final Type stringType;
@ -184,6 +185,7 @@ public class Symtab {
public final Type retentionType;
public final Type deprecatedType;
public final Type suppressWarningsType;
public final Type supplierType;
public final Type inheritedType;
public final Type profileType;
public final Type proprietaryType;
@ -407,6 +409,7 @@ public class Symtab {
// Enter predefined classes.
objectType = enterClass("java.lang.Object");
objectsType = enterClass("java.util.Objects");
classType = enterClass("java.lang.Class");
stringType = enterClass("java.lang.String");
stringBufferType = enterClass("java.lang.StringBuffer");
@ -449,6 +452,7 @@ public class Symtab {
retentionType = enterClass("java.lang.annotation.Retention");
deprecatedType = enterClass("java.lang.Deprecated");
suppressWarningsType = enterClass("java.lang.SuppressWarnings");
supplierType = enterClass("java.util.function.Supplier");
inheritedType = enterClass("java.lang.annotation.Inherited");
repeatableType = enterClass("java.lang.annotation.Repeatable");
documentedType = enterClass("java.lang.annotation.Documented");

View File

@ -168,6 +168,18 @@ public class Types {
}
else return t;
}
/**
* Recursively skip type-variables until a class/array type is found; capture conversion is then
* (optionally) applied to the resulting type. This is useful for i.e. computing a site that is
* suitable for a method lookup.
*/
public Type skipTypeVars(Type site, boolean capture) {
while (site.hasTag(TYPEVAR)) {
site = site.getUpperBound();
}
return capture ? capture(site) : site;
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isUnbounded">
@ -1787,12 +1799,9 @@ public class Types {
}
private Type relaxBound(Type t) {
if (t.hasTag(TYPEVAR)) {
while (t.hasTag(TYPEVAR))
t = t.getUpperBound();
t = rewriteQuantifiers(t, true, true);
}
return t;
return (t.hasTag(TYPEVAR)) ?
rewriteQuantifiers(skipTypeVars(t, false), true, true) :
t;
}
// </editor-fold>
@ -1872,10 +1881,7 @@ public class Types {
*/
private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
public Type apply(Type t) {
while (t.hasTag(TYPEVAR)) {
t = t.getUpperBound();
}
return elemtype(t);
return elemtype(skipTypeVars(t, false));
}
};
@ -2662,8 +2668,7 @@ public class Types {
private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
for (Type t = origin.type; t.hasTag(CLASS) || t.hasTag(TYPEVAR); t = supertype(t)) {
while (t.hasTag(TYPEVAR))
t = t.getUpperBound();
t = skipTypeVars(t, false);
TypeSymbol c = t.tsym;
Symbol bestSoFar = null;
for (Symbol sym : c.members().getSymbolsByName(ms.name, implFilter)) {

View File

@ -3176,8 +3176,7 @@ public class Attr extends JCTree.Visitor {
tree.sym = sym;
if (site.hasTag(TYPEVAR) && !isType(sym) && sym.kind != ERR) {
while (site.hasTag(TYPEVAR)) site = site.getUpperBound();
site = capture(site);
site = types.skipTypeVars(site, true);
}
// If that symbol is a variable, ...

View File

@ -1056,9 +1056,9 @@ public class Check {
if ((sym.owner.flags_field & ANNOTATION) != 0) {
mask = AnnotationTypeElementMask;
implicit = PUBLIC | ABSTRACT;
} else if ((flags & (DEFAULT | STATIC)) != 0) {
} else if ((flags & (DEFAULT | STATIC | PRIVATE)) != 0) {
mask = InterfaceMethodMask;
implicit = PUBLIC;
implicit = (flags & PRIVATE) != 0 ? 0 : PUBLIC;
if ((flags & DEFAULT) != 0) {
implicit |= ABSTRACT;
}
@ -1128,7 +1128,7 @@ public class Check {
PRIVATE | STATIC | DEFAULT))
&&
checkDisjoint(pos, flags,
STATIC,
STATIC | PRIVATE,
DEFAULT)
&&
checkDisjoint(pos, flags,
@ -1623,8 +1623,7 @@ public class Check {
}
// Error if overriding method has weaker access (JLS 8.4.6.3).
if ((origin.flags() & INTERFACE) == 0 &&
protection(m.flags()) > protection(other.flags())) {
if (protection(m.flags()) > protection(other.flags())) {
log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.weaker.access",
cannotOverride(m, other),
(other.flags() & AccessFlags) == 0 ?

View File

@ -28,7 +28,6 @@ package com.sun.tools.javac.comp;
import com.sun.source.tree.LambdaExpressionTree.BodyKind;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.comp.Resolve.ResolveError;
import com.sun.tools.javac.resources.CompilerProperties;
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.util.*;
@ -1372,11 +1371,7 @@ public class DeferredAttr extends JCTree.Visitor {
site = env.enclClass.sym.type;
}
while (site.hasTag(TYPEVAR)) {
site = site.getUpperBound();
}
site = types.capture(site);
site = types.skipTypeVars(site, true);
List<Type> args = rs.dummyArgs(tree.args.length());
Name name = TreeInfo.name(tree.meth);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2015, 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
@ -1037,7 +1037,7 @@ public class Lower extends TreeTranslator {
MethodSymbol accessor = accessors[acode];
if (accessor == null) {
accessor = new MethodSymbol(
STATIC | SYNTHETIC,
STATIC | SYNTHETIC | (accOwner.isInterface() ? PUBLIC : 0),
accessName(anum.intValue(), acode),
new MethodType(argtypes, restype, thrown, syms.methodClass),
accOwner);
@ -3446,10 +3446,7 @@ public class Lower extends TreeTranslator {
syms.iterableType.tsym);
if (iterableType.getTypeArguments().nonEmpty())
iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
Type eType = tree.expr.type;
while (eType.hasTag(TYPEVAR)) {
eType = eType.getUpperBound();
}
Type eType = types.skipTypeVars(tree.expr.type, false);
tree.expr.type = types.erasure(eType);
if (eType.isCompound())
tree.expr = make.TypeCast(types.erasure(iterableType), tree.expr);

View File

@ -1791,8 +1791,7 @@ public class Resolve {
!t.hasTag(TYPEVAR)) {
return null;
}
while (t.hasTag(TYPEVAR))
t = t.getUpperBound();
t = types.skipTypeVars(t, false);
if (seen.contains(t.tsym)) {
//degenerate case in which we have a circular
//class hierarchy - because of ill-formed classfiles
@ -2656,11 +2655,9 @@ public class Resolve {
InferenceContext inferenceContext,
ReferenceChooser referenceChooser) {
site = types.capture(site);
//step 1 - bound lookup
ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
referenceTree, site, name, argtypes, typeargtypes, VARARITY);
//step 1 - bound lookup
Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
boundSearchResolveContext.methodCheck = methodCheck;
@ -3044,9 +3041,13 @@ public class Resolve {
*/
class MethodReferenceLookupHelper extends ReferenceLookupHelper {
/** The original method reference lookup site. */
Type originalSite;
MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
super(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase);
this.originalSite = site;
}
@Override
@ -3062,7 +3063,7 @@ public class Resolve {
(argtypes.head.hasTag(NONE) ||
types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) {
return new UnboundMethodReferenceLookupHelper(referenceTree, name,
site, argtypes, typeargtypes, maxPhase);
originalSite, argtypes, typeargtypes, maxPhase);
} else {
return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
@Override
@ -3114,7 +3115,7 @@ public class Resolve {
super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
this.site = types.capture(asSuperSite);
this.site = types.skipTypeVars(asSuperSite, true);
}
}

View File

@ -818,9 +818,7 @@ public class TransTypes extends TreeTranslator {
}
public void visitSelect(JCFieldAccess tree) {
Type t = tree.selected.type;
while (t.hasTag(TYPEVAR))
t = t.getUpperBound();
Type t = types.skipTypeVars(tree.selected.type, false);
if (t.isCompound()) {
if ((tree.sym.flags() & IPROXY) != 0) {
tree.sym = ((MethodSymbol)tree.sym).

View File

@ -49,6 +49,7 @@ import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -682,8 +683,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
@Override @DefinedBy(Api.COMPILER)
public String inferBinaryName(Location location, JavaFileObject file) {
file.getClass(); // null check
location.getClass(); // null check
Objects.requireNonNull(file);
Objects.requireNonNull(location);
// Need to match the path semantics of list(location, ...)
Iterable<? extends Path> path = getLocationAsPaths(location);
if (path == null) {

View File

@ -44,6 +44,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@ -784,7 +785,7 @@ public class Locations {
}
protected LocationHandler getHandler(Location location) {
location.getClass(); // null check
Objects.requireNonNull(location);
return handlersForLocation.get(location);
}

View File

@ -40,6 +40,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.Normalizer;
import java.util.Objects;
import javax.tools.JavaFileObject;
@ -186,7 +187,7 @@ class RegularFileObject extends BaseFileObject {
@Override @DefinedBy(Api.COMPILER)
public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) {
cn.getClass();
Objects.requireNonNull(cn);
// null check
if (kind == Kind.OTHER && getKind() != kind) {
return false;

View File

@ -40,6 +40,7 @@ import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@ -254,7 +255,7 @@ public class ZipArchive implements Archive {
@Override @DefinedBy(Api.COMPILER)
public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
cn.getClass();
Objects.requireNonNull(cn);
// null check
if (k == Kind.OTHER && getKind() != k) {
return false;

View File

@ -35,6 +35,7 @@ import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Set;
import javax.tools.JavaFileObject;
@ -206,7 +207,7 @@ public class ZipFileIndexArchive implements Archive {
@Override @DefinedBy(Api.COMPILER)
public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
cn.getClass(); // null check
Objects.requireNonNull(cn);
if (k == Kind.OTHER && getKind() != k)
return false;
return name.equals(cn + k.extension);

View File

@ -124,6 +124,7 @@ public class Gen extends JCTree.Visitor {
genCrt = options.isSet(XJCOV);
debugCode = options.isSet("debugcode");
allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic");
allowBetterNullChecks = target.hasObjects();
pool = new Pool(types);
// ignore cldc because we cannot have both stackmap formats
@ -150,6 +151,7 @@ public class Gen extends JCTree.Visitor {
private final boolean genCrt;
private final boolean debugCode;
private final boolean allowInvokedynamic;
private final boolean allowBetterNullChecks;
/** Default limit of (approximate) size of finalizer to inline.
* Zero means always use jsr. 100 or greater means never use
@ -1983,8 +1985,13 @@ public class Gen extends JCTree.Visitor {
/** Generate a null check from the object value at stack top. */
private void genNullCheck(DiagnosticPosition pos) {
callMethod(pos, syms.objectType, names.getClass,
List.<Type>nil(), false);
if (allowBetterNullChecks) {
callMethod(pos, syms.objectsType, names.requireNonNull,
List.of(syms.objectType), true);
} else {
callMethod(pos, syms.objectType, names.getClass,
List.<Type>nil(), false);
}
code.emitop0(pop);
}

View File

@ -121,6 +121,12 @@ public enum Target {
return compareTo(JDK1_7) >= 0;
}
/** Does the target JDK contains the java.util.Objects class?
*/
public boolean hasObjects() {
return compareTo(JDK1_7) >= 0;
}
/** Does the VM support polymorphic method handle invocation?
* Affects the linkage information output to the classfile.
* An alias for {@code hasInvokedynamic}, since all the JSR 292 features appear together.

View File

@ -39,6 +39,7 @@ import java.nio.charset.CharsetDecoder;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.util.Objects;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.tools.JavaFileObject;
@ -151,10 +152,8 @@ public abstract class PathFileObject implements JavaFileObject {
}
protected PathFileObject(BaseFileManager fileManager, Path path) {
fileManager.getClass(); // null check
path.getClass(); // null check
this.fileManager = fileManager;
this.path = path;
this.fileManager = Objects.requireNonNull(fileManager);
this.path = Objects.requireNonNull(path);
}
public abstract String inferBinaryName(Iterable<? extends Path> paths);
@ -174,7 +173,7 @@ public abstract class PathFileObject implements JavaFileObject {
@Override @DefinedBy(Api.COMPILER)
public boolean isNameCompatible(String simpleName, Kind kind) {
simpleName.getClass();
Objects.requireNonNull(simpleName);
// null check
if (kind == Kind.OTHER && getKind() != kind) {
return false;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2015, 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
@ -32,6 +32,7 @@ import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.parser.Tokens.*;
import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
import com.sun.tools.javac.resources.CompilerProperties;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.*;
@ -158,6 +159,7 @@ public class JavacParser implements Parser {
this.allowTypeAnnotations = source.allowTypeAnnotations();
this.allowAnnotationsAfterTypeParams = source.allowAnnotationsAfterTypeParams();
this.allowUnderscoreIdentifier = source.allowUnderscoreIdentifier();
this.allowPrivateInterfaceMethods = source.allowPrivateInterfaceMethods();
this.keepDocComments = keepDocComments;
docComments = newDocCommentTable(keepDocComments, fac);
this.keepLineMap = keepLineMap;
@ -211,6 +213,10 @@ public class JavacParser implements Parser {
*/
boolean allowStaticInterfaceMethods;
/** Switch: should we allow private (instance) methods in interfaces?
*/
boolean allowPrivateInterfaceMethods;
/** Switch: should we allow intersection types in cast?
*/
boolean allowIntersectionTypesInCast;
@ -3487,8 +3493,13 @@ public class JavacParser implements Parser {
List<JCTypeParameter> typarams,
boolean isInterface, boolean isVoid,
Comment dc) {
if (isInterface && (mods.flags & Flags.STATIC) != 0) {
checkStaticInterfaceMethods();
if (isInterface) {
if ((mods.flags & Flags.STATIC) != 0) {
checkStaticInterfaceMethods();
}
if ((mods.flags & Flags.PRIVATE) != 0) {
checkPrivateInterfaceMethods();
}
}
JCVariableDecl prevReceiverParam = this.receiverParam;
try {
@ -4002,6 +4013,12 @@ public class JavacParser implements Parser {
allowTypeAnnotations = true;
}
}
void checkPrivateInterfaceMethods() {
if (!allowPrivateInterfaceMethods) {
log.error(token.pos, CompilerProperties.Errors.PrivateIntfMethodsNotSupportedInSource(source.name));
allowPrivateInterfaceMethods = true;
}
}
protected void checkAnnotationsAfterTypeParams(int pos) {
if (!allowAnnotationsAfterTypeParams) {
log.error(pos, "annotations.after.type.params.not.supported.in.source", source.name);

View File

@ -2421,6 +2421,11 @@ compiler.err.static.intf.method.invoke.not.supported.in.source=\
static interface method invocations are not supported in -source {0}\n\
(use -source 8 or higher to enable static interface method invocations)
# 0: string
compiler.err.private.intf.methods.not.supported.in.source=\
private interface methods are not supported in -source {0}\n\
(use -source 9 or higher to enable private interface methods)
########################################
# Diagnostics for verbose resolution
# used by Resolve (debug only)

View File

@ -2443,8 +2443,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public TypeBoundKind kind;
public JCTree inner;
protected JCWildcard(TypeBoundKind kind, JCTree inner) {
kind.getClass(); // null-check
this.kind = kind;
this.kind = Assert.checkNonNull(kind);
this.inner = inner;
}
@Override

View File

@ -129,7 +129,7 @@ public class TreeMaker implements JCTree.Factory {
|| node instanceof JCErroneous
|| (node instanceof JCExpressionStatement
&& ((JCExpressionStatement)node).expr instanceof JCErroneous),
node.getClass().getSimpleName());
() -> node.getClass().getSimpleName());
JCCompilationUnit tree = new JCCompilationUnit(defs);
tree.pos = pos;
return tree;

View File

@ -25,6 +25,8 @@
package com.sun.tools.javac.util;
import java.util.function.Supplier;
/**
* Simple facility for unconditional assertions.
* The methods in this class are described in terms of equivalent assert
@ -93,6 +95,15 @@ public class Assert {
error(msg);
}
/** Equivalent to
* assert cond : msg.get();
* Note: message string is computed lazily.
*/
public static void check(boolean cond, Supplier<String> msg) {
if (!cond)
error(msg.get());
}
/** Equivalent to
* assert (o == null) : value;
*/
@ -109,6 +120,15 @@ public class Assert {
error(msg);
}
/** Equivalent to
* assert (o == null) : msg.get();
* Note: message string is computed lazily.
*/
public static void checkNull(Object o, Supplier<String> msg) {
if (o != null)
error(msg.get());
}
/** Equivalent to
* assert (o != null) : msg;
*/
@ -118,6 +138,16 @@ public class Assert {
return t;
}
/** Equivalent to
* assert (o != null) : msg.get();
* Note: message string is computed lazily.
*/
public static <T> T checkNonNull(T t, Supplier<String> msg) {
if (t == null)
error(msg.get());
return t;
}
/** Equivalent to
* assert false;
*/

View File

@ -46,6 +46,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.tools.JavaFileManager;
@ -431,13 +432,12 @@ public abstract class BaseFileManager implements JavaFileManager {
}
protected static <T> T nullCheck(T o) {
o.getClass(); // null check
return o;
return Objects.requireNonNull(o);
}
protected static <T> Collection<T> nullCheck(Collection<T> it) {
for (T t : it)
t.getClass(); // null check
Objects.requireNonNull(t);
return it;
}
}

View File

@ -124,7 +124,7 @@ public class ListBuffer<A> extends AbstractQueue<A> {
/** Append an element to buffer.
*/
public ListBuffer<A> append(A x) {
x.getClass(); // null check
Assert.checkNonNull(x);
if (shared) copy();
List<A> newLast = List.<A>of(x);
if (last != null) {

View File

@ -341,7 +341,7 @@ public class Log extends AbstractLog {
}
public void setEndPosTable(JavaFileObject name, EndPosTable endPosTable) {
name.getClass(); // null check
Assert.checkNonNull(name);
getSource(name).setEndPosTable(endPosTable);
}
@ -373,7 +373,7 @@ public class Log extends AbstractLog {
}
public void setWriter(WriterKind kind, PrintWriter pw) {
pw.getClass();
Assert.checkNonNull(pw);
switch (kind) {
case NOTICE: noticeWriter = pw; break;
case WARNING: warnWriter = pw; break;
@ -383,8 +383,7 @@ public class Log extends AbstractLog {
}
public void setWriters(PrintWriter pw) {
pw.getClass();
noticeWriter = warnWriter = errWriter = pw;
noticeWriter = warnWriter = errWriter = Assert.checkNonNull(pw);
}
/**

View File

@ -171,6 +171,7 @@ public class Names {
public final Name deprecated;
public final Name ex;
public final Name package_info;
public final Name requireNonNull;
//lambda-related
public final Name lambda;
@ -307,6 +308,7 @@ public class Names {
deprecated = fromString("deprecated");
ex = fromString("ex");
package_info = fromString("package-info");
requireNonNull = fromString("requireNonNull");
//lambda-related
lambda = fromString("lambda$");

View File

@ -43,6 +43,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.Set;
@ -268,7 +269,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
this.classes = new ArrayList<>();
if (classes != null) {
for (String classname: classes) {
classname.getClass(); // null-check
Objects.requireNonNull(classname);
this.classes.add(classname);
}
}

View File

@ -62,6 +62,8 @@ import com.sun.tools.classfile.StackMap_attribute;
import com.sun.tools.classfile.Synthetic_attribute;
import static com.sun.tools.classfile.AccessFlags.*;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.StringUtils;
/*
@ -93,9 +95,8 @@ public class AttributeWriter extends BasicWriter
public void write(Object owner, Attribute attr, ConstantPool constant_pool) {
if (attr != null) {
// null checks
owner.getClass();
constant_pool.getClass();
Assert.checkNonNull(constant_pool);
Assert.checkNonNull(owner);
this.constant_pool = constant_pool;
this.owner = owner;
attr.accept(this, null);
@ -104,9 +105,8 @@ public class AttributeWriter extends BasicWriter
public void write(Object owner, Attributes attrs, ConstantPool constant_pool) {
if (attrs != null) {
// null checks
owner.getClass();
constant_pool.getClass();
Assert.checkNonNull(constant_pool);
Assert.checkNonNull(owner);
this.constant_pool = constant_pool;
this.owner = owner;
for (Attribute attr: attrs)

View File

@ -53,6 +53,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Objects;
import java.util.ResourceBundle;
import javax.lang.model.element.Modifier;
@ -329,7 +330,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
this.classes = new ArrayList<>();
for (String classname: classes) {
classname.getClass(); // null-check
Objects.requireNonNull(classname);
this.classes.add(classname);
}

View File

@ -28,6 +28,7 @@ package com.sun.tools.doclets.internal.toolkit;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Objects;
import com.sun.tools.doclets.internal.toolkit.util.*;
@ -112,7 +113,6 @@ public abstract class Content {
* @return the reference type if not null or else throws a null pointer exception
*/
protected static <T> T nullCheck(T t) {
t.getClass();
return t;
return Objects.requireNonNull(t);
}
}

View File

@ -33,6 +33,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
@ -139,8 +140,7 @@ public class Start extends ToolOption.Helper {
}
public Start(Context context) {
context.getClass(); // null check
this.context = context;
this.context = Objects.requireNonNull(context);
apiMode = true;
defaultDocletClassName = standardDocletClassName;
docletParentClassLoader = null;

View File

@ -34,6 +34,7 @@ import java.nio.charset.Charset;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import javax.lang.model.SourceVersion;
@ -89,7 +90,7 @@ public class JavadocTool implements DocumentationTool {
if (options != null) {
for (String option : options)
option.getClass(); // null check
Objects.requireNonNull(option);
}
if (compilationUnits != null) {

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2015, 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 8074306
* @summary NULLCHK is emitted as Object.getClass
* @compile -source 6 -target 6 TestSyntheticNullChecks.java
* @run main TestSyntheticNullChecks 6
* @clean TestSyntheticNullChecks*
* @compile -source 7 -target 7 TestSyntheticNullChecks.java
* @run main TestSyntheticNullChecks 7
* @clean TestSyntheticNullChecks*
* @compile TestSyntheticNullChecks.java
* @run main TestSyntheticNullChecks 9
*/
public class TestSyntheticNullChecks {
class Inner { }
static void generateSyntheticNPE(TestSyntheticNullChecks outer) {
outer.new Inner(); //javac will generate a synthetic NPE check for 'outer'
}
public static void main(String[] args) {
int version = Integer.valueOf(args[0]);
boolean useObjects = version >= 7;
try {
generateSyntheticNPE(null);
} catch (NullPointerException npe) {
boolean hasRequireNotNull = false;
for (StackTraceElement e : npe.getStackTrace()) {
if (e.getClassName().equals("java.util.Objects") &&
e.getMethodName().equals("requireNonNull")) {
hasRequireNotNull = true;
break;
}
}
if (hasRequireNotNull != useObjects) {
throw new AssertionError();
}
}
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2015, 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 8071453
* @summary smoke test for private interface methods featuring accessor methods
*/
public class Private01 {
interface P {
private void foo() { System.out.println("foo!" + this); }
default void m() {
new Object() { void test() { foo(); } }.test();
}
}
public static void main(String[] args) {
P p = new P() {};
p.m(); p.foo();
}
}

View File

@ -0,0 +1,24 @@
/*
* @test /nodynamiccopyright/
* @bug 8071453
* @author sadayapalam
* @summary Various tests for private methods in interfaces.
* @compile/fail/ref=Private02.out -XDrawDiagnostics Private02.java
*/
public class Private02 {
interface I {
private void foo(String s); // Error: private method must declare body.
private abstract void foo(int i, int j); // Error: private & abstract: bad combo
void foo(int x); // OK.
private I foo() { return null; } // OK.
private void foo(int x) {} // Name clash.
}
interface J extends I {
private J foo() { return null; } // OK.
}
interface K extends J {
void foo(); // OK
}
}

View File

@ -0,0 +1,4 @@
Private02.java:13:31: compiler.err.illegal.combination.of.modifiers: abstract, private
Private02.java:16:22: compiler.err.already.defined: kindname.method, foo(int), kindname.interface, Private02.I
Private02.java:12:22: compiler.err.missing.meth.body.or.decl.abstract
3 errors

View File

@ -0,0 +1,27 @@
/*
* @test /nodynamiccopyright/
* @bug 8071453
* @author sadayapalam
* @summary Various tests for private methods in interfaces.
* @compile/fail/ref=Private03.out -XDrawDiagnostics Private03.java
*/
public class Private03 {
interface I {
private void foo(int x) {}
private void goo(int x) {}
}
interface J extends I {
// Verify that we are able to declare a public abstract method with the same signature as a private method in super type.
void foo(int x);
// Verify that we are able to declare a public default method with the same signature as a private method in super type.
default void goo(int x) {}
}
interface K extends J {
private void foo(int x) {} // Error, cannot reduce visibility
private void goo(int x) {} // Ditto.
}
}

View File

@ -0,0 +1,3 @@
Private03.java:25:22: compiler.err.override.weaker.access: (compiler.misc.clashes.with: goo(int), Private03.K, goo(int), Private03.J), public
Private03.java:24:22: compiler.err.override.weaker.access: (compiler.misc.clashes.with: foo(int), Private03.K, foo(int), Private03.J), public
2 errors

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2015, 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 8071453
* @author sadayapalam
* @summary Verify that adding private methods does not disqualify an interface from being functional
*/
public class Private04 {
@FunctionalInterface
interface SubRunnable extends Runnable {
private void run(int x) {
SubRunnable s = () -> {};
}
}
public static void main(String [] args) {
SubRunnable s = () -> {};
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, 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 8071453
* @author sadayapalam
* @summary Execution test for private interface methods (instance and static)
*/
public interface Private05 {
private static String staticPrivate() {
return "static private";
}
private String instancePrivate() {
return "instance private";
}
public static void main(String [] args) {
String result = staticPrivate();
if (!result.equals("static private"))
throw new AssertionError("Incorrect result for static private interface method");
Private05 pvt = new Private05() {};
result = pvt.instancePrivate();
if (!result.equals("instance private"))
throw new AssertionError("Incorrect result for instance private interface method");
}
}

View File

@ -0,0 +1,30 @@
/* @test /nodynamiccopyright/
* @bug 8071453
* @author sadayapalam
* @summary Test that a lone private interface method cannot supply the SAM.
* @compile/fail/ref=Private06.out -XDrawDiagnostics Private06.java
*/
public class Private06 {
@FunctionalInterface
interface NAFI {
private void foo() {
}
}
@FunctionalInterface
interface FI {
void foo(NAFI nafi);
}
public static void main(String [] args) {
Private06.NAFI nafi = () -> {};
Private06.FI fi = Private06.NAFI::foo; // OK.
}
}
class Private06_01 {
public static void main(String [] args) {
Private06.FI fi = Private06.NAFI::foo; // NOT OK.
}
}

View File

@ -0,0 +1,4 @@
Private06.java:9:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: Private06.NAFI, (compiler.misc.no.abstracts: kindname.interface, Private06.NAFI))
Private06.java:21:31: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: Private06.NAFI, (compiler.misc.no.abstracts: kindname.interface, Private06.NAFI))
Private06.java:28:27: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.report.access: foo(), private, Private06.NAFI))
3 errors

View File

@ -0,0 +1,10 @@
/* @test /nodynamiccopyright/
* @bug 8071453
* @author sadayapalam
* @summary Test that annotations types cannot declare private methods
* @compile/fail/ref=Private07.out -XDrawDiagnostics Private07.java
*/
@interface Private07 {
private String name();
}

View File

@ -0,0 +1,2 @@
Private07.java:9:20: compiler.err.mod.not.allowed.here: private
1 error

View File

@ -0,0 +1,37 @@
/* @test /nodynamiccopyright/
* @bug 8071453
* @author sadayapalam
* @summary Test various JLS changes made for supporting private interface methods.
* @compile/fail/ref=Private08.out -XDrawDiagnostics Private08.java
*/
class Private08 {
interface I {
private void poo() {}
private int foo() { return 0; }
int goo();
default int doo() { return foo(); }
private public int bad(); // 9.4 illegal combination of modifiers
private abstract int verybad(); // 9.4 illegal combination of modifiers
private default int alsobad() { return foo(); } // 9.4 illegal combination of modifiers
protected void blah();
private void missingBody(); // private methods are not abstract.
}
}
class Private08_01 {
int y = ((Private08.I) null).foo(); // 9.4 test that private methods are not implicitly public.
interface J extends Private08.I {
default void foo() { // foo not inherited from super, change of return type is OK.
super.foo(); // super in static context - Error.
}
private int doo() { return 0; } // private cannot override public.
};
Private08.I i = new Private08.I () {
public void foo() { // foo not inherited from super, change of return type is OK.
super.foo(); // super's foo not inherited, NOT OK.
}
private int doo() { return 0; } // private cannot override public.
}; // should not complain about poo() not being implemented.
}

View File

@ -0,0 +1,13 @@
Private08.java:13:28: compiler.err.illegal.combination.of.modifiers: public, private
Private08.java:14:30: compiler.err.illegal.combination.of.modifiers: abstract, private
Private08.java:15:29: compiler.err.illegal.combination.of.modifiers: private, default
Private08.java:16:24: compiler.err.mod.not.allowed.here: protected
Private08.java:17:22: compiler.err.missing.meth.body.or.decl.abstract
Private08.java:22:33: compiler.err.report.access: foo(), private, Private08.I
Private08.java:27:21: compiler.err.override.weaker.access: (compiler.misc.clashes.with: doo(), Private08_01.J, doo(), Private08.I), public
Private08.java:25:13: compiler.err.non-static.cant.be.ref: kindname.variable, super
Private08.java:25:18: compiler.err.cant.resolve.args: kindname.method, foo, ,
Private08.java:30:40: compiler.err.does.not.override.abstract: compiler.misc.anonymous.class: Private08_01$1, blah(), Private08.I
Private08.java:34:21: compiler.err.override.weaker.access: (compiler.misc.cant.implement: doo(), compiler.misc.anonymous.class: Private08_01$1, doo(), Private08.I), public
Private08.java:32:18: compiler.err.cant.resolve.args: kindname.method, foo, ,
12 errors

View File

@ -0,0 +1,11 @@
/* @test /nodynamiccopyright/
* @bug 8071453
* @author sadayapalam
* @summary Test various JLS changes made for supporting private interface methods.
* @compile/fail/ref=Private09.out -XDrawDiagnostics Private09.java
*/
class Private09 {
interface I {
private private void poo() {}
}
}

View File

@ -0,0 +1,2 @@
Private09.java:9:17: compiler.err.repeated.modifier
1 error

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/*
* @test
* @bug 7192245 8005851 8005166
* @bug 7192245 8005851 8005166 8071453
* @summary Automatic test for checking set of allowed modifiers on interface methods
*/
@ -45,7 +45,8 @@ public class TestDefaultMethodsSyntax {
enum VersionKind {
PRE_LAMBDA("7"),
LAMBDA("8");
LAMBDA("8"),
POST_LAMBDA("9");
String versionString;
@ -87,7 +88,8 @@ public class TestDefaultMethodsSyntax {
static boolean compatible(MethodKind mk, ModifierKind mod1, ModifierKind mod2, EnclosingKind ek) {
if (intersect(ABSTRACT, mod1, mod2) || intersect(NATIVE, mod1, mod2)) {
return mk == MethodKind.NO_BODY;
} else if (intersect(DEFAULT, mod1, mod2) || intersect(STATIC, mod1, mod2)) {
} else if (intersect(DEFAULT, mod1, mod2) || intersect(STATIC, mod1, mod2)
|| intersect(PRIVATE, mod1, mod2)) {
return mk == MethodKind.BODY;
} else {
return ek == EnclosingKind.INTERFACE ?
@ -97,7 +99,6 @@ public class TestDefaultMethodsSyntax {
boolean compatible(EnclosingKind ek) {
switch (this) {
case PRIVATE:
case PROTECTED:
return ek != EnclosingKind.INTERFACE;
default:
@ -149,16 +150,16 @@ public class TestDefaultMethodsSyntax {
static Result[][] allowedModifierPairs = {
/* NONE PUBLIC PROTECTED PRIVATE ABSTRACT STATIC NATIVE SYNCHRONIZED FINAL STRICTFP DEFAULT */
/* NONE */ { T , T , C , C , T , T , C , C , C , C , I },
/* NONE */ { T , T , C , T , T , T , C , C , C , C , I },
/* PUBLIC */ { T , F , F , F , T , T , C , C , C , C , I },
/* PROTECTED */ { C , F , F , F , C , C , C , C , C , C , F },
/* PRIVATE */ { C , F , F , F , F , C , C , C , C , C , F },
/* PRIVATE */ { T , F , F , F , F , T , C , C , C , T , F },
/* ABSTRACT */ { T , T , C , F , F , F , F , F , F , F , F },
/* STATIC */ { T , T , C , C , F , F , C , C , C , T , F },
/* STATIC */ { T , T , C , T , F , F , C , C , C , T , F },
/* NATIVE */ { C , C , C , C , F , C , F , C , C , F , F },
/* SYNCHRONIZED */ { C , C , C , C , F , C , C , F , C , C , F },
/* FINAL */ { C , C , C , C , F , C , C , C , F , C , F },
/* STRICTFP */ { C , C , C , C , F , T , F , C , C , F , I },
/* STRICTFP */ { C , C , C , T , F , T , F , C , C , F , I },
/* DEFAULT */ { I , I , F , F , F , F , F , F , F , I , F }};
}
@ -268,6 +269,9 @@ public class TestDefaultMethodsSyntax {
errorExpected |= ModifierKind.intersect(ModifierKind.STATIC, modk1, modk2) &&
ek == EnclosingKind.INTERFACE && vk == VersionKind.PRE_LAMBDA;
errorExpected |= ModifierKind.intersect(ModifierKind.PRIVATE, modk1, modk2) &&
ek == EnclosingKind.INTERFACE && (vk == VersionKind.LAMBDA || vk == VersionKind.PRE_LAMBDA);
checkCount++;
if (diagChecker.errorFound != errorExpected) {
throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) +

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// key: compiler.err.private.intf.methods.not.supported.in.source
// key: compiler.warn.source.no.bootclasspath
// options: -source 8
interface PrivateInterfaceMethodsNotSupported {
private void foo() {}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2015, 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 8073842
* @summary Invalid method reference when referencing a method on a wildcard type
* @compile T8073842.java
*/
import java.util.stream.Stream;
class T8073842 {
static class Chunck {
public void work() { }
}
void test(Stream<? extends Chunck> s) {
Stream<Runnable> r = s.map(o -> o::work);
}
}