Fri, 12 Dec 2014 14:57:02 -0800
Merge
.hgtags | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Mon Dec 01 11:39:34 2014 -0800 1.2 +++ b/.hgtags Fri Dec 12 14:57:02 2014 -0800 1.3 @@ -362,4 +362,6 @@ 1.4 f18c5b47f27b387d94487890684abe5a554b0d9b jdk8u40-b14 1.5 682a6c1aefd766eaf774ffeb1207a5189edf94d6 jdk8u40-b15 1.6 74c51ff270c51d17732250411fe9cd5392bc925e jdk8u40-b16 1.7 +a12a9932f649dd3df174d3e340527433d3695c49 jdk8u40-b17 1.8 +94f30e5fde53e3ddcd3c4e9842349318eae8fe10 jdk8u40-b18 1.9 dbae37f50c43453f7d6f22d96adc8b5b6cd1e90d jdk8u45-b00
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Dec 01 11:39:34 2014 -0800 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Dec 12 14:57:02 2014 -0800 2.3 @@ -3226,8 +3226,9 @@ 2.4 elt = ((ArrayType)elt.unannotatedType()).elemtype; 2.5 if (elt.hasTag(TYPEVAR)) { 2.6 log.error(tree.pos(), "type.var.cant.be.deref"); 2.7 - result = types.createErrorType(tree.type); 2.8 - return; 2.9 + result = tree.type = types.createErrorType(tree.name, site.tsym, site); 2.10 + tree.sym = tree.type.tsym; 2.11 + return ; 2.12 } 2.13 } 2.14 2.15 @@ -3243,6 +3244,10 @@ 2.16 // Determine the symbol represented by the selection. 2.17 env.info.pendingResolutionPhase = null; 2.18 Symbol sym = selectSym(tree, sitesym, site, env, resultInfo); 2.19 + if (sym.kind == VAR && sym.name != names._super && env.info.defaultSuperCallSite != null) { 2.20 + log.error(tree.selected.pos(), "not.encl.class", site.tsym); 2.21 + sym = syms.errSymbol; 2.22 + } 2.23 if (sym.exists() && !isType(sym) && (pkind() & (PCK | TYP)) != 0) { 2.24 site = capture(site); 2.25 sym = selectSym(tree, sitesym, site, env, resultInfo); 2.26 @@ -4499,14 +4504,15 @@ 2.27 super.visitTypeTest(tree); 2.28 } 2.29 public void visitNewClass(JCNewClass tree) { 2.30 - if (tree.clazz.hasTag(ANNOTATED_TYPE)) { 2.31 - checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations, 2.32 - tree.clazz.type.tsym); 2.33 - } 2.34 - if (tree.def != null) { 2.35 - checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym); 2.36 - } 2.37 - if (tree.clazz.type != null) { 2.38 + if (tree.clazz != null && tree.clazz.type != null) { 2.39 + if (tree.clazz.hasTag(ANNOTATED_TYPE)) { 2.40 + checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations, 2.41 + tree.clazz.type.tsym); 2.42 + } 2.43 + if (tree.def != null) { 2.44 + checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym); 2.45 + } 2.46 + 2.47 validateAnnotatedType(tree.clazz, tree.clazz.type); 2.48 } 2.49 super.visitNewClass(tree);
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Mon Dec 01 11:39:34 2014 -0800 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Dec 12 14:57:02 2014 -0800 3.3 @@ -242,9 +242,15 @@ 3.4 Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); 3.5 try { 3.6 new AssignAnalyzer() { 3.7 + Scope enclosedSymbols = new Scope(env.enclClass.sym); 3.8 + @Override 3.9 + public void visitVarDef(JCVariableDecl tree) { 3.10 + enclosedSymbols.enter(tree.sym); 3.11 + super.visitVarDef(tree); 3.12 + } 3.13 @Override 3.14 protected boolean trackable(VarSymbol sym) { 3.15 - return !env.info.scope.includes(sym) && 3.16 + return enclosedSymbols.includes(sym) && 3.17 sym.owner.kind == MTH; 3.18 } 3.19 }.analyzeTree(env, that);
4.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Dec 01 11:39:34 2014 -0800 4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Fri Dec 12 14:57:02 2014 -0800 4.3 @@ -41,6 +41,7 @@ 4.4 import com.sun.tools.javac.code.Symtab; 4.5 import com.sun.tools.javac.code.Type; 4.6 import com.sun.tools.javac.code.Type.MethodType; 4.7 +import com.sun.tools.javac.code.Type.TypeVar; 4.8 import com.sun.tools.javac.code.Types; 4.9 import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor.*; 4.10 import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector; 4.11 @@ -61,6 +62,7 @@ 4.12 import static com.sun.tools.javac.code.Kinds.*; 4.13 import static com.sun.tools.javac.code.TypeTag.*; 4.14 import static com.sun.tools.javac.tree.JCTree.Tag.*; 4.15 +import javax.lang.model.type.TypeKind; 4.16 4.17 /** 4.18 * This pass desugars lambda expressions into static methods 4.19 @@ -321,7 +323,9 @@ 4.20 4.21 ListBuffer<JCExpression> syntheticInits = new ListBuffer<>(); 4.22 4.23 - if (!sym.isStatic()) { 4.24 + if (localContext.methodReferenceReceiver != null) { 4.25 + syntheticInits.append(localContext.methodReferenceReceiver); 4.26 + } else if (!sym.isStatic()) { 4.27 syntheticInits.append(makeThis( 4.28 sym.owner.enclClass().asType(), 4.29 localContext.owner.enclClass())); 4.30 @@ -364,17 +368,10 @@ 4.31 4.32 //first determine the method symbol to be used to generate the sam instance 4.33 //this is either the method reference symbol, or the bridged reference symbol 4.34 - Symbol refSym = localContext.needsBridge() 4.35 - ? localContext.bridgeSym 4.36 - : localContext.isSignaturePolymorphic() 4.37 + Symbol refSym = localContext.isSignaturePolymorphic() 4.38 ? localContext.sigPolySym 4.39 : tree.sym; 4.40 4.41 - //build the bridge method, if needed 4.42 - if (localContext.needsBridge()) { 4.43 - bridgeMemberReference(tree, localContext); 4.44 - } 4.45 - 4.46 //the qualifying expression is treated as a special captured arg 4.47 JCExpression init; 4.48 switch(tree.kind) { 4.49 @@ -744,130 +741,146 @@ 4.50 // </editor-fold> 4.51 4.52 /** 4.53 - * Generate an adapter method "bridge" for a method reference which cannot 4.54 - * be used directly. 4.55 + * Converts a method reference which cannot be used directly into a lambda 4.56 */ 4.57 - private class MemberReferenceBridger { 4.58 + private class MemberReferenceToLambda { 4.59 4.60 private final JCMemberReference tree; 4.61 private final ReferenceTranslationContext localContext; 4.62 + private final Symbol owner; 4.63 private final ListBuffer<JCExpression> args = new ListBuffer<>(); 4.64 private final ListBuffer<JCVariableDecl> params = new ListBuffer<>(); 4.65 4.66 - MemberReferenceBridger(JCMemberReference tree, ReferenceTranslationContext localContext) { 4.67 + private JCExpression receiverExpression = null; 4.68 + 4.69 + MemberReferenceToLambda(JCMemberReference tree, ReferenceTranslationContext localContext, Symbol owner) { 4.70 this.tree = tree; 4.71 this.localContext = localContext; 4.72 + this.owner = owner; 4.73 } 4.74 4.75 - /** 4.76 - * Generate the bridge 4.77 - */ 4.78 - JCMethodDecl bridge() { 4.79 + JCLambda lambda() { 4.80 int prevPos = make.pos; 4.81 try { 4.82 make.at(tree); 4.83 - Type samDesc = localContext.bridgedRefSig(); 4.84 - List<Type> samPTypes = samDesc.getParameterTypes(); 4.85 4.86 - //an extra argument is prepended to the signature of the bridge in case 4.87 - //the member reference is an instance method reference (in which case 4.88 - //the receiver expression is passed to the bridge itself). 4.89 - Type recType = null; 4.90 - switch (tree.kind) { 4.91 - case IMPLICIT_INNER: 4.92 - recType = tree.sym.owner.type.getEnclosingType(); 4.93 - break; 4.94 - case BOUND: 4.95 - recType = tree.getQualifierExpression().type; 4.96 - break; 4.97 - case UNBOUND: 4.98 - recType = samPTypes.head; 4.99 - samPTypes = samPTypes.tail; 4.100 - break; 4.101 - } 4.102 + //body generation - this can be either a method call or a 4.103 + //new instance creation expression, depending on the member reference kind 4.104 + VarSymbol rcvr = addParametersReturnReceiver(); 4.105 + JCExpression expr = (tree.getMode() == ReferenceMode.INVOKE) 4.106 + ? expressionInvoke(rcvr) 4.107 + : expressionNew(); 4.108 4.109 - //generate the parameter list for the bridged member reference - the 4.110 - //bridge signature will match the signature of the target sam descriptor 4.111 - 4.112 - VarSymbol rcvr = (recType == null) 4.113 - ? null 4.114 - : addParameter("rec$", recType, false); 4.115 - 4.116 - List<Type> refPTypes = tree.sym.type.getParameterTypes(); 4.117 - int refSize = refPTypes.size(); 4.118 - int samSize = samPTypes.size(); 4.119 - // Last parameter to copy from referenced method 4.120 - int last = localContext.needsVarArgsConversion() ? refSize - 1 : refSize; 4.121 - 4.122 - List<Type> l = refPTypes; 4.123 - // Use parameter types of the referenced method, excluding final var args 4.124 - for (int i = 0; l.nonEmpty() && i < last; ++i) { 4.125 - addParameter("x$" + i, l.head, true); 4.126 - l = l.tail; 4.127 - } 4.128 - // Flatten out the var args 4.129 - for (int i = last; i < samSize; ++i) { 4.130 - addParameter("xva$" + i, tree.varargsElement, true); 4.131 - } 4.132 - 4.133 - //generate the bridge method declaration 4.134 - JCMethodDecl bridgeDecl = make.MethodDef(make.Modifiers(localContext.bridgeSym.flags()), 4.135 - localContext.bridgeSym.name, 4.136 - make.QualIdent(samDesc.getReturnType().tsym), 4.137 - List.<JCTypeParameter>nil(), 4.138 - params.toList(), 4.139 - tree.sym.type.getThrownTypes() == null 4.140 - ? List.<JCExpression>nil() 4.141 - : make.Types(tree.sym.type.getThrownTypes()), 4.142 - null, 4.143 - null); 4.144 - bridgeDecl.sym = (MethodSymbol) localContext.bridgeSym; 4.145 - bridgeDecl.type = localContext.bridgeSym.type = 4.146 - types.createMethodTypeWithParameters(samDesc, TreeInfo.types(params.toList())); 4.147 - 4.148 - //bridge method body generation - this can be either a method call or a 4.149 - //new instance creation expression, depending on the member reference kind 4.150 - JCExpression bridgeExpr = (tree.getMode() == ReferenceMode.INVOKE) 4.151 - ? bridgeExpressionInvoke(makeReceiver(rcvr)) 4.152 - : bridgeExpressionNew(); 4.153 - 4.154 - //the body is either a return expression containing a method call, 4.155 - //or the method call itself, depending on whether the return type of 4.156 - //the bridge is non-void/void. 4.157 - bridgeDecl.body = makeLambdaExpressionBody(bridgeExpr, bridgeDecl); 4.158 - 4.159 - return bridgeDecl; 4.160 + JCLambda slam = make.Lambda(params.toList(), expr); 4.161 + slam.targets = tree.targets; 4.162 + slam.type = tree.type; 4.163 + slam.pos = tree.pos; 4.164 + return slam; 4.165 } finally { 4.166 make.at(prevPos); 4.167 } 4.168 } 4.169 - //where 4.170 - private JCExpression makeReceiver(VarSymbol rcvr) { 4.171 - if (rcvr == null) return null; 4.172 - JCExpression rcvrExpr = make.Ident(rcvr); 4.173 - Type rcvrType = tree.sym.enclClass().type; 4.174 - if (rcvrType == syms.arrayClass.type) { 4.175 - // Map the receiver type to the actually type, not just "array" 4.176 - rcvrType = tree.getQualifierExpression().type; 4.177 + 4.178 + /** 4.179 + * Generate the parameter list for the converted member reference. 4.180 + * 4.181 + * @return The receiver variable symbol, if any 4.182 + */ 4.183 + VarSymbol addParametersReturnReceiver() { 4.184 + Type samDesc = localContext.bridgedRefSig(); 4.185 + List<Type> samPTypes = samDesc.getParameterTypes(); 4.186 + List<Type> descPTypes = tree.getDescriptorType(types).getParameterTypes(); 4.187 + 4.188 + // Determine the receiver, if any 4.189 + VarSymbol rcvr; 4.190 + switch (tree.kind) { 4.191 + case BOUND: 4.192 + // The receiver is explicit in the method reference 4.193 + rcvr = addParameter("rec$", tree.getQualifierExpression().type, false); 4.194 + receiverExpression = attr.makeNullCheck(tree.getQualifierExpression()); 4.195 + break; 4.196 + case UNBOUND: 4.197 + // The receiver is the first parameter, extract it and 4.198 + // adjust the SAM and unerased type lists accordingly 4.199 + rcvr = addParameter("rec$", samDesc.getParameterTypes().head, false); 4.200 + samPTypes = samPTypes.tail; 4.201 + descPTypes = descPTypes.tail; 4.202 + break; 4.203 + default: 4.204 + rcvr = null; 4.205 + break; 4.206 + } 4.207 + List<Type> implPTypes = tree.sym.type.getParameterTypes(); 4.208 + int implSize = implPTypes.size(); 4.209 + int samSize = samPTypes.size(); 4.210 + // Last parameter to copy from referenced method, exclude final var args 4.211 + int last = localContext.needsVarArgsConversion() ? implSize - 1 : implSize; 4.212 + 4.213 + // Failsafe -- assure match-up 4.214 + boolean checkForIntersection = tree.varargsElement != null || implSize == descPTypes.size(); 4.215 + 4.216 + // Use parameter types of the implementation method unless the unerased 4.217 + // SAM parameter type is an intersection type, in that case use the 4.218 + // erased SAM parameter type so that the supertype relationship 4.219 + // the implementation method parameters is not obscured. 4.220 + // Note: in this loop, the lists implPTypes, samPTypes, and descPTypes 4.221 + // are used as pointers to the current parameter type information 4.222 + // and are thus not usable afterwards. 4.223 + for (int i = 0; implPTypes.nonEmpty() && i < last; ++i) { 4.224 + // By default use the implementation method parmeter type 4.225 + Type parmType = implPTypes.head; 4.226 + // If the unerased parameter type is a type variable whose 4.227 + // bound is an intersection (eg. <T extends A & B>) then 4.228 + // use the SAM parameter type 4.229 + if (checkForIntersection && descPTypes.head.getKind() == TypeKind.TYPEVAR) { 4.230 + TypeVar tv = (TypeVar) descPTypes.head; 4.231 + if (tv.bound.getKind() == TypeKind.INTERSECTION) { 4.232 + parmType = samPTypes.head; 4.233 + } 4.234 } 4.235 - if (!rcvr.type.tsym.isSubClass(rcvrType.tsym, types)) { 4.236 - rcvrExpr = make.TypeCast(make.Type(rcvrType), rcvrExpr).setType(rcvrType); 4.237 - } 4.238 - return rcvrExpr; 4.239 + addParameter("x$" + i, parmType, true); 4.240 + 4.241 + // Advance to the next parameter 4.242 + implPTypes = implPTypes.tail; 4.243 + samPTypes = samPTypes.tail; 4.244 + descPTypes = descPTypes.tail; 4.245 + } 4.246 + // Flatten out the var args 4.247 + for (int i = last; i < samSize; ++i) { 4.248 + addParameter("xva$" + i, tree.varargsElement, true); 4.249 } 4.250 4.251 + return rcvr; 4.252 + } 4.253 + 4.254 + JCExpression getReceiverExpression() { 4.255 + return receiverExpression; 4.256 + } 4.257 + 4.258 + private JCExpression makeReceiver(VarSymbol rcvr) { 4.259 + if (rcvr == null) return null; 4.260 + JCExpression rcvrExpr = make.Ident(rcvr); 4.261 + Type rcvrType = tree.sym.enclClass().type; 4.262 + if (rcvrType == syms.arrayClass.type) { 4.263 + // Map the receiver type to the actually type, not just "array" 4.264 + rcvrType = tree.getQualifierExpression().type; 4.265 + } 4.266 + if (!rcvr.type.tsym.isSubClass(rcvrType.tsym, types)) { 4.267 + rcvrExpr = make.TypeCast(make.Type(rcvrType), rcvrExpr).setType(rcvrType); 4.268 + } 4.269 + return rcvrExpr; 4.270 + } 4.271 + 4.272 /** 4.273 - * determine the receiver of the bridged method call - the receiver can 4.274 - * be either the synthetic receiver parameter or a type qualifier; the 4.275 - * original qualifier expression is never used here, as it might refer 4.276 - * to symbols not available in the static context of the bridge 4.277 + * determine the receiver of the method call - the receiver can 4.278 + * be a type qualifier, the synthetic receiver parameter or 'super'. 4.279 */ 4.280 - private JCExpression bridgeExpressionInvoke(JCExpression rcvr) { 4.281 + private JCExpression expressionInvoke(VarSymbol rcvr) { 4.282 JCExpression qualifier = 4.283 tree.sym.isStatic() ? 4.284 make.Type(tree.sym.owner.type) : 4.285 (rcvr != null) ? 4.286 - rcvr : 4.287 + makeReceiver(rcvr) : 4.288 tree.getQualifierExpression(); 4.289 4.290 //create the qualifier expression 4.291 @@ -886,10 +899,9 @@ 4.292 } 4.293 4.294 /** 4.295 - * the enclosing expression is either 'null' (no enclosing type) or set 4.296 - * to the first bridge synthetic parameter 4.297 + * Lambda body to use for a 'new'. 4.298 */ 4.299 - private JCExpression bridgeExpressionNew() { 4.300 + private JCExpression expressionNew() { 4.301 if (tree.kind == ReferenceKind.ARRAY_CTOR) { 4.302 //create the array creation expression 4.303 JCNewArray newArr = make.NewArray( 4.304 @@ -899,15 +911,10 @@ 4.305 newArr.type = tree.getQualifierExpression().type; 4.306 return newArr; 4.307 } else { 4.308 - JCExpression encl = null; 4.309 - switch (tree.kind) { 4.310 - case UNBOUND: 4.311 - case IMPLICIT_INNER: 4.312 - encl = make.Ident(params.first()); 4.313 - } 4.314 - 4.315 //create the instance creation expression 4.316 - JCNewClass newClass = make.NewClass(encl, 4.317 + //note that method reference syntax does not allow an explicit 4.318 + //enclosing class (so the enclosing class is null) 4.319 + JCNewClass newClass = make.NewClass(null, 4.320 List.<JCExpression>nil(), 4.321 make.Type(tree.getQualifierExpression().type), 4.322 convertArgs(tree.sym, args.toList(), tree.varargsElement), 4.323 @@ -921,7 +928,8 @@ 4.324 } 4.325 4.326 private VarSymbol addParameter(String name, Type p, boolean genArg) { 4.327 - VarSymbol vsym = new VarSymbol(0, names.fromString(name), p, localContext.bridgeSym); 4.328 + VarSymbol vsym = new VarSymbol(PARAMETER | SYNTHETIC, names.fromString(name), p, owner); 4.329 + vsym.pos = tree.pos; 4.330 params.append(make.VarDef(vsym, null)); 4.331 if (genArg) { 4.332 args.append(make.Ident(vsym)); 4.333 @@ -930,15 +938,6 @@ 4.334 } 4.335 } 4.336 4.337 - /** 4.338 - * Bridges a member reference - this is needed when: 4.339 - * * Var args in the referenced method need to be flattened away 4.340 - * * super is used 4.341 - */ 4.342 - private void bridgeMemberReference(JCMemberReference tree, ReferenceTranslationContext localContext) { 4.343 - kInfo.addMethod(new MemberReferenceBridger(tree, localContext).bridge()); 4.344 - } 4.345 - 4.346 private MethodType typeToMethodType(Type mt) { 4.347 Type type = types.erasure(mt); 4.348 return new MethodType(type.getParameterTypes(), 4.349 @@ -1258,9 +1257,25 @@ 4.350 4.351 @Override 4.352 public void visitLambda(JCLambda tree) { 4.353 + analyzeLambda(tree, "lambda.stat"); 4.354 + } 4.355 + 4.356 + private void analyzeLambda(JCLambda tree, JCExpression methodReferenceReceiver) { 4.357 + // Translation of the receiver expression must occur first 4.358 + JCExpression rcvr = translate(methodReferenceReceiver); 4.359 + LambdaTranslationContext context = analyzeLambda(tree, "mref.stat.1"); 4.360 + if (rcvr != null) { 4.361 + context.methodReferenceReceiver = rcvr; 4.362 + } 4.363 + } 4.364 + 4.365 + private LambdaTranslationContext analyzeLambda(JCLambda tree, String statKey) { 4.366 List<Frame> prevStack = frameStack; 4.367 try { 4.368 - LambdaTranslationContext context = (LambdaTranslationContext)makeLambdaContext(tree); 4.369 + LambdaTranslationContext context = new LambdaTranslationContext(tree); 4.370 + if (dumpLambdaToMethodStats) { 4.371 + log.note(tree, statKey, context.needsAltMetafactory(), context.translatedSym); 4.372 + } 4.373 frameStack = frameStack.prepend(new Frame(tree)); 4.374 for (JCVariableDecl param : tree.params) { 4.375 context.addSymbol(param.sym, PARAM); 4.376 @@ -1269,6 +1284,7 @@ 4.377 contextMap.put(tree, context); 4.378 super.visitLambda(tree); 4.379 context.complete(); 4.380 + return context; 4.381 } 4.382 finally { 4.383 frameStack = prevStack; 4.384 @@ -1357,47 +1373,24 @@ 4.385 * information added in the LambdaToMethod pass will have the wrong 4.386 * signature. Hooks between Lower and LambdaToMethod have been added to 4.387 * handle normal "new" in this case. This visitor converts potentially 4.388 - * effected method references into a lambda containing a normal "new" of 4.389 - * the class. 4.390 + * affected method references into a lambda containing a normal 4.391 + * expression. 4.392 * 4.393 * @param tree 4.394 */ 4.395 @Override 4.396 public void visitReference(JCMemberReference tree) { 4.397 - if (tree.getMode() == ReferenceMode.NEW 4.398 - && tree.kind != ReferenceKind.ARRAY_CTOR 4.399 - && tree.sym.owner.isLocal()) { 4.400 - MethodSymbol consSym = (MethodSymbol) tree.sym; 4.401 - List<Type> ptypes = ((MethodType) consSym.type).getParameterTypes(); 4.402 - Type classType = consSym.owner.type; 4.403 - 4.404 - // Build lambda parameters 4.405 - // partially cloned from TreeMaker.Params until 8014021 is fixed 4.406 - Symbol owner = owner(); 4.407 - ListBuffer<JCVariableDecl> paramBuff = new ListBuffer<JCVariableDecl>(); 4.408 - int i = 0; 4.409 - for (List<Type> l = ptypes; l.nonEmpty(); l = l.tail) { 4.410 - JCVariableDecl param = make.Param(make.paramName(i++), l.head, owner); 4.411 - param.sym.pos = tree.pos; 4.412 - paramBuff.append(param); 4.413 - } 4.414 - List<JCVariableDecl> params = paramBuff.toList(); 4.415 - 4.416 - // Make new-class call 4.417 - JCNewClass nc = makeNewClass(classType, make.Idents(params)); 4.418 - nc.pos = tree.pos; 4.419 - 4.420 - // Make lambda holding the new-class call 4.421 - JCLambda slam = make.Lambda(params, nc); 4.422 - slam.targets = tree.targets; 4.423 - slam.type = tree.type; 4.424 - slam.pos = tree.pos; 4.425 - 4.426 - // Now it is a lambda, process as such 4.427 - visitLambda(slam); 4.428 + ReferenceTranslationContext rcontext = new ReferenceTranslationContext(tree); 4.429 + contextMap.put(tree, rcontext); 4.430 + if (rcontext.needsConversionToLambda()) { 4.431 + // Convert to a lambda, and process as such 4.432 + MemberReferenceToLambda conv = new MemberReferenceToLambda(tree, rcontext, owner()); 4.433 + analyzeLambda(conv.lambda(), conv.getReceiverExpression()); 4.434 } else { 4.435 super.visitReference(tree); 4.436 - contextMap.put(tree, makeReferenceContext(tree)); 4.437 + if (dumpLambdaToMethodStats) { 4.438 + log.note(tree, "mref.stat", rcontext.needsAltMetafactory(), null); 4.439 + } 4.440 } 4.441 } 4.442 4.443 @@ -1652,14 +1645,6 @@ 4.444 } 4.445 } 4.446 4.447 - private TranslationContext<JCLambda> makeLambdaContext(JCLambda tree) { 4.448 - return new LambdaTranslationContext(tree); 4.449 - } 4.450 - 4.451 - private TranslationContext<JCMemberReference> makeReferenceContext(JCMemberReference tree) { 4.452 - return new ReferenceTranslationContext(tree); 4.453 - } 4.454 - 4.455 private class Frame { 4.456 final JCTree tree; 4.457 List<Symbol> locals; 4.458 @@ -1779,6 +1764,13 @@ 4.459 */ 4.460 final Set<Symbol> freeVarProcessedLocalClasses; 4.461 4.462 + /** 4.463 + * For method references converted to lambdas. The method 4.464 + * reference receiver expression. Must be treated like a captured 4.465 + * variable. 4.466 + */ 4.467 + JCExpression methodReferenceReceiver; 4.468 + 4.469 LambdaTranslationContext(JCLambda tree) { 4.470 super(tree); 4.471 Frame frame = frameStack.head; 4.472 @@ -1798,9 +1790,6 @@ 4.473 // This symbol will be filled-in in complete 4.474 this.translatedSym = makePrivateSyntheticMethod(0, null, null, owner.enclClass()); 4.475 4.476 - if (dumpLambdaToMethodStats) { 4.477 - log.note(tree, "lambda.stat", needsAltMetafactory(), translatedSym); 4.478 - } 4.479 translatedSymbols = new EnumMap<>(LambdaSymbolKind.class); 4.480 4.481 translatedSymbols.put(PARAM, new LinkedHashMap<Symbol, Symbol>()); 4.482 @@ -2017,6 +2006,13 @@ 4.483 for (Symbol thisSym : getSymbolMap(CAPTURED_VAR).values()) { 4.484 params.append(make.VarDef((VarSymbol) thisSym, null)); 4.485 } 4.486 + if (methodReferenceReceiver != null) { 4.487 + params.append(make.VarDef( 4.488 + make.Modifiers(PARAMETER|FINAL), 4.489 + names.fromString("$rcvr$"), 4.490 + make.Type(methodReferenceReceiver.type), 4.491 + null)); 4.492 + } 4.493 for (Symbol thisSym : getSymbolMap(PARAM).values()) { 4.494 params.append(make.VarDef((VarSymbol) thisSym, null)); 4.495 } 4.496 @@ -2044,40 +2040,27 @@ 4.497 * and the used by the main translation routines in order to adjust method 4.498 * references (i.e. in case a bridge is needed) 4.499 */ 4.500 - private class ReferenceTranslationContext extends TranslationContext<JCMemberReference> { 4.501 + private final class ReferenceTranslationContext extends TranslationContext<JCMemberReference> { 4.502 4.503 final boolean isSuper; 4.504 - final Symbol bridgeSym; 4.505 final Symbol sigPolySym; 4.506 4.507 ReferenceTranslationContext(JCMemberReference tree) { 4.508 super(tree); 4.509 this.isSuper = tree.hasKind(ReferenceKind.SUPER); 4.510 - this.bridgeSym = needsBridge() 4.511 - ? makePrivateSyntheticMethod(isSuper ? 0 : STATIC, 4.512 - referenceBridgeName(), null, 4.513 - owner.enclClass()) 4.514 - : null; 4.515 this.sigPolySym = isSignaturePolymorphic() 4.516 ? makePrivateSyntheticMethod(tree.sym.flags(), 4.517 tree.sym.name, 4.518 bridgedRefSig(), 4.519 tree.sym.enclClass()) 4.520 : null; 4.521 - if (dumpLambdaToMethodStats) { 4.522 - String key = bridgeSym == null ? 4.523 - "mref.stat" : "mref.stat.1"; 4.524 - log.note(tree, key, needsAltMetafactory(), bridgeSym); 4.525 - } 4.526 } 4.527 4.528 /** 4.529 * Get the opcode associated with this method reference 4.530 */ 4.531 int referenceKind() { 4.532 - return LambdaToMethod.this.referenceKind(needsBridge() 4.533 - ? bridgeSym 4.534 - : tree.sym); 4.535 + return LambdaToMethod.this.referenceKind(tree.sym); 4.536 } 4.537 4.538 boolean needsVarArgsConversion() { 4.539 @@ -2085,62 +2068,6 @@ 4.540 } 4.541 4.542 /** 4.543 - * Generate a disambiguating string to increase stability (important 4.544 - * if serialized) 4.545 - * 4.546 - * @return String to differentiate synthetic lambda method names 4.547 - */ 4.548 - private String referenceBridgeDisambiguation() { 4.549 - StringBuilder buf = new StringBuilder(); 4.550 - // Append the enclosing method signature to differentiate 4.551 - // overloaded enclosing methods. 4.552 - if (owner.type != null) { 4.553 - buf.append(typeSig(owner.type)); 4.554 - buf.append(":"); 4.555 - } 4.556 - 4.557 - // Append qualifier type 4.558 - buf.append(classSig(tree.sym.owner.type)); 4.559 - 4.560 - // Note static/instance 4.561 - buf.append(tree.sym.isStatic()? " S " : " I "); 4.562 - 4.563 - // Append referenced signature 4.564 - buf.append(typeSig(tree.sym.erasure(types))); 4.565 - 4.566 - return buf.toString(); 4.567 - } 4.568 - 4.569 - /** 4.570 - * Construct a unique stable name for the method reference bridge 4.571 - * 4.572 - * @return Name to use for the synthetic method name 4.573 - */ 4.574 - private Name referenceBridgeName() { 4.575 - StringBuilder buf = new StringBuilder(); 4.576 - // Append lambda ID, this is semantically significant 4.577 - buf.append(names.lambda); 4.578 - // Note that it is a method reference bridge 4.579 - buf.append("MR$"); 4.580 - // Append the enclosing method name 4.581 - buf.append(enclosingMethodName()); 4.582 - buf.append('$'); 4.583 - // Append the referenced method name 4.584 - buf.append(syntheticMethodNameComponent(tree.sym.name)); 4.585 - buf.append('$'); 4.586 - // Append a hash of the disambiguating string : enclosing method 4.587 - // signature, etc. 4.588 - String disam = referenceBridgeDisambiguation(); 4.589 - buf.append(Integer.toHexString(disam.hashCode())); 4.590 - buf.append('$'); 4.591 - // The above appended name components may not be unique, append 4.592 - // a count based on the above name components. 4.593 - buf.append(syntheticMethodNameCounts.getIndex(buf)); 4.594 - String result = buf.toString(); 4.595 - return names.fromString(result); 4.596 - } 4.597 - 4.598 - /** 4.599 * @return Is this an array operation like clone() 4.600 */ 4.601 boolean isArrayOp() { 4.602 @@ -2175,13 +2102,40 @@ 4.603 } 4.604 4.605 /** 4.606 - * Does this reference needs a bridge (i.e. var args need to be 4.607 - * expanded or "super" is used) 4.608 + * Erasure destroys the implementation parameter subtype 4.609 + * relationship for intersection types 4.610 */ 4.611 - final boolean needsBridge() { 4.612 - return isSuper || needsVarArgsConversion() || isArrayOp() || 4.613 + boolean interfaceParameterIsIntersectionType() { 4.614 + List<Type> tl = tree.getDescriptorType(types).getParameterTypes(); 4.615 + if (tree.kind == ReferenceKind.UNBOUND) { 4.616 + tl = tl.tail; 4.617 + } 4.618 + for (; tl.nonEmpty(); tl = tl.tail) { 4.619 + Type pt = tl.head; 4.620 + if (pt.getKind() == TypeKind.TYPEVAR) { 4.621 + TypeVar tv = (TypeVar) pt; 4.622 + if (tv.bound.getKind() == TypeKind.INTERSECTION) { 4.623 + return true; 4.624 + } 4.625 + } 4.626 + } 4.627 + return false; 4.628 + } 4.629 + 4.630 + /** 4.631 + * Does this reference need to be converted to a lambda 4.632 + * (i.e. var args need to be expanded or "super" is used) 4.633 + */ 4.634 + final boolean needsConversionToLambda() { 4.635 + return interfaceParameterIsIntersectionType() || 4.636 + isSuper || 4.637 + needsVarArgsConversion() || 4.638 + isArrayOp() || 4.639 isPrivateInOtherClass() || 4.640 - !receiverAccessible(); 4.641 + !receiverAccessible() || 4.642 + (tree.getMode() == ReferenceMode.NEW && 4.643 + tree.kind != ReferenceKind.ARRAY_CTOR && 4.644 + (tree.sym.owner.isLocal() || tree.sym.owner.isInner())); 4.645 } 4.646 4.647 Type generatedRefSig() {
5.1 --- a/src/share/classes/com/sun/tools/javac/comp/Lower.java Mon Dec 01 11:39:34 2014 -0800 5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri Dec 12 14:57:02 2014 -0800 5.3 @@ -2716,9 +2716,10 @@ 5.4 syms.intType, tree.sym); 5.5 ordParam.mods.flags |= SYNTHETIC; ordParam.sym.flags_field |= SYNTHETIC; 5.6 5.7 + MethodSymbol m = tree.sym; 5.8 tree.params = tree.params.prepend(ordParam).prepend(nameParam); 5.9 - 5.10 - MethodSymbol m = tree.sym; 5.11 + incrementParamTypeAnnoIndexes(m, 2); 5.12 + 5.13 m.extraParams = m.extraParams.prepend(ordParam.sym); 5.14 m.extraParams = m.extraParams.prepend(nameParam.sym); 5.15 Type olderasure = m.erasure(types); 5.16 @@ -2741,6 +2742,17 @@ 5.17 } 5.18 } 5.19 //where 5.20 + private void incrementParamTypeAnnoIndexes(MethodSymbol m, 5.21 + int amount) { 5.22 + for (final Attribute.TypeCompound anno : m.getRawTypeAttributes()) { 5.23 + // Increment the parameter_index of any existing formal 5.24 + // parameter annotations. 5.25 + if (anno.position.type == TargetType.METHOD_FORMAL_PARAMETER) { 5.26 + anno.position.parameter_index += amount; 5.27 + } 5.28 + } 5.29 + } 5.30 + 5.31 private void visitMethodDefInternal(JCMethodDecl tree) { 5.32 if (tree.name == names.init && 5.33 (currentClass.isInner() || currentClass.isLocal())) { 5.34 @@ -2771,8 +2783,10 @@ 5.35 // Add this$n (if needed) in front of and free variables behind 5.36 // constructor parameter list. 5.37 tree.params = tree.params.appendList(fvdefs); 5.38 - if (currentClass.hasOuterInstance()) 5.39 + if (currentClass.hasOuterInstance()) { 5.40 tree.params = tree.params.prepend(otdef); 5.41 + incrementParamTypeAnnoIndexes(m, 1); 5.42 + } 5.43 5.44 // If this is an initial constructor, i.e., it does not start with 5.45 // this(...), insert initializers for this$n and proxies
6.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Dec 01 11:39:34 2014 -0800 6.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Dec 12 14:57:02 2014 -0800 6.3 @@ -3220,7 +3220,7 @@ 6.4 super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase); 6.5 if (site.isRaw() && !argtypes.head.hasTag(NONE)) { 6.6 Type asSuperSite = types.asSuper(argtypes.head, site.tsym); 6.7 - this.site = asSuperSite; 6.8 + this.site = types.capture(asSuperSite); 6.9 } 6.10 } 6.11
7.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Mon Dec 01 11:39:34 2014 -0800 7.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Dec 12 14:57:02 2014 -0800 7.3 @@ -670,6 +670,27 @@ 7.4 } 7.5 7.6 7.7 + private void writeParamAnnotations(List<VarSymbol> params, 7.8 + RetentionPolicy retention) { 7.9 + for (VarSymbol s : params) { 7.10 + ListBuffer<Attribute.Compound> buf = new ListBuffer<>(); 7.11 + for (Attribute.Compound a : s.getRawAttributes()) 7.12 + if (types.getRetention(a) == retention) 7.13 + buf.append(a); 7.14 + databuf.appendChar(buf.length()); 7.15 + for (Attribute.Compound a : buf) 7.16 + writeCompoundAttribute(a); 7.17 + } 7.18 + 7.19 + } 7.20 + 7.21 + private void writeParamAnnotations(MethodSymbol m, 7.22 + RetentionPolicy retention) { 7.23 + databuf.appendByte(m.params.length() + m.extraParams.length()); 7.24 + writeParamAnnotations(m.extraParams, retention); 7.25 + writeParamAnnotations(m.params, retention); 7.26 + } 7.27 + 7.28 /** Write method parameter annotations; 7.29 * return number of attributes written. 7.30 */ 7.31 @@ -692,31 +713,13 @@ 7.32 int attrCount = 0; 7.33 if (hasVisible) { 7.34 int attrIndex = writeAttr(names.RuntimeVisibleParameterAnnotations); 7.35 - databuf.appendByte(m.params.length()); 7.36 - for (VarSymbol s : m.params) { 7.37 - ListBuffer<Attribute.Compound> buf = new ListBuffer<Attribute.Compound>(); 7.38 - for (Attribute.Compound a : s.getRawAttributes()) 7.39 - if (types.getRetention(a) == RetentionPolicy.RUNTIME) 7.40 - buf.append(a); 7.41 - databuf.appendChar(buf.length()); 7.42 - for (Attribute.Compound a : buf) 7.43 - writeCompoundAttribute(a); 7.44 - } 7.45 + writeParamAnnotations(m, RetentionPolicy.RUNTIME); 7.46 endAttr(attrIndex); 7.47 attrCount++; 7.48 } 7.49 if (hasInvisible) { 7.50 int attrIndex = writeAttr(names.RuntimeInvisibleParameterAnnotations); 7.51 - databuf.appendByte(m.params.length()); 7.52 - for (VarSymbol s : m.params) { 7.53 - ListBuffer<Attribute.Compound> buf = new ListBuffer<Attribute.Compound>(); 7.54 - for (Attribute.Compound a : s.getRawAttributes()) 7.55 - if (types.getRetention(a) == RetentionPolicy.CLASS) 7.56 - buf.append(a); 7.57 - databuf.appendChar(buf.length()); 7.58 - for (Attribute.Compound a : buf) 7.59 - writeCompoundAttribute(a); 7.60 - } 7.61 + writeParamAnnotations(m, RetentionPolicy.CLASS); 7.62 endAttr(attrIndex); 7.63 attrCount++; 7.64 }
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/test/lib/annotations/annotations/classfile/ClassfileInspector.java Fri Dec 12 14:57:02 2014 -0800 8.3 @@ -0,0 +1,1733 @@ 8.4 +/* 8.5 + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. 8.11 + * 8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.15 + * version 2 for more details (a copy is included in the LICENSE file that 8.16 + * accompanied this code). 8.17 + * 8.18 + * You should have received a copy of the GNU General Public License version 8.19 + * 2 along with this work; if not, write to the Free Software Foundation, 8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.21 + * 8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.23 + * or visit www.oracle.com if you need additional information or have any 8.24 + * questions. 8.25 + */ 8.26 + 8.27 +package annotations.classfile; 8.28 + 8.29 +import java.io.*; 8.30 +import java.net.URL; 8.31 +import java.util.List; 8.32 + 8.33 +import com.sun.tools.classfile.*; 8.34 + 8.35 +/** 8.36 + * A class providing utilities for writing tests that inspect class 8.37 + * files directly, looking for specific type annotations. 8.38 + * 8.39 + * Note: this framework does not currently handle repeating 8.40 + * annotations. 8.41 + */ 8.42 +public class ClassfileInspector { 8.43 + 8.44 + /** 8.45 + * A group of expected annotations to be found in a given class. 8.46 + * If the class name is null, then the template will be applied to 8.47 + * every class. 8.48 + */ 8.49 + public static class Expected { 8.50 + /** 8.51 + * The name of the class. If {@code null} this template will 8.52 + * apply to every class; otherwise, it will only be applied to 8.53 + * the named class. 8.54 + */ 8.55 + public final String classname; 8.56 + 8.57 + /** 8.58 + * The expected class annotations. These will be checked 8.59 + * against the class' attributes. 8.60 + */ 8.61 + public final ExpectedAnnotation[] classAnnos; 8.62 + 8.63 + /** 8.64 + * The expected method annotations. These will be checked 8.65 + * against all methods in the class. 8.66 + */ 8.67 + public final ExpectedMethodAnnotation[] methodAnnos; 8.68 + 8.69 + /** 8.70 + * The expected method parameter annotations. These will be checked 8.71 + * against all methods in the class. 8.72 + */ 8.73 + public final ExpectedParameterAnnotation[] methodParamAnnos; 8.74 + 8.75 + /** 8.76 + * The expected field type annotations. These will be checked 8.77 + * against all fields in the class. 8.78 + */ 8.79 + public final ExpectedFieldAnnotation[] fieldAnnos; 8.80 + 8.81 + /** 8.82 + * The expected class type annotations. These will be checked 8.83 + * against the class' attributes. 8.84 + */ 8.85 + public final ExpectedTypeAnnotation[] classTypeAnnos; 8.86 + 8.87 + /** 8.88 + * The expected method type annotations. These will be checked 8.89 + * against all methods in the class. 8.90 + */ 8.91 + public final ExpectedMethodTypeAnnotation[] methodTypeAnnos; 8.92 + 8.93 + /** 8.94 + * The expected field type annotations. These will be checked 8.95 + * against all fields in the class. 8.96 + */ 8.97 + public final ExpectedFieldTypeAnnotation[] fieldTypeAnnos; 8.98 + 8.99 + /** 8.100 + * Create an {@code Expected} from all components. 8.101 + * 8.102 + * @param classname The name of the class to match, or {@code 8.103 + * null} for all classes. 8.104 + * @param classAnnos The expected class annotations. 8.105 + * @param methodAnnos The expected method annotations. 8.106 + * @param methodParamAnnos The expected method parameter annotations. 8.107 + * @param fieldAnnos The expected field annotations. 8.108 + * @param classTypeAnnos The expected class type annotations. 8.109 + * @param methodTypeAnnos The expected method type annotations. 8.110 + * @param fieldTypeAnnos The expected field type annotations. 8.111 + */ 8.112 + public Expected(String classname, 8.113 + ExpectedAnnotation[] classAnnos, 8.114 + ExpectedMethodAnnotation[] methodAnnos, 8.115 + ExpectedParameterAnnotation[] methodParamAnnos, 8.116 + ExpectedFieldAnnotation[] fieldAnnos, 8.117 + ExpectedTypeAnnotation[] classTypeAnnos, 8.118 + ExpectedMethodTypeAnnotation[] methodTypeAnnos, 8.119 + ExpectedFieldTypeAnnotation[] fieldTypeAnnos) { 8.120 + this.classname = classname; 8.121 + this.classAnnos = classAnnos; 8.122 + this.methodAnnos = methodAnnos; 8.123 + this.methodParamAnnos = methodParamAnnos; 8.124 + this.fieldAnnos = fieldAnnos; 8.125 + this.classTypeAnnos = classTypeAnnos; 8.126 + this.methodTypeAnnos = methodTypeAnnos; 8.127 + this.fieldTypeAnnos = fieldTypeAnnos; 8.128 + } 8.129 + 8.130 + /** 8.131 + * Create an {@code Expected} from regular annotation components. 8.132 + * 8.133 + * @param classname The name of the class to match, or {@code 8.134 + * null} for all classes. 8.135 + * @param classAnnos The expected class annotations. 8.136 + * @param methodAnnos The expected method annotations. 8.137 + * @param methodParamAnnos The expected method parameter annotations. 8.138 + * @param fieldAnnos The expected field annotations. 8.139 + */ 8.140 + public Expected(String classname, 8.141 + ExpectedAnnotation[] classAnnos, 8.142 + ExpectedMethodAnnotation[] methodAnnos, 8.143 + ExpectedParameterAnnotation[] methodParamAnnos, 8.144 + ExpectedFieldAnnotation[] fieldAnnos) { 8.145 + this(classname, classAnnos, methodAnnos, methodParamAnnos, 8.146 + fieldAnnos, null, null, null); 8.147 + } 8.148 + 8.149 + /** 8.150 + * Create an {@code Expected} from type annotation components. 8.151 + * 8.152 + * @param classname The name of the class to match, or {@code 8.153 + * null} for all classes. 8.154 + * @param classTypeAnnos The expected class type annotations. 8.155 + * @param methodTypeAnnos The expected method type annotations. 8.156 + * @param fieldTypeAnnos The expected field type annotations. 8.157 + */ 8.158 + public Expected(String classname, 8.159 + ExpectedTypeAnnotation[] classTypeAnnos, 8.160 + ExpectedMethodTypeAnnotation[] methodTypeAnnos, 8.161 + ExpectedFieldTypeAnnotation[] fieldTypeAnnos) { 8.162 + this(classname, null, null, null, null, 8.163 + classTypeAnnos, methodTypeAnnos, fieldTypeAnnos); 8.164 + } 8.165 + 8.166 + public String toString() { 8.167 + final StringBuilder sb = new StringBuilder(); 8.168 + final String newline = System.lineSeparator(); 8.169 + sb.append("Expected on class ").append(classname); 8.170 + if (null != classAnnos) { 8.171 + sb.append(newline).append("Class annotations:").append(newline); 8.172 + for(ExpectedAnnotation anno : classAnnos) { 8.173 + sb.append(anno).append(newline); 8.174 + } 8.175 + } 8.176 + if (null != methodAnnos) { 8.177 + sb.append(newline).append("Method annotations:").append(newline); 8.178 + for(ExpectedAnnotation anno : methodAnnos) { 8.179 + sb.append(anno).append(newline); 8.180 + } 8.181 + } 8.182 + if (null != methodParamAnnos) { 8.183 + sb.append(newline).append("Method param annotations:").append(newline); 8.184 + for(ExpectedAnnotation anno : methodParamAnnos) { 8.185 + sb.append(anno).append(newline); 8.186 + } 8.187 + } 8.188 + if (null != fieldAnnos) { 8.189 + sb.append(newline).append("Field annotations:").append(newline); 8.190 + for(ExpectedAnnotation anno : fieldAnnos) { 8.191 + sb.append(anno).append(newline); 8.192 + } 8.193 + } 8.194 + if (null != classTypeAnnos) { 8.195 + sb.append(newline).append("Class type annotations:").append(newline); 8.196 + for(ExpectedAnnotation anno : classTypeAnnos) { 8.197 + sb.append(anno).append(newline); 8.198 + } 8.199 + } 8.200 + if (null != methodTypeAnnos) { 8.201 + sb.append(newline).append("Method type annotations:").append(newline); 8.202 + for(ExpectedAnnotation anno : methodTypeAnnos) { 8.203 + sb.append(anno).append(newline); 8.204 + } 8.205 + } 8.206 + if (null != fieldTypeAnnos) { 8.207 + sb.append(newline).append("Field type annotations:").append(newline); 8.208 + for(ExpectedAnnotation anno : fieldTypeAnnos) { 8.209 + sb.append(anno).append(newline); 8.210 + } 8.211 + } 8.212 + return sb.toString(); 8.213 + } 8.214 + 8.215 + /** 8.216 + * See if this template applies to a class. 8.217 + * 8.218 + * @param classname The classname to check. 8.219 + * @return Whether or not this template should apply. 8.220 + */ 8.221 + public boolean matchClassName(String classname) { 8.222 + return this.classname == null || this.classname.equals(classname); 8.223 + } 8.224 + 8.225 + /** 8.226 + * After applying the template to all classes, check to see if 8.227 + * any of the expected annotations weren't matched. 8.228 + * 8.229 + * @return The number of missed matches. 8.230 + */ 8.231 + public int check() { 8.232 + int count = 0; 8.233 + if (classAnnos != null) { 8.234 + for(ExpectedAnnotation expected : classAnnos) { 8.235 + if (!expected.check()) { 8.236 + count++; 8.237 + } 8.238 + } 8.239 + } 8.240 + if (methodAnnos != null) { 8.241 + for(ExpectedAnnotation expected : methodAnnos) { 8.242 + if (!expected.check()) { 8.243 + count++; 8.244 + } 8.245 + } 8.246 + } 8.247 + if (methodParamAnnos != null) { 8.248 + for(ExpectedAnnotation expected : methodParamAnnos) { 8.249 + if (!expected.check()) { 8.250 + count++; 8.251 + } 8.252 + } 8.253 + } 8.254 + if (fieldAnnos != null) { 8.255 + for(ExpectedAnnotation expected : fieldAnnos) { 8.256 + if (!expected.check()) { 8.257 + count++; 8.258 + } 8.259 + } 8.260 + } 8.261 + if (classTypeAnnos != null) { 8.262 + for(ExpectedAnnotation expected : classTypeAnnos) { 8.263 + if (!expected.check()) { 8.264 + count++; 8.265 + } 8.266 + } 8.267 + } 8.268 + if (methodTypeAnnos != null) { 8.269 + for(ExpectedAnnotation expected : methodTypeAnnos) { 8.270 + if (!expected.check()) { 8.271 + count++; 8.272 + } 8.273 + } 8.274 + } 8.275 + if (fieldTypeAnnos != null) { 8.276 + for(ExpectedAnnotation expected : fieldTypeAnnos) { 8.277 + if (!expected.check()) { 8.278 + count++; 8.279 + } 8.280 + } 8.281 + } 8.282 + return count; 8.283 + } 8.284 + } 8.285 + 8.286 + /** 8.287 + * An expected annotation. This is both a superclass for 8.288 + * method, field, and type annotations, as well as a class for 8.289 + * annotations on a class. 8.290 + */ 8.291 + public static class ExpectedAnnotation { 8.292 + protected int count = 0; 8.293 + protected final String expectedName; 8.294 + protected final int expectedCount; 8.295 + protected final boolean visibility; 8.296 + 8.297 + /** 8.298 + * Create an {@code ExpectedAnnotation} from its 8.299 + * components. It is usually a better idea to use a {@code 8.300 + * Builder} to do this. 8.301 + * 8.302 + * @param expectedName The expected annotation name. 8.303 + * @param visibility Whether this annotation should be runtime-visible. 8.304 + * @param expectedCount The number of annotations that should 8.305 + * be seen. If 0, this asserts that the 8.306 + * described annotation is not present. 8.307 + */ 8.308 + public ExpectedAnnotation(String expectedName, 8.309 + boolean visibility, 8.310 + int expectedCount) { 8.311 + this.expectedName = expectedName; 8.312 + this.visibility = visibility; 8.313 + this.expectedCount = expectedCount; 8.314 + } 8.315 + 8.316 + public String toString() { 8.317 + final StringBuilder sb = new StringBuilder(); 8.318 + sb.append("Expected "); 8.319 + sb.append(expectedCount); 8.320 + sb.append(" annotation "); 8.321 + sb.append(expectedName); 8.322 + sb.append(visibility ? ", runtime visibile " : ", runtime invisibile "); 8.323 + return sb.toString(); 8.324 + } 8.325 + 8.326 + /** 8.327 + * See if this template matches the given visibility. 8.328 + * 8.329 + * @param Whether or not the annotation is visible at runtime. 8.330 + * @return Whether or not this template matches the visibility. 8.331 + */ 8.332 + public boolean matchVisibility(boolean visibility) { 8.333 + return this.visibility == visibility; 8.334 + } 8.335 + 8.336 + /** 8.337 + * Attempty to match this template against an annotation. If 8.338 + * it does match, then the match count for the template will 8.339 + * be incremented. Otherwise, nothing will be done. 8.340 + * 8.341 + * @param anno The annotation to attempt to match. 8.342 + */ 8.343 + public void matchAnnotation(ConstantPool cpool, 8.344 + Annotation anno) { 8.345 + if (checkMatch(cpool, anno)) { 8.346 + count++; 8.347 + } 8.348 + } 8.349 + 8.350 + /** 8.351 + * Indicate whether an annotation matches this expected 8.352 + * annotation. 8.353 + * 8.354 + * @param ConstantPool The constant pool to use. 8.355 + * @param anno The annotation to check. 8.356 + * @return Whether the annotation matches. 8.357 + */ 8.358 + protected boolean checkMatch(ConstantPool cpool, 8.359 + Annotation anno) { 8.360 + try { 8.361 + return cpool.getUTF8Info(anno.type_index).value.equals("L" + expectedName + ";"); 8.362 + } catch(Exception e) { 8.363 + return false; 8.364 + } 8.365 + } 8.366 + 8.367 + /** 8.368 + * After all matching, check to see if the expected number of 8.369 + * matches equals the actual number. If not, then print a 8.370 + * failure message and return {@code false}. 8.371 + * 8.372 + * @return Whether or not the expected number of matched 8.373 + * equals the actual number. 8.374 + */ 8.375 + public boolean check() { 8.376 + if (count != expectedCount) { 8.377 + System.err.println(this + ", but saw " + count); 8.378 + return false; 8.379 + } else { 8.380 + return true; 8.381 + } 8.382 + } 8.383 + } 8.384 + 8.385 + /** 8.386 + * An annotation found on a method. 8.387 + */ 8.388 + public static class ExpectedMethodAnnotation extends ExpectedAnnotation { 8.389 + protected final String methodname; 8.390 + 8.391 + /** 8.392 + * Create an {@code ExpectedMethodAnnotation} from its 8.393 + * components. It is usually a better idea to use a {@code 8.394 + * Builder} to do this. 8.395 + * 8.396 + * @param methodname The expected method name. 8.397 + * @param expectedName The expected annotation name. 8.398 + * @param visibility Whether this annotation should be runtime-visible. 8.399 + * @param expectedCount The number of annotations that should be seen. 8.400 + */ 8.401 + public ExpectedMethodAnnotation(String methodname, 8.402 + String expectedName, 8.403 + boolean visibility, 8.404 + int expectedCount) { 8.405 + super(expectedName, visibility, expectedCount); 8.406 + this.methodname = methodname; 8.407 + } 8.408 + 8.409 + public String toString() { 8.410 + final StringBuilder sb = new StringBuilder(); 8.411 + sb.append("Expected "); 8.412 + sb.append(expectedCount); 8.413 + sb.append(" annotation "); 8.414 + sb.append(expectedName); 8.415 + sb.append(visibility ? ", runtime visibile " : ", runtime invisibile "); 8.416 + sb.append(" on method "); 8.417 + sb.append(methodname); 8.418 + return sb.toString(); 8.419 + } 8.420 + 8.421 + /** 8.422 + * See if this template applies to a method. 8.423 + * 8.424 + * @param methodname The method name to check. 8.425 + * @return Whether or not this template should apply. 8.426 + */ 8.427 + public boolean matchMethodName(String methodname) { 8.428 + return this.methodname.equals(methodname); 8.429 + } 8.430 + 8.431 + } 8.432 + 8.433 + /** 8.434 + * An annotation found on a method parameter. 8.435 + */ 8.436 + public static class ExpectedParameterAnnotation 8.437 + extends ExpectedMethodAnnotation { 8.438 + protected final int index; 8.439 + 8.440 + /** 8.441 + * Create an {@code ExpectedParameterAnnotation} from its 8.442 + * components. It is usually a better idea to use a {@code 8.443 + * Builder} to do this. 8.444 + * 8.445 + * @param methodname The expected method name. 8.446 + * @param index The parameter index. 8.447 + * @param expectedName The expected annotation name. 8.448 + * @param visibility Whether this annotation should be runtime-visible. 8.449 + * @param expectedCount The number of annotations that should be seen. 8.450 + */ 8.451 + public ExpectedParameterAnnotation(String methodname, 8.452 + int index, 8.453 + String expectedName, 8.454 + boolean visibility, 8.455 + int expectedCount) { 8.456 + super(methodname, expectedName, visibility, expectedCount); 8.457 + this.index = index; 8.458 + } 8.459 + 8.460 + public String toString() { 8.461 + final StringBuilder sb = new StringBuilder(); 8.462 + sb.append("Expected "); 8.463 + sb.append(expectedCount); 8.464 + sb.append(" annotation "); 8.465 + sb.append(expectedName); 8.466 + sb.append(visibility ? ", runtime visibile " : ", runtime invisibile "); 8.467 + sb.append(" on method "); 8.468 + sb.append(methodname); 8.469 + sb.append(" parameter " + index); 8.470 + return sb.toString(); 8.471 + } 8.472 + 8.473 + } 8.474 + 8.475 + /** 8.476 + * An annotation found on a field. 8.477 + */ 8.478 + public static class ExpectedFieldAnnotation extends ExpectedAnnotation { 8.479 + private final String fieldname; 8.480 + 8.481 + /** 8.482 + * Create an {@code ExpectedFieldAnnotation} from its 8.483 + * components. It is usually a better idea to use a {@code 8.484 + * Builder} to do this. 8.485 + * 8.486 + * @param fieldname The expected field name. 8.487 + * @param expectedName The expected annotation name. 8.488 + * @param visibility Whether this annotation should be runtime-visible. 8.489 + * @param expectedCount The number of annotations that should be seen. 8.490 + */ 8.491 + public ExpectedFieldAnnotation(String fieldname, 8.492 + String expectedName, 8.493 + boolean visibility, 8.494 + int expectedCount) { 8.495 + super(expectedName, visibility, expectedCount); 8.496 + this.fieldname = fieldname; 8.497 + } 8.498 + 8.499 + public String toString() { 8.500 + final StringBuilder sb = new StringBuilder(); 8.501 + sb.append("Expected ").append(expectedCount) 8.502 + .append(" annotation ").append(expectedName) 8.503 + .append(visibility ? ", runtime visibile " : ", runtime invisibile ") 8.504 + .append(" on field ").append(fieldname); 8.505 + return sb.toString(); 8.506 + } 8.507 + 8.508 + /** 8.509 + * See if this template applies to a field. 8.510 + * 8.511 + * @param fieldname The field name to check. 8.512 + * @return Whether or not this template should apply. 8.513 + */ 8.514 + public boolean matchFieldName(String fieldname) { 8.515 + return this.fieldname.equals(fieldname); 8.516 + } 8.517 + 8.518 + } 8.519 + 8.520 + /** 8.521 + * An expected type annotation. This is both a superclass for 8.522 + * method and field type annotations, as well as a class for type 8.523 + * annotations on a class. 8.524 + */ 8.525 + public static class ExpectedTypeAnnotation extends ExpectedAnnotation { 8.526 + protected final TypeAnnotation.TargetType targetType; 8.527 + protected final int bound_index; 8.528 + protected final int parameter_index; 8.529 + protected final int type_index; 8.530 + protected final int exception_index; 8.531 + protected final TypeAnnotation.Position.TypePathEntry[] typePath; 8.532 + 8.533 + /** 8.534 + * Create an {@code ExpectedTypeAnnotation} from its 8.535 + * components. It is usually a better idea to use a {@code 8.536 + * Builder} to do this. 8.537 + * 8.538 + * @param expectedName The expected annotation name. 8.539 + * @param visibility Whether this annotation should be runtime-visible. 8.540 + * @param expectedCount The number of annotations that should 8.541 + * be seen. If 0, this asserts that the 8.542 + * described annotation is not present. 8.543 + * @param targetType The expected target type. 8.544 + * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}. 8.545 + * @param parameter_index The expected parameter index, or 8.546 + * {@code Integer.MIN_VALUE}. 8.547 + * @param type_index The expected type index, or {@code Integer.MIN_VALUE}. 8.548 + * @param exception_index The expected exception index, or 8.549 + * {@code Integer.MIN_VALUE}. 8.550 + * @param typePath The expected type path. 8.551 + */ 8.552 + public ExpectedTypeAnnotation(String expectedName, 8.553 + boolean visibility, 8.554 + int expectedCount, 8.555 + TypeAnnotation.TargetType targetType, 8.556 + int bound_index, 8.557 + int parameter_index, 8.558 + int type_index, 8.559 + int exception_index, 8.560 + TypeAnnotation.Position.TypePathEntry... typePath) { 8.561 + super(expectedName, visibility, expectedCount); 8.562 + this.targetType = targetType; 8.563 + this.bound_index = bound_index; 8.564 + this.parameter_index = parameter_index; 8.565 + this.type_index = type_index; 8.566 + this.exception_index = exception_index; 8.567 + this.typePath = typePath; 8.568 + } 8.569 + 8.570 + public String toString() { 8.571 + final StringBuilder sb = new StringBuilder(); 8.572 + sb.append("Expected "); 8.573 + sb.append(expectedCount); 8.574 + sb.append(" annotation "); 8.575 + sb.append(expectedName); 8.576 + sb.append(visibility ? ", runtime visibile " : ", runtime invisibile "); 8.577 + sb.append(targetType); 8.578 + sb.append(", bound_index = "); 8.579 + sb.append(bound_index); 8.580 + sb.append(", parameter_index = "); 8.581 + sb.append(parameter_index); 8.582 + sb.append(", type_index = "); 8.583 + sb.append(type_index); 8.584 + sb.append(", exception_index = "); 8.585 + sb.append(exception_index); 8.586 + sb.append(", type_path = ["); 8.587 + for(int i = 0; i < typePath.length; i++) { 8.588 + if (i != 0) { 8.589 + sb.append(", "); 8.590 + } 8.591 + sb.append(typePath[i]); 8.592 + } 8.593 + sb.append("]"); 8.594 + return sb.toString(); 8.595 + } 8.596 + 8.597 + @Override 8.598 + public void matchAnnotation(ConstantPool cpool, 8.599 + Annotation anno) {} 8.600 + 8.601 + public void matchAnnotation(TypeAnnotation anno) { 8.602 + if (checkMatch(anno)) { 8.603 + count++; 8.604 + } 8.605 + } 8.606 + 8.607 + public boolean checkMatch(TypeAnnotation anno) { 8.608 + boolean matches = checkMatch(anno.constant_pool, anno.annotation); 8.609 + 8.610 + matches = matches && anno.position.type == targetType; 8.611 + matches = matches && anno.position.bound_index == bound_index; 8.612 + matches = matches && anno.position.parameter_index == parameter_index; 8.613 + matches = matches && anno.position.type_index == type_index; 8.614 + matches = matches && anno.position.exception_index == exception_index; 8.615 + matches = matches && anno.position.location.size() == typePath.length; 8.616 + 8.617 + if (matches) { 8.618 + int i = 0; 8.619 + for(TypeAnnotation.Position.TypePathEntry entry : 8.620 + anno.position.location) { 8.621 + matches = matches && typePath[i++].equals(entry); 8.622 + } 8.623 + } 8.624 + 8.625 + return matches; 8.626 + } 8.627 + 8.628 + /** 8.629 + * A builder class for creating {@code 8.630 + * ExpectedTypeAnnotation}s in a more convenient fashion. The 8.631 + * constructor for {@code ExpectedTypeAnnotation} takes a 8.632 + * large number of parameters (by necessity). This class 8.633 + * allows users to construct a {@code ExpectedTypeAnnotation}s 8.634 + * using only the ones they need. 8.635 + */ 8.636 + public static class Builder { 8.637 + protected final String expectedName; 8.638 + protected final boolean visibility; 8.639 + protected final int expectedCount; 8.640 + protected final TypeAnnotation.TargetType targetType; 8.641 + protected int bound_index = Integer.MIN_VALUE; 8.642 + protected int parameter_index = Integer.MIN_VALUE; 8.643 + protected int type_index = Integer.MIN_VALUE; 8.644 + protected int exception_index = Integer.MIN_VALUE; 8.645 + protected TypeAnnotation.Position.TypePathEntry[] typePath = 8.646 + new TypeAnnotation.Position.TypePathEntry[0]; 8.647 + 8.648 + /** 8.649 + * Create a {@code Builder} from the mandatory parameters. 8.650 + * 8.651 + * @param expectedName The expected annotation name. 8.652 + * @param targetType The expected target type. 8.653 + * @param visibility Whether this annotation should be runtime-visible. 8.654 + * @param expectedCount The number of annotations that should be seen. 8.655 + */ 8.656 + public Builder(String expectedName, 8.657 + TypeAnnotation.TargetType targetType, 8.658 + boolean visibility, 8.659 + int expectedCount) { 8.660 + this.expectedName = expectedName; 8.661 + this.visibility = visibility; 8.662 + this.expectedCount = expectedCount; 8.663 + this.targetType = targetType; 8.664 + } 8.665 + 8.666 + /** 8.667 + * Create an {@code ExpectedTypeAnnotation} from all 8.668 + * parameters that have been provided. The default values 8.669 + * will be used for those that have not. 8.670 + * 8.671 + * @return The cretaed {@code ExpectedTypeAnnotation}. 8.672 + */ 8.673 + public ExpectedTypeAnnotation build() { 8.674 + return new ExpectedTypeAnnotation(expectedName, visibility, 8.675 + expectedCount, targetType, 8.676 + bound_index, parameter_index, 8.677 + type_index, exception_index, 8.678 + typePath); 8.679 + } 8.680 + 8.681 + /** 8.682 + * Provide a bound index parameter. 8.683 + * 8.684 + * @param bound_index The bound_index value. 8.685 + */ 8.686 + public Builder setBoundIndex(int bound_index) { 8.687 + this.bound_index = bound_index; 8.688 + return this; 8.689 + } 8.690 + 8.691 + /** 8.692 + * Provide a parameter index parameter. 8.693 + * 8.694 + * @param bound_index The parameter_index value. 8.695 + */ 8.696 + public Builder setParameterIndex(int parameter_index) { 8.697 + this.parameter_index = parameter_index; 8.698 + return this; 8.699 + } 8.700 + 8.701 + /** 8.702 + * Provide a type index parameter. 8.703 + * 8.704 + * @param type_index The type_index value. 8.705 + */ 8.706 + public Builder setTypeIndex(int type_index) { 8.707 + this.type_index = type_index; 8.708 + return this; 8.709 + } 8.710 + 8.711 + /** 8.712 + * Provide an exception index parameter. 8.713 + * 8.714 + * @param exception_index The exception_index value. 8.715 + */ 8.716 + public Builder setExceptionIndex(int exception_index) { 8.717 + this.exception_index = exception_index; 8.718 + return this; 8.719 + } 8.720 + 8.721 + /** 8.722 + * Provide a type path parameter. 8.723 + * 8.724 + * @param typePath The type path value. 8.725 + */ 8.726 + public Builder setTypePath(TypeAnnotation.Position.TypePathEntry[] typePath) { 8.727 + this.typePath = typePath; 8.728 + return this; 8.729 + } 8.730 + } 8.731 + } 8.732 + 8.733 + /** 8.734 + * A type annotation found on a method. 8.735 + */ 8.736 + public static class ExpectedMethodTypeAnnotation extends ExpectedTypeAnnotation { 8.737 + private final String methodname; 8.738 + 8.739 + /** 8.740 + * Create an {@code ExpectedMethodTypeAnnotation} from its 8.741 + * components. It is usually a better idea to use a {@code 8.742 + * Builder} to do this. 8.743 + * 8.744 + * @param methodname The expected method name. 8.745 + * @param expectedName The expected annotation name. 8.746 + * @param visibility Whether this annotation should be runtime-visible. 8.747 + * @param expectedCount The number of annotations that should be seen. 8.748 + * @param targetType The expected target type. 8.749 + * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}. 8.750 + * @param parameter_index The expected parameter index, or 8.751 + * {@code Integer.MIN_VALUE}. 8.752 + * @param type_index The expected type index, or {@code Integer.MIN_VALUE}. 8.753 + * @param exception_index The expected exception index, or 8.754 + * {@code Integer.MIN_VALUE}. 8.755 + * @param typePath The expected type path. 8.756 + */ 8.757 + public ExpectedMethodTypeAnnotation(String methodname, 8.758 + String expectedName, 8.759 + boolean visibility, 8.760 + int expectedCount, 8.761 + TypeAnnotation.TargetType targetType, 8.762 + int bound_index, 8.763 + int parameter_index, 8.764 + int type_index, 8.765 + int exception_index, 8.766 + TypeAnnotation.Position.TypePathEntry... typePath) { 8.767 + super(expectedName, visibility, expectedCount, targetType, bound_index, 8.768 + parameter_index, type_index, exception_index, typePath); 8.769 + this.methodname = methodname; 8.770 + } 8.771 + 8.772 + public String toString() { 8.773 + final StringBuilder sb = new StringBuilder(); 8.774 + sb.append("Expected "); 8.775 + sb.append(expectedCount); 8.776 + sb.append(" annotation "); 8.777 + sb.append(expectedName); 8.778 + sb.append(visibility ? ", runtime visibile " : ", runtime invisibile "); 8.779 + sb.append(targetType); 8.780 + sb.append(", bound_index = "); 8.781 + sb.append(bound_index); 8.782 + sb.append(", parameter_index = "); 8.783 + sb.append(parameter_index); 8.784 + sb.append(", type_index = "); 8.785 + sb.append(type_index); 8.786 + sb.append(", exception_index = "); 8.787 + sb.append(exception_index); 8.788 + sb.append(", type_path = ["); 8.789 + for(int i = 0; i < typePath.length; i++) { 8.790 + if (i != 0) { 8.791 + sb.append(", "); 8.792 + } 8.793 + sb.append(typePath[i]); 8.794 + } 8.795 + sb.append("]"); 8.796 + sb.append(" on method "); 8.797 + sb.append(methodname); 8.798 + return sb.toString(); 8.799 + } 8.800 + 8.801 + /** 8.802 + * See if this template applies to a method. 8.803 + * 8.804 + * @param methodname The method name to check. 8.805 + * @return Whether or not this template should apply. 8.806 + */ 8.807 + public boolean matchMethodName(String methodname) { 8.808 + return this.methodname.equals(methodname); 8.809 + } 8.810 + 8.811 + /** 8.812 + * A builder class for creating {@code 8.813 + * ExpectedMethodTypeAnnotation}s in a more convenient fashion. The 8.814 + * constructor for {@code ExpectedMethodTypeAnnotation} takes a 8.815 + * large number of parameters (by necessity). This class 8.816 + * allows users to construct a {@code ExpectedMethodTypeAnnotation}s 8.817 + * using only the ones they need. 8.818 + */ 8.819 + public static class Builder extends ExpectedTypeAnnotation.Builder { 8.820 + protected final String methodname; 8.821 + 8.822 + /** 8.823 + * Create a {@code Builder} from the mandatory parameters. 8.824 + * 8.825 + * @param methodname The expected method name. 8.826 + * @param expectedName The expected annotation name. 8.827 + * @param targetType The expected target type. 8.828 + * @param visibility Whether this annotation should be runtime-visible. 8.829 + * @param expectedCount The number of annotations that should be seen. 8.830 + */ 8.831 + public Builder(String methodname, 8.832 + String expectedName, 8.833 + TypeAnnotation.TargetType targetType, 8.834 + boolean visibility, 8.835 + int expectedCount) { 8.836 + super(expectedName, targetType, visibility, expectedCount); 8.837 + this.methodname = methodname; 8.838 + } 8.839 + 8.840 + /** 8.841 + * Create an {@code ExpectedMethodTypeAnnotation} from all 8.842 + * parameters that have been provided. The default values 8.843 + * will be used for those that have not. 8.844 + * 8.845 + * @return The cretaed {@code ExpectedMethodTypeAnnotation}. 8.846 + */ 8.847 + public ExpectedMethodTypeAnnotation build() { 8.848 + return new ExpectedMethodTypeAnnotation(methodname, expectedName, 8.849 + visibility, expectedCount, 8.850 + targetType, bound_index, 8.851 + parameter_index, type_index, 8.852 + exception_index, typePath); 8.853 + } 8.854 + } 8.855 + } 8.856 + 8.857 + /** 8.858 + * A type annotation found on a field. 8.859 + */ 8.860 + public static class ExpectedFieldTypeAnnotation extends ExpectedTypeAnnotation { 8.861 + private final String fieldname; 8.862 + 8.863 + /** 8.864 + * Create an {@code ExpectedFieldTypeAnnotation} from its 8.865 + * components. It is usually a better idea to use a {@code 8.866 + * Builder} to do this. 8.867 + * 8.868 + * @param fieldname The expected field name. 8.869 + * @param expectedName The expected annotation name. 8.870 + * @param visibility Whether this annotation should be runtime-visible. 8.871 + * @param expectedCount The number of annotations that should be seen. 8.872 + * @param targetType The expected target type. 8.873 + * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}. 8.874 + * @param parameter_index The expected parameter index, or 8.875 + * {@code Integer.MIN_VALUE}. 8.876 + * @param type_index The expected type index, or {@code Integer.MIN_VALUE}. 8.877 + * @param exception_index The expected exception index, or 8.878 + * {@code Integer.MIN_VALUE}. 8.879 + * @param typePath The expected type path. 8.880 + */ 8.881 + public ExpectedFieldTypeAnnotation(String fieldname, 8.882 + String expectedName, 8.883 + boolean visibility, 8.884 + int expectedCount, 8.885 + TypeAnnotation.TargetType targetType, 8.886 + int bound_index, 8.887 + int parameter_index, 8.888 + int type_index, 8.889 + int exception_index, 8.890 + TypeAnnotation.Position.TypePathEntry... typePath) { 8.891 + super(expectedName, visibility, expectedCount, targetType, bound_index, 8.892 + parameter_index, type_index, exception_index, typePath); 8.893 + this.fieldname = fieldname; 8.894 + } 8.895 + 8.896 + public String toString() { 8.897 + final StringBuilder sb = new StringBuilder(); 8.898 + sb.append("Expected ").append(expectedCount) 8.899 + .append(" annotation ").append(expectedName) 8.900 + .append(visibility ? ", runtime visibile " : ", runtime invisibile ") 8.901 + .append(targetType) 8.902 + .append(", bound_index = ").append(bound_index) 8.903 + .append(", parameter_index = ").append(parameter_index) 8.904 + .append(", type_index = ").append(type_index) 8.905 + .append(", exception_index = ").append(exception_index) 8.906 + .append(", type_path = ["); 8.907 + 8.908 + for(int i = 0; i < typePath.length; i++) { 8.909 + if (i != 0) { 8.910 + sb.append(", "); 8.911 + } 8.912 + sb.append(typePath[i]); 8.913 + } 8.914 + sb.append("]") 8.915 + .append(" on field ").append(fieldname); 8.916 + return sb.toString(); 8.917 + } 8.918 + 8.919 + /** 8.920 + * See if this template applies to a field. 8.921 + * 8.922 + * @param fieldname The field name to check. 8.923 + * @return Whether or not this template should apply. 8.924 + */ 8.925 + public boolean matchFieldName(String fieldname) { 8.926 + return this.fieldname.equals(fieldname); 8.927 + } 8.928 + 8.929 + /** 8.930 + * A builder class for creating {@code 8.931 + * ExpectedFieldTypeAnnotation}s in a more convenient fashion. The 8.932 + * constructor for {@code ExpectedFieldTypeAnnotation} takes a 8.933 + * large number of parameters (by necessity). This class 8.934 + * allows users to construct a {@code ExpectedFieldTypeAnnotation}s 8.935 + * using only the ones they need. 8.936 + */ 8.937 + public static class Builder extends ExpectedTypeAnnotation.Builder { 8.938 + protected final String fieldname; 8.939 + 8.940 + /** 8.941 + * Create a {@code Builder} from the mandatory parameters. 8.942 + * 8.943 + * @param fieldname The expected field name. 8.944 + * @param expectedName The expected annotation name. 8.945 + * @param targetType The expected target type. 8.946 + * @param visibility Whether this annotation should be runtime-visible. 8.947 + * @param expectedCount The number of annotations that should be seen. 8.948 + */ 8.949 + public Builder(String fieldname, 8.950 + String expectedName, 8.951 + TypeAnnotation.TargetType targetType, 8.952 + boolean visibility, 8.953 + int expectedCount) { 8.954 + super(expectedName, targetType, visibility, expectedCount); 8.955 + this.fieldname = fieldname; 8.956 + } 8.957 + 8.958 + /** 8.959 + * Create an {@code ExpectedFieldTypeAnnotation} from all 8.960 + * parameters that have been provided. The default values 8.961 + * will be used for those that have not. 8.962 + * 8.963 + * @return The cretaed {@code ExpectedFieldTypeAnnotation}. 8.964 + */ 8.965 + public ExpectedFieldTypeAnnotation build() { 8.966 + return new ExpectedFieldTypeAnnotation(fieldname, expectedName, 8.967 + visibility, expectedCount, 8.968 + targetType, bound_index, 8.969 + parameter_index, type_index, 8.970 + exception_index, typePath); 8.971 + } 8.972 + } 8.973 + } 8.974 + 8.975 + private void matchClassAnnotation(ClassFile classfile, 8.976 + ExpectedAnnotation expected) 8.977 + throws ConstantPoolException { 8.978 + for(Attribute attr : classfile.attributes) { 8.979 + attr.accept(annoMatcher(classfile.constant_pool), expected); 8.980 + } 8.981 + } 8.982 + 8.983 + private void matchMethodAnnotation(ClassFile classfile, 8.984 + ExpectedMethodAnnotation expected) 8.985 + throws ConstantPoolException { 8.986 + for(Method meth : classfile.methods) { 8.987 + if (expected.matchMethodName(meth.getName(classfile.constant_pool))) { 8.988 + for(Attribute attr : meth.attributes) { 8.989 + attr.accept(annoMatcher(classfile.constant_pool), expected); 8.990 + } 8.991 + } 8.992 + } 8.993 + } 8.994 + 8.995 + private void matchParameterAnnotation(ClassFile classfile, 8.996 + ExpectedParameterAnnotation expected) 8.997 + throws ConstantPoolException { 8.998 + for(Method meth : classfile.methods) { 8.999 + if (expected.matchMethodName(meth.getName(classfile.constant_pool))) { 8.1000 + for(Attribute attr : meth.attributes) { 8.1001 + attr.accept(paramMatcher(classfile.constant_pool), expected); 8.1002 + } 8.1003 + } 8.1004 + } 8.1005 + } 8.1006 + 8.1007 + private void matchFieldAnnotation(ClassFile classfile, 8.1008 + ExpectedFieldAnnotation expected) 8.1009 + throws ConstantPoolException { 8.1010 + for(Field field : classfile.fields) { 8.1011 + if (expected.matchFieldName(field.getName(classfile.constant_pool))) { 8.1012 + for(Attribute attr : field.attributes) { 8.1013 + attr.accept(annoMatcher(classfile.constant_pool), expected); 8.1014 + } 8.1015 + } 8.1016 + } 8.1017 + } 8.1018 + 8.1019 + private void matchClassTypeAnnotation(ClassFile classfile, 8.1020 + ExpectedTypeAnnotation expected) 8.1021 + throws ConstantPoolException { 8.1022 + for(Attribute attr : classfile.attributes) { 8.1023 + attr.accept(typeAnnoMatcher, expected); 8.1024 + } 8.1025 + } 8.1026 + 8.1027 + private void matchMethodTypeAnnotation(ClassFile classfile, 8.1028 + ExpectedMethodTypeAnnotation expected) 8.1029 + throws ConstantPoolException { 8.1030 + for(Method meth : classfile.methods) { 8.1031 + if (expected.matchMethodName(meth.getName(classfile.constant_pool))) { 8.1032 + for(Attribute attr : meth.attributes) { 8.1033 + attr.accept(typeAnnoMatcher, expected); 8.1034 + } 8.1035 + } 8.1036 + } 8.1037 + } 8.1038 + 8.1039 + private void matchFieldTypeAnnotation(ClassFile classfile, 8.1040 + ExpectedFieldTypeAnnotation expected) 8.1041 + throws ConstantPoolException { 8.1042 + for(Field field : classfile.fields) { 8.1043 + if (expected.matchFieldName(field.getName(classfile.constant_pool))) { 8.1044 + for(Attribute attr : field.attributes) { 8.1045 + attr.accept(typeAnnoMatcher, expected); 8.1046 + } 8.1047 + } 8.1048 + } 8.1049 + } 8.1050 + 8.1051 + private void matchClassAnnotations(ClassFile classfile, 8.1052 + ExpectedAnnotation[] expected) 8.1053 + throws ConstantPoolException { 8.1054 + for(ExpectedAnnotation one : expected) { 8.1055 + matchClassAnnotation(classfile, one); 8.1056 + } 8.1057 + } 8.1058 + 8.1059 + private void matchMethodAnnotations(ClassFile classfile, 8.1060 + ExpectedMethodAnnotation[] expected) 8.1061 + throws ConstantPoolException { 8.1062 + for(ExpectedMethodAnnotation one : expected) { 8.1063 + matchMethodAnnotation(classfile, one); 8.1064 + } 8.1065 + } 8.1066 + 8.1067 + private void matchParameterAnnotations(ClassFile classfile, 8.1068 + ExpectedParameterAnnotation[] expected) 8.1069 + throws ConstantPoolException { 8.1070 + for(ExpectedParameterAnnotation one : expected) { 8.1071 + matchParameterAnnotation(classfile, one); 8.1072 + } 8.1073 + } 8.1074 + 8.1075 + private void matchFieldAnnotations(ClassFile classfile, 8.1076 + ExpectedFieldAnnotation[] expected) 8.1077 + throws ConstantPoolException { 8.1078 + for(ExpectedFieldAnnotation one : expected) { 8.1079 + matchFieldAnnotation(classfile, one); 8.1080 + } 8.1081 + } 8.1082 + 8.1083 + private void matchClassTypeAnnotations(ClassFile classfile, 8.1084 + ExpectedTypeAnnotation[] expected) 8.1085 + throws ConstantPoolException { 8.1086 + for(ExpectedTypeAnnotation one : expected) { 8.1087 + matchClassTypeAnnotation(classfile, one); 8.1088 + } 8.1089 + } 8.1090 + 8.1091 + private void matchMethodTypeAnnotations(ClassFile classfile, 8.1092 + ExpectedMethodTypeAnnotation[] expected) 8.1093 + throws ConstantPoolException { 8.1094 + for(ExpectedMethodTypeAnnotation one : expected) { 8.1095 + matchMethodTypeAnnotation(classfile, one); 8.1096 + } 8.1097 + } 8.1098 + 8.1099 + private void matchFieldTypeAnnotations(ClassFile classfile, 8.1100 + ExpectedFieldTypeAnnotation[] expected) 8.1101 + throws ConstantPoolException { 8.1102 + for(ExpectedFieldTypeAnnotation one : expected) { 8.1103 + matchFieldTypeAnnotation(classfile, one); 8.1104 + } 8.1105 + } 8.1106 + 8.1107 + /** 8.1108 + * Run a template on a single {@code ClassFile}. 8.1109 + * 8.1110 + * @param classfile The {@code ClassFile} on which to run tests. 8.1111 + * @param expected The expected annotation template. 8.1112 + */ 8.1113 + public void run(ClassFile classfile, 8.1114 + Expected... expected) 8.1115 + throws ConstantPoolException { 8.1116 + run(new ClassFile[] { classfile }, expected); 8.1117 + } 8.1118 + 8.1119 + /** 8.1120 + * Run a template on multiple {@code ClassFile}s. 8.1121 + * 8.1122 + * @param classfile The {@code ClassFile}s on which to run tests. 8.1123 + * @param expected The expected annotation template. 8.1124 + */ 8.1125 + public void run(ClassFile[] classfiles, 8.1126 + Expected... expected) 8.1127 + throws ConstantPoolException { 8.1128 + for(ClassFile classfile : classfiles) { 8.1129 + for(Expected one : expected) { 8.1130 + if (one.matchClassName(classfile.getName())) { 8.1131 + if (one.classAnnos != null) 8.1132 + matchClassAnnotations(classfile, one.classAnnos); 8.1133 + if (one.methodAnnos != null) 8.1134 + matchMethodAnnotations(classfile, one.methodAnnos); 8.1135 + if (one.methodParamAnnos != null) 8.1136 + matchParameterAnnotations(classfile, one.methodParamAnnos); 8.1137 + if (one.fieldAnnos != null) 8.1138 + matchFieldAnnotations(classfile, one.fieldAnnos); 8.1139 + if (one.classTypeAnnos != null) 8.1140 + matchClassTypeAnnotations(classfile, one.classTypeAnnos); 8.1141 + if (one.methodTypeAnnos != null) 8.1142 + matchMethodTypeAnnotations(classfile, one.methodTypeAnnos); 8.1143 + if (one.fieldTypeAnnos != null) 8.1144 + matchFieldTypeAnnotations(classfile, one.fieldTypeAnnos); 8.1145 + } 8.1146 + } 8.1147 + } 8.1148 + int count = 0; 8.1149 + for (Expected one : expected) { 8.1150 + count += one.check(); 8.1151 + } 8.1152 + 8.1153 + if (count != 0) { 8.1154 + throw new RuntimeException(count + " errors occurred in test"); 8.1155 + } 8.1156 + } 8.1157 + 8.1158 + /** 8.1159 + * Get a {@code ClassFile} from its file name. 8.1160 + * 8.1161 + * @param name The class' file name. 8.1162 + * @param host A class in the same package. 8.1163 + * @return The {@code ClassFile} 8.1164 + */ 8.1165 + public static ClassFile getClassFile(String name, 8.1166 + Class<?> host) 8.1167 + throws IOException, ConstantPoolException { 8.1168 + final URL url = host.getResource(name); 8.1169 + final InputStream in = url.openStream(); 8.1170 + try { 8.1171 + return ClassFile.read(in); 8.1172 + } finally { 8.1173 + in.close(); 8.1174 + } 8.1175 + } 8.1176 + 8.1177 + private static final Attribute.Visitor<Void, ExpectedTypeAnnotation> typeAnnoMatcher = 8.1178 + new Attribute.Visitor<Void, ExpectedTypeAnnotation>() { 8.1179 + 8.1180 + @Override 8.1181 + public Void visitBootstrapMethods(BootstrapMethods_attribute attr, 8.1182 + ExpectedTypeAnnotation expected) { 8.1183 + return null; 8.1184 + } 8.1185 + 8.1186 + @Override 8.1187 + public Void visitDefault(DefaultAttribute attr, 8.1188 + ExpectedTypeAnnotation expected) { 8.1189 + return null; 8.1190 + } 8.1191 + 8.1192 + @Override 8.1193 + public Void visitAnnotationDefault(AnnotationDefault_attribute attr, 8.1194 + ExpectedTypeAnnotation expected) { 8.1195 + return null; 8.1196 + } 8.1197 + 8.1198 + @Override 8.1199 + public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, 8.1200 + ExpectedTypeAnnotation expected) { 8.1201 + return null; 8.1202 + } 8.1203 + 8.1204 + @Override 8.1205 + public Void visitCode(Code_attribute attr, 8.1206 + ExpectedTypeAnnotation expected) { 8.1207 + return null; 8.1208 + } 8.1209 + 8.1210 + @Override 8.1211 + public Void visitCompilationID(CompilationID_attribute attr, 8.1212 + ExpectedTypeAnnotation expected) { 8.1213 + return null; 8.1214 + } 8.1215 + 8.1216 + @Override 8.1217 + public Void visitConstantValue(ConstantValue_attribute attr, 8.1218 + ExpectedTypeAnnotation expected) { 8.1219 + return null; 8.1220 + } 8.1221 + 8.1222 + @Override 8.1223 + public Void visitDeprecated(Deprecated_attribute attr, 8.1224 + ExpectedTypeAnnotation expected) { 8.1225 + return null; 8.1226 + } 8.1227 + 8.1228 + @Override 8.1229 + public Void visitEnclosingMethod(EnclosingMethod_attribute attr, 8.1230 + ExpectedTypeAnnotation expected) { 8.1231 + return null; 8.1232 + } 8.1233 + 8.1234 + @Override 8.1235 + public Void visitExceptions(Exceptions_attribute attr, 8.1236 + ExpectedTypeAnnotation expected) { 8.1237 + return null; 8.1238 + } 8.1239 + 8.1240 + @Override 8.1241 + public Void visitInnerClasses(InnerClasses_attribute attr, 8.1242 + ExpectedTypeAnnotation expected) { 8.1243 + return null; 8.1244 + } 8.1245 + 8.1246 + @Override 8.1247 + public Void visitLineNumberTable(LineNumberTable_attribute attr, 8.1248 + ExpectedTypeAnnotation expected) { 8.1249 + return null; 8.1250 + } 8.1251 + 8.1252 + @Override 8.1253 + public Void visitLocalVariableTable(LocalVariableTable_attribute attr, 8.1254 + ExpectedTypeAnnotation expected) { 8.1255 + return null; 8.1256 + } 8.1257 + 8.1258 + @Override 8.1259 + public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, 8.1260 + ExpectedTypeAnnotation expected) { 8.1261 + return null; 8.1262 + } 8.1263 + 8.1264 + @Override 8.1265 + public Void visitMethodParameters(MethodParameters_attribute attr, 8.1266 + ExpectedTypeAnnotation expected) { 8.1267 + return null; 8.1268 + } 8.1269 + 8.1270 + @Override 8.1271 + public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, 8.1272 + ExpectedTypeAnnotation expected) { 8.1273 + return null; 8.1274 + } 8.1275 + 8.1276 + @Override 8.1277 + public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, 8.1278 + ExpectedTypeAnnotation expected) { 8.1279 + return null; 8.1280 + } 8.1281 + 8.1282 + @Override 8.1283 + public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, 8.1284 + ExpectedTypeAnnotation expected) { 8.1285 + return null; 8.1286 + } 8.1287 + 8.1288 + @Override 8.1289 + public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, 8.1290 + ExpectedTypeAnnotation expected) { 8.1291 + return null; 8.1292 + } 8.1293 + 8.1294 + @Override 8.1295 + public Void visitSignature(Signature_attribute attr, 8.1296 + ExpectedTypeAnnotation expected) { 8.1297 + return null; 8.1298 + } 8.1299 + 8.1300 + @Override 8.1301 + public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, 8.1302 + ExpectedTypeAnnotation expected) { 8.1303 + return null; 8.1304 + } 8.1305 + 8.1306 + @Override 8.1307 + public Void visitSourceFile(SourceFile_attribute attr, 8.1308 + ExpectedTypeAnnotation expected) { 8.1309 + return null; 8.1310 + } 8.1311 + 8.1312 + @Override 8.1313 + public Void visitSourceID(SourceID_attribute attr, 8.1314 + ExpectedTypeAnnotation expected) { 8.1315 + return null; 8.1316 + } 8.1317 + 8.1318 + @Override 8.1319 + public Void visitStackMap(StackMap_attribute attr, 8.1320 + ExpectedTypeAnnotation expected) { 8.1321 + return null; 8.1322 + } 8.1323 + 8.1324 + @Override 8.1325 + public Void visitStackMapTable(StackMapTable_attribute attr, 8.1326 + ExpectedTypeAnnotation expected) { 8.1327 + return null; 8.1328 + } 8.1329 + 8.1330 + @Override 8.1331 + public Void visitSynthetic(Synthetic_attribute attr, 8.1332 + ExpectedTypeAnnotation expected) { 8.1333 + return null; 8.1334 + } 8.1335 + 8.1336 + @Override 8.1337 + public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, 8.1338 + ExpectedTypeAnnotation expected) { 8.1339 + if (expected.matchVisibility(true)) { 8.1340 + for(TypeAnnotation anno : attr.annotations) { 8.1341 + expected.matchAnnotation(anno); 8.1342 + } 8.1343 + } 8.1344 + 8.1345 + return null; 8.1346 + } 8.1347 + 8.1348 + @Override 8.1349 + public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, 8.1350 + ExpectedTypeAnnotation expected) { 8.1351 + if (expected.matchVisibility(false)) { 8.1352 + for(TypeAnnotation anno : attr.annotations) { 8.1353 + expected.matchAnnotation(anno); 8.1354 + } 8.1355 + } 8.1356 + 8.1357 + return null; 8.1358 + } 8.1359 + }; 8.1360 + 8.1361 + private static Attribute.Visitor<Void, ExpectedAnnotation> annoMatcher(ConstantPool cpool) { 8.1362 + return new Attribute.Visitor<Void, ExpectedAnnotation>() { 8.1363 + 8.1364 + @Override 8.1365 + public Void visitBootstrapMethods(BootstrapMethods_attribute attr, 8.1366 + ExpectedAnnotation expected) { 8.1367 + return null; 8.1368 + } 8.1369 + 8.1370 + @Override 8.1371 + public Void visitDefault(DefaultAttribute attr, 8.1372 + ExpectedAnnotation expected) { 8.1373 + return null; 8.1374 + } 8.1375 + 8.1376 + @Override 8.1377 + public Void visitAnnotationDefault(AnnotationDefault_attribute attr, 8.1378 + ExpectedAnnotation expected) { 8.1379 + return null; 8.1380 + } 8.1381 + 8.1382 + @Override 8.1383 + public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, 8.1384 + ExpectedAnnotation expected) { 8.1385 + return null; 8.1386 + } 8.1387 + 8.1388 + @Override 8.1389 + public Void visitCode(Code_attribute attr, 8.1390 + ExpectedAnnotation expected) { 8.1391 + return null; 8.1392 + } 8.1393 + 8.1394 + @Override 8.1395 + public Void visitCompilationID(CompilationID_attribute attr, 8.1396 + ExpectedAnnotation expected) { 8.1397 + return null; 8.1398 + } 8.1399 + 8.1400 + @Override 8.1401 + public Void visitConstantValue(ConstantValue_attribute attr, 8.1402 + ExpectedAnnotation expected) { 8.1403 + return null; 8.1404 + } 8.1405 + 8.1406 + @Override 8.1407 + public Void visitDeprecated(Deprecated_attribute attr, 8.1408 + ExpectedAnnotation expected) { 8.1409 + return null; 8.1410 + } 8.1411 + 8.1412 + @Override 8.1413 + public Void visitEnclosingMethod(EnclosingMethod_attribute attr, 8.1414 + ExpectedAnnotation expected) { 8.1415 + return null; 8.1416 + } 8.1417 + 8.1418 + @Override 8.1419 + public Void visitExceptions(Exceptions_attribute attr, 8.1420 + ExpectedAnnotation expected) { 8.1421 + return null; 8.1422 + } 8.1423 + 8.1424 + @Override 8.1425 + public Void visitInnerClasses(InnerClasses_attribute attr, 8.1426 + ExpectedAnnotation expected) { 8.1427 + return null; 8.1428 + } 8.1429 + 8.1430 + @Override 8.1431 + public Void visitLineNumberTable(LineNumberTable_attribute attr, 8.1432 + ExpectedAnnotation expected) { 8.1433 + return null; 8.1434 + } 8.1435 + 8.1436 + @Override 8.1437 + public Void visitLocalVariableTable(LocalVariableTable_attribute attr, 8.1438 + ExpectedAnnotation expected) { 8.1439 + return null; 8.1440 + } 8.1441 + 8.1442 + @Override 8.1443 + public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, 8.1444 + ExpectedAnnotation expected) { 8.1445 + return null; 8.1446 + } 8.1447 + 8.1448 + @Override 8.1449 + public Void visitMethodParameters(MethodParameters_attribute attr, 8.1450 + ExpectedAnnotation expected) { 8.1451 + return null; 8.1452 + } 8.1453 + 8.1454 + @Override 8.1455 + public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, 8.1456 + ExpectedAnnotation expected) { 8.1457 + return null; 8.1458 + } 8.1459 + 8.1460 + @Override 8.1461 + public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, 8.1462 + ExpectedAnnotation expected) { 8.1463 + return null; 8.1464 + } 8.1465 + 8.1466 + @Override 8.1467 + public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, 8.1468 + ExpectedAnnotation expected) { 8.1469 + return null; 8.1470 + } 8.1471 + 8.1472 + @Override 8.1473 + public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, 8.1474 + ExpectedAnnotation expected) { 8.1475 + return null; 8.1476 + } 8.1477 + 8.1478 + @Override 8.1479 + public Void visitSignature(Signature_attribute attr, 8.1480 + ExpectedAnnotation expected) { 8.1481 + return null; 8.1482 + } 8.1483 + 8.1484 + @Override 8.1485 + public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, 8.1486 + ExpectedAnnotation expected) { 8.1487 + return null; 8.1488 + } 8.1489 + 8.1490 + @Override 8.1491 + public Void visitSourceFile(SourceFile_attribute attr, 8.1492 + ExpectedAnnotation expected) { 8.1493 + return null; 8.1494 + } 8.1495 + 8.1496 + @Override 8.1497 + public Void visitSourceID(SourceID_attribute attr, 8.1498 + ExpectedAnnotation expected) { 8.1499 + return null; 8.1500 + } 8.1501 + 8.1502 + @Override 8.1503 + public Void visitStackMap(StackMap_attribute attr, 8.1504 + ExpectedAnnotation expected) { 8.1505 + return null; 8.1506 + } 8.1507 + 8.1508 + @Override 8.1509 + public Void visitStackMapTable(StackMapTable_attribute attr, 8.1510 + ExpectedAnnotation expected) { 8.1511 + return null; 8.1512 + } 8.1513 + 8.1514 + @Override 8.1515 + public Void visitSynthetic(Synthetic_attribute attr, 8.1516 + ExpectedAnnotation expected) { 8.1517 + return null; 8.1518 + } 8.1519 + 8.1520 + @Override 8.1521 + public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, 8.1522 + ExpectedAnnotation expected) { 8.1523 + if (expected.matchVisibility(true)) { 8.1524 + for(Annotation anno : attr.annotations) { 8.1525 + expected.matchAnnotation(cpool, anno); 8.1526 + } 8.1527 + } 8.1528 + 8.1529 + return null; 8.1530 + } 8.1531 + 8.1532 + @Override 8.1533 + public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, 8.1534 + ExpectedAnnotation expected) { 8.1535 + if (expected.matchVisibility(false)) { 8.1536 + for(Annotation anno : attr.annotations) { 8.1537 + expected.matchAnnotation(cpool, anno); 8.1538 + } 8.1539 + } 8.1540 + 8.1541 + return null; 8.1542 + } 8.1543 + }; 8.1544 + } 8.1545 + 8.1546 + private static Attribute.Visitor<Void, ExpectedParameterAnnotation> paramMatcher(ConstantPool cpool) { 8.1547 + return new Attribute.Visitor<Void, ExpectedParameterAnnotation>() { 8.1548 + 8.1549 + @Override 8.1550 + public Void visitBootstrapMethods(BootstrapMethods_attribute attr, 8.1551 + ExpectedParameterAnnotation expected) { 8.1552 + return null; 8.1553 + } 8.1554 + 8.1555 + @Override 8.1556 + public Void visitDefault(DefaultAttribute attr, 8.1557 + ExpectedParameterAnnotation expected) { 8.1558 + return null; 8.1559 + } 8.1560 + 8.1561 + @Override 8.1562 + public Void visitAnnotationDefault(AnnotationDefault_attribute attr, 8.1563 + ExpectedParameterAnnotation expected) { 8.1564 + return null; 8.1565 + } 8.1566 + 8.1567 + @Override 8.1568 + public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, 8.1569 + ExpectedParameterAnnotation expected) { 8.1570 + return null; 8.1571 + } 8.1572 + 8.1573 + @Override 8.1574 + public Void visitCode(Code_attribute attr, 8.1575 + ExpectedParameterAnnotation expected) { 8.1576 + return null; 8.1577 + } 8.1578 + 8.1579 + @Override 8.1580 + public Void visitCompilationID(CompilationID_attribute attr, 8.1581 + ExpectedParameterAnnotation expected) { 8.1582 + return null; 8.1583 + } 8.1584 + 8.1585 + @Override 8.1586 + public Void visitConstantValue(ConstantValue_attribute attr, 8.1587 + ExpectedParameterAnnotation expected) { 8.1588 + return null; 8.1589 + } 8.1590 + 8.1591 + @Override 8.1592 + public Void visitDeprecated(Deprecated_attribute attr, 8.1593 + ExpectedParameterAnnotation expected) { 8.1594 + return null; 8.1595 + } 8.1596 + 8.1597 + @Override 8.1598 + public Void visitEnclosingMethod(EnclosingMethod_attribute attr, 8.1599 + ExpectedParameterAnnotation expected) { 8.1600 + return null; 8.1601 + } 8.1602 + 8.1603 + @Override 8.1604 + public Void visitExceptions(Exceptions_attribute attr, 8.1605 + ExpectedParameterAnnotation expected) { 8.1606 + return null; 8.1607 + } 8.1608 + 8.1609 + @Override 8.1610 + public Void visitInnerClasses(InnerClasses_attribute attr, 8.1611 + ExpectedParameterAnnotation expected) { 8.1612 + return null; 8.1613 + } 8.1614 + 8.1615 + @Override 8.1616 + public Void visitLineNumberTable(LineNumberTable_attribute attr, 8.1617 + ExpectedParameterAnnotation expected) { 8.1618 + return null; 8.1619 + } 8.1620 + 8.1621 + @Override 8.1622 + public Void visitLocalVariableTable(LocalVariableTable_attribute attr, 8.1623 + ExpectedParameterAnnotation expected) { 8.1624 + return null; 8.1625 + } 8.1626 + 8.1627 + @Override 8.1628 + public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, 8.1629 + ExpectedParameterAnnotation expected) { 8.1630 + return null; 8.1631 + } 8.1632 + 8.1633 + @Override 8.1634 + public Void visitMethodParameters(MethodParameters_attribute attr, 8.1635 + ExpectedParameterAnnotation expected) { 8.1636 + return null; 8.1637 + } 8.1638 + 8.1639 + @Override 8.1640 + public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, 8.1641 + ExpectedParameterAnnotation expected) { 8.1642 + return null; 8.1643 + } 8.1644 + 8.1645 + @Override 8.1646 + public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, 8.1647 + ExpectedParameterAnnotation expected) { 8.1648 + return null; 8.1649 + } 8.1650 + 8.1651 + @Override 8.1652 + public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, 8.1653 + ExpectedParameterAnnotation expected) { 8.1654 + return null; 8.1655 + } 8.1656 + 8.1657 + @Override 8.1658 + public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, 8.1659 + ExpectedParameterAnnotation expected) { 8.1660 + return null; 8.1661 + } 8.1662 + 8.1663 + @Override 8.1664 + public Void visitSignature(Signature_attribute attr, 8.1665 + ExpectedParameterAnnotation expected) { 8.1666 + return null; 8.1667 + } 8.1668 + 8.1669 + @Override 8.1670 + public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, 8.1671 + ExpectedParameterAnnotation expected) { 8.1672 + return null; 8.1673 + } 8.1674 + 8.1675 + @Override 8.1676 + public Void visitSourceFile(SourceFile_attribute attr, 8.1677 + ExpectedParameterAnnotation expected) { 8.1678 + return null; 8.1679 + } 8.1680 + 8.1681 + @Override 8.1682 + public Void visitSourceID(SourceID_attribute attr, 8.1683 + ExpectedParameterAnnotation expected) { 8.1684 + return null; 8.1685 + } 8.1686 + 8.1687 + @Override 8.1688 + public Void visitStackMap(StackMap_attribute attr, 8.1689 + ExpectedParameterAnnotation expected) { 8.1690 + return null; 8.1691 + } 8.1692 + 8.1693 + @Override 8.1694 + public Void visitStackMapTable(StackMapTable_attribute attr, 8.1695 + ExpectedParameterAnnotation expected) { 8.1696 + return null; 8.1697 + } 8.1698 + 8.1699 + @Override 8.1700 + public Void visitSynthetic(Synthetic_attribute attr, 8.1701 + ExpectedParameterAnnotation expected) { 8.1702 + return null; 8.1703 + } 8.1704 + 8.1705 + @Override 8.1706 + public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, 8.1707 + ExpectedParameterAnnotation expected) { 8.1708 + if (expected.matchVisibility(true)) { 8.1709 + if (expected.index < attr.parameter_annotations.length) { 8.1710 + for(Annotation anno : 8.1711 + attr.parameter_annotations[expected.index]) { 8.1712 + expected.matchAnnotation(cpool, anno); 8.1713 + } 8.1714 + } 8.1715 + } 8.1716 + 8.1717 + return null; 8.1718 + } 8.1719 + 8.1720 + @Override 8.1721 + public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, 8.1722 + ExpectedParameterAnnotation expected) { 8.1723 + if (expected.matchVisibility(false)) { 8.1724 + if (expected.index < attr.parameter_annotations.length) { 8.1725 + for(Annotation anno : 8.1726 + attr.parameter_annotations[expected.index]) { 8.1727 + expected.matchAnnotation(cpool, anno); 8.1728 + } 8.1729 + } 8.1730 + } 8.1731 + 8.1732 + return null; 8.1733 + } 8.1734 + }; 8.1735 + } 8.1736 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/test/tools/javac/8062359/UnresolvableClassNPEInAttrTest.java Fri Dec 12 14:57:02 2014 -0800 9.3 @@ -0,0 +1,17 @@ 9.4 +/* 9.5 + * @test /nodynamiccopyright/ 9.6 + * @bug 8062359 9.7 + * @summary NullPointerException in Attr when type-annotating an anonymous 9.8 + * inner class in an unresolvable class 9.9 + * @compile/fail/ref=UnresolvableClassNPEInAttrTest.out -XDrawDiagnostics UnresolvableClassNPEInAttrTest.java 9.10 + */ 9.11 + 9.12 +public class UnresolvableClassNPEInAttrTest { 9.13 + public static void main(String[] args) { 9.14 + new Undefined() { 9.15 + void test() { 9.16 + new Object() {}; 9.17 + } 9.18 + }; 9.19 + } 9.20 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/test/tools/javac/8062359/UnresolvableClassNPEInAttrTest.out Fri Dec 12 14:57:02 2014 -0800 10.3 @@ -0,0 +1,2 @@ 10.4 +UnresolvableClassNPEInAttrTest.java:11:13: compiler.err.cant.resolve.location: kindname.class, Undefined, , , (compiler.misc.location: kindname.class, UnresolvableClassNPEInAttrTest, null) 10.5 +1 error
11.1 --- a/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Mon Dec 01 11:39:34 2014 -0800 11.2 +++ b/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Fri Dec 12 14:57:02 2014 -0800 11.3 @@ -138,7 +138,7 @@ 11.4 checkClassFile(new File(Paths.get(System.getProperty("user.dir"), 11.5 "Foo.class").toUri()), "$deserializeLambda$", deserializeExpectedLNT); 11.6 checkClassFile(new File(Paths.get(System.getProperty("user.dir"), 11.7 - "Foo.class").toUri()), "lambda$MR$variablesInLambdas$notify$8bc4f5bd$1", lambdaBridgeExpectedLNT); 11.8 + "Foo.class").toUri()), "lambda$variablesInLambdas$3", lambdaBridgeExpectedLNT); 11.9 checkClassFile(new File(Paths.get(System.getProperty("user.dir"), 11.10 "Foo.class").toUri()), "assignLambda", assignmentExpectedLNT); 11.11 checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/test/tools/javac/T8059921/ForbidAccessToFieldUsingSuperTest.java Fri Dec 12 14:57:02 2014 -0800 12.3 @@ -0,0 +1,31 @@ 12.4 +/* 12.5 + * @test /nodynamiccopyright/ 12.6 + * @bug 8059921 12.7 + * @summary Missing compile error in Java 8 mode for Interface.super.field access 12.8 + * @compile/fail/ref=ForbidAccessToFieldUsingSuperTest.out -XDrawDiagnostics ForbidAccessToFieldUsingSuperTest.java 12.9 + */ 12.10 + 12.11 +public class ForbidAccessToFieldUsingSuperTest { 12.12 + class C { 12.13 + int m() { return 0; } 12.14 + } 12.15 + 12.16 + interface T { 12.17 + int f = 0; 12.18 + C c = null; 12.19 + default int mm() { 12.20 + return 0; 12.21 + } 12.22 + } 12.23 + 12.24 + interface T1 extends T {} 12.25 + 12.26 + class X implements T1 { 12.27 + int i = T1.super.f; //fail 12.28 + int j = T1.super.c.m(); //fail 12.29 + 12.30 + void foo(Runnable r) { 12.31 + foo(T1.super::mm); //should'n fail 12.32 + } 12.33 + } 12.34 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/test/tools/javac/T8059921/ForbidAccessToFieldUsingSuperTest.out Fri Dec 12 14:57:02 2014 -0800 13.3 @@ -0,0 +1,3 @@ 13.4 +ForbidAccessToFieldUsingSuperTest.java:24:19: compiler.err.not.encl.class: ForbidAccessToFieldUsingSuperTest.T1 13.5 +ForbidAccessToFieldUsingSuperTest.java:25:19: compiler.err.not.encl.class: ForbidAccessToFieldUsingSuperTest.T1 13.6 +2 errors
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/test/tools/javac/annotations/SyntheticParameters.java Fri Dec 12 14:57:02 2014 -0800 14.3 @@ -0,0 +1,198 @@ 14.4 +/* 14.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.7 + * 14.8 + * This code is free software; you can redistribute it and/or modify it 14.9 + * under the terms of the GNU General Public License version 2 only, as 14.10 + * published by the Free Software Foundation. 14.11 + * 14.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 14.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14.15 + * version 2 for more details (a copy is included in the LICENSE file that 14.16 + * accompanied this code). 14.17 + * 14.18 + * You should have received a copy of the GNU General Public License version 14.19 + * 2 along with this work; if not, write to the Free Software Foundation, 14.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 14.21 + * 14.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 14.23 + * or visit www.oracle.com if you need additional information or have any 14.24 + * questions. 14.25 + */ 14.26 + 14.27 +/* 14.28 + * @test SyntheticParameters 14.29 + * @bug 8065132 14.30 + * @summary Test generation of annotations on inner class parameters. 14.31 + * @library /lib/annotations/ 14.32 + * @run main SyntheticParameters 14.33 + */ 14.34 + 14.35 +import annotations.classfile.ClassfileInspector; 14.36 + 14.37 +import java.io.*; 14.38 +import java.lang.annotation.*; 14.39 + 14.40 +import com.sun.tools.classfile.*; 14.41 + 14.42 +public class SyntheticParameters extends ClassfileInspector { 14.43 + 14.44 + private static final String Inner_class = "SyntheticParameters$Inner.class"; 14.45 + private static final String Foo_class = "SyntheticParameters$Foo.class"; 14.46 + private static final Expected Inner_expected = 14.47 + new Expected("SyntheticParameters$Inner", 14.48 + null, 14.49 + null, 14.50 + new ExpectedParameterAnnotation[] { 14.51 + (ExpectedParameterAnnotation) 14.52 + // Assert there is no annotation on the 14.53 + // this$0 parameter. 14.54 + new ExpectedParameterAnnotation( 14.55 + "<init>", 14.56 + 0, 14.57 + "A", 14.58 + true, 14.59 + 0), 14.60 + (ExpectedParameterAnnotation) 14.61 + // Assert there is an annotation on the 14.62 + // first parameter. 14.63 + new ExpectedParameterAnnotation( 14.64 + "<init>", 14.65 + 1, 14.66 + "A", 14.67 + true, 14.68 + 1), 14.69 + (ExpectedParameterAnnotation) 14.70 + new ExpectedParameterAnnotation( 14.71 + "foo", 14.72 + 0, 14.73 + "A", 14.74 + true, 14.75 + 1), 14.76 + (ExpectedParameterAnnotation) 14.77 + new ExpectedParameterAnnotation( 14.78 + "foo", 14.79 + 1, 14.80 + "A", 14.81 + true, 14.82 + 0), 14.83 + (ExpectedParameterAnnotation) 14.84 + // Assert there is no annotation on the 14.85 + // this$0 parameter. 14.86 + new ExpectedParameterAnnotation( 14.87 + "<init>", 14.88 + 0, 14.89 + "B", 14.90 + false, 14.91 + 0), 14.92 + (ExpectedParameterAnnotation) 14.93 + // Assert there is an annotation on the 14.94 + // first parameter. 14.95 + new ExpectedParameterAnnotation( 14.96 + "<init>", 14.97 + 1, 14.98 + "B", 14.99 + false, 14.100 + 1), 14.101 + (ExpectedParameterAnnotation) 14.102 + new ExpectedParameterAnnotation( 14.103 + "foo", 14.104 + 0, 14.105 + "B", 14.106 + false, 14.107 + 1), 14.108 + (ExpectedParameterAnnotation) 14.109 + new ExpectedParameterAnnotation( 14.110 + "foo", 14.111 + 1, 14.112 + "B", 14.113 + false, 14.114 + 0) 14.115 + }, 14.116 + null); 14.117 + private static final Expected Foo_expected = 14.118 + new Expected("SyntheticParameters$Foo", 14.119 + null, 14.120 + null, 14.121 + new ExpectedParameterAnnotation[] { 14.122 + (ExpectedParameterAnnotation) 14.123 + // Assert there is no annotation on the 14.124 + // $enum$name parameter. 14.125 + new ExpectedParameterAnnotation( 14.126 + "<init>", 14.127 + 0, 14.128 + "A", 14.129 + true, 14.130 + 0), 14.131 + (ExpectedParameterAnnotation) 14.132 + // Assert there is no annotation on the 14.133 + // $enum$ordinal parameter. 14.134 + new ExpectedParameterAnnotation( 14.135 + "<init>", 14.136 + 1, 14.137 + "A", 14.138 + true, 14.139 + 0), 14.140 + (ExpectedParameterAnnotation) 14.141 + // Assert there is an annotation on the 14.142 + // first parameter. 14.143 + new ExpectedParameterAnnotation( 14.144 + "<init>", 14.145 + 2, 14.146 + "A", 14.147 + true, 14.148 + 1), 14.149 + (ExpectedParameterAnnotation) 14.150 + // Assert there is no annotation on the 14.151 + // $enum$name parameter. 14.152 + new ExpectedParameterAnnotation( 14.153 + "<init>", 14.154 + 0, 14.155 + "B", 14.156 + false, 14.157 + 0), 14.158 + (ExpectedParameterAnnotation) 14.159 + // Assert there is no annotation on the 14.160 + // $enum$ordinal parameter. 14.161 + new ExpectedParameterAnnotation( 14.162 + "<init>", 14.163 + 1, 14.164 + "B", 14.165 + false, 14.166 + 0), 14.167 + (ExpectedParameterAnnotation) 14.168 + // Assert there is an annotation on the 14.169 + // first parameter. 14.170 + new ExpectedParameterAnnotation( 14.171 + "<init>", 14.172 + 2, 14.173 + "B", 14.174 + false, 14.175 + 1) 14.176 + }, 14.177 + null); 14.178 + 14.179 + public static void main(String... args) throws Exception { 14.180 + new SyntheticParameters().run( 14.181 + new ClassFile[] { getClassFile(Inner_class, Inner.class), 14.182 + getClassFile(Foo_class, Foo.class) }, 14.183 + new Expected[] { Inner_expected, Foo_expected }); 14.184 + } 14.185 + 14.186 + public class Inner { 14.187 + public Inner(@A @B int a) {} 14.188 + public void foo(@A @B int a, int b) {} 14.189 + } 14.190 + 14.191 + public static enum Foo { 14.192 + ONE(null); 14.193 + Foo(@A @B Object a) {} 14.194 + } 14.195 +} 14.196 + 14.197 +@Retention(RetentionPolicy.RUNTIME) 14.198 +@interface A {} 14.199 + 14.200 +@Retention(RetentionPolicy.CLASS) 14.201 +@interface B {}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/test/tools/javac/annotations/typeAnnotations/classfile/SyntheticParameters.java Fri Dec 12 14:57:02 2014 -0800 15.3 @@ -0,0 +1,133 @@ 15.4 +/* 15.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.7 + * 15.8 + * This code is free software; you can redistribute it and/or modify it 15.9 + * under the terms of the GNU General Public License version 2 only, as 15.10 + * published by the Free Software Foundation. 15.11 + * 15.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 15.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15.15 + * version 2 for more details (a copy is included in the LICENSE file that 15.16 + * accompanied this code). 15.17 + * 15.18 + * You should have received a copy of the GNU General Public License version 15.19 + * 2 along with this work; if not, write to the Free Software Foundation, 15.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 15.21 + * 15.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 15.23 + * or visit www.oracle.com if you need additional information or have any 15.24 + * questions. 15.25 + */ 15.26 + 15.27 +/* 15.28 + * @test SyntheticParameters 15.29 + * @summary Test generation of annotations on inner class parameters. 15.30 + * @library /lib/annotations/ 15.31 + * @run main SyntheticParameters 15.32 + */ 15.33 + 15.34 +import annotations.classfile.ClassfileInspector; 15.35 + 15.36 +import java.io.*; 15.37 +import java.lang.annotation.*; 15.38 + 15.39 +import com.sun.tools.classfile.*; 15.40 + 15.41 +public class SyntheticParameters extends ClassfileInspector { 15.42 + 15.43 + private static final String Inner_class = "SyntheticParameters$Inner.class"; 15.44 + private static final String Foo_class = "SyntheticParameters$Foo.class"; 15.45 + private static final Expected Inner_expected = 15.46 + new Expected("SyntheticParameters$Inner", 15.47 + null, 15.48 + new ExpectedMethodTypeAnnotation[] { 15.49 + (ExpectedMethodTypeAnnotation) 15.50 + // Assert there is no annotation on the 15.51 + // this$0 parameter. 15.52 + new ExpectedMethodTypeAnnotation.Builder( 15.53 + "<init>", 15.54 + "A", 15.55 + TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, 15.56 + false, 15.57 + 0).setParameterIndex(0).build(), 15.58 + (ExpectedMethodTypeAnnotation) 15.59 + // Assert there is an annotation on the 15.60 + // first parameter. 15.61 + new ExpectedMethodTypeAnnotation.Builder( 15.62 + "<init>", 15.63 + "A", 15.64 + TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, 15.65 + false, 15.66 + 1).setParameterIndex(1).build(), 15.67 + (ExpectedMethodTypeAnnotation) 15.68 + new ExpectedMethodTypeAnnotation.Builder( 15.69 + "foo", 15.70 + "A", 15.71 + TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, 15.72 + false, 15.73 + 1).setParameterIndex(0).build(), 15.74 + (ExpectedMethodTypeAnnotation) 15.75 + new ExpectedMethodTypeAnnotation.Builder( 15.76 + "foo", 15.77 + "A", 15.78 + TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, 15.79 + false, 15.80 + 0).setParameterIndex(1).build() 15.81 + }, 15.82 + null); 15.83 + private static final Expected Foo_expected = 15.84 + new Expected("SyntheticParameters$Foo", 15.85 + null, 15.86 + new ExpectedMethodTypeAnnotation[] { 15.87 + (ExpectedMethodTypeAnnotation) 15.88 + // Assert there is no annotation on the 15.89 + // $enum$name parameter. 15.90 + new ExpectedMethodTypeAnnotation.Builder( 15.91 + "<init>", 15.92 + "A", 15.93 + TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, 15.94 + false, 15.95 + 0).setParameterIndex(0).build(), 15.96 + (ExpectedMethodTypeAnnotation) 15.97 + // Assert there is no annotation on the 15.98 + // $enum$ordinal parameter. 15.99 + new ExpectedMethodTypeAnnotation.Builder( 15.100 + "<init>", 15.101 + "A", 15.102 + TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, 15.103 + false, 15.104 + 0).setParameterIndex(1).build(), 15.105 + (ExpectedMethodTypeAnnotation) 15.106 + // Assert there is an annotation on the 15.107 + // first parameter. 15.108 + new ExpectedMethodTypeAnnotation.Builder( 15.109 + "<init>", 15.110 + "A", 15.111 + TypeAnnotation.TargetType.METHOD_FORMAL_PARAMETER, 15.112 + false, 15.113 + 1).setParameterIndex(2).build() 15.114 + }, 15.115 + null); 15.116 + 15.117 + public static void main(String... args) throws Exception { 15.118 + new SyntheticParameters().run( 15.119 + new ClassFile[] { getClassFile(Inner_class, Inner.class), 15.120 + getClassFile(Foo_class, Foo.class) }, 15.121 + new Expected[] { Inner_expected, Foo_expected }); 15.122 + } 15.123 + 15.124 + public class Inner { 15.125 + public Inner(@A int a) {} 15.126 + public void foo(@A int a, int b) {} 15.127 + } 15.128 + 15.129 + public static enum Foo { 15.130 + ONE(null); 15.131 + Foo(@A Object a) {} 15.132 + } 15.133 +} 15.134 + 15.135 +@Target({ElementType.TYPE_USE}) 15.136 +@interface A {}
16.1 --- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java Mon Dec 01 11:39:34 2014 -0800 16.2 +++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java Fri Dec 12 14:57:02 2014 -0800 16.3 @@ -46,7 +46,7 @@ 16.4 @TADescriptions({ 16.5 @TADescription(annotation = "TA", type = METHOD_RETURN, genericLocation = {1, 0}), 16.6 @TADescription(annotation = "TB", type = METHOD_RETURN, genericLocation = {1, 0}), 16.7 - @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) 16.8 + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 1) 16.9 }) 16.10 @TestClass("Test$Inner") 16.11 public String innerClass() { 16.12 @@ -61,7 +61,7 @@ 16.13 @TADescription(annotation = "TB", type = METHOD_RETURN, genericLocation = {1, 0}), 16.14 @TADescription(annotation = "TC", type = METHOD_RECEIVER), 16.15 @TADescription(annotation = "TD", type = METHOD_RETURN, genericLocation = {1, 0}), 16.16 - @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) 16.17 + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, paramIndex = 1) 16.18 }) 16.19 @TestClass("Test$Inner") 16.20 public String innerClass2() { 16.21 @@ -77,7 +77,7 @@ 16.22 @TADescription(annotation = "TC", type = METHOD_RETURN, genericLocation = {1, 0, 1, 0}), 16.23 @TADescription(annotation = "TD", type = METHOD_RECEIVER, genericLocation = {1, 0}), 16.24 @TADescription(annotation = "TE", type = METHOD_RETURN, genericLocation = {1, 0, 1, 0}), 16.25 - @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) 16.26 + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, paramIndex = 1) 16.27 }) 16.28 @TestClass("Outer$Middle$Inner") 16.29 public String innerClass3() {
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/test/tools/javac/flow/T8062747.java Fri Dec 12 14:57:02 2014 -0800 17.3 @@ -0,0 +1,24 @@ 17.4 +/** 17.5 + * @test 17.6 + * @bug 8062747 17.7 + * @summary Avoiding an error for lambdas with thrown types inference inside an anonymous class. 17.8 + * @compile T8062747.java 17.9 + */ 17.10 +public class T8062747 { 17.11 + 17.12 + public interface Throwing<Y extends Exception> { 17.13 + void canThrow() throws Y; 17.14 + } 17.15 + 17.16 + public static <Y extends Exception> void wrap(Throwing<Y> action) { 17.17 + } 17.18 + 17.19 + public static void invoke(String a) { 17.20 + Runnable r = new Runnable() { 17.21 + @Override 17.22 + public void run() { 17.23 + wrap(() -> System.out.println(a)); 17.24 + } 17.25 + }; 17.26 + } 17.27 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/test/tools/javac/lambda/T8057794.java Fri Dec 12 14:57:02 2014 -0800 18.3 @@ -0,0 +1,12 @@ 18.4 +/** 18.5 + * @test /nodynamiccopyright/ 18.6 + * @bug 8057794 18.7 + * @summary The tree for TypeVar.class does not have a type set, which leads to an NPE when 18.8 + * checking if deferred attribution is needed 18.9 + * @compile/fail/ref=T8057794.out -XDrawDiagnostics T8057794.java 18.10 + */ 18.11 +class T8057794<T> { 18.12 + void t() { 18.13 + System.out.println(T.class.getSimpleName()); 18.14 + } 18.15 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/test/tools/javac/lambda/T8057794.out Fri Dec 12 14:57:02 2014 -0800 19.3 @@ -0,0 +1,2 @@ 19.4 +T8057794.java:10:29: compiler.err.type.var.cant.be.deref 19.5 +1 error
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/test/tools/javac/lambda/methodReference/MethodRef8.java Fri Dec 12 14:57:02 2014 -0800 20.3 @@ -0,0 +1,43 @@ 20.4 +/* 20.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.7 + * 20.8 + * This code is free software; you can redistribute it and/or modify it 20.9 + * under the terms of the GNU General Public License version 2 only, as 20.10 + * published by the Free Software Foundation. 20.11 + * 20.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 20.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20.15 + * version 2 for more details (a copy is included in the LICENSE file that 20.16 + * accompanied this code). 20.17 + * 20.18 + * You should have received a copy of the GNU General Public License version 20.19 + * 2 along with this work; if not, write to the Free Software Foundation, 20.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20.21 + * 20.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20.23 + * or visit www.oracle.com if you need additional information or have any 20.24 + * questions. 20.25 + */ 20.26 + 20.27 +/** 20.28 + * @test 20.29 + * @bug 8063052 20.30 + * @summary Inference chokes on wildcard derived from method reference 20.31 + * @compile MethodRef8.java 20.32 + */ 20.33 + 20.34 +public class MethodRef8 { 20.35 + void test(Box<? extends Box<? extends Number>> b) { 20.36 + Number n1 = b.map(Box::get).get(); 20.37 + Number n2 = b.<Number>map(Box::get).get(); 20.38 + } 20.39 + 20.40 + interface Func<S,T> { T apply(S arg); } 20.41 + 20.42 + interface Box<T> { 20.43 + T get(); 20.44 + <R> Box<R> map(Func<T,R> f); 20.45 + } 20.46 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerBootstrap.java Fri Dec 12 14:57:02 2014 -0800 21.3 @@ -0,0 +1,72 @@ 21.4 +/* 21.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.7 + * 21.8 + * This code is free software; you can redistribute it and/or modify it 21.9 + * under the terms of the GNU General Public License version 2 only, as 21.10 + * published by the Free Software Foundation. 21.11 + * 21.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 21.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21.15 + * version 2 for more details (a copy is included in the LICENSE file that 21.16 + * accompanied this code). 21.17 + * 21.18 + * You should have received a copy of the GNU General Public License version 21.19 + * 2 along with this work; if not, write to the Free Software Foundation, 21.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21.21 + * 21.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21.23 + * or visit www.oracle.com if you need additional information or have any 21.24 + * questions. 21.25 + */ 21.26 + 21.27 +/** 21.28 + * @test 21.29 + * @bug 8044748 21.30 + * @summary JVM cannot access constructor though ::new reference although can call it directly 21.31 + */ 21.32 + 21.33 +public class MethodRefNewInnerBootstrap { 21.34 + 21.35 + interface Constructor { 21.36 + public MyTest execute(int i); 21.37 + } 21.38 + 21.39 + public class MyTest { 21.40 + public MyTest(int i) { System.out.println("Constructor executed " + i); } 21.41 + } 21.42 + 21.43 + public Constructor getConstructor() { 21.44 + return MyTest::new; 21.45 + } 21.46 + 21.47 + public static void main(String argv[]) { 21.48 + new MethodRefNewInnerBootstrap().call(); 21.49 + } 21.50 + 21.51 + public void call() { 21.52 + MyTest mt = new MyTest(0); 21.53 + 21.54 + Constructor c1 = MyTest::new; 21.55 + c1.execute(1); 21.56 + 21.57 + Constructor c2 = getConstructor(); 21.58 + c2.execute(2); 21.59 + 21.60 + Constructor c3 = new Constructor() { 21.61 + public MyTest execute(int i) { 21.62 + return new MyTest(3); 21.63 + } 21.64 + }; 21.65 + c3.execute(3); 21.66 + 21.67 + Constructor c4 = new Constructor() { 21.68 + public MyTest execute(int i) { 21.69 + Constructor c = MyTest::new; 21.70 + return c.execute(i); 21.71 + } 21.72 + }; 21.73 + c4.execute(4); 21.74 + } 21.75 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaNPE1.java Fri Dec 12 14:57:02 2014 -0800 22.3 @@ -0,0 +1,48 @@ 22.4 +/* 22.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.7 + * 22.8 + * This code is free software; you can redistribute it and/or modify it 22.9 + * under the terms of the GNU General Public License version 2 only, as 22.10 + * published by the Free Software Foundation. 22.11 + * 22.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 22.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 22.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 22.15 + * version 2 for more details (a copy is included in the LICENSE file that 22.16 + * accompanied this code). 22.17 + * 22.18 + * You should have received a copy of the GNU General Public License version 22.19 + * 2 along with this work; if not, write to the Free Software Foundation, 22.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22.21 + * 22.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22.23 + * or visit www.oracle.com if you need additional information or have any 22.24 + * questions. 22.25 + */ 22.26 + 22.27 +/** 22.28 + * @test 22.29 + * @bug 8037404 22.30 + * @summary javac NPE or VerifyError for code with constructor reference of inner class 22.31 + */ 22.32 + 22.33 +import java.util.function.Supplier; 22.34 +import java.util.stream.Stream; 22.35 + 22.36 +public class MethodRefNewInnerInLambdaNPE1 { 22.37 + public static void main(String[] args) { 22.38 + if (new MethodRefNewInnerInLambdaNPE1().getList().get().getClass() != TT.class) 22.39 + throw new AssertionError("sanity failed"); 22.40 + } 22.41 + 22.42 + Supplier<TT> getList() { 22.43 + return () -> Stream.of(1).map(TT::new).findFirst().get(); 22.44 + } 22.45 + 22.46 + class TT { 22.47 + public TT(int i) { 22.48 + 22.49 + } 22.50 + } 22.51 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaNPE2.java Fri Dec 12 14:57:02 2014 -0800 23.3 @@ -0,0 +1,57 @@ 23.4 +/* 23.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.7 + * 23.8 + * This code is free software; you can redistribute it and/or modify it 23.9 + * under the terms of the GNU General Public License version 2 only, as 23.10 + * published by the Free Software Foundation. 23.11 + * 23.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 23.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23.15 + * version 2 for more details (a copy is included in the LICENSE file that 23.16 + * accompanied this code). 23.17 + * 23.18 + * You should have received a copy of the GNU General Public License version 23.19 + * 2 along with this work; if not, write to the Free Software Foundation, 23.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23.21 + * 23.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23.23 + * or visit www.oracle.com if you need additional information or have any 23.24 + * questions. 23.25 + */ 23.26 + 23.27 +/** 23.28 + * @test 23.29 + * @bug 8044737 23.30 + * @summary Lambda: NPE while obtaining method reference through lambda expression 23.31 + * @compile MethodRefNewInnerInLambdaNPE2.java 23.32 + */ 23.33 + 23.34 +public class MethodRefNewInnerInLambdaNPE2 { 23.35 + 23.36 + interface Constructor { 23.37 + MyTest execute(); 23.38 + } 23.39 + 23.40 + class MyTest { 23.41 + MyTest() { System.out.println("Constructor executed"); } 23.42 + } 23.43 + 23.44 + public Constructor getConstructor() { 23.45 + return getConstructor(() -> { return MyTest::new; }); 23.46 + } 23.47 + 23.48 + public static void main(String argv[]) { 23.49 + MethodRefNewInnerInLambdaNPE2 t = new MethodRefNewInnerInLambdaNPE2(); 23.50 + MyTest mytest = t.getConstructor().execute(); 23.51 + } 23.52 + 23.53 + Constructor getConstructor(Wrapper arg) { 23.54 + return arg.unwrap(); 23.55 + } 23.56 + 23.57 + interface Wrapper { 23.58 + Constructor unwrap(); 23.59 + } 23.60 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaVerify1.java Fri Dec 12 14:57:02 2014 -0800 24.3 @@ -0,0 +1,48 @@ 24.4 +/* 24.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.7 + * 24.8 + * This code is free software; you can redistribute it and/or modify it 24.9 + * under the terms of the GNU General Public License version 2 only, as 24.10 + * published by the Free Software Foundation. 24.11 + * 24.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 24.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 24.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 24.15 + * version 2 for more details (a copy is included in the LICENSE file that 24.16 + * accompanied this code). 24.17 + * 24.18 + * You should have received a copy of the GNU General Public License version 24.19 + * 2 along with this work; if not, write to the Free Software Foundation, 24.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 24.21 + * 24.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 24.23 + * or visit www.oracle.com if you need additional information or have any 24.24 + * questions. 24.25 + */ 24.26 + 24.27 +/** 24.28 + * @test 24.29 + * @bug 8037404 24.30 + * @summary javac NPE or VerifyError for code with constructor reference of inner class 24.31 + */ 24.32 + 24.33 +import java.util.function.Function; 24.34 +import java.util.stream.Stream; 24.35 + 24.36 +public class MethodRefNewInnerInLambdaVerify1 { 24.37 + public static void main(String[] args) { 24.38 + if (new MethodRefNewInnerInLambdaVerify1().map().apply(1).getClass() != TT.class) 24.39 + throw new AssertionError("sanity failed"); 24.40 + } 24.41 + 24.42 + Function<Integer,TT> map() { 24.43 + return (i) -> Stream.of(i).map(TT::new).findFirst().get(); 24.44 + } 24.45 + 24.46 + class TT { 24.47 + public TT(int i) { 24.48 + 24.49 + } 24.50 + } 24.51 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaVerify2.java Fri Dec 12 14:57:02 2014 -0800 25.3 @@ -0,0 +1,62 @@ 25.4 +/* 25.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 25.7 + * 25.8 + * This code is free software; you can redistribute it and/or modify it 25.9 + * under the terms of the GNU General Public License version 2 only, as 25.10 + * published by the Free Software Foundation. 25.11 + * 25.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 25.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 25.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25.15 + * version 2 for more details (a copy is included in the LICENSE file that 25.16 + * accompanied this code). 25.17 + * 25.18 + * You should have received a copy of the GNU General Public License version 25.19 + * 2 along with this work; if not, write to the Free Software Foundation, 25.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 25.21 + * 25.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 25.23 + * or visit www.oracle.com if you need additional information or have any 25.24 + * questions. 25.25 + */ 25.26 + 25.27 +/** 25.28 + * @test 25.29 + * @bug 8038776 25.30 + * @summary VerifyError when running successfully compiled java class 25.31 + */ 25.32 + 25.33 +import java.util.function.Function; 25.34 + 25.35 +/** 25.36 + * Derived from code by: 25.37 + * @author Yawkat 25.38 + */ 25.39 +public class MethodRefNewInnerInLambdaVerify2 { 25.40 + public static void main(String[] args) { new MethodRefNewInnerInLambdaVerify2().runTest(); } 25.41 + 25.42 + private void runTest() { 25.43 + Worker worker = new Worker(); 25.44 + run(() -> worker.check(field -> new SomeClass(field))); 25.45 + run(() -> worker.check(SomeClass::new)); 25.46 + } 25.47 + 25.48 + private void run(Runnable runnable) { 25.49 + runnable.run(); 25.50 + } 25.51 + 25.52 + private class SomeClass { 25.53 + final Object field; 25.54 + 25.55 + SomeClass(Object field) { 25.56 + this.field = field; 25.57 + } 25.58 + } 25.59 + 25.60 + private static class Worker { 25.61 + void check(Function<Object, SomeClass> i) { 25.62 + if (!i.apply("frank").field.equals("frank")) throw new AssertionError("sanity failed"); 25.63 + } 25.64 + } 25.65 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaVerify2simple.java Fri Dec 12 14:57:02 2014 -0800 26.3 @@ -0,0 +1,50 @@ 26.4 +/* 26.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 26.7 + * 26.8 + * This code is free software; you can redistribute it and/or modify it 26.9 + * under the terms of the GNU General Public License version 2 only, as 26.10 + * published by the Free Software Foundation. 26.11 + * 26.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 26.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 26.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26.15 + * version 2 for more details (a copy is included in the LICENSE file that 26.16 + * accompanied this code). 26.17 + * 26.18 + * You should have received a copy of the GNU General Public License version 26.19 + * 2 along with this work; if not, write to the Free Software Foundation, 26.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26.21 + * 26.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 26.23 + * or visit www.oracle.com if you need additional information or have any 26.24 + * questions. 26.25 + */ 26.26 + 26.27 +/** 26.28 + * @test 26.29 + * @bug 8038776 26.30 + * @summary VerifyError when running successfully compiled java class 26.31 + */ 26.32 + 26.33 +import java.util.function.Function; 26.34 + 26.35 +/** 26.36 + * Derived from code by: 26.37 + * @author Yawkat 26.38 + */ 26.39 +public class MethodRefNewInnerInLambdaVerify2simple { 26.40 + public static void main(String[] args) { new MethodRefNewInnerInLambdaVerify2simple().runTest(); } 26.41 + 26.42 + private void runTest() { 26.43 + Runnable r = (() -> { Sup w = SomeClass::new; } ); 26.44 + } 26.45 + 26.46 + private class SomeClass { 26.47 + SomeClass() { } 26.48 + } 26.49 +} 26.50 + 26.51 +interface Sup { 26.52 + Object get(); 26.53 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/test/tools/javac/lambda/methodReference/MethodRefQualifier1.java Fri Dec 12 14:57:02 2014 -0800 27.3 @@ -0,0 +1,62 @@ 27.4 +/* 27.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 27.7 + * 27.8 + * This code is free software; you can redistribute it and/or modify it 27.9 + * under the terms of the GNU General Public License version 2 only, as 27.10 + * published by the Free Software Foundation. 27.11 + * 27.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 27.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 27.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 27.15 + * version 2 for more details (a copy is included in the LICENSE file that 27.16 + * accompanied this code). 27.17 + * 27.18 + * You should have received a copy of the GNU General Public License version 27.19 + * 2 along with this work; if not, write to the Free Software Foundation, 27.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 27.21 + * 27.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 27.23 + * or visit www.oracle.com if you need additional information or have any 27.24 + * questions. 27.25 + */ 27.26 + 27.27 +/** 27.28 + * @test 27.29 + * @bug 8048121 27.30 + * @summary javac complex method references: revamp and simplify 27.31 + */ 27.32 + 27.33 +public class MethodRefQualifier1 { 27.34 + 27.35 + interface SAM { 27.36 + void m(); 27.37 + } 27.38 + 27.39 + static int count = 0; 27.40 + 27.41 + static void assertTrue(boolean cond, String msg) { 27.42 + if (!cond) 27.43 + throw new AssertionError(msg); 27.44 + } 27.45 + 27.46 + MethodRefQualifier1 check() { 27.47 + count++; 27.48 + return this; 27.49 + } 27.50 + 27.51 + void ido(Object... args) { } 27.52 + 27.53 + public static void main(String[] args) { 27.54 + new MethodRefQualifier1().test(); 27.55 + } 27.56 + 27.57 + void test() { 27.58 + count = 0; 27.59 + SAM s = check()::ido; 27.60 + assertTrue(count == 1, "creation: unexpected: " + count); 27.61 + count = 0; 27.62 + s.m(); 27.63 + assertTrue(count == 0, "evaluation: unexpected: " + count); 27.64 + } 27.65 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/test/tools/javac/lambda/methodReference/MethodRefSingleRefEvalBridge.java Fri Dec 12 14:57:02 2014 -0800 28.3 @@ -0,0 +1,70 @@ 28.4 +/* 28.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 28.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 28.7 + * 28.8 + * This code is free software; you can redistribute it and/or modify it 28.9 + * under the terms of the GNU General Public License version 2 only, as 28.10 + * published by the Free Software Foundation. 28.11 + * 28.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 28.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 28.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 28.15 + * version 2 for more details (a copy is included in the LICENSE file that 28.16 + * accompanied this code). 28.17 + * 28.18 + * You should have received a copy of the GNU General Public License version 28.19 + * 2 along with this work; if not, write to the Free Software Foundation, 28.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 28.21 + * 28.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28.23 + * or visit www.oracle.com if you need additional information or have any 28.24 + * questions. 28.25 + */ 28.26 + 28.27 +/** 28.28 + * @test 28.29 + * @bug 8048121 28.30 + * @summary javac complex method references: revamp and simplify 28.31 + * 28.32 + * Make sure that the method reference receiver is evaluated exactly once 28.33 + * even in this bridging case. 28.34 + */ 28.35 + 28.36 + public class MethodRefSingleRefEvalBridge { 28.37 + 28.38 + interface SAM { 28.39 + int m(); 28.40 + } 28.41 + 28.42 + class ZZ { 28.43 + // private to force bridging 28.44 + private int four() { return 4; } 28.45 + } 28.46 + 28.47 + static int count = 0; 28.48 + ZZ azz = new ZZ(); 28.49 + 28.50 + static void assertEqual(int expected, int got) { 28.51 + if (got != expected) 28.52 + throw new AssertionError("Expected " + expected + " got " + got); 28.53 + } 28.54 + 28.55 + public static void main(String[] args) { 28.56 + new MethodRefSingleRefEvalBridge().test(); 28.57 + } 28.58 + 28.59 + ZZ check() { 28.60 + count++; 28.61 + return azz; 28.62 + } 28.63 + 28.64 + void test() { 28.65 + count = 0; 28.66 + SAM s = check()::four; 28.67 + assertEqual(1, count); 28.68 + 28.69 + count = 0; 28.70 + assertEqual(4, s.m()); 28.71 + assertEqual(0, count); 28.72 + } 28.73 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/test/tools/javac/lambda/methodReference/MethodRefToInner.java Fri Dec 12 14:57:02 2014 -0800 29.3 @@ -0,0 +1,52 @@ 29.4 +/* 29.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.7 + * 29.8 + * This code is free software; you can redistribute it and/or modify it 29.9 + * under the terms of the GNU General Public License version 2 only, as 29.10 + * published by the Free Software Foundation. 29.11 + * 29.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 29.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 29.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 29.15 + * version 2 for more details (a copy is included in the LICENSE file that 29.16 + * accompanied this code). 29.17 + * 29.18 + * You should have received a copy of the GNU General Public License version 29.19 + * 2 along with this work; if not, write to the Free Software Foundation, 29.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 29.21 + * 29.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 29.23 + * or visit www.oracle.com if you need additional information or have any 29.24 + * questions. 29.25 + */ 29.26 + 29.27 +/** 29.28 + * @test 29.29 + * @bug 8047341 29.30 + * @summary lambda reference to inner class in base class causes LambdaConversionException 29.31 + */ 29.32 + 29.33 +import java.util.List; 29.34 +import java.util.ArrayList; 29.35 + 29.36 +class MethodRefToInnerBase { 29.37 + class TestString { 29.38 + String str; 29.39 + TestString(String strin) { 29.40 + str = strin; 29.41 + } 29.42 + } 29.43 +} 29.44 +public class MethodRefToInner extends MethodRefToInnerBase { 29.45 + public static void main(String[] args) { 29.46 + new MethodRefToInner().run(); 29.47 + } 29.48 + MethodRefToInner() { 29.49 + super(); 29.50 + } 29.51 + void run() { 29.52 + List<String> list = new ArrayList<>(); 29.53 + list.stream().forEach(TestString::new); 29.54 + } 29.55 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/test/tools/javac/lambda/methodReference/MethodReferenceComplexNullCheckTest.java Fri Dec 12 14:57:02 2014 -0800 30.3 @@ -0,0 +1,54 @@ 30.4 +/* 30.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.7 + * 30.8 + * This code is free software; you can redistribute it and/or modify it 30.9 + * under the terms of the GNU General Public License version 2 only, as 30.10 + * published by the Free Software Foundation. Oracle designates this 30.11 + * particular file as subject to the "Classpath" exception as provided 30.12 + * by Oracle in the LICENSE file that accompanied this code. 30.13 + * 30.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 30.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 30.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 30.17 + * version 2 for more details (a copy is included in the LICENSE file that 30.18 + * accompanied this code). 30.19 + * 30.20 + * You should have received a copy of the GNU General Public License version 30.21 + * 2 along with this work; if not, write to the Free Software Foundation, 30.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 30.23 + * 30.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 30.25 + * or visit www.oracle.com if you need additional information or have any 30.26 + * questions. 30.27 + */ 30.28 + 30.29 +/** 30.30 + * @test 30.31 + * @bug 8048121 30.32 + * @summary javac complex method references: revamp and simplify 30.33 + * 30.34 + * Make sure NPE check is done even in the convert to Lambda case 30.35 + */ 30.36 + 30.37 +public class MethodReferenceComplexNullCheckTest { 30.38 + public static void main(String[] args) { 30.39 + F fr = null; 30.40 + boolean npeFired = false; 30.41 + try { 30.42 + IForm frf = fr::doit; 30.43 + } catch (NullPointerException npe) { 30.44 + npeFired = true; 30.45 + } finally { 30.46 + if (!npeFired) throw new AssertionError( "NPE should have been thrown"); 30.47 + } 30.48 + } 30.49 + 30.50 + interface IForm { 30.51 + void xyz(Object... args); 30.52 + } 30.53 + 30.54 + class F { 30.55 + private void doit(Object... args) { } 30.56 + } 30.57 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection1.java Fri Dec 12 14:57:02 2014 -0800 31.3 @@ -0,0 +1,88 @@ 31.4 +/* 31.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.7 + * 31.8 + * This code is free software; you can redistribute it and/or modify it 31.9 + * under the terms of the GNU General Public License version 2 only, as 31.10 + * published by the Free Software Foundation. Oracle designates this 31.11 + * particular file as subject to the "Classpath" exception as provided 31.12 + * by Oracle in the LICENSE file that accompanied this code. 31.13 + * 31.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 31.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 31.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 31.17 + * version 2 for more details (a copy is included in the LICENSE file that 31.18 + * accompanied this code). 31.19 + * 31.20 + * You should have received a copy of the GNU General Public License version 31.21 + * 2 along with this work; if not, write to the Free Software Foundation, 31.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 31.23 + * 31.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 31.25 + * or visit www.oracle.com if you need additional information or have any 31.26 + * questions. 31.27 + */ 31.28 + 31.29 +/** 31.30 + * @test 31.31 + * @bug 8058112 31.32 + * @summary Invalid BootstrapMethod for constructor/method reference 31.33 + */ 31.34 + 31.35 +import java.util.Arrays; 31.36 +import java.util.Comparator; 31.37 +import java.util.List; 31.38 + 31.39 +import static java.util.stream.Collectors.toList; 31.40 + 31.41 +public class MethodReferenceIntersection1 { 31.42 + 31.43 + public static void main(String[] args) { 31.44 + MethodReferenceIntersection1 main = new MethodReferenceIntersection1(); 31.45 + List<Info_MRI1> list = main.toInfoListError(Arrays.asList(new Base_MRI1())); 31.46 + System.out.printf("result %d\n", list.size()); 31.47 + } 31.48 + 31.49 + public <H extends B_MRI1 & A_MRI1> List<Info_MRI1> toInfoListError(List<H> list) { 31.50 + Comparator<B_MRI1> byNameComparator = 31.51 + (B_MRI1 b1, B_MRI1 b2) -> b1.getB().compareToIgnoreCase(b2.getB()); 31.52 + return list.stream().sorted(byNameComparator).map(Info_MRI1::new).collect(toList()); 31.53 + } 31.54 + 31.55 + public <H extends B_MRI1 & A_MRI1> List<Info_MRI1> toInfoListWorks(List<H> list) { 31.56 + Comparator<B_MRI1> byNameComparator = 31.57 + (B_MRI1 b1, B_MRI1 b2) -> b1.getB().compareToIgnoreCase(b2.getB()); 31.58 + return list.stream().sorted(byNameComparator).map(s -> new Info_MRI1(s)).collect(toList()); 31.59 + } 31.60 +} 31.61 + 31.62 +interface B_MRI1 { 31.63 + public String getB(); 31.64 +} 31.65 + 31.66 +interface A_MRI1 { 31.67 + public long getA(); 31.68 +} 31.69 + 31.70 +class Info_MRI1 { 31.71 + private final long a; 31.72 + private final String b; 31.73 + 31.74 + <H extends A_MRI1 & B_MRI1> Info_MRI1(H h) { 31.75 + a = h.getA(); 31.76 + b = h.getB(); 31.77 + } 31.78 +} 31.79 + 31.80 +class Base_MRI1 implements A_MRI1, B_MRI1 { 31.81 + 31.82 + @Override 31.83 + public long getA() { 31.84 + return 7L; 31.85 + } 31.86 + 31.87 + @Override 31.88 + public String getB() { 31.89 + return "hello"; 31.90 + } 31.91 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection2.java Fri Dec 12 14:57:02 2014 -0800 32.3 @@ -0,0 +1,68 @@ 32.4 +/* 32.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.7 + * 32.8 + * This code is free software; you can redistribute it and/or modify it 32.9 + * under the terms of the GNU General Public License version 2 only, as 32.10 + * published by the Free Software Foundation. Oracle designates this 32.11 + * particular file as subject to the "Classpath" exception as provided 32.12 + * by Oracle in the LICENSE file that accompanied this code. 32.13 + * 32.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 32.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 32.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 32.17 + * version 2 for more details (a copy is included in the LICENSE file that 32.18 + * accompanied this code). 32.19 + * 32.20 + * You should have received a copy of the GNU General Public License version 32.21 + * 2 along with this work; if not, write to the Free Software Foundation, 32.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 32.23 + * 32.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 32.25 + * or visit www.oracle.com if you need additional information or have any 32.26 + * questions. 32.27 + */ 32.28 + 32.29 +/** 32.30 + * @test 32.31 + * @bug 8058112 32.32 + * @summary Invalid BootstrapMethod for constructor/method reference 32.33 + */ 32.34 + 32.35 +import java.util.function.Function; 32.36 + 32.37 +public class MethodReferenceIntersection2 { 32.38 + 32.39 + interface B { } 32.40 + 32.41 + interface A { } 32.42 + 32.43 + static class C implements A, B { } 32.44 + 32.45 + static class Info { 32.46 + <H extends A & B> Info(H h) { } 32.47 + 32.48 + static <H extends A & B> Info info(H h) { 32.49 + return new Info(h); 32.50 + } 32.51 + } 32.52 + 32.53 + public static void main(String[] args) { 32.54 + test(); 32.55 + } 32.56 + 32.57 + // Note the switch in order compared to that on Info 32.58 + static <H extends B & A> void test() { 32.59 + Function<H, Info> f1L = _h -> new Info(_h); 32.60 + Function<H, Info> f1 = Info::new; 32.61 + Function<H, Info> f2L = _h -> Info.info(_h); 32.62 + Function<H, Info> f2 = Info::info; 32.63 + H c = (H) new C(); 32.64 + if(f1.apply(c) instanceof Info && 32.65 + f2.apply(c) instanceof Info) { 32.66 + System.out.println("Passes."); 32.67 + } else { 32.68 + throw new AssertionError(); 32.69 + } 32.70 + } 32.71 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection3.java Fri Dec 12 14:57:02 2014 -0800 33.3 @@ -0,0 +1,50 @@ 33.4 +/* 33.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.7 + * 33.8 + * This code is free software; you can redistribute it and/or modify it 33.9 + * under the terms of the GNU General Public License version 2 only, as 33.10 + * published by the Free Software Foundation. Oracle designates this 33.11 + * particular file as subject to the "Classpath" exception as provided 33.12 + * by Oracle in the LICENSE file that accompanied this code. 33.13 + * 33.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 33.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 33.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 33.17 + * version 2 for more details (a copy is included in the LICENSE file that 33.18 + * accompanied this code). 33.19 + * 33.20 + * You should have received a copy of the GNU General Public License version 33.21 + * 2 along with this work; if not, write to the Free Software Foundation, 33.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 33.23 + * 33.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 33.25 + * or visit www.oracle.com if you need additional information or have any 33.26 + * questions. 33.27 + */ 33.28 + 33.29 +/** 33.30 + * @test 33.31 + * @bug 8058112 33.32 + * @summary Invalid BootstrapMethod for constructor/method reference 33.33 + */ 33.34 + 33.35 +/** 33.36 + * @author Remi Forax 33.37 + */ 33.38 + 33.39 +public class MethodReferenceIntersection3 { 33.40 + interface A {} 33.41 + 33.42 + interface Foo { 33.43 + <T extends Object & A> void foo(T t); 33.44 + } 33.45 + 33.46 + static <T extends A> void bar(T t) { 33.47 + } 33.48 + 33.49 + public static void main(String[] args) { 33.50 + Foo foo = MethodReferenceIntersection3::bar; 33.51 + foo.foo(new A(){}); 33.52 + } 33.53 +}