This commit is contained in:
Lana Steuck 2014-06-18 10:54:24 -07:00
commit dfedac648b
34 changed files with 764 additions and 456 deletions

View File

@ -31,6 +31,7 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.text.Collator;
import java.util.*;
import javax.tools.StandardLocation;
import com.sun.javadoc.*;
@ -783,9 +784,8 @@ public class Util {
}
/**
* A general purpose String comparator, which compares two Strings using a Collator
* strength of "SECONDARY", thus providing optimum case insensitive comparisons in
* most Locales.
* A general purpose case insensitive String comparator, which compares two Strings using a Collator
* strength of "TERTIARY".
*
* @param s1 first String to compare.
* @param s2 second String to compare.
@ -793,14 +793,32 @@ public class Util {
* argument is less than, equal to, or greater than the second.
*/
public static int compareStrings(String s1, String s2) {
return compareStrings(true, s1, s2);
}
/**
* A general purpose case sensitive String comparator, which compares two Strings using a Collator
* strength of "SECONDARY".
*
* @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 compareCaseCompare(String s1, String s2) {
return compareStrings(false, s1, s2);
}
private static int compareStrings(boolean caseSensitive, String s1, String s2) {
Collator collator = Collator.getInstance();
collator.setStrength(Collator.SECONDARY);
collator.setStrength(caseSensitive ? Collator.TERTIARY : 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.
* A comparator for index file uses,
* 1. this sorts first on simple names
* 2. if equal, case insensitive comparison of Parameter types
* 3. if equal, case sensitive comparison of Parameter types
* 4. if equal, compare the FQNs of the entities
* 5. if equal, then compare the DocKinds ex: Package, Interface etc.
* @return a comparator for index file use
*/
public static Comparator<Doc> makeComparatorForIndexUse() {
@ -816,29 +834,35 @@ public class Util {
* 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());
int result = compareNames(d1, d2);
if (result != 0) {
return result;
}
if (d1 instanceof ExecutableMemberDoc && d2 instanceof ExecutableMemberDoc) {
result = compareExecutableMembers(
(ExecutableMemberDoc) d1,
(ExecutableMemberDoc) d2);
Parameter[] param1 = ((ExecutableMemberDoc) d1).parameters();
Parameter[] param2 = ((ExecutableMemberDoc) d2).parameters();
result = compareParameters(false, param1, param2);
if (result != 0) {
return result;
}
result = compareParameters(true, param1, param2);
}
if (d1 instanceof ProgramElementDoc && d2 instanceof ProgramElementDoc) {
return compareProgramElementDoc((ProgramElementDoc)d1, (ProgramElementDoc)d2);
if (result != 0) {
return result;
}
return 0;
result = compareFullyQualifiedNames(d1, d2);
if (result != 0) {
return result;
}
return compareDocKinds(d1, d2);
}
};
}
/**
* Comparator for ClassUse representations, this sorts on member names,
* fully qualified member names and then the parameter types if applicable.
* fully qualified member names and then the parameter types if applicable,
* and finally the Doc kinds ie. package, class, interface etc.
* @return a comparator to sort classes and members for class use
*/
public static Comparator<Doc> makeComparatorForClassUse() {
@ -853,46 +877,88 @@ public class Util {
* 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());
int result = compareNames(d1, d2);
if (result != 0) {
return result;
}
if (d1 instanceof ProgramElementDoc && d2 instanceof ProgramElementDoc) {
result = compareProgramElementDoc((ProgramElementDoc) d1, (ProgramElementDoc) d2);
result = compareFullyQualifiedNames(d1, d2);
if (result != 0) {
return result;
}
if (d1 instanceof ExecutableMemberDoc && d2 instanceof ExecutableMemberDoc) {
Parameter[] param1 = ((ExecutableMemberDoc) d1).parameters();
Parameter[] param2 = ((ExecutableMemberDoc) d2).parameters();
result = compareParameters(false, param1, param2);
if (result != 0) {
return result;
}
return compareParameters(true, param1, param2);
}
if (d1 instanceof ExecutableMemberDoc && d2 instanceof ExecutableMemberDoc) {
return compareExecutableMembers((ExecutableMemberDoc)d1, (ExecutableMemberDoc)d2);
}
return 0;
return compareDocKinds(d1, d2);
}
};
}
/**
* 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> {
static enum DocKinds {
PACKAGE,
FIELD,
ENUM,
ANNOTATION,
INTERFACE,
CLASS,
CONSTRUCTOR,
METHOD
};
private DocKinds getValue(Doc d) {
if (d.isAnnotationType() || d.isAnnotationTypeElement()) {
return DocKinds.ANNOTATION;
} else if (d.isEnum() || d.isEnumConstant()) {
return DocKinds.ENUM;
} else if (d.isField()) {
return DocKinds.FIELD;
} else if (d.isInterface()) {
return DocKinds.INTERFACE;
} else if (d.isClass()) {
return DocKinds.CLASS;
} else if (d.isConstructor()) {
return DocKinds.CONSTRUCTOR;
} else if (d.isMethod()) {
return DocKinds.METHOD;
} else {
return DocKinds.PACKAGE;
}
}
/**
* compares two parameter arrays by comparing each Type of the parameter in the array,
* as possible, if the matched strings are identical, and have mismatched array lengths
* then compare the lengths.
* Compares two Doc entities' kinds, and these are ordered as defined in
* the DocKinds enumeration.
* @param d1 the first Doc object
* @param d2 the second Doc object
* @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 compareDocKinds(Doc d1, Doc d2) {
return getValue(d1).compareTo(getValue(d2));
}
/**
* Compares two parameter arrays by comparing each Type of the parameter in the array,
* and as many as possible, otherwise compare their lengths.
* @param ignoreCase specifies case sensitive or insensitive comparison.
* @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;
}
protected int compareParameters(boolean ignoreCase, Parameter[] params1, Parameter[] params2) {
// try to compare as many as possible
for (int i = 0; i < params1.length && i < params2.length; i++) {
int result = compareStrings(params1[i].typeName(), params2[i].typeName());
int result = compareStrings(ignoreCase, params1[i].typeName(), params2[i].typeName());
if (result != 0) {
return result;
}
@ -901,41 +967,32 @@ public class Util {
}
/**
* Compares two MemberDocs, typically the name of a method,
* field or constructor.
* @param e1 the first MemberDoc.
* @param e2 the second MemberDoc.
* Compares two Doc entities typically the simple name of a method,
* field, constructor etc.
* @param d1 the first Doc.
* @param d2 the second Doc.
* @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;
protected int compareNames(Doc d1, Doc d2) {
return compareStrings(d1.name(), d2.name());
}
/**
* Compares the fully qualified names of the entities
* @param p1 the first ProgramElementDoc.
* @param p2 the first ProgramElementDoc.
* @param d1 the first entity
* @param d2 the second entity
* @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());
protected int compareFullyQualifiedNames(Doc d1, Doc d2) {
String name1 = (d1 instanceof ProgramElementDoc)
? ((ProgramElementDoc)d1).qualifiedName()
: d1.name();
String name2 = (d2 instanceof ProgramElementDoc)
? ((ProgramElementDoc)d2).qualifiedName()
: d2.name();
return compareStrings(name1, name2);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 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
@ -161,7 +161,7 @@ public final class JavacTool implements JavaCompiler {
}
}
public static void processOptions(Context context,
private void processOptions(Context context,
JavaFileManager fileManager,
Iterable<String> options)
{

View File

@ -277,6 +277,11 @@ public class Flags {
*/
public static final long LAMBDA_METHOD = 1L<<49;
/**
* Flag to control recursion in TransTypes
*/
public static final long TYPE_TRANSLATED = 1L<<50;
/** Modifier masks.
*/
public static final int
@ -386,7 +391,8 @@ public class Flags {
BAD_OVERRIDE(Flags.BAD_OVERRIDE),
SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC),
THROWS(Flags.THROWS),
LAMBDA_METHOD(Flags.LAMBDA_METHOD);
LAMBDA_METHOD(Flags.LAMBDA_METHOD),
TYPE_TRANSLATED(Flags.TYPE_TRANSLATED);
Flag(long flag) {
this.value = flag;

View File

@ -237,6 +237,9 @@ public enum Source {
public boolean allowFunctionalInterfaceMostSpecific() {
return compareTo(JDK1_8) >= 0;
}
public boolean allowPostApplicabilityVarargsAccessCheck() {
return compareTo(JDK1_8) >= 0;
}
public static SourceVersion toSourceVersion(Source source) {
switch(source) {
case JDK1_2:

View File

@ -770,42 +770,41 @@ public abstract class Symbol extends AnnoConstruct implements Element {
@Override
public List<Attribute.Compound> getAnnotationMirrors() {
return onlyTypeVariableAnnotations(owner.getRawTypeAttributes());
}
private List<Attribute.Compound> onlyTypeVariableAnnotations(
List<Attribute.TypeCompound> candidates) {
// Declaration annotations on TypeParameters are stored in type attributes
// Declaration annotations on type variables are stored in type attributes
// on the owner of the TypeVariableSymbol
List<Attribute.TypeCompound> candidates = owner.getRawTypeAttributes();
int index = owner.getTypeParameters().indexOf(this);
List<Attribute.Compound> res = List.nil();
for (Attribute.TypeCompound a : candidates) {
if (a.position.type == TargetType.CLASS_TYPE_PARAMETER ||
a.position.type == TargetType.METHOD_TYPE_PARAMETER)
if (isCurrentSymbolsAnnotation(a, index))
res = res.prepend(a);
}
return res = res.reverse();
return res.reverse();
}
// Helper to getAnnotation[s]
@Override
public <A extends Annotation> Attribute.Compound getAttribute(Class<A> annoType) {
String name = annoType.getName();
// Declaration annotations on type variables are stored in type attributes
// on the owner of the TypeVariableSymbol
List<Attribute.TypeCompound> candidates = owner.getRawTypeAttributes();
int index = owner.getTypeParameters().indexOf(this);
for (Attribute.TypeCompound anno : candidates)
if (anno.position.type == TargetType.CLASS_TYPE_PARAMETER ||
anno.position.type == TargetType.METHOD_TYPE_PARAMETER)
if (name.contentEquals(anno.type.tsym.flatName()))
return anno;
if (isCurrentSymbolsAnnotation(anno, index) &&
name.contentEquals(anno.type.tsym.flatName()))
return anno;
return null;
}
//where:
boolean isCurrentSymbolsAnnotation(Attribute.TypeCompound anno, int index) {
return (anno.position.type == TargetType.CLASS_TYPE_PARAMETER ||
anno.position.type == TargetType.METHOD_TYPE_PARAMETER) &&
anno.position.parameter_index == index;
}
@Override

View File

@ -92,6 +92,7 @@ public class Attr extends JCTree.Visitor {
final JCDiagnostic.Factory diags;
final Annotate annotate;
final DeferredLintHandler deferredLintHandler;
final TypeEnvs typeEnvs;
public static Attr instance(Context context) {
Attr instance = context.get(attrKey);
@ -120,6 +121,7 @@ public class Attr extends JCTree.Visitor {
diags = JCDiagnostic.Factory.instance(context);
annotate = Annotate.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
typeEnvs = TypeEnvs.instance(context);
Options options = Options.instance(context);
@ -429,7 +431,7 @@ public class Attr extends JCTree.Visitor {
}
public Type attribType(JCTree node, TypeSymbol sym) {
Env<AttrContext> env = enter.typeEnvs.get(sym);
Env<AttrContext> env = typeEnvs.get(sym);
Env<AttrContext> localEnv = env.dup(node, env.info.dup());
return attribTree(node, localEnv, unknownTypeInfo);
}
@ -4252,7 +4254,7 @@ public class Attr extends JCTree.Visitor {
// ... and attribute the bound class
c.flags_field |= UNATTRIBUTED;
Env<AttrContext> cenv = enter.classEnv(cd, env);
enter.typeEnvs.put(c, cenv);
typeEnvs.put(c, cenv);
attribClass(c);
return owntype;
}
@ -4398,9 +4400,9 @@ public class Attr extends JCTree.Visitor {
c.flags_field &= ~UNATTRIBUTED;
// Get environment current at the point of class definition.
Env<AttrContext> env = enter.typeEnvs.get(c);
Env<AttrContext> env = typeEnvs.get(c);
// The info.lint field in the envs stored in enter.typeEnvs is deliberately uninitialized,
// The info.lint field in the envs stored in typeEnvs is deliberately uninitialized,
// because the annotations were not available at the time the env was created. Therefore,
// we look up the environment chain for the first enclosing environment for which the
// lint value is set. Typically, this is the parent env, but might be further if there

View File

@ -78,6 +78,7 @@ public class DeferredAttr extends JCTree.Visitor {
final Flow flow;
final Names names;
final Annotate annotate;
final TypeEnvs typeEnvs;
public static DeferredAttr instance(Context context) {
DeferredAttr instance = context.get(deferredAttrKey);
@ -102,6 +103,7 @@ public class DeferredAttr extends JCTree.Visitor {
names = Names.instance(context);
stuckTree = make.Ident(names.empty).setType(Type.stuckType);
annotate = Annotate.instance(context);
typeEnvs = TypeEnvs.instance(context);
emptyDeferredAttrContext =
new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) {
@Override
@ -420,7 +422,7 @@ public class DeferredAttr extends JCTree.Visitor {
//it is possible that nested expressions inside argument expression
//are left unchecked - in such cases there's nothing to clean up.
if (csym == null) return;
enter.typeEnvs.remove(csym);
typeEnvs.remove(csym);
chk.compiled.remove(csym.flatname);
syms.classes.remove(csym.flatname);
super.visitClassDef(tree);

View File

@ -103,6 +103,7 @@ public class Enter extends JCTree.Visitor {
Names names;
JavaFileManager fileManager;
PkgInfo pkginfoOpt;
TypeEnvs typeEnvs;
private final Todo todo;
@ -139,13 +140,9 @@ public class Enter extends JCTree.Visitor {
Options options = Options.instance(context);
pkginfoOpt = PkgInfo.get(options);
typeEnvs = TypeEnvs.instance(context);
}
/** A hashtable mapping classes and packages to the environments current
* at the points of their definitions.
*/
Map<TypeSymbol,Env<AttrContext>> typeEnvs = new HashMap<>();
/** Accessor for typeEnvs
*/
public Env<AttrContext> getEnv(TypeSymbol sym) {

View File

@ -79,6 +79,7 @@ public class Lower extends TreeTranslator {
private final ConstFold cfolder;
private final Target target;
private final Source source;
private final TypeEnvs typeEnvs;
private final boolean allowEnums;
private final Name dollarAssertionsDisabled;
private final Name classDollar;
@ -99,6 +100,7 @@ public class Lower extends TreeTranslator {
cfolder = ConstFold.instance(context);
target = Target.instance(context);
source = Source.instance(context);
typeEnvs = TypeEnvs.instance(context);
allowEnums = source.allowEnums();
dollarAssertionsDisabled = names.
fromString(target.syntheticNameChar() + "assertionsDisabled");
@ -2450,10 +2452,16 @@ public class Lower extends TreeTranslator {
}
public void visitClassDef(JCClassDecl tree) {
Env<AttrContext> prevEnv = attrEnv;
ClassSymbol currentClassPrev = currentClass;
MethodSymbol currentMethodSymPrev = currentMethodSym;
currentClass = tree.sym;
currentMethodSym = null;
attrEnv = typeEnvs.remove(currentClass);
if (attrEnv == null)
attrEnv = prevEnv;
classdefs.put(currentClass, tree);
proxies = proxies.dup(currentClass);
@ -2525,6 +2533,7 @@ public class Lower extends TreeTranslator {
// Append translated tree to `translated' queue.
translated.append(tree);
attrEnv = prevEnv;
currentClass = currentClassPrev;
currentMethodSym = currentMethodSymPrev;

View File

@ -82,6 +82,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
private final Target target;
private final DeferredLintHandler deferredLintHandler;
private final Lint lint;
private final TypeEnvs typeEnvs;
public static MemberEnter instance(Context context) {
MemberEnter instance = context.get(memberEnterKey);
@ -107,6 +108,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
target = Target.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
lint = Lint.instance(context);
typeEnvs = TypeEnvs.instance(context);
allowTypeAnnos = source.allowTypeAnnotations();
}
@ -1000,7 +1002,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
ClassSymbol c = (ClassSymbol)sym;
ClassType ct = (ClassType)c.type;
Env<AttrContext> env = enter.typeEnvs.get(c);
Env<AttrContext> env = typeEnvs.get(c);
JCClassDecl tree = (JCClassDecl)env.tree;
boolean wasFirst = isFirst;
isFirst = false;

View File

@ -95,6 +95,7 @@ public class Resolve {
public final boolean varargsEnabled;
public final boolean allowMethodHandles;
public final boolean allowFunctionalInterfaceMostSpecific;
public final boolean checkVarargsAccessDuringResolution;
private final boolean debugResolve;
private final boolean compactMethodDiags;
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
@ -136,6 +137,8 @@ public class Resolve {
Target target = Target.instance(context);
allowMethodHandles = target.hasMethodHandles();
allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
checkVarargsAccessDuringResolution =
source.allowPostApplicabilityVarargsAccessCheck();
polymorphicSignatureScope = new Scope(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags);
@ -833,7 +836,10 @@ public class Resolve {
Warner warn) {
super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
//should we expand formals?
if (deferredAttrContext.phase.isVarargsRequired()) {
if ((!checkVarargsAccessDuringResolution ||
(checkVarargsAccessDuringResolution &&
deferredAttrContext.mode == AttrMode.CHECK)) &&
deferredAttrContext.phase.isVarargsRequired()) {
//check varargs element type accessibility
varargsAccessible(env, types.elemtype(formals.last()),
deferredAttrContext.inferenceContext);

View File

@ -966,10 +966,11 @@ public class TransTypes extends TreeTranslator {
translateClass((ClassSymbol)st.tsym);
}
Env<AttrContext> myEnv = enter.typeEnvs.remove(c);
if (myEnv == null) {
Env<AttrContext> myEnv = enter.getEnv(c);
if (myEnv == null || (c.flags_field & TYPE_TRANSLATED) != 0) {
return;
}
c.flags_field |= TYPE_TRANSLATED;
/* The two assertions below are set for early detection of any attempt
* to translate a class that:

View File

@ -0,0 +1,63 @@
/*
* 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.
*/
package com.sun.tools.javac.comp;
import java.util.Collection;
import java.util.HashMap;
import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.util.Context;
/** This class contains the type environments used by Enter, MemberEnter,
* Attr, DeferredAttr, and Lower.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
class TypeEnvs {
private static final long serialVersionUID = 571524752489954631L;
protected static final Context.Key<TypeEnvs> typeEnvsKey = new Context.Key<>();
public static TypeEnvs instance(Context context) {
TypeEnvs instance = context.get(typeEnvsKey);
if (instance == null)
instance = new TypeEnvs(context);
return instance;
}
private HashMap<TypeSymbol,Env<AttrContext>> map;
protected TypeEnvs(Context context) {
map = new HashMap<>();
context.put(typeEnvsKey, this);
}
Env<AttrContext> get(TypeSymbol sym) { return map.get(sym); }
Env<AttrContext> put(TypeSymbol sym, Env<AttrContext> env) { return map.put(sym, env); }
Env<AttrContext> remove(TypeSymbol sym) { return map.remove(sym); }
Collection<Env<AttrContext>> values() { return map.values(); }
void clear() { map.clear(); }
}

View File

@ -384,7 +384,7 @@ public class Main {
/** Programmatic interface for main function.
* @param args The command line parameters.
*/
public Result compile(String[] args,
protected Result compile(String[] args,
Context context,
List<JavaFileObject> fileObjects,
Iterable<? extends Processor> processors)

View File

@ -354,13 +354,41 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
private final DiagnosticType type;
private final DiagnosticSource source;
private final DiagnosticPosition position;
private final int line;
private final int column;
private final String key;
protected final Object[] args;
private final Set<DiagnosticFlag> flags;
private final LintCategory lintCategory;
/** source line position (set lazily) */
private SourcePosition sourcePosition;
/**
* This class is used to defer the line/column position fetch logic after diagnostic construction.
*/
class SourcePosition {
private final int line;
private final int column;
SourcePosition() {
int n = (position == null ? Position.NOPOS : position.getPreferredPosition());
if (n == Position.NOPOS || source == null)
line = column = -1;
else {
line = source.getLineNumber(n);
column = source.getColumnNumber(n, true);
}
}
public int getLineNumber() {
return line;
}
public int getColumnNumber() {
return column;
}
}
/**
* Create a diagnostic object.
* @param formatter the formatter to use for the diagnostic
@ -390,14 +418,6 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
this.position = pos;
this.key = key;
this.args = args;
int n = (pos == null ? Position.NOPOS : pos.getPreferredPosition());
if (n == Position.NOPOS || source == null)
line = column = -1;
else {
line = source.getLineNumber(n);
column = source.getColumnNumber(n, true);
}
}
/**
@ -494,7 +514,10 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
* @return the line number within the source referred to by this diagnostic
*/
public long getLineNumber() {
return line;
if (sourcePosition == null) {
sourcePosition = new SourcePosition();
}
return sourcePosition.getLineNumber();
}
/**
@ -502,7 +525,10 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
* @return the column number within the line of source referred to by this diagnostic
*/
public long getColumnNumber() {
return column;
if (sourcePosition == null) {
sourcePosition = new SourcePosition();
}
return sourcePosition.getColumnNumber();
}
/**

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
@ -72,10 +72,6 @@ public class Dependencies {
private Dependencies(Context context) {
context.put(dependenciesKey, this);
log = Log.instance(context);
}
public void reset()
{
deps = new HashMap<>();
explicitPackages = new HashSet<>();
publicApiPerClass = new HashMap<>();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 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
@ -39,23 +39,26 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.util.BaseFileManager;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.BaseFileManager;
import com.sun.tools.javac.util.StringUtils;
import com.sun.tools.sjavac.comp.AttrWithDeps;
import com.sun.tools.sjavac.comp.Dependencies;
import com.sun.tools.sjavac.comp.JavaCompilerWithDeps;
import com.sun.tools.sjavac.comp.SmartFileManager;
import com.sun.tools.sjavac.comp.ResolveWithDeps;
import com.sun.tools.sjavac.comp.SmartFileManager;
/**
* The compiler thread maintains a JavaCompiler instance and
@ -78,7 +81,6 @@ public class CompilerThread implements Runnable {
// The necessary classes to do a compilation.
private com.sun.tools.javac.api.JavacTool compiler;
private StandardJavaFileManager fileManager;
private BaseFileManager fileManagerBase;
private SmartFileManager smartFileManager;
private Context context;
@ -127,10 +129,8 @@ public class CompilerThread implements Runnable {
inUse = true;
compiler = com.sun.tools.javac.api.JavacTool.create();
fileManager = compiler.getStandardFileManager(null, null, null);
fileManagerBase = (BaseFileManager)fileManager;
smartFileManager = new SmartFileManager(fileManager);
context = new Context();
context.put(JavaFileManager.class, smartFileManager);
ResolveWithDeps.preRegister(context);
AttrWithDeps.preRegister(context);
JavaCompilerWithDeps.preRegister(context, this);
@ -145,7 +145,6 @@ public class CompilerThread implements Runnable {
inUse = false;
compiler = null;
fileManager = null;
fileManagerBase = null;
smartFileManager = null;
context = null;
subTasks = null;
@ -315,24 +314,13 @@ public class CompilerThread implements Runnable {
com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
try {
if (compilationUnits.size() > 0) {
// Bind the new logger to the existing context.
context.put(Log.outKey, stderr);
Log.instance(context).setWriter(Log.WriterKind.NOTICE, stdout);
Log.instance(context).setWriter(Log.WriterKind.WARNING, stderr);
Log.instance(context).setWriter(Log.WriterKind.ERROR, stderr);
// Process the options.
com.sun.tools.javac.api.JavacTool.processOptions(context, smartFileManager, the_options);
fileManagerBase.setContext(context);
smartFileManager.setVisibleSources(visibleSources);
smartFileManager.cleanArtifacts();
smartFileManager.setLog(stdout);
Dependencies.instance(context).reset();
com.sun.tools.javac.main.Main ccompiler = new com.sun.tools.javac.main.Main("javacTask", stderr);
String[] aa = the_options.toArray(new String[0]);
// Do the compilation!
rc = ccompiler.compile(aa, context, compilationUnits.toList(), null);
CompilationTask task = compiler.getTask(stderr, smartFileManager, null, the_options, null, compilationUnits, context);
rc = ((JavacTaskImpl) task).doCall();
while (numActiveSubTasks()>0) {
try { Thread.sleep(1000); } catch (InterruptedException e) { }

View File

@ -451,8 +451,12 @@ public abstract class JavadocTester {
for (String s : strings) {
int currentIndex = fileString.indexOf(s);
checking(s + " at index " + currentIndex);
if (currentIndex >= prevIndex) {
passed(s + "is in the correct order");
if (currentIndex == -1) {
failed(s + " not found.");
continue;
}
if (currentIndex > prevIndex) {
passed(s + " is in the correct order");
} else {
failed(s + " is in the wrong order.");
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8039410 8042601
* @bug 8039410 8042601 8042829
* @summary test to determine if members are ordered correctly
* @author ksrini
* @library ../lib/
@ -31,6 +31,16 @@
* @run main TestOrdering
*/
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static java.nio.file.StandardOpenOption.*;
public class TestOrdering extends JavadocTester {
public static void main(String[] args) throws Exception {
@ -39,7 +49,7 @@ public class TestOrdering extends JavadocTester {
}
@Test
void testUnnamedPackages() {
void testUnnamedPackagesForClassUse() {
javadoc("-d", "out",
"-sourcepath", testSrc,
"-use",
@ -49,16 +59,94 @@ public class TestOrdering extends JavadocTester {
}
@Test
void testNamedPackages() {
void testNamedPackagesForClassUse() {
javadoc("-d", "out-1",
"-sourcepath", testSrc,
"-use",
"pkg1");
checkExit(Exit.OK);
checkClassUseOrdering("pkg1/class-use/UsedClass.html");
checkIndexPathOrdering("index-all.html");
}
enum ListOrder { NONE, REVERSE, SHUFFLE };
/*
* By default we do not shuffle the input list, in order to keep the list deterministic,
* and the test predictable. However, we can turn on the stress mode, by setting the following
* property if required.
*/
static final ListOrder STRESS_MODE = Boolean.getBoolean("TestOrder.STRESS")
? ListOrder.SHUFFLE
: ListOrder.REVERSE;
/*
* Controls the number of sibling packages, pkg0, pkg1, pkg2, .....
*/
static final int MAX_PACKAGES = 4;
/*
* Controls the number of children packages, pkg0, pkg0.pkg, pkg0.pkg.pkg, .....
* Note: having too long a depth (> 256 chars on Windows), will likely lead to
* cause problems with automated build and test systems.
*/
static final int MAX_SUBPACKAGES_DEPTH = 4;
@Test
void testIndexOrdering() throws IOException {
final String clsname = "Add";
List<String> cmdArgs = new ArrayList();
cmdArgs.add("-d");
cmdArgs.add("out-2");
cmdArgs.add("-sourcepath");
cmdArgs.add("src");
cmdArgs.add("-package");
System.out.println("STRESS_MODE: " + STRESS_MODE);
emitFile(null, clsname, STRESS_MODE);
for (int width = 0 ; width < MAX_PACKAGES ; width++) {
String wpkgname = "add" + width;
String dpkgname = wpkgname;
emitFile(wpkgname, clsname, ListOrder.NONE); // list as-is
cmdArgs.add(wpkgname);
for (int depth = 1 ; depth < MAX_SUBPACKAGES_DEPTH ; depth++) {
dpkgname = dpkgname + ".add";
emitFile(dpkgname, clsname, STRESS_MODE);
cmdArgs.add(dpkgname);
}
}
File srcDir = new File(new File("."), "src");
cmdArgs.add(new File(srcDir, clsname + ".java").getPath());
javadoc(cmdArgs.toArray(new String[cmdArgs.size()]));
checkExit(Exit.OK);
checkOrder("index-all.html", composeTestVectors());
}
String[] composeTestVectors() {
List<String> testList = new ArrayList<>();
for (String x : expectedMethodOrdering) {
testList.add(x);
for (int i = 0; i < MAX_PACKAGES; i++) {
String wpkg = "add" + i;
testList.add(wpkg + "/" + x);
String dpkg = wpkg;
for (int j = 1; j < MAX_SUBPACKAGES_DEPTH; j++) {
dpkg = dpkg + "/" + "add";
testList.add(dpkg + "/" + x);
}
}
}
for (String x : expectedEnumOrdering) {
testList.add(x.replace("REPLACE_ME", "&lt;Unnamed&gt;"));
for (int i = 0; i < MAX_PACKAGES; i++) {
String wpkg = "add" + i;
testList.add(wpkg + "/" + x.replace("REPLACE_ME", wpkg));
String dpkg = wpkg;
for (int j = 1; j < MAX_SUBPACKAGES_DEPTH; j++) {
dpkg = dpkg + "/" + "add";
testList.add(dpkg + "/" + x.replace("REPLACE_ME", pathToPackage(dpkg)));
}
}
}
testList.addAll(Arrays.asList(expectedFieldOrdering));
return testList.toArray(new String[testList.size()]);
}
void checkExecutableMemberOrdering(String usePage) {
String contents = readFile(usePage);
// check constructors
@ -109,29 +197,125 @@ public class TestOrdering extends JavadocTester {
}
}
void checkIndexPathOrdering(String indexPage) {
checkOrder(indexPage,
"pkg1/UsedClass.html#add--",
"pkg1/ZZTop.html#add--",
"pkg1/UsedClass.html#add-double-",
"pkg1/UsedClass.html#add-java.lang.Double-",
"pkg1/ZZTop.html#add-double-",
"pkg1/ZZTop.html#add-java.lang.Double-",
"pkg1/UsedClass.html#add-double-byte-",
"pkg1/ZZTop.html#add-double-byte-",
"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-",
"pkg1/UsedClass.html#add-float-",
"pkg1/ZZTop.html#add-float-",
"pkg1/UsedClass.html#add-float-int-",
"pkg1/ZZTop.html#add-float-int-",
"pkg1/UsedClass.html#add-int-",
"pkg1/ZZTop.html#add-int-",
"pkg1/UsedClass.html#add-int-float-",
"pkg1/ZZTop.html#add-int-float-",
"pkg1/UsedClass.html#add-java.lang.Integer-",
"pkg1/ZZTop.html#add-java.lang.Integer-");
static String[] contents = {
"public add ADDADD;",
"public add AddAdd;",
"public add addadd;",
"public enum add {add, ADD, addd, ADDD};",
"public enum ADD {ADD, add, addd, ADDD};",
"public void add(){}",
"public void add(double d){}",
"public void add(int i, float f){}",
"public void add(float f, int i){}",
"public void add(double d, byte b){}",
"public Double add(Double d) {return (double) 22/7;}",
"public double add(double d1, double d2) {return d1 + d2;}",
"public double add(double d1, Double d2) {return d1 + d2;}",
"public Float add(float f) {return (float) 22/7;}",
"public void add(int i){}",
"public int add(Integer i) {return 0;}"
};
void emitFile(String pkgname, String clsname, ListOrder order) throws IOException {
File srcDir = new File("src");
File outDir = pkgname == null
? srcDir
: new File(srcDir, pkgname.replace(".", File.separator));
File outFile = new File(outDir, clsname + ".java");
outDir.mkdirs();
List<String> scratch = new ArrayList<>(Arrays.asList(contents));
switch (order) {
case SHUFFLE:
Collections.shuffle(scratch);
break;
case REVERSE:
Collections.reverse(scratch);
break;
default:
// leave list as-is
}
// insert the header
scratch.add(0, "public class " + clsname + " {");
if (pkgname != null) {
scratch.add(0, "package " + pkgname + ";");
}
// append the footer
scratch.add("}");
Files.write(outFile.toPath(), scratch, CREATE, TRUNCATE_EXISTING);
}
String pathToPackage(String in) {
return in.replace("/", ".");
}
final String expectedMethodOrdering[] = {
"Add.html#add--",
"Add.html#add-double-",
"Add.html#add-java.lang.Double-",
"Add.html#add-double-byte-",
"Add.html#add-double-double-",
"Add.html#add-double-java.lang.Double-",
"Add.html#add-float-",
"Add.html#add-float-int-",
"Add.html#add-int-",
"Add.html#add-int-float-",
"Add.html#add-java.lang.Integer-"
};
final String expectedEnumOrdering[] = {
"Add.add.html\" title=\"enum in REPLACE_ME\"",
"Add.ADD.html\" title=\"enum in REPLACE_ME\""
};
final String expectedFieldOrdering[] = {
"Add.html#addadd\"",
"add0/add/add/add/Add.html#addadd\"",
"add0/add/add/Add.html#addadd\"",
"add0/add/Add.html#addadd\"",
"add0/Add.html#addadd\"",
"add1/add/add/add/Add.html#addadd\"",
"add1/add/add/Add.html#addadd\"",
"add1/add/Add.html#addadd\"",
"add1/Add.html#addadd\"",
"add2/add/add/add/Add.html#addadd\"",
"add2/add/add/Add.html#addadd\"",
"add2/add/Add.html#addadd\"",
"add2/Add.html#addadd\"",
"add3/add/add/add/Add.html#addadd\"",
"add3/add/add/Add.html#addadd\"",
"add3/add/Add.html#addadd\"",
"add3/Add.html#addadd\"",
"Add.html#AddAdd\"",
"add0/add/add/add/Add.html#AddAdd\"",
"add0/add/add/Add.html#AddAdd\"",
"add0/add/Add.html#AddAdd\"",
"add0/Add.html#AddAdd\"",
"add1/add/add/add/Add.html#AddAdd\"",
"add1/add/add/Add.html#AddAdd\"",
"add1/add/Add.html#AddAdd\"",
"add1/Add.html#AddAdd\"",
"add2/add/add/add/Add.html#AddAdd\"",
"add2/add/add/Add.html#AddAdd\"",
"add2/add/Add.html#AddAdd\"",
"add2/Add.html#AddAdd\"",
"add3/add/add/add/Add.html#AddAdd\"",
"add3/add/add/Add.html#AddAdd\"",
"add3/add/Add.html#AddAdd\"",
"add3/Add.html#AddAdd\"",
"Add.html#ADDADD\"",
"add0/add/add/add/Add.html#ADDADD\"",
"add0/add/add/Add.html#ADDADD\"",
"add0/add/Add.html#ADDADD\"",
"add0/Add.html#ADDADD\"",
"add1/add/add/add/Add.html#ADDADD\"",
"add1/add/add/Add.html#ADDADD\"",
"add1/add/Add.html#ADDADD\"",
"add1/Add.html#ADDADD\"",
"add2/add/add/add/Add.html#ADDADD\"",
"add2/add/add/Add.html#ADDADD\"",
"add2/add/Add.html#ADDADD\"",
"add2/Add.html#ADDADD\"",
"add3/add/add/add/Add.html#ADDADD\"",
"add3/add/add/Add.html#ADDADD\"",
"add3/add/Add.html#ADDADD\"",
"add3/Add.html#ADDADD\""
};
}

View File

@ -23,72 +23,6 @@
package pkg1;
/**
* For index and class-use testing
* For class-use testing
*/
public class UsedClass {
/**
* just an empty param method.
*/
public void add(){}
/**
* @param d param
*/
public void add(double d){}
/**
* @param i param
* @param f param
*/
public void add(int i, float f){}
/**
* @param f param
* @param i param
*/
public void add(float f, int i){}
/**
* @param d param
* @param b param
*/
public void add(double d, byte b){}
/**
* @param d param
* @return Double
*/
public Double add(Double d) {return (double) 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;}
/**
* @param f param
* @return Float
*/
public Float add(float f) {return (float) 22/7;}
/**
* @param i param
*/
public void add(int i){}
/**
* @param i param
* @return double
*/
public int add(Integer i) {return 0;}
}
public class UsedClass {}

View File

@ -1,94 +0,0 @@
/*
* 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 {
/**
* just an empty param method.
*/
public void add(){}
/**
* @param d param
*/
public void add(double d){}
/**
* @param i param
* @param f param
*/
public void add(int i, float f){}
/**
* @param f param
* @param i param
*/
public void add(float f, int i){}
/**
* @param d param
* @param b param
*/
public void add(double d, byte b){}
/**
* @param d param
* @return Double
*/
public Double add(Double d) {return (double) 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;}
/**
* @param f param
* @return Float
*/
public Float add(float f) {return (float) 22/7;}
/**
* @param i param
*/
public void add(int i){}
/**
* @param i param
* @return double
*/
public int add(Integer i) {return 0;}
}

View File

@ -0,0 +1,39 @@
/*
* 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 8038975
* @summary Access control in enhanced for
* @compile AccessTest.java
*/
import a.*;
public class AccessTest {
private static class Impl extends B {
public void method(Inner inner) {
for (A a : inner)
System.out.println(a);
}
}
}

View File

@ -0,0 +1,25 @@
/*
* 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 a;
public class A { }

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.
*/
package a;
public class B {
protected abstract class Inner implements Iterable<A> { }
}

View File

@ -26,7 +26,6 @@
* @summary Tests which path is used to represent an implicit type given
* various xprefer arguments and multiple .class / .java files involved.
* @bug 8028196
* @ignore 8042839 XPreferTest fails on Windows
*/
import java.io.File;
@ -42,6 +41,7 @@ import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.regex.Pattern;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
@ -180,10 +180,16 @@ public class XPreferTest {
Scanner s = new Scanner(compilerOutput);
while (s.hasNextLine()) {
String line = s.nextLine();
if (line.matches("\\[loading .*\\]"))
for (Dir dir : Dir.values())
if (line.contains(dir.file.getName() + "/" + classId))
if (line.matches("\\[loading .*\\]")) {
for (Dir dir : Dir.values()) {
// On Windows all paths are printed with '/' except
// paths inside zip-files, which are printed with '\'.
// For this reason we accept both '/' and '\' below.
String regex = dir.file.getName() + "[\\\\/]" + classId;
if (Pattern.compile(regex).matcher(line).find())
return dir;
}
}
}
return null;
}

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
@ -23,7 +23,7 @@
/*
* @test
* @bug 8011027
* @bug 8011027 8046916
* @library /tools/javac/lib
* @build JavacTestingAbstractProcessor TestTypeParameterAnnotations
* @compile -processor TestTypeParameterAnnotations -proc:only TestTypeParameterAnnotations.java
@ -33,10 +33,16 @@ import java.util.*;
import java.lang.annotation.*;
import javax.annotation.processing.*;
import javax.lang.model.element.*;
import javax.lang.model.util.*;
import javax.tools.*;
public class TestTypeParameterAnnotations<@Foo @Bar @Baz T> extends JavacTestingAbstractProcessor {
@ExpectedTypeParameterAnnotations(typeParameterName="T1",
annotations={"Foo1", "Bar1", "Baz1"})
@ExpectedTypeParameterAnnotations(typeParameterName="T2", annotations={})
@ExpectedTypeParameterAnnotations(typeParameterName="T3",
annotations={"Foo2", "Bar2", "Baz2"})
@ExpectedTypeParameterAnnotations(typeParameterName="T4", annotations={})
public class TestTypeParameterAnnotations<@Foo1 @Bar1 @Baz1 T1, T2, @Foo2 @Bar2 @Baz2 T3, T4> extends
JavacTestingAbstractProcessor {
int round = 0;
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
@ -74,82 +80,69 @@ public class TestTypeParameterAnnotations<@Foo @Bar @Baz T> extends JavacTesting
int check(Element e, List<? extends TypeParameterElement> typarams) {
if (typarams.isEmpty())
return 0;
if (typarams.size() != 1)
return 0;
for (TypeParameterElement tpe: typarams) {
boolean b1 = checkAnnotationMirrors(tpe, tpe.getAnnotationMirrors());
boolean b2 = checkAnnotationMirrors(tpe, elements.getAllAnnotationMirrors(tpe));
boolean b3 = checkGetAnnotation(tpe);
boolean b4 = checkGetAnnotations(tpe);
return b1 && b2 && b3 && b4 ? 1 : 0;
for (TypeParameterElement tpe : typarams) {
ExpectedTypeParameterAnnotations expected = null;
for (ExpectedTypeParameterAnnotations a : e.getAnnotationsByType(ExpectedTypeParameterAnnotations.class)) {
if (tpe.getSimpleName().contentEquals(a.typeParameterName())) {
expected = a;
break;
}
}
if (expected == null) {
throw new IllegalStateException("Does not have expected values annotation.");
}
checkAnnotationMirrors(tpe, tpe.getAnnotationMirrors(), expected);
checkAnnotationMirrors(tpe, elements.getAllAnnotationMirrors(tpe), expected);
checkGetAnnotation(tpe, expected);
checkGetAnnotations(tpe, expected);
}
return 0;
return typarams.size();
}
boolean checkAnnotationMirrors(TypeParameterElement tpe, List<? extends AnnotationMirror> l) {
if (l.size() != 3) {
error("To few annotations, got " + l.size() +
", should be 3", tpe);
return false;
void checkAnnotationMirrors(TypeParameterElement tpe, List<? extends AnnotationMirror> l, ExpectedTypeParameterAnnotations expected) {
String[] expectedAnnotations = expected.annotations();
if (l.size() != expectedAnnotations.length) {
error("Incorrect number of annotations, got " + l.size() +
", should be " + expectedAnnotations.length, tpe);
return ;
}
AnnotationMirror m = l.get(0);
if (!m.getAnnotationType().asElement().equals(elements.getTypeElement("Foo"))) {
error("Wrong type of annotation, was expecting @Foo", m.getAnnotationType().asElement());
return false;
for (int i = 0; i < expectedAnnotations.length; i++) {
AnnotationMirror m = l.get(i);
if (!m.getAnnotationType().asElement().equals(elements.getTypeElement(expectedAnnotations[i]))) {
error("Wrong type of annotation, was expecting @Foo", m.getAnnotationType().asElement());
return ;
}
}
m = l.get(1);
if (!m.getAnnotationType().asElement().equals(elements.getTypeElement("Bar"))) {
error("Wrong type of annotation, was expecting @Bar", m.getAnnotationType().asElement());
return false;
}
m = l.get(2);
if (!m.getAnnotationType().asElement().equals(elements.getTypeElement("Baz"))) {
error("Wrong type of annotation, was expecting @Baz", m.getAnnotationType().asElement());
return false;
}
return true;
}
boolean checkGetAnnotation(TypeParameterElement tpe) {
Foo f = tpe.getAnnotation(Foo.class);
if (f == null)
error("Expecting @Foo to be present in getAnnotation()", tpe);
void checkGetAnnotation(TypeParameterElement tpe, ExpectedTypeParameterAnnotations expected) {
List<String> expectedAnnotations = Arrays.asList(expected.annotations());
Bar b = tpe.getAnnotation(Bar.class);
if (b == null)
error("Expecting @Bar to be present in getAnnotation()", tpe);
for (Class<? extends Annotation> c : ALL_ANNOTATIONS) {
Object a = tpe.getAnnotation(c);
Baz z = tpe.getAnnotation(Baz.class);
if (z == null)
error("Expecting @Baz to be present in getAnnotation()", tpe);
return f != null &&
b != null &&
z != null;
if (a != null ^ expectedAnnotations.indexOf(c.getName()) != (-1)) {
error("Unexpected behavior for " + c.getName(), tpe);
return ;
}
}
}
boolean checkGetAnnotations(TypeParameterElement tpe) {
Foo[] f = tpe.getAnnotationsByType(Foo.class);
if (f.length != 1) {
error("Expecting 1 @Foo to be present in getAnnotationsByType()", tpe);
return false;
}
void checkGetAnnotations(TypeParameterElement tpe, ExpectedTypeParameterAnnotations expected) {
List<String> expectedAnnotations = Arrays.asList(expected.annotations());
Bar[] b = tpe.getAnnotationsByType(Bar.class);
if (b.length != 1) {
error("Expecting 1 @Bar to be present in getAnnotationsByType()", tpe);
return false;
}
for (Class<? extends Annotation> c : ALL_ANNOTATIONS) {
Object[] a = tpe.getAnnotationsByType(c);
Baz[] z = tpe.getAnnotationsByType(Baz.class);
if (z.length != 1) {
error("Expecting 1 @Baz to be present in getAnnotationsByType()", tpe);
return false;
if (a.length > 0 ^ expectedAnnotations.indexOf(c.getName()) != (-1)) {
error("Unexpected behavior for " + c.getName(), tpe);
return ;
}
}
return true;
}
void note(String msg) {
@ -168,23 +161,71 @@ public class TestTypeParameterAnnotations<@Foo @Bar @Baz T> extends JavacTesting
messager.printMessage(Diagnostic.Kind.ERROR, msg);
}
Class<? extends Annotation>[] ALL_ANNOTATIONS = new Class[] {
Foo1.class, Bar1.class, Baz1.class,
Foo2.class, Bar2.class, Baz2.class,
};
// additional generic elements to test
<@Foo @Bar @Baz X> X m(X x) { return x; }
@ExpectedTypeParameterAnnotations(typeParameterName="W",
annotations={"Foo1", "Bar1", "Baz1"})
@ExpectedTypeParameterAnnotations(typeParameterName="X", annotations={})
@ExpectedTypeParameterAnnotations(typeParameterName="Y",
annotations={"Foo2", "Bar2", "Baz2"})
@ExpectedTypeParameterAnnotations(typeParameterName="Z", annotations={})
<@Foo1 @Bar1 @Baz1 W, X, @Foo2 @Bar2 @Baz2 Y, Z> X m(X x) { return x; }
interface Intf<@Foo @Bar @Baz X> { X m() ; }
@ExpectedTypeParameterAnnotations(typeParameterName="W",
annotations={"Foo1", "Bar1", "Baz1"})
@ExpectedTypeParameterAnnotations(typeParameterName="X", annotations={})
@ExpectedTypeParameterAnnotations(typeParameterName="Y",
annotations={"Foo2", "Bar2", "Baz2"})
@ExpectedTypeParameterAnnotations(typeParameterName="Z", annotations={})
interface Intf<@Foo1 @Bar1 @Baz1 W, X, @Foo2 @Bar2 @Baz2 Y, Z> { X m() ; }
class Class<@Foo @Bar @Baz X> {
<@Foo @Bar @Baz Y> Class() { }
@ExpectedTypeParameterAnnotations(typeParameterName="W",
annotations={"Foo1", "Bar1", "Baz1"})
@ExpectedTypeParameterAnnotations(typeParameterName="X", annotations={})
@ExpectedTypeParameterAnnotations(typeParameterName="Y",
annotations={"Foo2", "Bar2", "Baz2"})
@ExpectedTypeParameterAnnotations(typeParameterName="Z", annotations={})
class Clazz<@Foo1 @Bar1 @Baz1 W, X, @Foo2 @Bar2 @Baz2 Y, Z> {
@ExpectedTypeParameterAnnotations(typeParameterName="W",
annotations={"Foo1", "Bar1", "Baz1"})
@ExpectedTypeParameterAnnotations(typeParameterName="X", annotations={})
@ExpectedTypeParameterAnnotations(typeParameterName="Y",
annotations={"Foo2", "Bar2", "Baz2"})
@ExpectedTypeParameterAnnotations(typeParameterName="Z", annotations={})
<@Foo1 @Bar1 @Baz1 W, X, @Foo2 @Bar2 @Baz2 Y, Z> Clazz() { }
}
final int expect = 5; // top level class, plus preceding examples
final int expect = 5 * 4; // top level class, plus preceding examples, 4 type variables each
}
@Target(ElementType.TYPE_PARAMETER)
@interface Foo {}
@interface Foo1 {}
@Target(ElementType.TYPE_PARAMETER)
@interface Bar {}
@interface Bar1 {}
@Target(ElementType.TYPE_PARAMETER)
@interface Baz {}
@interface Baz1 {}
@Target(ElementType.TYPE_PARAMETER)
@interface Foo2 {}
@Target(ElementType.TYPE_PARAMETER)
@interface Bar2 {}
@Target(ElementType.TYPE_PARAMETER)
@interface Baz2 {}
@Repeatable(ExpectedTypeParameterAnnotationsCollection.class)
@interface ExpectedTypeParameterAnnotations {
public String typeParameterName();
public String[] annotations();
}
@interface ExpectedTypeParameterAnnotationsCollection {
public ExpectedTypeParameterAnnotations[] value();
}

View File

@ -1,18 +1,26 @@
/*
* @test /nodynamiccopyright/
* @bug 6313164
* @bug 6313164 8036953
* @author mcimadamore
* @summary javac generates code that fails byte code verification for the varargs feature
* @compile/fail/ref=T6313164.out -XDrawDiagnostics T6313164.java
* @compile/fail/ref=T6313164Source7.out -source 7 -XDrawDiagnostics T6313164.java
* @compile/fail/ref=T6313164Source8AndHigher.out -XDrawDiagnostics T6313164.java
*/
import p1.*;
class T6313164 {
{ B b = new B();
b.foo1(new B(), new B()); //error - A not accesible
b.foo2(new B(), new B()); //ok - A not accessible, but foo2(Object...) applicable
b.foo3(null, null); //error - A (inferred) not accesible
b.foo4(null, null); //error - A (inferred in 15.12.2.8 - no resolution backtrack) not accesible
b.foo4(new B(), new C()); //ok - A (inferred in 15.12.2.7) not accessible, but foo4(Object...) applicable
{
B b = new B();
b.foo1(new B(), new B()); //error - A not accessible
/* 7 : ok - A not accessible, but foo2(Object...) applicable
* 8+ : error - A not accessible
*/
b.foo2(new B(), new B());
b.foo3(null, null); //error - A (inferred) not accessible
b.foo4(null, null); //error - A not accesible
/* 7 : ok - A not accessible, but foo4(Object...) applicable
* 8+ : error - A not accessible
*/
b.foo4(new B(), new C());
}
}

View File

@ -1,6 +0,0 @@
T6313164.java:12:8: compiler.err.cant.apply.symbol: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
T6313164.java:14:13: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
T6313164.java:15:13: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
- compiler.note.unchecked.filename: B.java
- compiler.note.unchecked.recompile
3 errors

View File

@ -0,0 +1,6 @@
- compiler.warn.source.no.bootclasspath: 1.7
T6313164.java:14:10: compiler.err.cant.apply.symbol: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
T6313164.java:19:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
T6313164.java:20:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
3 errors
1 warning

View File

@ -0,0 +1,6 @@
T6313164.java:14:15: compiler.err.cant.apply.symbol: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
T6313164.java:18:15: compiler.err.cant.apply.symbol: kindname.method, foo2, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
T6313164.java:19:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
T6313164.java:20:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
T6313164.java:24:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
5 errors

View File

@ -1,31 +1,8 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @test /nodynamiccopyright/
* @bug 7175433 6313164
* @summary Inference cleanup: add helper class to handle inference variables
*
* @compile/fail/ref=T7175433.out -XDrawDiagnostics T7175433.java
*/
import java.util.List;
@ -34,26 +11,16 @@ class Bar {
private class Foo { }
<Z> List<Z> m(Object... o) { T7175433.assertTrue(true); return null; }
<Z> List<Z> m(Foo... o) { T7175433.assertTrue(false); return null; }
<Z> List<Z> m(Object... o) { return null; }
<Z> List<Z> m(Foo... o) { return null; }
Foo getFoo() { return null; }
}
public class T7175433 {
static int assertionCount;
static void assertTrue(boolean b) {
assertionCount++;
if (!b) {
throw new AssertionError();
}
}
public static void main(String[] args) {
Bar b = new Bar();
b.m(b.getFoo());
assertTrue(assertionCount == 1);
}
}

View File

@ -0,0 +1,2 @@
T7175433.java:24:12: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: Bar.Foo, kindname.class, T7175433)
1 error

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 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
@ -23,13 +23,12 @@
package p1;
@SuppressWarnings("unchecked")
public class B extends A {
public B() {}
public void foo1(A... args) { }
public void foo2(A... args) { }
public void foo2(Object... args) { }
public <X extends A> void foo3(X... args) { }
public <X extends A> void foo4(X... args) { }
public void foo4(Object... args) { }
}

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
@ -34,8 +34,12 @@ public
class SJavac {
public static void main(String... args) throws Exception {
SJavac s = new SJavac();
s.test();
try {
SJavac s = new SJavac();
s.test();
} finally {
System.out.println("\ntest complete\n");
}
}
FileSystem defaultfs = FileSystems.getDefault();
@ -412,7 +416,7 @@ class SJavac {
}
void incrementalCompileTestFullyQualifiedRef() throws Exception {
System.out.println("Verify that \"alfa.omega.A a;\" does create a proper dependency.");
System.out.println("\nVerify that \"alfa.omega.A a;\" does create a proper dependency.");
System.out.println("----------------------------------------------------------------");
populate(gensrc,
@ -517,8 +521,7 @@ class SJavac {
if (rc == 0) throw new Exception("Expected error during compile! Did not fail!");
}
Map<String,Long> collectState(Path dir) throws IOException
{
Map<String,Long> collectState(Path dir) throws IOException {
final Map<String,Long> files = new HashMap<>();
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override