|
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 | 39 | import java.util.function.IntFunction; |
41 | | -import java.util.function.Predicate; |
42 | 40 |
|
43 | 41 | import javax.lang.model.element.Modifier; |
44 | 42 | import javax.lang.model.element.NestingKind; |
@@ -2187,320 +2185,12 @@ public void run() { |
2187 | 2185 | currentClassFile = classFile; |
2188 | 2186 | List<Attribute.TypeCompound> newList = deproxyTypeCompoundList(proxies); |
2189 | 2187 | sym.setTypeAttributes(newList.prependList(sym.getRawTypeAttributes())); |
2190 | | - addTypeAnnotationsToSymbol(sym, newList); |
2191 | 2188 | } finally { |
2192 | 2189 | currentClassFile = previousClassFile; |
2193 | 2190 | } |
2194 | 2191 | } |
2195 | 2192 | } |
2196 | 2193 |
|
2197 | | - /** |
2198 | | - * Rewrites types in the given symbol to include type annotations. |
2199 | | - * |
2200 | | - * <p>The list of type annotations includes annotations for all types in the signature of the |
2201 | | - * symbol. Associating the annotations with the correct type requires interpreting the JVMS |
2202 | | - * 4.7.20-A target_type to locate the correct type to rewrite, and then interpreting the JVMS |
2203 | | - * 4.7.20.2 type_path to associate the annotation with the correct contained type. |
2204 | | - */ |
2205 | | - private static void addTypeAnnotationsToSymbol( |
2206 | | - Symbol s, List<Attribute.TypeCompound> attributes) { |
2207 | | - new TypeAnnotationSymbolVisitor(attributes).visit(s, null); |
2208 | | - } |
2209 | | - |
2210 | | - private static class TypeAnnotationSymbolVisitor |
2211 | | - extends Types.DefaultSymbolVisitor<Void, Void> { |
2212 | | - |
2213 | | - private final List<Attribute.TypeCompound> attributes; |
2214 | | - |
2215 | | - private TypeAnnotationSymbolVisitor(List<Attribute.TypeCompound> attributes) { |
2216 | | - this.attributes = attributes; |
2217 | | - } |
2218 | | - |
2219 | | - @Override |
2220 | | - public Void visitClassSymbol(Symbol.ClassSymbol s, Void unused) { |
2221 | | - ClassType t = (ClassType) s.type; |
2222 | | - int i = 0; |
2223 | | - ListBuffer<Type> interfaces = new ListBuffer<>(); |
2224 | | - for (Type itf : t.interfaces_field) { |
2225 | | - interfaces.add(addTypeAnnotations(itf, classExtends(i++))); |
2226 | | - } |
2227 | | - t.interfaces_field = interfaces.toList(); |
2228 | | - t.supertype_field = addTypeAnnotations(t.supertype_field, classExtends(65535)); |
2229 | | - if (t.typarams_field != null) { |
2230 | | - t.typarams_field = |
2231 | | - rewriteTypeParameters( |
2232 | | - t.typarams_field, TargetType.CLASS_TYPE_PARAMETER_BOUND); |
2233 | | - } |
2234 | | - return null; |
2235 | | - } |
2236 | | - |
2237 | | - @Override |
2238 | | - public Void visitMethodSymbol(Symbol.MethodSymbol s, Void unused) { |
2239 | | - Type t = s.type; |
2240 | | - if (t.hasTag(TypeTag.FORALL)) { |
2241 | | - Type.ForAll fa = (Type.ForAll) t; |
2242 | | - fa.tvars = rewriteTypeParameters(fa.tvars, TargetType.METHOD_TYPE_PARAMETER_BOUND); |
2243 | | - t = fa.qtype; |
2244 | | - } |
2245 | | - MethodType mt = (MethodType) t; |
2246 | | - ListBuffer<Type> argtypes = new ListBuffer<>(); |
2247 | | - int i = 0; |
2248 | | - for (Symbol.VarSymbol param : s.params) { |
2249 | | - param.type = addTypeAnnotations(param.type, methodFormalParameter(i++)); |
2250 | | - argtypes.add(param.type); |
2251 | | - } |
2252 | | - mt.argtypes = argtypes.toList(); |
2253 | | - ListBuffer<Type> thrown = new ListBuffer<>(); |
2254 | | - i = 0; |
2255 | | - for (Type thrownType : mt.thrown) { |
2256 | | - thrown.add(addTypeAnnotations(thrownType, thrownType(i++))); |
2257 | | - } |
2258 | | - mt.thrown = thrown.toList(); |
2259 | | - /* possible information loss if the type of the method is void then we can't add type |
2260 | | - * annotations to it |
2261 | | - */ |
2262 | | - if (!mt.restype.hasTag(TypeTag.VOID)) { |
2263 | | - mt.restype = addTypeAnnotations(mt.restype, TargetType.METHOD_RETURN); |
2264 | | - } |
2265 | | - if (mt.recvtype != null) { |
2266 | | - mt.recvtype = addTypeAnnotations(mt.recvtype, TargetType.METHOD_RECEIVER); |
2267 | | - } |
2268 | | - return null; |
2269 | | - } |
2270 | | - |
2271 | | - @Override |
2272 | | - public Void visitVarSymbol(Symbol.VarSymbol s, Void unused) { |
2273 | | - s.type = addTypeAnnotations(s.type, TargetType.FIELD); |
2274 | | - return null; |
2275 | | - } |
2276 | | - |
2277 | | - @Override |
2278 | | - public Void visitSymbol(Symbol s, Void unused) { |
2279 | | - return null; |
2280 | | - } |
2281 | | - |
2282 | | - private List<Type> rewriteTypeParameters(List<Type> tvars, TargetType boundType) { |
2283 | | - ListBuffer<Type> tvarbuf = new ListBuffer<>(); |
2284 | | - int typeVariableIndex = 0; |
2285 | | - for (Type tvar : tvars) { |
2286 | | - Type bound = tvar.getUpperBound(); |
2287 | | - if (bound.isCompound()) { |
2288 | | - ClassType ct = (ClassType) bound; |
2289 | | - int boundIndex = 0; |
2290 | | - if (ct.supertype_field != null) { |
2291 | | - ct.supertype_field = |
2292 | | - addTypeAnnotations( |
2293 | | - ct.supertype_field, |
2294 | | - typeParameterBound( |
2295 | | - boundType, typeVariableIndex, boundIndex++)); |
2296 | | - } |
2297 | | - ListBuffer<Type> itfbuf = new ListBuffer<>(); |
2298 | | - for (Type itf : ct.interfaces_field) { |
2299 | | - itfbuf.add( |
2300 | | - addTypeAnnotations( |
2301 | | - itf, |
2302 | | - typeParameterBound( |
2303 | | - boundType, typeVariableIndex, boundIndex++))); |
2304 | | - } |
2305 | | - ct.interfaces_field = itfbuf.toList(); |
2306 | | - } else { |
2307 | | - bound = |
2308 | | - addTypeAnnotations( |
2309 | | - bound, |
2310 | | - typeParameterBound( |
2311 | | - boundType, |
2312 | | - typeVariableIndex, |
2313 | | - bound.isInterface() ? 1 : 0)); |
2314 | | - } |
2315 | | - ((TypeVar) tvar).setUpperBound(bound); |
2316 | | - tvarbuf.add(tvar); |
2317 | | - typeVariableIndex++; |
2318 | | - } |
2319 | | - return tvarbuf.toList(); |
2320 | | - } |
2321 | | - |
2322 | | - private Type addTypeAnnotations(Type type, TargetType targetType) { |
2323 | | - return addTypeAnnotations(type, pos -> pos.type == targetType); |
2324 | | - } |
2325 | | - |
2326 | | - private Type addTypeAnnotations(Type type, Predicate<TypeAnnotationPosition> filter) { |
2327 | | - Assert.checkNonNull(type); |
2328 | | - |
2329 | | - // Find type annotations that match the given target type |
2330 | | - ListBuffer<Attribute.TypeCompound> filtered = new ListBuffer<>(); |
2331 | | - for (Attribute.TypeCompound attribute : this.attributes) { |
2332 | | - if (filter.test(attribute.position)) { |
2333 | | - filtered.add(attribute); |
2334 | | - } |
2335 | | - } |
2336 | | - if (filtered.isEmpty()) { |
2337 | | - return type; |
2338 | | - } |
2339 | | - |
2340 | | - // Group the matching annotations by their type path. Each group of annotations will be |
2341 | | - // added to a type at that location. |
2342 | | - Map<List<TypeAnnotationPosition.TypePathEntry>, ListBuffer<Attribute.TypeCompound>> |
2343 | | - attributesByPath = new HashMap<>(); |
2344 | | - for (Attribute.TypeCompound attribute : filtered.toList()) { |
2345 | | - attributesByPath |
2346 | | - .computeIfAbsent(attribute.position.location, k -> new ListBuffer<>()) |
2347 | | - .add(attribute); |
2348 | | - } |
2349 | | - |
2350 | | - // Search the structure of the type to find the contained types at each type path |
2351 | | - Map<Type, List<Attribute.TypeCompound>> attributesByType = new HashMap<>(); |
2352 | | - new TypeAnnotationLocator(attributesByPath, attributesByType).visit(type, List.nil()); |
2353 | | - |
2354 | | - // Rewrite the type and add the annotations |
2355 | | - type = new TypeAnnotationTypeMapping(attributesByType).visit(type, null); |
2356 | | - Assert.check(attributesByType.isEmpty(), "Failed to apply annotations to types"); |
2357 | | - |
2358 | | - return type; |
2359 | | - } |
2360 | | - |
2361 | | - private static Predicate<TypeAnnotationPosition> typeParameterBound( |
2362 | | - TargetType targetType, int parameterIndex, int boundIndex) { |
2363 | | - return pos -> |
2364 | | - pos.type == targetType |
2365 | | - && pos.parameter_index == parameterIndex |
2366 | | - && pos.bound_index == boundIndex; |
2367 | | - } |
2368 | | - |
2369 | | - private static Predicate<TypeAnnotationPosition> methodFormalParameter(int index) { |
2370 | | - return pos -> |
2371 | | - pos.type == TargetType.METHOD_FORMAL_PARAMETER && pos.parameter_index == index; |
2372 | | - } |
2373 | | - |
2374 | | - private static Predicate<TypeAnnotationPosition> thrownType(int index) { |
2375 | | - return pos -> pos.type == TargetType.THROWS && pos.type_index == index; |
2376 | | - } |
2377 | | - |
2378 | | - private static Predicate<TypeAnnotationPosition> classExtends(int index) { |
2379 | | - return pos -> pos.type == TargetType.CLASS_EXTENDS && pos.type_index == index; |
2380 | | - } |
2381 | | - } |
2382 | | - |
2383 | | - /** |
2384 | | - * Visit all contained types, assembling a type path to represent the current location, and |
2385 | | - * record the types at each type path that need to be annotated. |
2386 | | - */ |
2387 | | - private static class TypeAnnotationLocator |
2388 | | - extends Types.DefaultTypeVisitor<Void, List<TypeAnnotationPosition.TypePathEntry>> { |
2389 | | - private final Map<List<TypeAnnotationPosition.TypePathEntry>, |
2390 | | - ListBuffer<Attribute.TypeCompound>> attributesByPath; |
2391 | | - private final Map<Type, List<Attribute.TypeCompound>> attributesByType; |
2392 | | - |
2393 | | - private TypeAnnotationLocator( |
2394 | | - Map<List<TypeAnnotationPosition.TypePathEntry>, ListBuffer<Attribute.TypeCompound>> |
2395 | | - attributesByPath, |
2396 | | - Map<Type, List<Attribute.TypeCompound>> attributesByType) { |
2397 | | - this.attributesByPath = attributesByPath; |
2398 | | - this.attributesByType = attributesByType; |
2399 | | - } |
2400 | | - |
2401 | | - @Override |
2402 | | - public Void visitClassType(ClassType t, List<TypeAnnotationPosition.TypePathEntry> path) { |
2403 | | - // As described in JVMS 4.7.20.2, type annotations on nested types are located with |
2404 | | - // 'left-to-right' steps starting on 'the outermost part of the type for which a type |
2405 | | - // annotation is admissible'. So the current path represents the outermost containing |
2406 | | - // type of the type being visited, and we add type path steps for every contained nested |
2407 | | - // type. |
2408 | | - List<ClassType> enclosing = List.nil(); |
2409 | | - for (Type curr = t; |
2410 | | - curr != null && curr != Type.noType; |
2411 | | - curr = curr.getEnclosingType()) { |
2412 | | - enclosing = enclosing.prepend((ClassType) curr); |
2413 | | - } |
2414 | | - for (ClassType te : enclosing) { |
2415 | | - if (te.typarams_field != null) { |
2416 | | - int i = 0; |
2417 | | - for (Type typaram : te.typarams_field) { |
2418 | | - visit(typaram, path.append(new TypeAnnotationPosition.TypePathEntry( |
2419 | | - TypeAnnotationPosition.TypePathEntryKind.TYPE_ARGUMENT, i++))); |
2420 | | - } |
2421 | | - } |
2422 | | - visitType(te, path); |
2423 | | - path = path.append(TypeAnnotationPosition.TypePathEntry.INNER_TYPE); |
2424 | | - } |
2425 | | - return null; |
2426 | | - } |
2427 | | - |
2428 | | - @Override |
2429 | | - public Void visitWildcardType( |
2430 | | - WildcardType t, List<TypeAnnotationPosition.TypePathEntry> path) { |
2431 | | - visit(t.type, path.append(TypeAnnotationPosition.TypePathEntry.WILDCARD)); |
2432 | | - return super.visitWildcardType(t, path); |
2433 | | - } |
2434 | | - |
2435 | | - @Override |
2436 | | - public Void visitArrayType(ArrayType t, List<TypeAnnotationPosition.TypePathEntry> path) { |
2437 | | - visit(t.elemtype, path.append(TypeAnnotationPosition.TypePathEntry.ARRAY)); |
2438 | | - return super.visitArrayType(t, path); |
2439 | | - } |
2440 | | - |
2441 | | - @Override |
2442 | | - public Void visitType(Type t, List<TypeAnnotationPosition.TypePathEntry> path) { |
2443 | | - ListBuffer<Attribute.TypeCompound> attributes = attributesByPath.remove(path); |
2444 | | - if (attributes != null) { |
2445 | | - attributesByType.put(t, attributes.toList()); |
2446 | | - } |
2447 | | - return null; |
2448 | | - } |
2449 | | - } |
2450 | | - |
2451 | | - /** A type mapping that rewrites the type to include type annotations. */ |
2452 | | - private static class TypeAnnotationTypeMapping extends Type.StructuralTypeMapping<Void> { |
2453 | | - |
2454 | | - private final Map<Type, List<Attribute.TypeCompound>> attributesByType; |
2455 | | - |
2456 | | - private TypeAnnotationTypeMapping( |
2457 | | - Map<Type, List<Attribute.TypeCompound>> attributesByType) { |
2458 | | - this.attributesByType = attributesByType; |
2459 | | - } |
2460 | | - |
2461 | | - private <T extends Type> Type reannotate(T t, BiFunction<T, Void, Type> f) { |
2462 | | - // We're relying on object identify of Type instances to record where the annotations |
2463 | | - // need to be added, so we have to retrieve the annotations for each type before |
2464 | | - // rewriting it, and then add them after its contained types have been rewritten. |
2465 | | - List<Attribute.TypeCompound> attributes = attributesByType.remove(t); |
2466 | | - Type mapped = f.apply(t, null); |
2467 | | - if (attributes == null) { |
2468 | | - return mapped; |
2469 | | - } |
2470 | | - // Runtime-visible and -invisible annotations are completed separately, so if the same |
2471 | | - // type has annotations from both it will get annotated twice. |
2472 | | - TypeMetadata metadata = mapped.getMetadata(); |
2473 | | - TypeMetadata.Annotations existing = |
2474 | | - (TypeMetadata.Annotations) metadata.get(TypeMetadata.Entry.Kind.ANNOTATIONS); |
2475 | | - if (existing != null) { |
2476 | | - TypeMetadata.Annotations combined = new TypeMetadata.Annotations( |
2477 | | - existing.getAnnotations().appendList(attributes)); |
2478 | | - return mapped.cloneWithMetadata( |
2479 | | - metadata.without(TypeMetadata.Entry.Kind.ANNOTATIONS).combine(combined)); |
2480 | | - } |
2481 | | - return mapped.annotatedType(attributes); |
2482 | | - } |
2483 | | - |
2484 | | - @Override |
2485 | | - public Type visitClassType(ClassType t, Void unused) { |
2486 | | - return reannotate(t, super::visitClassType); |
2487 | | - } |
2488 | | - |
2489 | | - @Override |
2490 | | - public Type visitWildcardType(WildcardType t, Void unused) { |
2491 | | - return reannotate(t, super::visitWildcardType); |
2492 | | - } |
2493 | | - |
2494 | | - @Override |
2495 | | - public Type visitArrayType(ArrayType t, Void unused) { |
2496 | | - return reannotate(t, super::visitArrayType); |
2497 | | - } |
2498 | | - |
2499 | | - @Override |
2500 | | - public Type visitType(Type t, Void unused) { |
2501 | | - return reannotate(t, (x, u) -> x); |
2502 | | - } |
2503 | | - } |
2504 | 2194 |
|
2505 | 2195 | /************************************************************************ |
2506 | 2196 | * Reading Symbols |
|
0 commit comments