@Test public void testGetTypeClosure() throws IOException { IndexView index = Basics.index(Foo.class, Baz.class, Producer.class, Object.class, List.class, Collection.class, Iterable.class); DotName bazName = DotName.createSimple(Baz.class.getName()); DotName fooName = DotName.createSimple(Foo.class.getName()); DotName producerName = DotName.createSimple(Producer.class.getName()); ClassInfo fooClass = index.getClassByName(fooName); Map<ClassInfo, Map<TypeVariable, Type>> resolvedTypeVariables = new HashMap<>(); BeanDeployment dummyDeployment = BeanProcessor.builder().setBeanArchiveIndex(index).build().getBeanDeployment(); Set<Type> bazTypes = Types.getTypeClosure(index.getClassByName(bazName), null, Collections.emptyMap(), dummyDeployment, resolvedTypeVariables::put); assertEquals(3, bazTypes.size()); assertTrue(bazTypes.contains(Type.create(bazName, Kind.CLASS))); assertTrue(bazTypes.contains(ParameterizedType.create(fooName, new Type[] { Type.create(DotName.createSimple(String.class.getName()), Kind.CLASS) }, null))); assertEquals(resolvedTypeVariables.size(), 1); assertTrue(resolvedTypeVariables.containsKey(fooClass)); assertEquals(resolvedTypeVariables.get(fooClass).get(fooClass.typeParameters().get(0)), Type.create(DotName.createSimple(String.class.getName()), Kind.CLASS)); resolvedTypeVariables.clear(); Set<Type> fooTypes = Types.getClassBeanTypeClosure(fooClass, dummyDeployment); assertEquals(2, fooTypes.size()); for (Type t : fooTypes) { if (t.kind().equals(Kind.PARAMETERIZED_TYPE)) { ParameterizedType fooType = t.asParameterizedType(); assertEquals("T", fooType.arguments().get(0).asTypeVariable().identifier()); assertEquals(DotNames.OBJECT, fooType.arguments().get(0).asTypeVariable().bounds().get(0).name()); } } ClassInfo producerClass = index.getClassByName(producerName); String producersName = "produce"; MethodInfo producerMethod = producerClass.method(producersName); Set<Type> producerMethodTypes = Types.getProducerMethodTypeClosure(producerMethod, dummyDeployment); assertEquals(1, producerMethodTypes.size()); FieldInfo producerField = producerClass.field(producersName); Set<Type> producerFieldTypes = Types.getProducerFieldTypeClosure(producerField, dummyDeployment); assertEquals(1, producerFieldTypes.size()); }
static Set<Type> getTypeClosure(ClassInfo classInfo, AnnotationTarget producerFieldOrMethod, Map<TypeVariable, Type> resolvedTypeParameters, BeanDeployment beanDeployment, BiConsumer<ClassInfo, Map<TypeVariable, Type>> resolvedTypeVariablesConsumer) { Set<Type> types = new HashSet<>(); List<TypeVariable> typeParameters = classInfo.typeParameters(); if (typeParameters.isEmpty() || !typeParameters.stream().allMatch(resolvedTypeParameters::containsKey)) { types.add(Type.create(classInfo.name(), Kind.CLASS)); } else { Type[] typeParams = new Type[typeParameters.size()]; boolean skipThisType = false; for (int i = 0; i < typeParameters.size(); i++) { typeParams[i] = resolvedTypeParameters.get(typeParameters.get(i)); if (typeParams[i].kind().equals(Kind.WILDCARD_TYPE) && producerFieldOrMethod != null) { LOGGER.info("Producer " + (producerFieldOrMethod.kind().equals(AnnotationTarget.Kind.FIELD) ? "field " : "method ") + producerFieldOrMethod + " contains a parameterized typed with a wildcard. This type is not a legal bean type" + " according to CDI specification and will be ignored during bean resolution."); skipThisType = true; } } if (resolvedTypeVariablesConsumer != null) { Map<TypeVariable, Type> resolved = new HashMap<>(); for (int i = 0; i < typeParameters.size(); i++) { resolved.put(typeParameters.get(i), typeParams[i]); } resolvedTypeVariablesConsumer.accept(classInfo, resolved); } if (!skipThisType) { types.add(ParameterizedType.create(classInfo.name(), typeParams, null)); } } for (Type interfaceType : classInfo.interfaceTypes()) { if (BANNED_INTERFACE_TYPES.contains(interfaceType.name())) { continue; } ClassInfo interfaceClassInfo = getClassByName(beanDeployment.getBeanArchiveIndex(), interfaceType.name()); if (interfaceClassInfo != null) { Map<TypeVariable, Type> resolved = Collections.emptyMap(); if (Kind.PARAMETERIZED_TYPE.equals(interfaceType.kind())) { resolved = buildResolvedMap(interfaceType.asParameterizedType().arguments(), interfaceClassInfo.typeParameters(), resolvedTypeParameters, beanDeployment.getBeanArchiveIndex()); } types.addAll(getTypeClosure(interfaceClassInfo, producerFieldOrMethod, resolved, beanDeployment, resolvedTypeVariablesConsumer)); } } if (classInfo.superClassType() != null) { ClassInfo superClassInfo = getClassByName(beanDeployment.getBeanArchiveIndex(), classInfo.superName()); if (superClassInfo != null) { Map<TypeVariable, Type> resolved = Collections.emptyMap(); if (Kind.PARAMETERIZED_TYPE.equals(classInfo.superClassType().kind())) { resolved = buildResolvedMap(classInfo.superClassType().asParameterizedType().arguments(), superClassInfo.typeParameters(), resolvedTypeParameters, beanDeployment.getBeanArchiveIndex()); } types.addAll(getTypeClosure(superClassInfo, producerFieldOrMethod, resolved, beanDeployment, resolvedTypeVariablesConsumer)); } } return types; }
Types { static Set<Type> getTypeClosure(ClassInfo classInfo, AnnotationTarget producerFieldOrMethod, Map<TypeVariable, Type> resolvedTypeParameters, BeanDeployment beanDeployment, BiConsumer<ClassInfo, Map<TypeVariable, Type>> resolvedTypeVariablesConsumer) { Set<Type> types = new HashSet<>(); List<TypeVariable> typeParameters = classInfo.typeParameters(); if (typeParameters.isEmpty() || !typeParameters.stream().allMatch(resolvedTypeParameters::containsKey)) { types.add(Type.create(classInfo.name(), Kind.CLASS)); } else { Type[] typeParams = new Type[typeParameters.size()]; boolean skipThisType = false; for (int i = 0; i < typeParameters.size(); i++) { typeParams[i] = resolvedTypeParameters.get(typeParameters.get(i)); if (typeParams[i].kind().equals(Kind.WILDCARD_TYPE) && producerFieldOrMethod != null) { LOGGER.info("Producer " + (producerFieldOrMethod.kind().equals(AnnotationTarget.Kind.FIELD) ? "field " : "method ") + producerFieldOrMethod + " contains a parameterized typed with a wildcard. This type is not a legal bean type" + " according to CDI specification and will be ignored during bean resolution."); skipThisType = true; } } if (resolvedTypeVariablesConsumer != null) { Map<TypeVariable, Type> resolved = new HashMap<>(); for (int i = 0; i < typeParameters.size(); i++) { resolved.put(typeParameters.get(i), typeParams[i]); } resolvedTypeVariablesConsumer.accept(classInfo, resolved); } if (!skipThisType) { types.add(ParameterizedType.create(classInfo.name(), typeParams, null)); } } for (Type interfaceType : classInfo.interfaceTypes()) { if (BANNED_INTERFACE_TYPES.contains(interfaceType.name())) { continue; } ClassInfo interfaceClassInfo = getClassByName(beanDeployment.getBeanArchiveIndex(), interfaceType.name()); if (interfaceClassInfo != null) { Map<TypeVariable, Type> resolved = Collections.emptyMap(); if (Kind.PARAMETERIZED_TYPE.equals(interfaceType.kind())) { resolved = buildResolvedMap(interfaceType.asParameterizedType().arguments(), interfaceClassInfo.typeParameters(), resolvedTypeParameters, beanDeployment.getBeanArchiveIndex()); } types.addAll(getTypeClosure(interfaceClassInfo, producerFieldOrMethod, resolved, beanDeployment, resolvedTypeVariablesConsumer)); } } if (classInfo.superClassType() != null) { ClassInfo superClassInfo = getClassByName(beanDeployment.getBeanArchiveIndex(), classInfo.superName()); if (superClassInfo != null) { Map<TypeVariable, Type> resolved = Collections.emptyMap(); if (Kind.PARAMETERIZED_TYPE.equals(classInfo.superClassType().kind())) { resolved = buildResolvedMap(classInfo.superClassType().asParameterizedType().arguments(), superClassInfo.typeParameters(), resolvedTypeParameters, beanDeployment.getBeanArchiveIndex()); } types.addAll(getTypeClosure(superClassInfo, producerFieldOrMethod, resolved, beanDeployment, resolvedTypeVariablesConsumer)); } } return types; } }
Types { static Set<Type> getTypeClosure(ClassInfo classInfo, AnnotationTarget producerFieldOrMethod, Map<TypeVariable, Type> resolvedTypeParameters, BeanDeployment beanDeployment, BiConsumer<ClassInfo, Map<TypeVariable, Type>> resolvedTypeVariablesConsumer) { Set<Type> types = new HashSet<>(); List<TypeVariable> typeParameters = classInfo.typeParameters(); if (typeParameters.isEmpty() || !typeParameters.stream().allMatch(resolvedTypeParameters::containsKey)) { types.add(Type.create(classInfo.name(), Kind.CLASS)); } else { Type[] typeParams = new Type[typeParameters.size()]; boolean skipThisType = false; for (int i = 0; i < typeParameters.size(); i++) { typeParams[i] = resolvedTypeParameters.get(typeParameters.get(i)); if (typeParams[i].kind().equals(Kind.WILDCARD_TYPE) && producerFieldOrMethod != null) { LOGGER.info("Producer " + (producerFieldOrMethod.kind().equals(AnnotationTarget.Kind.FIELD) ? "field " : "method ") + producerFieldOrMethod + " contains a parameterized typed with a wildcard. This type is not a legal bean type" + " according to CDI specification and will be ignored during bean resolution."); skipThisType = true; } } if (resolvedTypeVariablesConsumer != null) { Map<TypeVariable, Type> resolved = new HashMap<>(); for (int i = 0; i < typeParameters.size(); i++) { resolved.put(typeParameters.get(i), typeParams[i]); } resolvedTypeVariablesConsumer.accept(classInfo, resolved); } if (!skipThisType) { types.add(ParameterizedType.create(classInfo.name(), typeParams, null)); } } for (Type interfaceType : classInfo.interfaceTypes()) { if (BANNED_INTERFACE_TYPES.contains(interfaceType.name())) { continue; } ClassInfo interfaceClassInfo = getClassByName(beanDeployment.getBeanArchiveIndex(), interfaceType.name()); if (interfaceClassInfo != null) { Map<TypeVariable, Type> resolved = Collections.emptyMap(); if (Kind.PARAMETERIZED_TYPE.equals(interfaceType.kind())) { resolved = buildResolvedMap(interfaceType.asParameterizedType().arguments(), interfaceClassInfo.typeParameters(), resolvedTypeParameters, beanDeployment.getBeanArchiveIndex()); } types.addAll(getTypeClosure(interfaceClassInfo, producerFieldOrMethod, resolved, beanDeployment, resolvedTypeVariablesConsumer)); } } if (classInfo.superClassType() != null) { ClassInfo superClassInfo = getClassByName(beanDeployment.getBeanArchiveIndex(), classInfo.superName()); if (superClassInfo != null) { Map<TypeVariable, Type> resolved = Collections.emptyMap(); if (Kind.PARAMETERIZED_TYPE.equals(classInfo.superClassType().kind())) { resolved = buildResolvedMap(classInfo.superClassType().asParameterizedType().arguments(), superClassInfo.typeParameters(), resolvedTypeParameters, beanDeployment.getBeanArchiveIndex()); } types.addAll(getTypeClosure(superClassInfo, producerFieldOrMethod, resolved, beanDeployment, resolvedTypeVariablesConsumer)); } } return types; } private  Types(); }
Types { static Set<Type> getTypeClosure(ClassInfo classInfo, AnnotationTarget producerFieldOrMethod, Map<TypeVariable, Type> resolvedTypeParameters, BeanDeployment beanDeployment, BiConsumer<ClassInfo, Map<TypeVariable, Type>> resolvedTypeVariablesConsumer) { Set<Type> types = new HashSet<>(); List<TypeVariable> typeParameters = classInfo.typeParameters(); if (typeParameters.isEmpty() || !typeParameters.stream().allMatch(resolvedTypeParameters::containsKey)) { types.add(Type.create(classInfo.name(), Kind.CLASS)); } else { Type[] typeParams = new Type[typeParameters.size()]; boolean skipThisType = false; for (int i = 0; i < typeParameters.size(); i++) { typeParams[i] = resolvedTypeParameters.get(typeParameters.get(i)); if (typeParams[i].kind().equals(Kind.WILDCARD_TYPE) && producerFieldOrMethod != null) { LOGGER.info("Producer " + (producerFieldOrMethod.kind().equals(AnnotationTarget.Kind.FIELD) ? "field " : "method ") + producerFieldOrMethod + " contains a parameterized typed with a wildcard. This type is not a legal bean type" + " according to CDI specification and will be ignored during bean resolution."); skipThisType = true; } } if (resolvedTypeVariablesConsumer != null) { Map<TypeVariable, Type> resolved = new HashMap<>(); for (int i = 0; i < typeParameters.size(); i++) { resolved.put(typeParameters.get(i), typeParams[i]); } resolvedTypeVariablesConsumer.accept(classInfo, resolved); } if (!skipThisType) { types.add(ParameterizedType.create(classInfo.name(), typeParams, null)); } } for (Type interfaceType : classInfo.interfaceTypes()) { if (BANNED_INTERFACE_TYPES.contains(interfaceType.name())) { continue; } ClassInfo interfaceClassInfo = getClassByName(beanDeployment.getBeanArchiveIndex(), interfaceType.name()); if (interfaceClassInfo != null) { Map<TypeVariable, Type> resolved = Collections.emptyMap(); if (Kind.PARAMETERIZED_TYPE.equals(interfaceType.kind())) { resolved = buildResolvedMap(interfaceType.asParameterizedType().arguments(), interfaceClassInfo.typeParameters(), resolvedTypeParameters, beanDeployment.getBeanArchiveIndex()); } types.addAll(getTypeClosure(interfaceClassInfo, producerFieldOrMethod, resolved, beanDeployment, resolvedTypeVariablesConsumer)); } } if (classInfo.superClassType() != null) { ClassInfo superClassInfo = getClassByName(beanDeployment.getBeanArchiveIndex(), classInfo.superName()); if (superClassInfo != null) { Map<TypeVariable, Type> resolved = Collections.emptyMap(); if (Kind.PARAMETERIZED_TYPE.equals(classInfo.superClassType().kind())) { resolved = buildResolvedMap(classInfo.superClassType().asParameterizedType().arguments(), superClassInfo.typeParameters(), resolvedTypeParameters, beanDeployment.getBeanArchiveIndex()); } types.addAll(getTypeClosure(superClassInfo, producerFieldOrMethod, resolved, beanDeployment, resolvedTypeVariablesConsumer)); } } return types; } private  Types();  }
Types { static Set<Type> getTypeClosure(ClassInfo classInfo, AnnotationTarget producerFieldOrMethod, Map<TypeVariable, Type> resolvedTypeParameters, BeanDeployment beanDeployment, BiConsumer<ClassInfo, Map<TypeVariable, Type>> resolvedTypeVariablesConsumer) { Set<Type> types = new HashSet<>(); List<TypeVariable> typeParameters = classInfo.typeParameters(); if (typeParameters.isEmpty() || !typeParameters.stream().allMatch(resolvedTypeParameters::containsKey)) { types.add(Type.create(classInfo.name(), Kind.CLASS)); } else { Type[] typeParams = new Type[typeParameters.size()]; boolean skipThisType = false; for (int i = 0; i < typeParameters.size(); i++) { typeParams[i] = resolvedTypeParameters.get(typeParameters.get(i)); if (typeParams[i].kind().equals(Kind.WILDCARD_TYPE) && producerFieldOrMethod != null) { LOGGER.info("Producer " + (producerFieldOrMethod.kind().equals(AnnotationTarget.Kind.FIELD) ? "field " : "method ") + producerFieldOrMethod + " contains a parameterized typed with a wildcard. This type is not a legal bean type" + " according to CDI specification and will be ignored during bean resolution."); skipThisType = true; } } if (resolvedTypeVariablesConsumer != null) { Map<TypeVariable, Type> resolved = new HashMap<>(); for (int i = 0; i < typeParameters.size(); i++) { resolved.put(typeParameters.get(i), typeParams[i]); } resolvedTypeVariablesConsumer.accept(classInfo, resolved); } if (!skipThisType) { types.add(ParameterizedType.create(classInfo.name(), typeParams, null)); } } for (Type interfaceType : classInfo.interfaceTypes()) { if (BANNED_INTERFACE_TYPES.contains(interfaceType.name())) { continue; } ClassInfo interfaceClassInfo = getClassByName(beanDeployment.getBeanArchiveIndex(), interfaceType.name()); if (interfaceClassInfo != null) { Map<TypeVariable, Type> resolved = Collections.emptyMap(); if (Kind.PARAMETERIZED_TYPE.equals(interfaceType.kind())) { resolved = buildResolvedMap(interfaceType.asParameterizedType().arguments(), interfaceClassInfo.typeParameters(), resolvedTypeParameters, beanDeployment.getBeanArchiveIndex()); } types.addAll(getTypeClosure(interfaceClassInfo, producerFieldOrMethod, resolved, beanDeployment, resolvedTypeVariablesConsumer)); } } if (classInfo.superClassType() != null) { ClassInfo superClassInfo = getClassByName(beanDeployment.getBeanArchiveIndex(), classInfo.superName()); if (superClassInfo != null) { Map<TypeVariable, Type> resolved = Collections.emptyMap(); if (Kind.PARAMETERIZED_TYPE.equals(classInfo.superClassType().kind())) { resolved = buildResolvedMap(classInfo.superClassType().asParameterizedType().arguments(), superClassInfo.typeParameters(), resolvedTypeParameters, beanDeployment.getBeanArchiveIndex()); } types.addAll(getTypeClosure(superClassInfo, producerFieldOrMethod, resolved, beanDeployment, resolvedTypeVariablesConsumer)); } } return types; } private  Types();   }