|
36 | 36 | import java.util.HashSet; |
37 | 37 | import java.util.Map; |
38 | 38 | import java.util.Set; |
39 | | -import java.util.function.BiFunction; |
40 | | -import java.util.function.Predicate; |
41 | 39 |
|
42 | 40 | import javax.lang.model.element.Modifier; |
43 | 41 | import javax.lang.model.element.NestingKind; |
@@ -2389,320 +2387,12 @@ public void run() { |
2389 | 2387 | currentClassFile = classFile; |
2390 | 2388 | List<Attribute.TypeCompound> newList = deproxyTypeCompoundList(proxies); |
2391 | 2389 | sym.setTypeAttributes(newList.prependList(sym.getRawTypeAttributes())); |
2392 | | - addTypeAnnotationsToSymbol(sym, newList); |
2393 | 2390 | } finally { |
2394 | 2391 | currentClassFile = previousClassFile; |
2395 | 2392 | } |
2396 | 2393 | } |
2397 | 2394 | } |
2398 | 2395 |
|
2399 | | - /** |
2400 | | - * Rewrites types in the given symbol to include type annotations. |
2401 | | - * |
2402 | | - * <p>The list of type annotations includes annotations for all types in the signature of the |
2403 | | - * symbol. Associating the annotations with the correct type requires interpreting the JVMS |
2404 | | - * 4.7.20-A target_type to locate the correct type to rewrite, and then interpreting the JVMS |
2405 | | - * 4.7.20.2 type_path to associate the annotation with the correct contained type. |
2406 | | - */ |
2407 | | - private static void addTypeAnnotationsToSymbol( |
2408 | | - Symbol s, List<Attribute.TypeCompound> attributes) { |
2409 | | - new TypeAnnotationSymbolVisitor(attributes).visit(s, null); |
2410 | | - } |
2411 | | - |
2412 | | - private static class TypeAnnotationSymbolVisitor |
2413 | | - extends Types.DefaultSymbolVisitor<Void, Void> { |
2414 | | - |
2415 | | - private final List<Attribute.TypeCompound> attributes; |
2416 | | - |
2417 | | - private TypeAnnotationSymbolVisitor(List<Attribute.TypeCompound> attributes) { |
2418 | | - this.attributes = attributes; |
2419 | | - } |
2420 | | - |
2421 | | - @Override |
2422 | | - public Void visitClassSymbol(Symbol.ClassSymbol s, Void unused) { |
2423 | | - ClassType t = (ClassType) s.type; |
2424 | | - int i = 0; |
2425 | | - ListBuffer<Type> interfaces = new ListBuffer<>(); |
2426 | | - for (Type itf : t.interfaces_field) { |
2427 | | - interfaces.add(addTypeAnnotations(itf, classExtends(i++))); |
2428 | | - } |
2429 | | - t.interfaces_field = interfaces.toList(); |
2430 | | - t.supertype_field = addTypeAnnotations(t.supertype_field, classExtends(65535)); |
2431 | | - if (t.typarams_field != null) { |
2432 | | - t.typarams_field = |
2433 | | - rewriteTypeParameters( |
2434 | | - t.typarams_field, TargetType.CLASS_TYPE_PARAMETER_BOUND); |
2435 | | - } |
2436 | | - return null; |
2437 | | - } |
2438 | | - |
2439 | | - @Override |
2440 | | - public Void visitMethodSymbol(Symbol.MethodSymbol s, Void unused) { |
2441 | | - Type t = s.type; |
2442 | | - if (t.hasTag(TypeTag.FORALL)) { |
2443 | | - Type.ForAll fa = (Type.ForAll) t; |
2444 | | - fa.tvars = rewriteTypeParameters(fa.tvars, TargetType.METHOD_TYPE_PARAMETER_BOUND); |
2445 | | - t = fa.qtype; |
2446 | | - } |
2447 | | - MethodType mt = (MethodType) t; |
2448 | | - ListBuffer<Type> argtypes = new ListBuffer<>(); |
2449 | | - int i = 0; |
2450 | | - for (Symbol.VarSymbol param : s.params) { |
2451 | | - param.type = addTypeAnnotations(param.type, methodFormalParameter(i++)); |
2452 | | - argtypes.add(param.type); |
2453 | | - } |
2454 | | - mt.argtypes = argtypes.toList(); |
2455 | | - ListBuffer<Type> thrown = new ListBuffer<>(); |
2456 | | - i = 0; |
2457 | | - for (Type thrownType : mt.thrown) { |
2458 | | - thrown.add(addTypeAnnotations(thrownType, thrownType(i++))); |
2459 | | - } |
2460 | | - mt.thrown = thrown.toList(); |
2461 | | - /* possible information loss if the type of the method is void then we can't add type |
2462 | | - * annotations to it |
2463 | | - */ |
2464 | | - if (!mt.restype.hasTag(TypeTag.VOID)) { |
2465 | | - mt.restype = addTypeAnnotations(mt.restype, TargetType.METHOD_RETURN); |
2466 | | - } |
2467 | | - if (mt.recvtype != null) { |
2468 | | - mt.recvtype = addTypeAnnotations(mt.recvtype, TargetType.METHOD_RECEIVER); |
2469 | | - } |
2470 | | - return null; |
2471 | | - } |
2472 | | - |
2473 | | - @Override |
2474 | | - public Void visitVarSymbol(Symbol.VarSymbol s, Void unused) { |
2475 | | - s.type = addTypeAnnotations(s.type, TargetType.FIELD); |
2476 | | - return null; |
2477 | | - } |
2478 | | - |
2479 | | - @Override |
2480 | | - public Void visitSymbol(Symbol s, Void unused) { |
2481 | | - return null; |
2482 | | - } |
2483 | | - |
2484 | | - private List<Type> rewriteTypeParameters(List<Type> tvars, TargetType boundType) { |
2485 | | - ListBuffer<Type> tvarbuf = new ListBuffer<>(); |
2486 | | - int typeVariableIndex = 0; |
2487 | | - for (Type tvar : tvars) { |
2488 | | - Type bound = tvar.getUpperBound(); |
2489 | | - if (bound.isCompound()) { |
2490 | | - ClassType ct = (ClassType) bound; |
2491 | | - int boundIndex = 0; |
2492 | | - if (ct.supertype_field != null) { |
2493 | | - ct.supertype_field = |
2494 | | - addTypeAnnotations( |
2495 | | - ct.supertype_field, |
2496 | | - typeParameterBound( |
2497 | | - boundType, typeVariableIndex, boundIndex++)); |
2498 | | - } |
2499 | | - ListBuffer<Type> itfbuf = new ListBuffer<>(); |
2500 | | - for (Type itf : ct.interfaces_field) { |
2501 | | - itfbuf.add( |
2502 | | - addTypeAnnotations( |
2503 | | - itf, |
2504 | | - typeParameterBound( |
2505 | | - boundType, typeVariableIndex, boundIndex++))); |
2506 | | - } |
2507 | | - ct.interfaces_field = itfbuf.toList(); |
2508 | | - } else { |
2509 | | - bound = |
2510 | | - addTypeAnnotations( |
2511 | | - bound, |
2512 | | - typeParameterBound( |
2513 | | - boundType, |
2514 | | - typeVariableIndex, |
2515 | | - bound.isInterface() ? 1 : 0)); |
2516 | | - } |
2517 | | - ((TypeVar) tvar).setUpperBound(bound); |
2518 | | - tvarbuf.add(tvar); |
2519 | | - typeVariableIndex++; |
2520 | | - } |
2521 | | - return tvarbuf.toList(); |
2522 | | - } |
2523 | | - |
2524 | | - private Type addTypeAnnotations(Type type, TargetType targetType) { |
2525 | | - return addTypeAnnotations(type, pos -> pos.type == targetType); |
2526 | | - } |
2527 | | - |
2528 | | - private Type addTypeAnnotations(Type type, Predicate<TypeAnnotationPosition> filter) { |
2529 | | - Assert.checkNonNull(type); |
2530 | | - |
2531 | | - // Find type annotations that match the given target type |
2532 | | - ListBuffer<Attribute.TypeCompound> filtered = new ListBuffer<>(); |
2533 | | - for (Attribute.TypeCompound attribute : this.attributes) { |
2534 | | - if (filter.test(attribute.position)) { |
2535 | | - filtered.add(attribute); |
2536 | | - } |
2537 | | - } |
2538 | | - if (filtered.isEmpty()) { |
2539 | | - return type; |
2540 | | - } |
2541 | | - |
2542 | | - // Group the matching annotations by their type path. Each group of annotations will be |
2543 | | - // added to a type at that location. |
2544 | | - Map<List<TypeAnnotationPosition.TypePathEntry>, ListBuffer<Attribute.TypeCompound>> |
2545 | | - attributesByPath = new HashMap<>(); |
2546 | | - for (Attribute.TypeCompound attribute : filtered.toList()) { |
2547 | | - attributesByPath |
2548 | | - .computeIfAbsent(attribute.position.location, k -> new ListBuffer<>()) |
2549 | | - .add(attribute); |
2550 | | - } |
2551 | | - |
2552 | | - // Search the structure of the type to find the contained types at each type path |
2553 | | - Map<Type, List<Attribute.TypeCompound>> attributesByType = new HashMap<>(); |
2554 | | - new TypeAnnotationLocator(attributesByPath, attributesByType).visit(type, List.nil()); |
2555 | | - |
2556 | | - // Rewrite the type and add the annotations |
2557 | | - type = new TypeAnnotationTypeMapping(attributesByType).visit(type, null); |
2558 | | - Assert.check(attributesByType.isEmpty(), "Failed to apply annotations to types"); |
2559 | | - |
2560 | | - return type; |
2561 | | - } |
2562 | | - |
2563 | | - private static Predicate<TypeAnnotationPosition> typeParameterBound( |
2564 | | - TargetType targetType, int parameterIndex, int boundIndex) { |
2565 | | - return pos -> |
2566 | | - pos.type == targetType |
2567 | | - && pos.parameter_index == parameterIndex |
2568 | | - && pos.bound_index == boundIndex; |
2569 | | - } |
2570 | | - |
2571 | | - private static Predicate<TypeAnnotationPosition> methodFormalParameter(int index) { |
2572 | | - return pos -> |
2573 | | - pos.type == TargetType.METHOD_FORMAL_PARAMETER && pos.parameter_index == index; |
2574 | | - } |
2575 | | - |
2576 | | - private static Predicate<TypeAnnotationPosition> thrownType(int index) { |
2577 | | - return pos -> pos.type == TargetType.THROWS && pos.type_index == index; |
2578 | | - } |
2579 | | - |
2580 | | - private static Predicate<TypeAnnotationPosition> classExtends(int index) { |
2581 | | - return pos -> pos.type == TargetType.CLASS_EXTENDS && pos.type_index == index; |
2582 | | - } |
2583 | | - } |
2584 | | - |
2585 | | - /** |
2586 | | - * Visit all contained types, assembling a type path to represent the current location, and |
2587 | | - * record the types at each type path that need to be annotated. |
2588 | | - */ |
2589 | | - private static class TypeAnnotationLocator |
2590 | | - extends Types.DefaultTypeVisitor<Void, List<TypeAnnotationPosition.TypePathEntry>> { |
2591 | | - private final Map<List<TypeAnnotationPosition.TypePathEntry>, |
2592 | | - ListBuffer<Attribute.TypeCompound>> attributesByPath; |
2593 | | - private final Map<Type, List<Attribute.TypeCompound>> attributesByType; |
2594 | | - |
2595 | | - private TypeAnnotationLocator( |
2596 | | - Map<List<TypeAnnotationPosition.TypePathEntry>, ListBuffer<Attribute.TypeCompound>> |
2597 | | - attributesByPath, |
2598 | | - Map<Type, List<Attribute.TypeCompound>> attributesByType) { |
2599 | | - this.attributesByPath = attributesByPath; |
2600 | | - this.attributesByType = attributesByType; |
2601 | | - } |
2602 | | - |
2603 | | - @Override |
2604 | | - public Void visitClassType(ClassType t, List<TypeAnnotationPosition.TypePathEntry> path) { |
2605 | | - // As described in JVMS 4.7.20.2, type annotations on nested types are located with |
2606 | | - // 'left-to-right' steps starting on 'the outermost part of the type for which a type |
2607 | | - // annotation is admissible'. So the current path represents the outermost containing |
2608 | | - // type of the type being visited, and we add type path steps for every contained nested |
2609 | | - // type. |
2610 | | - List<ClassType> enclosing = List.nil(); |
2611 | | - for (Type curr = t; |
2612 | | - curr != null && curr != Type.noType; |
2613 | | - curr = curr.getEnclosingType()) { |
2614 | | - enclosing = enclosing.prepend((ClassType) curr); |
2615 | | - } |
2616 | | - for (ClassType te : enclosing) { |
2617 | | - if (te.typarams_field != null) { |
2618 | | - int i = 0; |
2619 | | - for (Type typaram : te.typarams_field) { |
2620 | | - visit(typaram, path.append(new TypeAnnotationPosition.TypePathEntry( |
2621 | | - TypeAnnotationPosition.TypePathEntryKind.TYPE_ARGUMENT, i++))); |
2622 | | - } |
2623 | | - } |
2624 | | - visitType(te, path); |
2625 | | - path = path.append(TypeAnnotationPosition.TypePathEntry.INNER_TYPE); |
2626 | | - } |
2627 | | - return null; |
2628 | | - } |
2629 | | - |
2630 | | - @Override |
2631 | | - public Void visitWildcardType( |
2632 | | - WildcardType t, List<TypeAnnotationPosition.TypePathEntry> path) { |
2633 | | - visit(t.type, path.append(TypeAnnotationPosition.TypePathEntry.WILDCARD)); |
2634 | | - return super.visitWildcardType(t, path); |
2635 | | - } |
2636 | | - |
2637 | | - @Override |
2638 | | - public Void visitArrayType(ArrayType t, List<TypeAnnotationPosition.TypePathEntry> path) { |
2639 | | - visit(t.elemtype, path.append(TypeAnnotationPosition.TypePathEntry.ARRAY)); |
2640 | | - return super.visitArrayType(t, path); |
2641 | | - } |
2642 | | - |
2643 | | - @Override |
2644 | | - public Void visitType(Type t, List<TypeAnnotationPosition.TypePathEntry> path) { |
2645 | | - ListBuffer<Attribute.TypeCompound> attributes = attributesByPath.remove(path); |
2646 | | - if (attributes != null) { |
2647 | | - attributesByType.put(t, attributes.toList()); |
2648 | | - } |
2649 | | - return null; |
2650 | | - } |
2651 | | - } |
2652 | | - |
2653 | | - /** A type mapping that rewrites the type to include type annotations. */ |
2654 | | - private static class TypeAnnotationTypeMapping extends Type.StructuralTypeMapping<Void> { |
2655 | | - |
2656 | | - private final Map<Type, List<Attribute.TypeCompound>> attributesByType; |
2657 | | - |
2658 | | - private TypeAnnotationTypeMapping( |
2659 | | - Map<Type, List<Attribute.TypeCompound>> attributesByType) { |
2660 | | - this.attributesByType = attributesByType; |
2661 | | - } |
2662 | | - |
2663 | | - private <T extends Type> Type reannotate(T t, BiFunction<T, Void, Type> f) { |
2664 | | - // We're relying on object identify of Type instances to record where the annotations |
2665 | | - // need to be added, so we have to retrieve the annotations for each type before |
2666 | | - // rewriting it, and then add them after its contained types have been rewritten. |
2667 | | - List<Attribute.TypeCompound> attributes = attributesByType.remove(t); |
2668 | | - Type mapped = f.apply(t, null); |
2669 | | - if (attributes == null) { |
2670 | | - return mapped; |
2671 | | - } |
2672 | | - // Runtime-visible and -invisible annotations are completed separately, so if the same |
2673 | | - // type has annotations from both it will get annotated twice. |
2674 | | - TypeMetadata metadata = mapped.getMetadata(); |
2675 | | - TypeMetadata.Annotations existing = |
2676 | | - (TypeMetadata.Annotations) metadata.get(TypeMetadata.Entry.Kind.ANNOTATIONS); |
2677 | | - if (existing != null) { |
2678 | | - TypeMetadata.Annotations combined = new TypeMetadata.Annotations( |
2679 | | - existing.getAnnotations().appendList(attributes)); |
2680 | | - return mapped.cloneWithMetadata( |
2681 | | - metadata.without(TypeMetadata.Entry.Kind.ANNOTATIONS).combine(combined)); |
2682 | | - } |
2683 | | - return mapped.annotatedType(attributes); |
2684 | | - } |
2685 | | - |
2686 | | - @Override |
2687 | | - public Type visitClassType(ClassType t, Void unused) { |
2688 | | - return reannotate(t, super::visitClassType); |
2689 | | - } |
2690 | | - |
2691 | | - @Override |
2692 | | - public Type visitWildcardType(WildcardType t, Void unused) { |
2693 | | - return reannotate(t, super::visitWildcardType); |
2694 | | - } |
2695 | | - |
2696 | | - @Override |
2697 | | - public Type visitArrayType(ArrayType t, Void unused) { |
2698 | | - return reannotate(t, super::visitArrayType); |
2699 | | - } |
2700 | | - |
2701 | | - @Override |
2702 | | - public Type visitType(Type t, Void unused) { |
2703 | | - return reannotate(t, (x, u) -> x); |
2704 | | - } |
2705 | | - } |
2706 | 2396 |
|
2707 | 2397 | /************************************************************************ |
2708 | 2398 | * Reading Symbols |
|
0 commit comments