@Override public boolean canContain(DataModelMirror other) { Precondition.checkMustNotBeNull(other, "other"); // $NON-NLS-1$ if (other instanceof ConcreteDataModelMirror) { ConcreteDataModelMirror that = (ConcreteDataModelMirror) other; return environment.getTypeUtils().isSameType(this.type, that.type); } if (other instanceof PartialDataModelMirror) { PartialDataModelMirror that = (PartialDataModelMirror) other; Types typeUtils = environment.getTypeUtils(); return typeUtils.isSubtype(this.type, that.type.getUpperBound()) && typeUtils.isSubtype(that.type.getLowerBound(), this.type); } return false; }
private Set<ConstraintCheckError> checkAnnotationValue( TypeElement element, AnnotationMirror annotation) { Set<ConstraintCheckError> errors = CollectionHelper.newHashSet(); AnnotationValue value = annotationApiHelper.getAnnotationValue(annotation, "value"); TypeMirror valueType = (TypeMirror) value.getValue(); TypeElement valueElement = (TypeElement) typeUtils.asElement(valueType); if (valueElement.getKind().isInterface() || valueElement.getModifiers().contains(Modifier.ABSTRACT)) { errors.add( new ConstraintCheckError( element, annotation, "GROUP_SEQUENCE_PROVIDER_ANNOTATION_VALUE_MUST_BE_AN_IMPLEMENTATION_CLASS")); } else { // the TypeElement hosting the annotation is a concrete implementation of the // DefaultGroupSequenceProvider // interface. In that case, we need to check that it has a public default constructor. if (!hasPublicDefaultConstructor(valueElement)) { errors.add( new ConstraintCheckError( element, annotation, "GROUP_SEQUENCE_PROVIDER_ANNOTATION_VALUE_CLASS_MUST_HAVE_DEFAULT_CONSTRUCTOR", valueType)); } } TypeMirror genericProviderType = retrieveGenericProviderType(valueType); if (!typeUtils.isSubtype(element.asType(), genericProviderType)) { errors.add( new ConstraintCheckError( element, annotation, "GROUP_SEQUENCE_PROVIDER_ANNOTATION_VALUE_DEFINED_PROVIDER_CLASS_WITH_WRONG_TYPE", genericProviderType, element.asType())); } return errors; }
public Type getType(TypeMirror mirror) { if (mirror.getKind() == TypeKind.ERROR) { throw new AnnotationProcessingException("Encountered erroneous type " + mirror); } Type implementationType = getImplementationType(mirror); boolean isIterableType = typeUtils.isSubtype(mirror, iterableType); boolean isCollectionType = typeUtils.isSubtype(mirror, collectionType); boolean isMapType = typeUtils.isSubtype(mirror, mapType); boolean isEnumType; boolean isInterface; String name; String packageName; String qualifiedName; TypeElement typeElement; Type componentType; if (mirror.getKind() == TypeKind.DECLARED) { DeclaredType declaredType = (DeclaredType) mirror; isEnumType = declaredType.asElement().getKind() == ElementKind.ENUM; isInterface = declaredType.asElement().getKind() == ElementKind.INTERFACE; name = declaredType.asElement().getSimpleName().toString(); typeElement = (TypeElement) declaredType.asElement(); if (typeElement != null) { packageName = elementUtils.getPackageOf(typeElement).getQualifiedName().toString(); qualifiedName = typeElement.getQualifiedName().toString(); } else { packageName = null; qualifiedName = name; } componentType = null; } else if (mirror.getKind() == TypeKind.ARRAY) { TypeMirror componentTypeMirror = getComponentType(mirror); if (componentTypeMirror.getKind() == TypeKind.DECLARED) { DeclaredType declaredType = (DeclaredType) componentTypeMirror; TypeElement componentTypeElement = (TypeElement) declaredType.asElement(); name = componentTypeElement.getSimpleName().toString() + "[]"; packageName = elementUtils.getPackageOf(componentTypeElement).getQualifiedName().toString(); qualifiedName = componentTypeElement.getQualifiedName().toString() + "[]"; } else { name = mirror.toString(); packageName = null; qualifiedName = name; } isEnumType = false; isInterface = false; typeElement = null; componentType = getType(componentTypeMirror); } else { isEnumType = false; isInterface = false; name = mirror.toString(); packageName = null; qualifiedName = name; typeElement = null; componentType = null; } return new Type( typeUtils, elementUtils, this, mirror, typeElement, getTypeParameters(mirror, false), implementationType, componentType, packageName, name, qualifiedName, isInterface, isEnumType, isIterableType, isCollectionType, isMapType, isImported(name, qualifiedName)); }
public boolean isInitializedForFrame(AnnotatedTypeMirror type, TypeMirror frame) { AnnotationMirror initializationAnno = type.getEffectiveAnnotationInHierarchy(UNCLASSIFIED); TypeMirror typeFrame = getTypeFrameFromAnnotation(initializationAnno); Types types = processingEnv.getTypeUtils(); return types.isSubtype(typeFrame, frame); }
/* * Provided that m is of a type that implements interface java.util.Map: * -Given a call m.containsKey(k), ensures that k is @KeyFor("m") in the thenStore of the transfer result. * -Given a call m.put(k, ...), ensures that k is @KeyFor("m") in the thenStore and elseStore of the transfer result. */ @Override public TransferResult<CFValue, CFStore> visitMethodInvocation( MethodInvocationNode node, TransferInput<CFValue, CFStore> in) { TransferResult<CFValue, CFStore> result = super.visitMethodInvocation(node, in); String methodName = node.getTarget().getMethod().toString(); // First verify if the method name is containsKey or put. This is an inexpensive check. boolean containsKey = methodName.startsWith("containsKey("); boolean put = methodName.startsWith("put("); if (containsKey || put) { // Now verify that the receiver of the method invocation is of a type // that extends that java.util.Map interface. This is a more expensive check. javax.lang.model.util.Types types = analysis.getTypes(); TypeMirror mapInterfaceTypeMirror = types.erasure( TypesUtils.typeFromClass(types, analysis.getEnv().getElementUtils(), Map.class)); TypeMirror receiverType = types.erasure(node.getTarget().getReceiver().getType()); if (types.isSubtype(receiverType, mapInterfaceTypeMirror)) { FlowExpressionContext flowExprContext = FlowExpressionParseUtil.buildFlowExprContextForUse(node, checker); String mapName = flowExprContext.receiver.toString(); Receiver keyReceiver = flowExprContext.arguments.get(0); KeyForAnnotatedTypeFactory atypeFactory = (KeyForAnnotatedTypeFactory) analysis.getTypeFactory(); LinkedHashSet<String> keyForMaps = new LinkedHashSet<>(); keyForMaps.add(mapName); final CFValue previousKeyValue = in.getValueOfSubNode(node.getArgument(0)); if (previousKeyValue != null) { final AnnotationMirror prevAm = previousKeyValue.getType().getAnnotationInHierarchy(KEYFOR); if (prevAm != null && AnnotationUtils.areSameByClass(prevAm, KeyFor.class)) { keyForMaps.addAll(getKeys(prevAm)); } } AnnotationMirror am = atypeFactory.createKeyForAnnotationMirrorWithValue(keyForMaps); if (containsKey) { ConditionalTransferResult<CFValue, CFStore> conditionalResult = (ConditionalTransferResult<CFValue, CFStore>) result; conditionalResult.getThenStore().insertValue(keyReceiver, am); } else if (put) { result.getThenStore().insertValue(keyReceiver, am); result.getElseStore().insertValue(keyReceiver, am); } } } return result; }