Merge
This commit is contained in:
commit
2775a21b88
@ -122,12 +122,15 @@ public class Checker extends DocTreeScanner<Void, Void> {
|
||||
private Deque<TagStackItem> tagStack; // TODO: maybe want to record starting tree as well
|
||||
private HtmlTag currHeaderTag;
|
||||
|
||||
private final int implicitHeaderLevel;
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Top level">
|
||||
|
||||
Checker(Env env) {
|
||||
env.getClass();
|
||||
this.env = env;
|
||||
tagStack = new LinkedList<TagStackItem>();
|
||||
implicitHeaderLevel = env.implicitHeaderLevel;
|
||||
}
|
||||
|
||||
public Void scan(DocCommentTree tree, TreePath p) {
|
||||
@ -386,7 +389,7 @@ public class Checker extends DocTreeScanner<Void, Void> {
|
||||
|
||||
private int getHeaderLevel(HtmlTag tag) {
|
||||
if (tag == null)
|
||||
return 0;
|
||||
return implicitHeaderLevel;
|
||||
switch (tag) {
|
||||
case H1: return 1;
|
||||
case H2: return 2;
|
||||
|
@ -30,6 +30,7 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.tools.StandardLocation;
|
||||
@ -72,6 +73,7 @@ public class DocLint implements Plugin {
|
||||
public static final String XMSGS_OPTION = "-Xmsgs";
|
||||
public static final String XMSGS_CUSTOM_PREFIX = "-Xmsgs:";
|
||||
private static final String STATS = "-stats";
|
||||
public static final String XIMPLICIT_HEADERS = "-XimplicitHeaders:";
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Command-line entry point">
|
||||
public static void main(String... args) {
|
||||
@ -289,6 +291,9 @@ public class DocLint implements Plugin {
|
||||
env.messages.setOptions(null);
|
||||
} else if (arg.startsWith(XMSGS_CUSTOM_PREFIX)) {
|
||||
env.messages.setOptions(arg.substring(arg.indexOf(":") + 1));
|
||||
} else if (arg.matches(XIMPLICIT_HEADERS + "[1-6]")) {
|
||||
char ch = arg.charAt(arg.length() - 1);
|
||||
env.setImplicitHeaders(Character.digit(ch, 10));
|
||||
} else
|
||||
throw new IllegalArgumentException(arg);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -83,6 +83,8 @@ public class Env {
|
||||
/** Message handler. */
|
||||
final Messages messages;
|
||||
|
||||
int implicitHeaderLevel = 0;
|
||||
|
||||
// Utility classes
|
||||
DocTrees trees;
|
||||
Elements elements;
|
||||
@ -102,7 +104,7 @@ public class Env {
|
||||
DocCommentTree currDocComment;
|
||||
/**
|
||||
* The access kind of the declaration containing the comment currently being analyzed.
|
||||
* This is the minimum (most restrictive) access kind of the declaration iteself
|
||||
* This is the minimum (most restrictive) access kind of the declaration itself
|
||||
* and that of its containers. For example, a public method in a private class is
|
||||
* noted as private.
|
||||
*/
|
||||
@ -128,6 +130,10 @@ public class Env {
|
||||
java_lang_Void = elements.getTypeElement("java.lang.Void").asType();
|
||||
}
|
||||
|
||||
void setImplicitHeaders(int n) {
|
||||
implicitHeaderLevel = n;
|
||||
}
|
||||
|
||||
/** Set the current declaration and its doc comment. */
|
||||
void setCurrent(TreePath path, DocCommentTree comment) {
|
||||
currPath = path;
|
||||
|
@ -314,6 +314,7 @@ public class Flags {
|
||||
modifiers.add(Modifier.SYNCHRONIZED);
|
||||
if (0 != (flags & NATIVE)) modifiers.add(Modifier.NATIVE);
|
||||
if (0 != (flags & STRICTFP)) modifiers.add(Modifier.STRICTFP);
|
||||
if (0 != (flags & DEFAULT)) modifiers.add(Modifier.DEFAULT);
|
||||
modifiers = Collections.unmodifiableSet(modifiers);
|
||||
modifierSets.put(flags, modifiers);
|
||||
}
|
||||
|
@ -908,6 +908,12 @@ public class Type implements PrimitiveType {
|
||||
return interfaces_field.prepend(supertype_field);
|
||||
}
|
||||
|
||||
public List<Type> getExplicitComponents() {
|
||||
return allInterfaces ?
|
||||
interfaces_field :
|
||||
getComponents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeKind getKind() {
|
||||
return TypeKind.INTERSECTION;
|
||||
|
@ -610,7 +610,7 @@ public class Types {
|
||||
|
||||
/**
|
||||
* Scope filter used to skip methods that should be ignored (such as methods
|
||||
* overridden by j.l.Object) during function interface conversion/marker interface checks
|
||||
* overridden by j.l.Object) during function interface conversion interface check
|
||||
*/
|
||||
class DescriptorFilter implements Filter<Symbol> {
|
||||
|
||||
@ -629,64 +629,6 @@ public class Types {
|
||||
}
|
||||
};
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="isMarker">
|
||||
|
||||
/**
|
||||
* A cache that keeps track of marker interfaces
|
||||
*/
|
||||
class MarkerCache {
|
||||
|
||||
private WeakHashMap<TypeSymbol, Entry> _map = new WeakHashMap<TypeSymbol, Entry>();
|
||||
|
||||
class Entry {
|
||||
final boolean isMarkerIntf;
|
||||
final int prevMark;
|
||||
|
||||
public Entry(boolean isMarkerIntf,
|
||||
int prevMark) {
|
||||
this.isMarkerIntf = isMarkerIntf;
|
||||
this.prevMark = prevMark;
|
||||
}
|
||||
|
||||
boolean matches(int mark) {
|
||||
return this.prevMark == mark;
|
||||
}
|
||||
}
|
||||
|
||||
boolean get(TypeSymbol origin) throws FunctionDescriptorLookupError {
|
||||
Entry e = _map.get(origin);
|
||||
CompoundScope members = membersClosure(origin.type, false);
|
||||
if (e == null ||
|
||||
!e.matches(members.getMark())) {
|
||||
boolean isMarkerIntf = isMarkerInterfaceInternal(origin, members);
|
||||
_map.put(origin, new Entry(isMarkerIntf, members.getMark()));
|
||||
return isMarkerIntf;
|
||||
}
|
||||
else {
|
||||
return e.isMarkerIntf;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is given symbol a marker interface
|
||||
*/
|
||||
public boolean isMarkerInterfaceInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError {
|
||||
return !origin.isInterface() ?
|
||||
false :
|
||||
!membersCache.getElements(new DescriptorFilter(origin)).iterator().hasNext();
|
||||
}
|
||||
}
|
||||
|
||||
private MarkerCache markerCache = new MarkerCache();
|
||||
|
||||
/**
|
||||
* Is given type a marker interface?
|
||||
*/
|
||||
public boolean isMarkerInterface(Type site) {
|
||||
return markerCache.get(site.tsym);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="isSubtype">
|
||||
/**
|
||||
* Is t an unchecked subtype of s?
|
||||
@ -2625,15 +2567,15 @@ public class Types {
|
||||
public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) {
|
||||
Filter<Symbol> filter = new MethodFilter(ms, site);
|
||||
List<MethodSymbol> candidates = List.nil();
|
||||
for (Symbol s : membersClosure(site, false).getElements(filter)) {
|
||||
if (!site.tsym.isInterface() && !s.owner.isInterface()) {
|
||||
return List.of((MethodSymbol)s);
|
||||
} else if (!candidates.contains(s)) {
|
||||
candidates = candidates.prepend((MethodSymbol)s);
|
||||
for (Symbol s : membersClosure(site, false).getElements(filter)) {
|
||||
if (!site.tsym.isInterface() && !s.owner.isInterface()) {
|
||||
return List.of((MethodSymbol)s);
|
||||
} else if (!candidates.contains(s)) {
|
||||
candidates = candidates.prepend((MethodSymbol)s);
|
||||
}
|
||||
}
|
||||
return prune(candidates);
|
||||
}
|
||||
return prune(candidates);
|
||||
}
|
||||
|
||||
public List<MethodSymbol> prune(List<MethodSymbol> methods) {
|
||||
ListBuffer<MethodSymbol> methodsMin = ListBuffer.lb();
|
||||
|
@ -2273,7 +2273,7 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
Type lambdaType;
|
||||
if (pt() != Type.recoveryType) {
|
||||
target = checkIntersectionTarget(that, target, resultInfo.checkContext);
|
||||
target = targetChecker.visit(target, that);
|
||||
lambdaType = types.findDescriptorType(target);
|
||||
chk.checkFunctionalInterface(that, target);
|
||||
} else {
|
||||
@ -2281,7 +2281,7 @@ public class Attr extends JCTree.Visitor {
|
||||
lambdaType = fallbackDescriptorType(that);
|
||||
}
|
||||
|
||||
setFunctionalInfo(that, pt(), lambdaType, resultInfo.checkContext.inferenceContext());
|
||||
setFunctionalInfo(that, pt(), lambdaType, target, resultInfo.checkContext.inferenceContext());
|
||||
|
||||
if (lambdaType.hasTag(FORALL)) {
|
||||
//lambda expression target desc cannot be a generic method
|
||||
@ -2340,11 +2340,34 @@ public class Attr extends JCTree.Visitor {
|
||||
new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
|
||||
localEnv.info.returnResult = bodyResultInfo;
|
||||
|
||||
if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
|
||||
attribTree(that.getBody(), localEnv, bodyResultInfo);
|
||||
} else {
|
||||
JCBlock body = (JCBlock)that.body;
|
||||
attribStats(body.stats, localEnv);
|
||||
Log.DeferredDiagnosticHandler lambdaDeferredHandler = new Log.DeferredDiagnosticHandler(log);
|
||||
try {
|
||||
if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
|
||||
attribTree(that.getBody(), localEnv, bodyResultInfo);
|
||||
} else {
|
||||
JCBlock body = (JCBlock)that.body;
|
||||
attribStats(body.stats, localEnv);
|
||||
}
|
||||
|
||||
if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.SPECULATIVE) {
|
||||
//check for errors in lambda body
|
||||
for (JCDiagnostic deferredDiag : lambdaDeferredHandler.getDiagnostics()) {
|
||||
if (deferredDiag.getKind() == JCDiagnostic.Kind.ERROR) {
|
||||
resultInfo.checkContext
|
||||
.report(that, diags.fragment("bad.arg.types.in.lambda", TreeInfo.types(that.params)));
|
||||
//we mark the lambda as erroneous - this is crucial in the recovery step
|
||||
//as parameter-dependent type error won't be reported in that stage,
|
||||
//meaning that a lambda will be deemed erroeneous only if there is
|
||||
//a target-independent error (which will cause method diagnostic
|
||||
//to be skipped).
|
||||
result = that.type = types.createErrorType(target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lambdaDeferredHandler.reportDeferredDiagnostics();
|
||||
log.popDiagnosticHandler(lambdaDeferredHandler);
|
||||
}
|
||||
|
||||
result = check(that, target, VAL, resultInfo);
|
||||
@ -2373,26 +2396,55 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Type checkIntersectionTarget(DiagnosticPosition pos, Type pt, CheckContext checkContext) {
|
||||
if (pt != Type.recoveryType && pt.isCompound()) {
|
||||
IntersectionClassType ict = (IntersectionClassType)pt;
|
||||
List<Type> bounds = ict.allInterfaces ?
|
||||
ict.getComponents().tail :
|
||||
ict.getComponents();
|
||||
types.findDescriptorType(bounds.head); //propagate exception outwards!
|
||||
for (Type bound : bounds.tail) {
|
||||
if (!types.isMarkerInterface(bound)) {
|
||||
checkContext.report(pos, diags.fragment("secondary.bound.must.be.marker.intf", bound));
|
||||
}
|
||||
}
|
||||
//for now (translation doesn't support intersection types)
|
||||
return bounds.head;
|
||||
} else {
|
||||
return pt;
|
||||
}
|
||||
}
|
||||
//where
|
||||
Types.MapVisitor<DiagnosticPosition> targetChecker = new Types.MapVisitor<DiagnosticPosition>() {
|
||||
|
||||
@Override
|
||||
public Type visitClassType(ClassType t, DiagnosticPosition pos) {
|
||||
return t.isCompound() ?
|
||||
visitIntersectionClassType((IntersectionClassType)t, pos) : t;
|
||||
}
|
||||
|
||||
public Type visitIntersectionClassType(IntersectionClassType ict, DiagnosticPosition pos) {
|
||||
Symbol desc = types.findDescriptorSymbol(makeNotionalInterface(ict));
|
||||
Type target = null;
|
||||
for (Type bound : ict.getExplicitComponents()) {
|
||||
TypeSymbol boundSym = bound.tsym;
|
||||
if (types.isFunctionalInterface(boundSym) &&
|
||||
types.findDescriptorSymbol(boundSym) == desc) {
|
||||
target = bound;
|
||||
} else if (!boundSym.isInterface() || (boundSym.flags() & ANNOTATION) != 0) {
|
||||
//bound must be an interface
|
||||
reportIntersectionError(pos, "not.an.intf.component", boundSym);
|
||||
}
|
||||
}
|
||||
return target != null ?
|
||||
target :
|
||||
ict.getExplicitComponents().head; //error recovery
|
||||
}
|
||||
|
||||
private TypeSymbol makeNotionalInterface(IntersectionClassType ict) {
|
||||
ListBuffer<Type> targs = ListBuffer.lb();
|
||||
ListBuffer<Type> supertypes = ListBuffer.lb();
|
||||
for (Type i : ict.interfaces_field) {
|
||||
if (i.isParameterized()) {
|
||||
targs.appendList(i.tsym.type.allparams());
|
||||
}
|
||||
supertypes.append(i.tsym.type);
|
||||
}
|
||||
IntersectionClassType notionalIntf =
|
||||
(IntersectionClassType)types.makeCompoundType(supertypes.toList());
|
||||
notionalIntf.allparams_field = targs.toList();
|
||||
notionalIntf.tsym.flags_field |= INTERFACE;
|
||||
return notionalIntf.tsym;
|
||||
}
|
||||
|
||||
private void reportIntersectionError(DiagnosticPosition pos, String key, Object... args) {
|
||||
resultInfo.checkContext.report(pos, diags.fragment("bad.intersection.target.for.functional.expr",
|
||||
diags.fragment(key, args)));
|
||||
}
|
||||
};
|
||||
|
||||
private Type fallbackDescriptorType(JCExpression tree) {
|
||||
switch (tree.getTag()) {
|
||||
case LAMBDA:
|
||||
@ -2563,7 +2615,7 @@ public class Attr extends JCTree.Visitor {
|
||||
Type target;
|
||||
Type desc;
|
||||
if (pt() != Type.recoveryType) {
|
||||
target = checkIntersectionTarget(that, pt(), resultInfo.checkContext);
|
||||
target = targetChecker.visit(pt(), that);
|
||||
desc = types.findDescriptorType(target);
|
||||
chk.checkFunctionalInterface(that, target);
|
||||
} else {
|
||||
@ -2571,11 +2623,12 @@ public class Attr extends JCTree.Visitor {
|
||||
desc = fallbackDescriptorType(that);
|
||||
}
|
||||
|
||||
setFunctionalInfo(that, pt(), desc, resultInfo.checkContext.inferenceContext());
|
||||
setFunctionalInfo(that, pt(), desc, target, resultInfo.checkContext.inferenceContext());
|
||||
List<Type> argtypes = desc.getParameterTypes();
|
||||
|
||||
Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = rs.resolveMemberReference(that.pos(), localEnv, that,
|
||||
that.expr.type, that.name, argtypes, typeargtypes, true);
|
||||
Pair<Symbol, Resolve.ReferenceLookupHelper> refResult =
|
||||
rs.resolveMemberReference(that.pos(), localEnv, that,
|
||||
that.expr.type, that.name, argtypes, typeargtypes, true, rs.resolveMethodCheck);
|
||||
|
||||
Symbol refSym = refResult.fst;
|
||||
Resolve.ReferenceLookupHelper lookupHelper = refResult.snd;
|
||||
@ -2765,19 +2818,24 @@ public class Attr extends JCTree.Visitor {
|
||||
* might contain inference variables, we might need to register an hook in the
|
||||
* current inference context.
|
||||
*/
|
||||
private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, final Type descriptorType, InferenceContext inferenceContext) {
|
||||
private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt,
|
||||
final Type descriptorType, final Type primaryTarget, InferenceContext inferenceContext) {
|
||||
if (inferenceContext.free(descriptorType)) {
|
||||
inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() {
|
||||
public void typesInferred(InferenceContext inferenceContext) {
|
||||
setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType), inferenceContext);
|
||||
setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType),
|
||||
inferenceContext.asInstType(primaryTarget), inferenceContext);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ListBuffer<TypeSymbol> targets = ListBuffer.lb();
|
||||
if (pt.hasTag(CLASS)) {
|
||||
if (pt.isCompound()) {
|
||||
targets.append(primaryTarget.tsym); //this goes first
|
||||
for (Type t : ((IntersectionClassType)pt()).interfaces_field) {
|
||||
targets.append(t.tsym);
|
||||
if (t != primaryTarget) {
|
||||
targets.append(t.tsym);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
targets.append(pt.tsym);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,6 +28,7 @@ package com.sun.tools.javac.comp;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.tree.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.comp.Attr.ResultInfo;
|
||||
@ -531,12 +532,13 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
attr.memberReferenceQualifierResult(tree));
|
||||
ListBuffer<Type> argtypes = ListBuffer.lb();
|
||||
for (Type t : types.findDescriptorType(pt).getParameterTypes()) {
|
||||
argtypes.append(syms.errType);
|
||||
argtypes.append(Type.noType);
|
||||
}
|
||||
JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
|
||||
mref2.expr = exprTree;
|
||||
Pair<Symbol, ?> lookupRes =
|
||||
rs.resolveMemberReference(tree, env, mref2, exprTree.type, tree.name, argtypes.toList(), null, true);
|
||||
rs.resolveMemberReference(tree, env, mref2, exprTree.type,
|
||||
tree.name, argtypes.toList(), null, true, rs.arityMethodCheck);
|
||||
switch (lookupRes.fst.kind) {
|
||||
//note: as argtypes are erroneous types, type-errors must
|
||||
//have been caused by arity mismatch
|
||||
|
@ -143,7 +143,6 @@ public class Infer {
|
||||
boolean allowBoxing,
|
||||
boolean useVarargs,
|
||||
Resolve.MethodResolutionContext resolveContext,
|
||||
Resolve.MethodCheck methodCheck,
|
||||
Warner warn) throws InferenceException {
|
||||
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
|
||||
final InferenceContext inferenceContext = new InferenceContext(tvars);
|
||||
@ -152,7 +151,7 @@ public class Infer {
|
||||
DeferredAttr.DeferredAttrContext deferredAttrContext =
|
||||
resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn);
|
||||
|
||||
methodCheck.argumentsAcceptable(env, deferredAttrContext,
|
||||
resolveContext.methodCheck.argumentsAcceptable(env, deferredAttrContext,
|
||||
argtypes, mt.getParameterTypes(), warn);
|
||||
|
||||
if (allowGraphInference &&
|
||||
|
@ -384,18 +384,6 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
Symbol translatedSym = lambdaContext.getSymbolMap(CAPTURED_VAR).get(tree.sym);
|
||||
result = make.Ident(translatedSym).setType(tree.type);
|
||||
} else {
|
||||
if (tree.sym.owner.kind == Kinds.TYP) {
|
||||
for (Map.Entry<Symbol, Symbol> encl_entry : lambdaContext.getSymbolMap(CAPTURED_THIS).entrySet()) {
|
||||
if (tree.sym.isMemberOf((ClassSymbol) encl_entry.getKey(), types)) {
|
||||
JCExpression enclRef = make.Ident(encl_entry.getValue());
|
||||
result = tree.sym.name == names._this
|
||||
? enclRef.setType(tree.type)
|
||||
: make.Select(enclRef, tree.sym).setType(tree.type);
|
||||
result = tree;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
//access to untranslated symbols (i.e. compile-time constants,
|
||||
//members defined inside the lambda body, etc.) )
|
||||
super.visitIdent(tree);
|
||||
@ -1315,6 +1303,7 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
// the generated lambda method will not have type yet, but the
|
||||
// enclosing method's name will have been generated with this same
|
||||
// method, so it will be unique and never be overloaded.
|
||||
Assert.check(owner.type != null || directlyEnclosingLambda() != null);
|
||||
if (owner.type != null) {
|
||||
int methTypeHash = methodSig(owner.type).hashCode();
|
||||
buf.append(Integer.toHexString(methTypeHash));
|
||||
|
@ -508,7 +508,6 @@ public class Resolve {
|
||||
List<Type> typeargtypes,
|
||||
boolean allowBoxing,
|
||||
boolean useVarargs,
|
||||
MethodCheck methodCheck,
|
||||
Warner warn) throws Infer.InferenceException {
|
||||
|
||||
Type mt = types.memberType(site, m);
|
||||
@ -561,10 +560,9 @@ public class Resolve {
|
||||
allowBoxing,
|
||||
useVarargs,
|
||||
currentResolutionContext,
|
||||
methodCheck,
|
||||
warn);
|
||||
|
||||
methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn),
|
||||
currentResolutionContext.methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn),
|
||||
argtypes, mt.getParameterTypes(), warn);
|
||||
return mt;
|
||||
}
|
||||
@ -582,7 +580,7 @@ public class Resolve {
|
||||
currentResolutionContext.attrMode = DeferredAttr.AttrMode.CHECK;
|
||||
MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
|
||||
return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
|
||||
step.isBoxingRequired(), step.isVarargsRequired(), resolveMethodCheck, warn);
|
||||
step.isBoxingRequired(), step.isVarargsRequired(), warn);
|
||||
}
|
||||
finally {
|
||||
currentResolutionContext = prevContext;
|
||||
@ -599,11 +597,10 @@ public class Resolve {
|
||||
List<Type> typeargtypes,
|
||||
boolean allowBoxing,
|
||||
boolean useVarargs,
|
||||
MethodCheck methodCheck,
|
||||
Warner warn) {
|
||||
try {
|
||||
return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
|
||||
allowBoxing, useVarargs, methodCheck, warn);
|
||||
allowBoxing, useVarargs, warn);
|
||||
} catch (InapplicableMethodException ex) {
|
||||
return null;
|
||||
}
|
||||
@ -628,6 +625,12 @@ public class Resolve {
|
||||
List<Type> argtypes,
|
||||
List<Type> formals,
|
||||
Warner warn);
|
||||
|
||||
/**
|
||||
* Retrieve the method check object that will be used during a
|
||||
* most specific check.
|
||||
*/
|
||||
MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -661,24 +664,25 @@ public class Resolve {
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method applicability routine. Given a list of actual types A,
|
||||
* a list of formal types F, determines whether the types in A are
|
||||
* compatible (by method invocation conversion) with the types in F.
|
||||
*
|
||||
* Since this routine is shared between overload resolution and method
|
||||
* type-inference, a (possibly empty) inference context is used to convert
|
||||
* formal types to the corresponding 'undet' form ahead of a compatibility
|
||||
* check so that constraints can be propagated and collected.
|
||||
*
|
||||
* Moreover, if one or more types in A is a deferred type, this routine uses
|
||||
* DeferredAttr in order to perform deferred attribution. If one or more actual
|
||||
* deferred types are stuck, they are placed in a queue and revisited later
|
||||
* after the remainder of the arguments have been seen. If this is not sufficient
|
||||
* to 'unstuck' the argument, a cyclic inference error is called out.
|
||||
*
|
||||
* A method check handler (see above) is used in order to report errors.
|
||||
* Dummy method check object. All methods are deemed applicable, regardless
|
||||
* of their formal parameter types.
|
||||
*/
|
||||
MethodCheck resolveMethodCheck = new MethodCheck() {
|
||||
MethodCheck nilMethodCheck = new MethodCheck() {
|
||||
public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) {
|
||||
//do nothing - method always applicable regardless of actuals
|
||||
}
|
||||
|
||||
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for 'real' method checks. The class defines the logic for
|
||||
* iterating through formals and actuals and provides and entry point
|
||||
* that can be used by subclasses in order to define the actual check logic.
|
||||
*/
|
||||
abstract class AbstractMethodCheck implements MethodCheck {
|
||||
@Override
|
||||
public void argumentsAcceptable(final Env<AttrContext> env,
|
||||
DeferredAttrContext deferredAttrContext,
|
||||
@ -699,8 +703,7 @@ public class Resolve {
|
||||
}
|
||||
|
||||
while (argtypes.nonEmpty() && formals.head != varargsFormal) {
|
||||
ResultInfo mresult = methodCheckResult(false, formals.head, deferredAttrContext, warn);
|
||||
mresult.check(null, argtypes.head);
|
||||
checkArg(false, argtypes.head, formals.head, deferredAttrContext, warn);
|
||||
argtypes = argtypes.tail;
|
||||
formals = formals.tail;
|
||||
}
|
||||
@ -713,17 +716,19 @@ public class Resolve {
|
||||
//note: if applicability check is triggered by most specific test,
|
||||
//the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
|
||||
final Type elt = types.elemtype(varargsFormal);
|
||||
ResultInfo mresult = methodCheckResult(true, elt, deferredAttrContext, warn);
|
||||
while (argtypes.nonEmpty()) {
|
||||
mresult.check(null, argtypes.head);
|
||||
checkArg(true, argtypes.head, elt, deferredAttrContext, warn);
|
||||
argtypes = argtypes.tail;
|
||||
}
|
||||
//check varargs element type accessibility
|
||||
varargsAccessible(env, elt, inferenceContext);
|
||||
}
|
||||
}
|
||||
|
||||
private void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
|
||||
/**
|
||||
* Does the actual argument conforms to the corresponding formal?
|
||||
*/
|
||||
abstract void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
|
||||
|
||||
protected void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
|
||||
boolean inferDiag = inferenceContext != infer.emptyContext;
|
||||
InapplicableMethodException ex = inferDiag ?
|
||||
infer.inferenceException : inapplicableMethodException;
|
||||
@ -736,6 +741,63 @@ public class Resolve {
|
||||
throw ex.setMessage(inferDiag ? diag.inferKey : diag.basicKey, args);
|
||||
}
|
||||
|
||||
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
|
||||
return nilMethodCheck;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Arity-based method check. A method is applicable if the number of actuals
|
||||
* supplied conforms to the method signature.
|
||||
*/
|
||||
MethodCheck arityMethodCheck = new AbstractMethodCheck() {
|
||||
@Override
|
||||
void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
|
||||
//do nothing - actual always compatible to formals
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Main method applicability routine. Given a list of actual types A,
|
||||
* a list of formal types F, determines whether the types in A are
|
||||
* compatible (by method invocation conversion) with the types in F.
|
||||
*
|
||||
* Since this routine is shared between overload resolution and method
|
||||
* type-inference, a (possibly empty) inference context is used to convert
|
||||
* formal types to the corresponding 'undet' form ahead of a compatibility
|
||||
* check so that constraints can be propagated and collected.
|
||||
*
|
||||
* Moreover, if one or more types in A is a deferred type, this routine uses
|
||||
* DeferredAttr in order to perform deferred attribution. If one or more actual
|
||||
* deferred types are stuck, they are placed in a queue and revisited later
|
||||
* after the remainder of the arguments have been seen. If this is not sufficient
|
||||
* to 'unstuck' the argument, a cyclic inference error is called out.
|
||||
*
|
||||
* A method check handler (see above) is used in order to report errors.
|
||||
*/
|
||||
MethodCheck resolveMethodCheck = new AbstractMethodCheck() {
|
||||
|
||||
@Override
|
||||
void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
|
||||
ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
|
||||
mresult.check(null, actual);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void argumentsAcceptable(final Env<AttrContext> env,
|
||||
DeferredAttrContext deferredAttrContext,
|
||||
List<Type> argtypes,
|
||||
List<Type> formals,
|
||||
Warner warn) {
|
||||
super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
|
||||
//should we expand formals?
|
||||
if (deferredAttrContext.phase.isVarargsRequired()) {
|
||||
//check varargs element type accessibility
|
||||
varargsAccessible(env, types.elemtype(formals.last()),
|
||||
deferredAttrContext.inferenceContext);
|
||||
}
|
||||
}
|
||||
|
||||
private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) {
|
||||
if (inferenceContext.free(t)) {
|
||||
inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() {
|
||||
@ -765,6 +827,11 @@ public class Resolve {
|
||||
};
|
||||
return new MethodResultInfo(to, checkContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
|
||||
return new MostSpecificCheck(strict, actuals);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1042,6 +1109,11 @@ public class Resolve {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
|
||||
Assert.error("Cannot get here!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class InapplicableMethodException extends RuntimeException {
|
||||
@ -1254,7 +1326,7 @@ public class Resolve {
|
||||
Assert.check(sym.kind < AMBIGUOUS);
|
||||
try {
|
||||
Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
|
||||
allowBoxing, useVarargs, resolveMethodCheck, types.noWarnings);
|
||||
allowBoxing, useVarargs, types.noWarnings);
|
||||
if (!operator)
|
||||
currentResolutionContext.addApplicableCandidate(sym, mt);
|
||||
} catch (InapplicableMethodException ex) {
|
||||
@ -1358,11 +1430,20 @@ public class Resolve {
|
||||
int maxLength = Math.max(
|
||||
Math.max(m1.type.getParameterTypes().length(), actuals.length()),
|
||||
m2.type.getParameterTypes().length());
|
||||
Type mst = instantiate(env, site, m2, null,
|
||||
adjustArgs(types.lowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
|
||||
allowBoxing, useVarargs, new MostSpecificCheck(!allowBoxing, actuals), noteWarner);
|
||||
return mst != null &&
|
||||
!noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
|
||||
MethodResolutionContext prevResolutionContext = currentResolutionContext;
|
||||
try {
|
||||
currentResolutionContext = new MethodResolutionContext();
|
||||
currentResolutionContext.step = prevResolutionContext.step;
|
||||
currentResolutionContext.methodCheck =
|
||||
prevResolutionContext.methodCheck.mostSpecificCheck(actuals, !allowBoxing);
|
||||
Type mst = instantiate(env, site, m2, null,
|
||||
adjustArgs(types.lowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
|
||||
allowBoxing, useVarargs, noteWarner);
|
||||
return mst != null &&
|
||||
!noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
|
||||
} finally {
|
||||
currentResolutionContext = prevResolutionContext;
|
||||
}
|
||||
}
|
||||
private List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
|
||||
if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
|
||||
@ -2124,14 +2205,14 @@ public class Resolve {
|
||||
Name name,
|
||||
List<Type> argtypes,
|
||||
List<Type> typeargtypes) {
|
||||
return lookupMethod(env, pos, env.enclClass.sym, new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
|
||||
@Override
|
||||
Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
|
||||
return findFun(env, name, argtypes, typeargtypes,
|
||||
phase.isBoxingRequired(),
|
||||
phase.isVarargsRequired());
|
||||
}
|
||||
});
|
||||
return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck,
|
||||
new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
|
||||
@Override
|
||||
Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
|
||||
return findFun(env, name, argtypes, typeargtypes,
|
||||
phase.isBoxingRequired(),
|
||||
phase.isVarargsRequired());
|
||||
}});
|
||||
}
|
||||
|
||||
/** Resolve a qualified method identifier
|
||||
@ -2313,36 +2394,36 @@ public class Resolve {
|
||||
Type site,
|
||||
List<Type> argtypes,
|
||||
List<Type> typeargtypes) {
|
||||
return lookupMethod(env, pos, site.tsym, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
|
||||
@Override
|
||||
Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
|
||||
return findDiamond(env, site, argtypes, typeargtypes,
|
||||
phase.isBoxingRequired(),
|
||||
phase.isVarargsRequired());
|
||||
}
|
||||
@Override
|
||||
Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
|
||||
if (sym.kind >= AMBIGUOUS) {
|
||||
final JCDiagnostic details = sym.kind == WRONG_MTH ?
|
||||
((InapplicableSymbolError)sym).errCandidate().details :
|
||||
null;
|
||||
sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
|
||||
@Override
|
||||
JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
|
||||
Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
|
||||
String key = details == null ?
|
||||
"cant.apply.diamond" :
|
||||
"cant.apply.diamond.1";
|
||||
return diags.create(dkind, log.currentSource(), pos, key,
|
||||
diags.fragment("diamond", site.tsym), details);
|
||||
return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
|
||||
new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
|
||||
@Override
|
||||
Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
|
||||
return findDiamond(env, site, argtypes, typeargtypes,
|
||||
phase.isBoxingRequired(),
|
||||
phase.isVarargsRequired());
|
||||
}
|
||||
@Override
|
||||
Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
|
||||
if (sym.kind >= AMBIGUOUS) {
|
||||
final JCDiagnostic details = sym.kind == WRONG_MTH ?
|
||||
((InapplicableSymbolError)sym).errCandidate().details :
|
||||
null;
|
||||
sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
|
||||
@Override
|
||||
JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
|
||||
Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
|
||||
String key = details == null ?
|
||||
"cant.apply.diamond" :
|
||||
"cant.apply.diamond.1";
|
||||
return diags.create(dkind, log.currentSource(), pos, key,
|
||||
diags.fragment("diamond", site.tsym), details);
|
||||
}
|
||||
};
|
||||
sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
|
||||
env.info.pendingResolutionPhase = currentResolutionContext.step;
|
||||
}
|
||||
};
|
||||
sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
|
||||
env.info.pendingResolutionPhase = currentResolutionContext.step;
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
});
|
||||
return sym;
|
||||
}});
|
||||
}
|
||||
|
||||
/** This method scans all the constructor symbol in a given class scope -
|
||||
@ -2475,7 +2556,8 @@ public class Resolve {
|
||||
Type site,
|
||||
Name name, List<Type> argtypes,
|
||||
List<Type> typeargtypes,
|
||||
boolean boxingAllowed) {
|
||||
boolean boxingAllowed,
|
||||
MethodCheck methodCheck) {
|
||||
MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC;
|
||||
|
||||
ReferenceLookupHelper boundLookupHelper;
|
||||
@ -2495,12 +2577,12 @@ public class Resolve {
|
||||
|
||||
//step 1 - bound lookup
|
||||
Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
|
||||
Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, boundLookupHelper);
|
||||
Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper);
|
||||
|
||||
//step 2 - unbound lookup
|
||||
ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup();
|
||||
Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
|
||||
Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, unboundLookupHelper);
|
||||
Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper);
|
||||
|
||||
//merge results
|
||||
Pair<Symbol, ReferenceLookupHelper> res;
|
||||
@ -2671,7 +2753,7 @@ public class Resolve {
|
||||
ReferenceLookupHelper unboundLookup() {
|
||||
if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
|
||||
argtypes.nonEmpty() &&
|
||||
types.isSubtypeUnchecked(argtypes.head, site)) {
|
||||
(argtypes.head.hasTag(NONE) || types.isSubtypeUnchecked(argtypes.head, site))) {
|
||||
return new UnboundMethodReferenceLookupHelper(referenceTree, name,
|
||||
site, argtypes, typeargtypes, maxPhase);
|
||||
} else {
|
||||
@ -2704,8 +2786,8 @@ public class Resolve {
|
||||
UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
|
||||
List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
|
||||
super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
|
||||
Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
|
||||
if (site.isRaw() && !asSuperSite.isErroneous()) {
|
||||
if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
|
||||
Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
|
||||
this.site = asSuperSite;
|
||||
}
|
||||
}
|
||||
@ -2800,8 +2882,10 @@ public class Resolve {
|
||||
* at the end of the lookup, the helper is used to validate the results
|
||||
* (this last step might trigger overload resolution diagnostics).
|
||||
*/
|
||||
Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, LookupHelper lookupHelper) {
|
||||
return lookupMethod(env, pos, location, new MethodResolutionContext(), lookupHelper);
|
||||
Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) {
|
||||
MethodResolutionContext resolveContext = new MethodResolutionContext();
|
||||
resolveContext.methodCheck = methodCheck;
|
||||
return lookupMethod(env, pos, location, resolveContext, lookupHelper);
|
||||
}
|
||||
|
||||
Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
|
||||
@ -3595,6 +3679,8 @@ public class Resolve {
|
||||
|
||||
MethodResolutionPhase step = null;
|
||||
|
||||
MethodCheck methodCheck = resolveMethodCheck;
|
||||
|
||||
private boolean internalResolution = false;
|
||||
private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
|
||||
|
||||
|
@ -373,6 +373,17 @@ public class Code {
|
||||
Assert.check(alive || state.stacksize == 0);
|
||||
}
|
||||
|
||||
/** Emit a ldc (or ldc_w) instruction, taking into account operand size
|
||||
*/
|
||||
public void emitLdc(int od) {
|
||||
if (od <= 255) {
|
||||
emitop1(ldc1, od);
|
||||
}
|
||||
else {
|
||||
emitop2(ldc2, od);
|
||||
}
|
||||
}
|
||||
|
||||
/** Emit a multinewarray instruction.
|
||||
*/
|
||||
public void emitMultianewarray(int ndims, int type, Type arrayType) {
|
||||
@ -459,7 +470,15 @@ public class Code {
|
||||
public void emitInvokedynamic(int desc, Type mtype) {
|
||||
// N.B. this format is under consideration by the JSR 292 EG
|
||||
int argsize = width(mtype.getParameterTypes());
|
||||
emitop(invokedynamic);
|
||||
int prevPos = pendingStatPos;
|
||||
try {
|
||||
//disable line number generation (we could have used 'emit1', that
|
||||
//bypasses stackmap generation - which is needed for indy calls)
|
||||
pendingStatPos = Position.NOPOS;
|
||||
emitop(invokedynamic);
|
||||
} finally {
|
||||
pendingStatPos = prevPos;
|
||||
}
|
||||
if (!alive) return;
|
||||
emit2(desc);
|
||||
emit2(0);
|
||||
|
@ -1748,10 +1748,13 @@ public class Gen extends JCTree.Visitor {
|
||||
// Generate code for all arguments, where the expected types are
|
||||
// the parameters of the method's external type (that is, any implicit
|
||||
// outer instance of a super(...) call appears as first parameter).
|
||||
MethodSymbol msym = (MethodSymbol)TreeInfo.symbol(tree.meth);
|
||||
genArgs(tree.args,
|
||||
TreeInfo.symbol(tree.meth).externalType(types).getParameterTypes());
|
||||
code.statBegin(tree.pos);
|
||||
code.markStatBegin();
|
||||
msym.externalType(types).getParameterTypes());
|
||||
if (!msym.isDynamic()) {
|
||||
code.statBegin(tree.pos);
|
||||
code.markStatBegin();
|
||||
}
|
||||
result = m.invoke();
|
||||
}
|
||||
|
||||
@ -2227,7 +2230,7 @@ public class Gen extends JCTree.Visitor {
|
||||
|
||||
if (tree.name == names._class) {
|
||||
Assert.check(target.hasClassLiterals());
|
||||
code.emitop2(ldc2, makeRef(tree.pos(), tree.selected.type));
|
||||
code.emitLdc(makeRef(tree.pos(), tree.selected.type));
|
||||
result = items.makeStackItem(pt);
|
||||
return;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -571,10 +571,8 @@ public class Items {
|
||||
int idx = pool.put(value);
|
||||
if (typecode == LONGcode || typecode == DOUBLEcode) {
|
||||
code.emitop2(ldc2w, idx);
|
||||
} else if (idx <= 255) {
|
||||
code.emitop1(ldc1, idx);
|
||||
} else {
|
||||
code.emitop2(ldc2, idx);
|
||||
code.emitLdc(idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -497,6 +497,8 @@ public class Main {
|
||||
if (!(doclintOpts.size() == 1
|
||||
&& doclintOpts.iterator().next().equals(DocLint.XMSGS_CUSTOM_PREFIX + "none"))) {
|
||||
JavacTask t = BasicJavacTask.instance(context);
|
||||
// standard doclet normally generates H1, H2
|
||||
doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2");
|
||||
new DocLint().init(t, doclintOpts.toArray(new String[doclintOpts.size()]));
|
||||
comp.keepComments = true;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -770,7 +770,7 @@ public class JavaTokenizer {
|
||||
* (which is treated as the beginning of the first line).
|
||||
* Stops positioned at the closing '/'.
|
||||
*/
|
||||
protected class BasicComment<U extends UnicodeReader> implements Comment {
|
||||
protected static class BasicComment<U extends UnicodeReader> implements Comment {
|
||||
|
||||
CommentStyle cs;
|
||||
U comment_reader;
|
||||
|
@ -171,8 +171,8 @@ public class JavacParser implements Parser {
|
||||
|
||||
protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
|
||||
return keepEndPositions
|
||||
? new SimpleEndPosTable()
|
||||
: new EmptyEndPosTable();
|
||||
? new SimpleEndPosTable(this)
|
||||
: new EmptyEndPosTable(this);
|
||||
}
|
||||
|
||||
protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
|
||||
@ -3088,6 +3088,7 @@ public class JavacParser implements Parser {
|
||||
toplevel.docComments = docComments;
|
||||
if (keepLineMap)
|
||||
toplevel.lineMap = S.getLineMap();
|
||||
this.endPosTable.setParser(null); // remove reference to parser
|
||||
toplevel.endPositions = this.endPosTable;
|
||||
return toplevel;
|
||||
}
|
||||
@ -4003,11 +4004,12 @@ public class JavacParser implements Parser {
|
||||
/*
|
||||
* a functional source tree and end position mappings
|
||||
*/
|
||||
protected class SimpleEndPosTable extends AbstractEndPosTable {
|
||||
protected static class SimpleEndPosTable extends AbstractEndPosTable {
|
||||
|
||||
private final Map<JCTree, Integer> endPosMap;
|
||||
|
||||
SimpleEndPosTable() {
|
||||
SimpleEndPosTable(JavacParser parser) {
|
||||
super(parser);
|
||||
endPosMap = new HashMap<JCTree, Integer>();
|
||||
}
|
||||
|
||||
@ -4016,12 +4018,12 @@ public class JavacParser implements Parser {
|
||||
}
|
||||
|
||||
protected <T extends JCTree> T to(T t) {
|
||||
storeEnd(t, token.endPos);
|
||||
storeEnd(t, parser.token.endPos);
|
||||
return t;
|
||||
}
|
||||
|
||||
protected <T extends JCTree> T toP(T t) {
|
||||
storeEnd(t, S.prevToken().endPos);
|
||||
storeEnd(t, parser.S.prevToken().endPos);
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -4043,7 +4045,11 @@ public class JavacParser implements Parser {
|
||||
/*
|
||||
* a default skeletal implementation without any mapping overhead.
|
||||
*/
|
||||
protected class EmptyEndPosTable extends AbstractEndPosTable {
|
||||
protected static class EmptyEndPosTable extends AbstractEndPosTable {
|
||||
|
||||
EmptyEndPosTable(JavacParser parser) {
|
||||
super(parser);
|
||||
}
|
||||
|
||||
protected void storeEnd(JCTree tree, int endpos) { /* empty */ }
|
||||
|
||||
@ -4065,13 +4071,21 @@ public class JavacParser implements Parser {
|
||||
|
||||
}
|
||||
|
||||
protected abstract class AbstractEndPosTable implements EndPosTable {
|
||||
protected static abstract class AbstractEndPosTable implements EndPosTable {
|
||||
/**
|
||||
* The current parser.
|
||||
*/
|
||||
protected JavacParser parser;
|
||||
|
||||
/**
|
||||
* Store the last error position.
|
||||
*/
|
||||
protected int errorEndPos;
|
||||
|
||||
public AbstractEndPosTable(JavacParser parser) {
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store ending position for a tree, the value of which is the greater
|
||||
* of last error position and the given ending position.
|
||||
@ -4106,5 +4120,9 @@ public class JavacParser implements Parser {
|
||||
errorEndPos = errPos;
|
||||
}
|
||||
}
|
||||
|
||||
protected void setParser(JavacParser parser) {
|
||||
this.parser = parser;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ public class JavadocTokenizer extends JavaTokenizer {
|
||||
}
|
||||
}
|
||||
|
||||
protected class JavadocComment extends JavaTokenizer.BasicComment<DocReader> {
|
||||
protected static class JavadocComment extends JavaTokenizer.BasicComment<DocReader> {
|
||||
|
||||
/**
|
||||
* Translated and stripped contents of doc comment
|
||||
|
@ -216,9 +216,14 @@ compiler.misc.descriptor.throws=\
|
||||
compiler.misc.no.suitable.functional.intf.inst=\
|
||||
cannot infer functional interface descriptor for {0}
|
||||
|
||||
# 0: message segment
|
||||
compiler.misc.bad.intersection.target.for.functional.expr=\
|
||||
bad intersection type target for lambda or method reference\n\
|
||||
{0}
|
||||
|
||||
# 0: type
|
||||
compiler.misc.secondary.bound.must.be.marker.intf=\
|
||||
secondary bound {0} must be a marker interface
|
||||
compiler.misc.not.an.intf.component=\
|
||||
component type {0} is not an interface
|
||||
|
||||
# 0: symbol kind, 1: message segment
|
||||
compiler.err.invalid.mref=\
|
||||
@ -731,6 +736,11 @@ compiler.misc.incompatible.arg.types.in.lambda=\
|
||||
compiler.misc.incompatible.arg.types.in.mref=\
|
||||
incompatible parameter types in method reference
|
||||
|
||||
# 0: list of type
|
||||
compiler.misc.bad.arg.types.in.lambda=\
|
||||
cannot type-check lambda expression with inferred parameter types\n\
|
||||
inferred types: {0}
|
||||
|
||||
compiler.err.new.not.allowed.in.annotation=\
|
||||
''new'' not allowed in an annotation
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -112,9 +112,8 @@ public abstract class BaseFileManager {
|
||||
protected ClassLoader getClassLoader(URL[] urls) {
|
||||
ClassLoader thisClassLoader = getClass().getClassLoader();
|
||||
|
||||
// Bug: 6558476
|
||||
// Ideally, ClassLoader should be Closeable, but before JDK7 it is not.
|
||||
// On older versions, try the following, to get a closeable classloader.
|
||||
// Allow the following to specify a closeable classloader
|
||||
// other than URLClassLoader.
|
||||
|
||||
// 1: Allow client to specify the class to use via hidden option
|
||||
if (classLoaderClass != null) {
|
||||
@ -128,19 +127,6 @@ public abstract class BaseFileManager {
|
||||
// ignore errors loading user-provided class loader, fall through
|
||||
}
|
||||
}
|
||||
|
||||
// 2: If URLClassLoader implements Closeable, use that.
|
||||
if (Closeable.class.isAssignableFrom(URLClassLoader.class))
|
||||
return new URLClassLoader(urls, thisClassLoader);
|
||||
|
||||
// 3: Try using private reflection-based CloseableURLClassLoader
|
||||
try {
|
||||
return new CloseableURLClassLoader(urls, thisClassLoader);
|
||||
} catch (Throwable t) {
|
||||
// ignore errors loading workaround class loader, fall through
|
||||
}
|
||||
|
||||
// 4: If all else fails, use plain old standard URLClassLoader
|
||||
return new URLClassLoader(urls, thisClassLoader);
|
||||
}
|
||||
|
||||
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.util;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
/**
|
||||
* A URLClassLoader that also implements Closeable.
|
||||
* Reflection is used to access internal data structures in the URLClassLoader,
|
||||
* since no public API exists for this purpose. Therefore this code is somewhat
|
||||
* fragile. Caveat emptor.
|
||||
* @throws Error if the internal data structures are not as expected.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class CloseableURLClassLoader
|
||||
extends URLClassLoader implements Closeable {
|
||||
public CloseableURLClassLoader(URL[] urls, ClassLoader parent) throws Error {
|
||||
super(urls, parent);
|
||||
try {
|
||||
getLoaders(); //proactive check that URLClassLoader is as expected
|
||||
} catch (Throwable t) {
|
||||
throw new Error("cannot create CloseableURLClassLoader", t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close any jar files that may have been opened by the class loader.
|
||||
* Reflection is used to access the jar files in the URLClassLoader's
|
||||
* internal data structures.
|
||||
* @throws java.io.IOException if the jar files cannot be found for any
|
||||
* reson, or if closing the jar file itself causes an IOException.
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
for (Object l: getLoaders()) {
|
||||
if (l.getClass().getName().equals("sun.misc.URLClassPath$JarLoader")) {
|
||||
Field jarField = l.getClass().getDeclaredField("jar");
|
||||
JarFile jar = (JarFile) getField(l, jarField);
|
||||
if (jar != null) {
|
||||
//System.err.println("CloseableURLClassLoader: closing " + jar);
|
||||
jar.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
IOException e = new IOException("cannot close class loader");
|
||||
e.initCause(t);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<?> getLoaders()
|
||||
throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
Field ucpField = URLClassLoader.class.getDeclaredField("ucp");
|
||||
Object urlClassPath = getField(this, ucpField);
|
||||
if (urlClassPath == null)
|
||||
throw new AssertionError("urlClassPath not set in URLClassLoader");
|
||||
Field loadersField = urlClassPath.getClass().getDeclaredField("loaders");
|
||||
return (ArrayList<?>) getField(urlClassPath, loadersField);
|
||||
}
|
||||
|
||||
private Object getField(Object o, Field f)
|
||||
throws IllegalArgumentException, IllegalAccessException {
|
||||
boolean prev = f.isAccessible();
|
||||
try {
|
||||
f.setAccessible(true);
|
||||
return f.get(o);
|
||||
} finally {
|
||||
f.setAccessible(prev);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/** A generic class for pairs.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
@ -46,15 +48,11 @@ public class Pair<A, B> {
|
||||
return "Pair[" + fst + "," + snd + "]";
|
||||
}
|
||||
|
||||
private static boolean equals(Object x, Object y) {
|
||||
return (x == null && y == null) || (x != null && x.equals(y));
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
return
|
||||
other instanceof Pair<?,?> &&
|
||||
equals(fst, ((Pair<?,?>)other).fst) &&
|
||||
equals(snd, ((Pair<?,?>)other).snd);
|
||||
Objects.equals(fst, ((Pair<?,?>)other).fst) &&
|
||||
Objects.equals(snd, ((Pair<?,?>)other).snd);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
|
@ -395,6 +395,9 @@ public class RichDiagnosticFormatter extends
|
||||
|
||||
@Override
|
||||
public String visitClassSymbol(ClassSymbol s, Locale locale) {
|
||||
if (s.type.isCompound()) {
|
||||
return visit(s.type, locale);
|
||||
}
|
||||
String name = nameSimplifier.simplify(s);
|
||||
if (name.length() == 0 ||
|
||||
!getConfiguration().isEnabled(RichFormatterFeature.SIMPLE_NAMES)) {
|
||||
@ -583,7 +586,11 @@ public class RichDiagnosticFormatter extends
|
||||
|
||||
@Override
|
||||
public Void visitClassSymbol(ClassSymbol s, Void ignored) {
|
||||
nameSimplifier.addUsage(s);
|
||||
if (s.type.isCompound()) {
|
||||
typePreprocessor.visit(s.type);
|
||||
} else {
|
||||
nameSimplifier.addUsage(s);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -810,6 +810,8 @@ public class DocEnv {
|
||||
|
||||
JavacTask t = BasicJavacTask.instance(context);
|
||||
doclint = new DocLint();
|
||||
// standard doclet normally generates H1, H2
|
||||
doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2");
|
||||
doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,6 +28,7 @@ package javax.annotation.processing;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import javax.lang.model.element.*;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.tools.Diagnostic;
|
||||
@ -146,8 +147,7 @@ public abstract class AbstractProcessor implements Processor {
|
||||
public synchronized void init(ProcessingEnvironment processingEnv) {
|
||||
if (initialized)
|
||||
throw new IllegalStateException("Cannot call init more than once.");
|
||||
if (processingEnv == null)
|
||||
throw new NullPointerException("Tool provided null ProcessingEnvironment");
|
||||
Objects.requireNonNull(processingEnv, "Tool provided null ProcessingEnvironment");
|
||||
|
||||
this.processingEnv = processingEnv;
|
||||
initialized = true;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -53,6 +53,11 @@ public enum Modifier {
|
||||
/** The modifier {@code protected} */ PROTECTED,
|
||||
/** The modifier {@code private} */ PRIVATE,
|
||||
/** The modifier {@code abstract} */ ABSTRACT,
|
||||
/**
|
||||
* The modifier {@code default}
|
||||
* @since 1.8
|
||||
*/
|
||||
DEFAULT,
|
||||
/** The modifier {@code static} */ STATIC,
|
||||
/** The modifier {@code final} */ FINAL,
|
||||
/** The modifier {@code transient} */ TRANSIENT,
|
||||
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4965689
|
||||
* @summary class literal code wastes a byte
|
||||
*/
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class ClassLiteralWastesByteTest {
|
||||
|
||||
private static final String assertionErrorMsg =
|
||||
"Instead of ldc_w, ldc instruction should have been generated";
|
||||
|
||||
public static void main(String[] args) {
|
||||
new ClassLiteralWastesByteTest().run();
|
||||
}
|
||||
|
||||
void run() {
|
||||
check("-c", Paths.get(System.getProperty("test.classes"),
|
||||
"test.class").toString());
|
||||
}
|
||||
|
||||
void check(String... params) {
|
||||
StringWriter s;
|
||||
String out;
|
||||
try (PrintWriter pw = new PrintWriter(s = new StringWriter())) {
|
||||
com.sun.tools.javap.Main.run(params, pw);
|
||||
out = s.toString();
|
||||
}
|
||||
if (out.contains("ldc_w")) {
|
||||
throw new AssertionError(assertionErrorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class test {
|
||||
void m() {
|
||||
Class<?> aClass = test.class;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,6 +23,8 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6558476
|
||||
* @summary com/sun/tools/javac/Main.compile don't release file handles on return
|
||||
* @run main/othervm -Xmx512m -Xms512m T6558476
|
||||
*/
|
||||
|
||||
@ -70,8 +72,7 @@ public class T6558476 {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
File javaHomeDir = new File(System.getProperty("java.home"));
|
||||
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
|
||||
File outputDir = new File(tmpDir, "outputDir" + new Random().nextInt(65536));
|
||||
File outputDir = new File("outputDir" + new Random().nextInt(65536));
|
||||
outputDir.mkdir();
|
||||
outputDir.deleteOnExit();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -39,7 +39,7 @@ public class T6900149 {
|
||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
StandardJavaFileManager fm =
|
||||
compiler.getStandardFileManager(null, null, null);
|
||||
File emptyFile = File.createTempFile("Empty", ".java");
|
||||
File emptyFile = createTempFile("Empty.java");
|
||||
File[] files = new File[] { emptyFile, emptyFile };
|
||||
CompilationTask task = compiler.getTask(null, fm, diag,
|
||||
null, null, fm.getJavaFileObjects(files));
|
||||
@ -47,4 +47,10 @@ public class T6900149 {
|
||||
throw new AssertionError("compilation failed");
|
||||
}
|
||||
}
|
||||
|
||||
private static File createTempFile(String path) throws IOException {
|
||||
File f = new File(path);
|
||||
try (FileWriter out = new FileWriter(f)) { }
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@ -53,7 +55,27 @@ public class CheckExamples {
|
||||
* Standard entry point.
|
||||
*/
|
||||
public static void main(String... args) throws Exception {
|
||||
new CheckExamples().run();
|
||||
boolean jtreg = (System.getProperty("test.src") != null);
|
||||
Path tmpDir;
|
||||
boolean deleteOnExit;
|
||||
if (jtreg) {
|
||||
// use standard jtreg scratch directory: the current directory
|
||||
tmpDir = Paths.get(System.getProperty("user.dir"));
|
||||
deleteOnExit = false;
|
||||
} else {
|
||||
tmpDir = Files.createTempDirectory(Paths.get(System.getProperty("java.io.tmpdir")),
|
||||
CheckExamples.class.getName());
|
||||
deleteOnExit = true;
|
||||
}
|
||||
Example.setTempDir(tmpDir.toFile());
|
||||
|
||||
try {
|
||||
new CheckExamples().run();
|
||||
} finally {
|
||||
if (deleteOnExit) {
|
||||
clean(tmpDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,6 +212,25 @@ public class CheckExamples {
|
||||
|
||||
int errors;
|
||||
|
||||
/**
|
||||
* Clean the contents of a directory.
|
||||
*/
|
||||
static void clean(Path dir) throws IOException {
|
||||
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
Files.delete(file);
|
||||
return super.visitFile(file, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||
if (exc == null) Files.delete(dir);
|
||||
return super.postVisitDirectory(dir, exc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static class Counts {
|
||||
static String[] prefixes = {
|
||||
"compiler.err.",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -33,7 +33,8 @@
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -56,16 +57,18 @@ import java.util.regex.Pattern;
|
||||
public class RunExamples {
|
||||
public static void main(String... args) throws Exception {
|
||||
jtreg = (System.getProperty("test.src") != null);
|
||||
File tmpDir;
|
||||
Path tmpDir;
|
||||
boolean deleteOnExit;
|
||||
if (jtreg) {
|
||||
// use standard jtreg scratch directory: the current directory
|
||||
tmpDir = new File(System.getProperty("user.dir"));
|
||||
tmpDir = Paths.get(System.getProperty("user.dir"));
|
||||
deleteOnExit = false;
|
||||
} else {
|
||||
tmpDir = new File(System.getProperty("java.io.tmpdir"),
|
||||
RunExamples.class.getName()
|
||||
+ (new SimpleDateFormat("yyMMddHHmmss")).format(new Date()));
|
||||
tmpDir = Files.createTempDirectory(Paths.get(System.getProperty("java.io.tmpdir")),
|
||||
RunExamples.class.getName());
|
||||
deleteOnExit = true;
|
||||
}
|
||||
Example.setTempDir(tmpDir);
|
||||
Example.setTempDir(tmpDir.toFile());
|
||||
|
||||
RunExamples r = new RunExamples();
|
||||
|
||||
@ -73,15 +76,8 @@ public class RunExamples {
|
||||
if (r.run(args))
|
||||
return;
|
||||
} finally {
|
||||
/* VERY IMPORTANT NOTE. In jtreg mode, tmpDir is set to the
|
||||
* jtreg scratch directory, which is the current directory.
|
||||
* In case someone is faking jtreg mode, make sure to only
|
||||
* clean tmpDir when it is reasonable to do so.
|
||||
*/
|
||||
if (tmpDir.isDirectory() &&
|
||||
tmpDir.getName().startsWith(RunExamples.class.getName())) {
|
||||
if (clean(tmpDir))
|
||||
tmpDir.delete();
|
||||
if (deleteOnExit) {
|
||||
clean(tmpDir);
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,14 +199,20 @@ public class RunExamples {
|
||||
/**
|
||||
* Clean the contents of a directory.
|
||||
*/
|
||||
static boolean clean(File dir) {
|
||||
boolean ok = true;
|
||||
for (File f: dir.listFiles()) {
|
||||
if (f.isDirectory())
|
||||
ok &= clean(f);
|
||||
ok &= f.delete();
|
||||
}
|
||||
return ok;
|
||||
static void clean(Path dir) throws IOException {
|
||||
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
Files.delete(file);
|
||||
return super.visitFile(file, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||
if (exc == null) Files.delete(dir);
|
||||
return super.postVisitDirectory(dir, exc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static abstract class Runner {
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// key: compiler.err.cant.apply.symbol
|
||||
// key: compiler.misc.no.conforming.assignment.exists
|
||||
// key: compiler.misc.bad.arg.types.in.lambda
|
||||
|
||||
class BadArgTypesInLambda {
|
||||
interface SAM {
|
||||
void m(Integer i);
|
||||
}
|
||||
|
||||
void g(SAM s) { }
|
||||
|
||||
void test() {
|
||||
g(x->{ String s = x; });
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,8 +22,9 @@
|
||||
*/
|
||||
|
||||
// key: compiler.err.prob.found.req
|
||||
// key: compiler.misc.secondary.bound.must.be.marker.intf
|
||||
// key: compiler.misc.bad.intersection.target.for.functional.expr
|
||||
// key: compiler.misc.not.an.intf.component
|
||||
|
||||
class SecondaryBoundMustBeMarkerInterface {
|
||||
Runnable r = (Runnable & Comparable<?>)()->{};
|
||||
class NotAnInterfaceComponent {
|
||||
Object o = (Object & Runnable) ()-> { };
|
||||
}
|
35
langtools/test/tools/javac/doclint/ImplicitHeadersTest.java
Normal file
35
langtools/test/tools/javac/doclint/ImplicitHeadersTest.java
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8006346
|
||||
* @summary doclint should make allowance for headers generated by standard doclet
|
||||
* @compile -Xdoclint:all/public ImplicitHeadersTest.java
|
||||
*/
|
||||
|
||||
/**
|
||||
* <h3> Header </h3>
|
||||
*/
|
||||
public class ImplicitHeadersTest { }
|
||||
|
@ -1,3 +1,2 @@
|
||||
BadRecovery.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, BadRecovery.SAM1, @369, kindname.class, BadRecovery, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.lambda))
|
||||
BadRecovery.java:17:77: compiler.err.cant.resolve.location: kindname.variable, f, , , (compiler.misc.location: kindname.class, BadRecovery, null)
|
||||
2 errors
|
||||
1 error
|
||||
|
@ -25,7 +25,7 @@
|
||||
* @test
|
||||
* @bug 8002099
|
||||
* @summary Add support for intersection types in cast expression
|
||||
* @compile/fail/ref=Intersection01.out -XDrawDiagnostics Intersection01.java
|
||||
* @compile Intersection01.java
|
||||
*/
|
||||
class Intersection01 {
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
|
||||
Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
|
||||
2 errors
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,11 +23,10 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8003280
|
||||
* @bug 8003280 8009131
|
||||
* @summary Add lambda tests
|
||||
* check nested case of overload resolution and lambda parameter inference
|
||||
* @author Maurizio Cimadamore
|
||||
* @compile/fail/ref=TargetType01.out -XDrawDiagnostics TargetType01.java
|
||||
* @compile TargetType01.java
|
||||
*/
|
||||
|
||||
class TargetType01 {
|
||||
|
@ -1,3 +0,0 @@
|
||||
TargetType01.java:46:9: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
|
||||
TargetType01.java:46:26: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
|
||||
2 errors
|
@ -1,5 +1,4 @@
|
||||
TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
|
||||
TargetType43.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
|
||||
TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
|
||||
TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
|
||||
4 errors
|
||||
3 errors
|
||||
|
26
langtools/test/tools/javac/lambda/TargetType66.java
Normal file
26
langtools/test/tools/javac/lambda/TargetType66.java
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8009131
|
||||
* @summary Overload: javac should discard methods that lead to errors in lambdas with implicit parameter types
|
||||
* @compile/fail/ref=TargetType66.out -XDrawDiagnostics TargetType66.java
|
||||
*/
|
||||
class TargetType66 {
|
||||
interface SAM1 {
|
||||
void m(String s);
|
||||
}
|
||||
|
||||
interface SAM2 {
|
||||
void m(Integer s);
|
||||
}
|
||||
|
||||
void g(SAM1 s1) { }
|
||||
void g(SAM2 s2) { }
|
||||
|
||||
void test() {
|
||||
g(x->{ String s = x; }); //g(SAM1)
|
||||
g(x->{ Integer i = x; }); //g(SAM2)
|
||||
g(x->{ Object o = x; }); //ambiguous
|
||||
g(x->{ Character c = x; }); //error: inapplicable methods
|
||||
g(x->{ Character c = ""; }); //error: incompatible types
|
||||
}
|
||||
}
|
4
langtools/test/tools/javac/lambda/TargetType66.out
Normal file
4
langtools/test/tools/javac/lambda/TargetType66.out
Normal file
@ -0,0 +1,4 @@
|
||||
TargetType66.java:22:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
|
||||
TargetType66.java:23:9: compiler.err.cant.apply.symbols: kindname.method, g, @578,{(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.String))),(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.Integer)))}
|
||||
TargetType66.java:24:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character)
|
||||
3 errors
|
@ -24,7 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 7194586
|
||||
* @bug 8003280 8006694
|
||||
* @bug 8003280 8006694 8010404
|
||||
* @summary Add lambda tests
|
||||
* Add back-end support for invokedynamic
|
||||
* temporarily workaround combo tests are causing time out in several platforms
|
||||
@ -48,6 +48,7 @@ import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.ConstantPool.*;
|
||||
import com.sun.tools.classfile.Instruction;
|
||||
import com.sun.tools.classfile.LineNumberTable_attribute;
|
||||
import com.sun.tools.classfile.Method;
|
||||
|
||||
import com.sun.tools.javac.api.JavacTaskImpl;
|
||||
@ -239,7 +240,7 @@ public class TestInvokeDynamic
|
||||
int id = checkCount.incrementAndGet();
|
||||
JavaSource source = new JavaSource(id);
|
||||
JavacTaskImpl ct = (JavacTaskImpl)comp.getTask(null, fm.get(), dc,
|
||||
null, null, Arrays.asList(source));
|
||||
Arrays.asList("-g"), null, Arrays.asList(source));
|
||||
Context context = ct.getContext();
|
||||
Symtab syms = Symtab.instance(context);
|
||||
Names names = Names.instance(context);
|
||||
@ -349,6 +350,16 @@ public class TestInvokeDynamic
|
||||
bsm_ref.getNameAndTypeInfo().getType() + " " +
|
||||
asBSMSignatureString());
|
||||
}
|
||||
|
||||
LineNumberTable_attribute lnt =
|
||||
(LineNumberTable_attribute)ea.attributes.get(Attribute.LineNumberTable);
|
||||
|
||||
if (lnt == null) {
|
||||
throw new Error("No LineNumberTable attribute");
|
||||
}
|
||||
if (lnt.line_number_table_length != 2) {
|
||||
throw new Error("Wrong number of entries in LineNumberTable");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new Error("error reading " + compiledTest +": " + e);
|
||||
@ -376,7 +387,10 @@ public class TestInvokeDynamic
|
||||
"}\n" +
|
||||
"class Test#ID {\n" +
|
||||
" void m() { }\n" +
|
||||
" void test() { m(); }\n" +
|
||||
" void test() {\n" +
|
||||
" Object o = this; // marker statement \n" +
|
||||
" m();\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
String source;
|
||||
|
@ -28,10 +28,11 @@
|
||||
*/
|
||||
|
||||
import com.sun.source.util.JavacTask;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
@ -45,37 +46,45 @@ public class IntersectionTargetTypeTest {
|
||||
|
||||
enum BoundKind {
|
||||
INTF,
|
||||
CLASS,
|
||||
SAM,
|
||||
ZAM;
|
||||
CLASS;
|
||||
}
|
||||
|
||||
enum MethodKind {
|
||||
NONE,
|
||||
ABSTRACT,
|
||||
DEFAULT;
|
||||
NONE(false),
|
||||
ABSTRACT_M(true),
|
||||
DEFAULT_M(false),
|
||||
ABSTRACT_G(true),
|
||||
DEFAULT_G(false);
|
||||
|
||||
boolean isAbstract;
|
||||
|
||||
MethodKind(boolean isAbstract) {
|
||||
this.isAbstract = isAbstract;
|
||||
}
|
||||
}
|
||||
|
||||
enum TypeKind {
|
||||
A("interface A { }\n", "A", BoundKind.ZAM),
|
||||
B("interface B { default void m() { } }\n", "B", BoundKind.ZAM),
|
||||
C("interface C { void m(); }\n", "C", BoundKind.SAM),
|
||||
D("interface D extends B { }\n", "D", BoundKind.ZAM),
|
||||
E("interface E extends C { }\n", "E", BoundKind.SAM),
|
||||
F("interface F extends C { void g(); }\n", "F", BoundKind.INTF),
|
||||
G("interface G extends B { void g(); }\n", "G", BoundKind.SAM),
|
||||
H("interface H extends A { void g(); }\n", "H", BoundKind.SAM),
|
||||
A("interface A { }\n", "A", BoundKind.INTF, MethodKind.NONE),
|
||||
B("interface B { default void m() { } }\n", "B", BoundKind.INTF, MethodKind.DEFAULT_M),
|
||||
C("interface C { void m(); }\n", "C", BoundKind.INTF, MethodKind.ABSTRACT_M),
|
||||
D("interface D extends B { }\n", "D", BoundKind.INTF, MethodKind.DEFAULT_M),
|
||||
E("interface E extends C { }\n", "E", BoundKind.INTF, MethodKind.ABSTRACT_M),
|
||||
F("interface F extends C { void g(); }\n", "F", BoundKind.INTF, MethodKind.ABSTRACT_G, MethodKind.ABSTRACT_M),
|
||||
G("interface G extends B { void g(); }\n", "G", BoundKind.INTF, MethodKind.ABSTRACT_G, MethodKind.DEFAULT_M),
|
||||
H("interface H extends A { void g(); }\n", "H", BoundKind.INTF, MethodKind.ABSTRACT_G),
|
||||
OBJECT("", "Object", BoundKind.CLASS),
|
||||
STRING("", "String", BoundKind.CLASS);
|
||||
|
||||
String declStr;
|
||||
String typeStr;
|
||||
BoundKind boundKind;
|
||||
MethodKind[] methodKinds;
|
||||
|
||||
private TypeKind(String declStr, String typeStr, BoundKind boundKind) {
|
||||
private TypeKind(String declStr, String typeStr, BoundKind boundKind, MethodKind... methodKinds) {
|
||||
this.declStr = declStr;
|
||||
this.typeStr = typeStr;
|
||||
this.boundKind = boundKind;
|
||||
this.methodKinds = methodKinds;
|
||||
}
|
||||
|
||||
boolean compatibleSupertype(TypeKind tk) {
|
||||
@ -263,14 +272,22 @@ public class IntersectionTargetTypeTest {
|
||||
boolean errorExpected = !cInfo.wellFormed();
|
||||
|
||||
if (ek.isFunctional) {
|
||||
//first bound must be a SAM
|
||||
errorExpected |= cInfo.types[0].boundKind != BoundKind.SAM;
|
||||
if (cInfo.types.length > 1) {
|
||||
//additional bounds must be ZAMs
|
||||
for (int i = 1; i < cInfo.types.length; i++) {
|
||||
errorExpected |= cInfo.types[i].boundKind != BoundKind.ZAM;
|
||||
List<MethodKind> mks = new ArrayList<>();
|
||||
for (TypeKind tk : cInfo.types) {
|
||||
if (tk.boundKind == BoundKind.CLASS) {
|
||||
errorExpected = true;
|
||||
break;
|
||||
} else {
|
||||
mks = mergeMethods(mks, Arrays.asList(tk.methodKinds));
|
||||
}
|
||||
}
|
||||
int abstractCount = 0;
|
||||
for (MethodKind mk : mks) {
|
||||
if (mk.isAbstract) {
|
||||
abstractCount++;
|
||||
}
|
||||
}
|
||||
errorExpected |= abstractCount != 1;
|
||||
}
|
||||
|
||||
if (errorExpected != diagChecker.errorFound) {
|
||||
@ -281,6 +298,32 @@ public class IntersectionTargetTypeTest {
|
||||
}
|
||||
}
|
||||
|
||||
List<MethodKind> mergeMethods(List<MethodKind> l1, List<MethodKind> l2) {
|
||||
List<MethodKind> mergedMethods = new ArrayList<>(l1);
|
||||
for (MethodKind mk2 : l2) {
|
||||
boolean add = !mergedMethods.contains(mk2);
|
||||
switch (mk2) {
|
||||
case ABSTRACT_G:
|
||||
add = add && !mergedMethods.contains(MethodKind.DEFAULT_G);
|
||||
break;
|
||||
case ABSTRACT_M:
|
||||
add = add && !mergedMethods.contains(MethodKind.DEFAULT_M);
|
||||
break;
|
||||
case DEFAULT_G:
|
||||
mergedMethods.remove(MethodKind.ABSTRACT_G);
|
||||
case DEFAULT_M:
|
||||
mergedMethods.remove(MethodKind.ABSTRACT_M);
|
||||
case NONE:
|
||||
add = false;
|
||||
break;
|
||||
}
|
||||
if (add) {
|
||||
mergedMethods.add(mk2);
|
||||
}
|
||||
}
|
||||
return mergedMethods;
|
||||
}
|
||||
|
||||
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||
|
||||
boolean errorFound;
|
||||
|
@ -427,6 +427,8 @@ public class DefaultMethodsTest extends TestHarness {
|
||||
*/
|
||||
public void testReflectCall() {
|
||||
Interface I = new Interface("I", DefaultMethod.std("99"));
|
||||
//workaround accessibility issue when loading C with DirectedClassLoader
|
||||
I.addAccessFlag(AccessFlag.PUBLIC);
|
||||
Class C = new Class("C", I);
|
||||
|
||||
Compiler.Flags[] flags = this.verbose ?
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8005046
|
||||
* @bug 8005046 8011052
|
||||
* @summary Test basic properties of javax.lang.element.Element
|
||||
* @author Joseph D. Darcy
|
||||
* @library /tools/javac/lib
|
||||
@ -35,6 +35,7 @@ import java.lang.annotation.*;
|
||||
import java.util.Formatter;
|
||||
import java.util.Set;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.*;
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import static javax.lang.model.SourceVersion.*;
|
||||
@ -79,9 +80,39 @@ public class TestExecutableElement extends JavacTestingAbstractProcessor impleme
|
||||
|
||||
boolean methodIsDefault = method.isDefault();
|
||||
|
||||
if (expectedDefault) {
|
||||
if (!method.getModifiers().contains(Modifier.DEFAULT)) {
|
||||
messager.printMessage(ERROR,
|
||||
"Modifier \"default\" not present as expected.",
|
||||
method);
|
||||
}
|
||||
|
||||
// Check printing output
|
||||
java.io.Writer stringWriter = new java.io.StringWriter();
|
||||
eltUtils.printElements(stringWriter, method);
|
||||
Pattern p = Pattern.compile(expectedIsDefault.expectedTextRegex(), Pattern.DOTALL);
|
||||
|
||||
if (! p.matcher(stringWriter.toString()).matches()) {
|
||||
messager.printMessage(ERROR,
|
||||
new Formatter().format("Unexpected printing ouptput:%n\tgot %s,%n\texpected pattern %s.",
|
||||
stringWriter.toString(),
|
||||
expectedIsDefault.expectedTextRegex()).toString(),
|
||||
method);
|
||||
}
|
||||
|
||||
System.out.println("\t" + stringWriter.toString());
|
||||
|
||||
} else {
|
||||
if (method.getModifiers().contains(Modifier.DEFAULT)) {
|
||||
messager.printMessage(ERROR,
|
||||
"Modifier \"default\" present when not expected.",
|
||||
method);
|
||||
}
|
||||
}
|
||||
|
||||
if (methodIsDefault != expectedDefault) {
|
||||
messager.printMessage(ERROR,
|
||||
new Formatter().format("Unexpected Executable.isDefault result: got %s, expected %s",
|
||||
new Formatter().format("Unexpected Executable.isDefault result: got ``%s'', expected ``%s''.",
|
||||
expectedDefault,
|
||||
methodIsDefault).toString(),
|
||||
method);
|
||||
@ -98,6 +129,7 @@ public class TestExecutableElement extends JavacTestingAbstractProcessor impleme
|
||||
@Target(ElementType.METHOD)
|
||||
@interface IsDefault {
|
||||
boolean value();
|
||||
String expectedTextRegex() default "";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,6 +140,6 @@ interface ProviderOfDefault {
|
||||
boolean process(Set<? extends TypeElement> annotations,
|
||||
RoundEnvironment roundEnv);
|
||||
|
||||
@IsDefault(true)
|
||||
default void quux() {};
|
||||
@IsDefault(value=true, expectedTextRegex="\\s*@IsDefault\\(.*\\)\\s*default strictfp void quux\\(\\);\\s*$")
|
||||
default strictfp void quux() {};
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8006346
|
||||
* @summary doclint should make allowance for headers generated by standard doclet
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* <h3> Header </h3>
|
||||
*/
|
||||
public class ImplicitHeadersTest {
|
||||
public static void main(String... args) {
|
||||
File testSrc = new File(System.getProperty("test.src"));
|
||||
File testFile = new File(testSrc, ImplicitHeadersTest.class.getSimpleName() + ".java");
|
||||
String[] javadocArgs = { "-d", "out", testFile.getPath() };
|
||||
int rc = com.sun.tools.javadoc.Main.execute(javadocArgs);
|
||||
if (rc != 0)
|
||||
throw new Error("unexpected exit: rc=" + rc);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user