下面列出了怎么用com.intellij.psi.PsiAnnotationMemberValue的API类实例代码及写法,或者点击链接到github查看源代码。
public static ImmutableList<EventDeclarationModel> getEventDeclarations(PsiClass psiClass) {
final PsiAnnotation layoutSpecAnnotation =
AnnotationUtil.findAnnotation(psiClass, LayoutSpec.class.getName());
if (layoutSpecAnnotation == null) {
throw new RuntimeException("LayoutSpec annotation not found on class");
}
PsiAnnotationMemberValue psiAnnotationMemberValue =
layoutSpecAnnotation.findAttributeValue("events");
ArrayList<EventDeclarationModel> eventDeclarationModels = new ArrayList<>();
if (psiAnnotationMemberValue instanceof PsiArrayInitializerMemberValue) {
PsiArrayInitializerMemberValue value =
(PsiArrayInitializerMemberValue) psiAnnotationMemberValue;
for (PsiAnnotationMemberValue annotationMemberValue : value.getInitializers()) {
PsiClassObjectAccessExpression accessExpression =
(PsiClassObjectAccessExpression) annotationMemberValue;
eventDeclarationModels.add(getEventDeclarationModel(accessExpression));
}
} else if (psiAnnotationMemberValue instanceof PsiClassObjectAccessExpression) {
eventDeclarationModels.add(
getEventDeclarationModel((PsiClassObjectAccessExpression) psiAnnotationMemberValue));
}
return ImmutableList.copyOf(eventDeclarationModels);
}
private Stream<Suggestion> fromComponent(final PsiClass clazz, final String defaultFamily) {
final PsiAnnotation componentAnnotation =
AnnotationUtil.findAnnotation(clazz, PARTITION_MAPPER, PROCESSOR, EMITTER);
final PsiAnnotationMemberValue name = componentAnnotation.findAttributeValue("name");
if (name == null || "\"\"".equals(name.getText())) {
return Stream.empty();
}
final PsiAnnotationMemberValue familyValue = componentAnnotation.findAttributeValue("family");
final String componentFamily = (familyValue == null || removeQuotes(familyValue.getText()).isEmpty()) ? null
: removeQuotes(familyValue.getText());
final String family = ofNullable(componentFamily).orElseGet(() -> ofNullable(defaultFamily).orElse(null));
if (family == null) {
return Stream.empty();
}
return Stream
.of(new Suggestion(family + "." + DISPLAY_NAME, Suggestion.Type.Family), new Suggestion(
family + "." + removeQuotes(name.getText()) + "." + DISPLAY_NAME, Suggestion.Type.Component));
}
@Override public boolean shouldShow(UsageTarget target, Usage usage) {
PsiElement element = ((UsageInfo2UsageAdapter) usage).getElement();
PsiMethod psimethod = PsiConsultantImpl.findMethod(element);
PsiAnnotationMemberValue attribValue = PsiConsultantImpl
.findTypeAttributeOfProvidesAnnotation(psimethod);
// Is it a @Provides method?
return psimethod != null
// Ensure it has an @Provides.
&& PsiConsultantImpl.hasAnnotation(psimethod, CLASS_PROVIDES)
// Check for Qualifier annotations.
&& PsiConsultantImpl.hasQuailifierAnnotations(psimethod, qualifierAnnotations)
// Right return type.
&& PsiConsultantImpl.getReturnClassFromMethod(psimethod, false)
.getName()
.equals(target.getName())
// Right type parameters.
&& PsiConsultantImpl.hasTypeParameters(psimethod, typeParameters)
// @Provides(type=SET)
&& attribValue != null
&& attribValue.textMatches(SET_TYPE);
}
@Override
protected void visitConfigGroupAnnotation(final UAnnotation node) {
final PsiArrayInitializerMemberValue configGroupValues = ConfigElementsUtils.getConfigGroupValuesAttribute(node.getJavaPsi());
for (PsiAnnotationMemberValue psiAnnotationMemberValue : configGroupValues.getInitializers()) {
if (!verifyConfigFieldReference(node, psiAnnotationMemberValue)) {
return;
}
}
}
public static <T> T getAttributeValue(final PsiAnnotation configAnnotation, String attribute) {
final PsiAnnotationMemberValue attributeValue = configAnnotation.findAttributeValue(attribute);
if (attributeValue == null) {
return null;
}
final PsiConstantEvaluationHelper evaluationHelper = JavaPsiFacade.getInstance(attributeValue.getProject())
.getConstantEvaluationHelper();
return (T) evaluationHelper.computeConstantExpression(attributeValue);
}
/**
* Returns the value of the given member name of the given annotation.
*
* @param annotation the annotation.
* @param memberName the member name.
* @return the value of the given member name of the given annotation.
*/
public static String getAnnotationMemberValue(PsiAnnotation annotation, String memberName) {
PsiAnnotationMemberValue member = annotation.findDeclaredAttributeValue(memberName);
String value = member != null && member.getText() != null ? member.getText() : null;
if (value != null && value.length() > 1 && value.charAt(0) == '"' && value.charAt(value.length() - 1) == '"') {
value = value.substring(1, value.length() - 1);
}
return value;
}
private Stream<Suggestion> fromConfiguration(final String family, final String configurationName,
final PsiClass configClazz) {
return Stream
.concat(of(configClazz.getAllFields())
.filter(field -> AnnotationUtil.findAnnotation(field, OPTION) != null)
.flatMap(field -> {
final PsiAnnotation fOption = AnnotationUtil.findAnnotation(field, OPTION);
final PsiAnnotationMemberValue fOptionValue = fOption.findAttributeValue("value");
String fieldName = removeQuotes(fOptionValue.getText());
if (fieldName.isEmpty()) {
fieldName = field.getName();
}
final Suggestion displayNameSuggestion =
new Suggestion(configurationName + "." + fieldName + "." + DISPLAY_NAME,
Suggestion.Type.Configuration);
final PsiType type = field.getType();
if ("java.lang.String".equals(type.getCanonicalText())) {
return Stream
.of(displayNameSuggestion,
new Suggestion(configurationName + "." + fieldName + "." + PLACEHOLDER,
Suggestion.Type.Configuration));
}
final PsiClass clazz = findClass(type);
if (clazz != null && clazz.isEnum()) {
return Stream
.concat(Stream.of(displayNameSuggestion),
Stream
.of(clazz.getFields())
.filter(PsiEnumConstant.class::isInstance)
.map(f -> clazz
.getName()
.substring(clazz.getName().lastIndexOf('.') + 1) + '.'
+ f.getName() + "._displayName")
.map(v -> new Suggestion(v, Suggestion.Type.Configuration)));
}
return Stream.of(displayNameSuggestion);
}), extractConfigTypes(family, configClazz));
}
private String getFamilyFromPackageInfo(final PsiPackage psiPackage, final Module module) {
return of(FilenameIndex
.getFilesByName(psiPackage.getProject(), "package-info.java", GlobalSearchScope.moduleScope(module)))
.map(psiFile -> {
if (!PsiJavaFile.class
.cast(psiFile)
.getPackageName()
.equals(psiPackage.getQualifiedName())) {
return null;
}
final String[] family = { null };
PsiJavaFile.class.cast(psiFile).accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitAnnotation(final PsiAnnotation annotation) {
super.visitAnnotation(annotation);
if (!COMPONENTS.equals(annotation.getQualifiedName())) {
return;
}
final PsiAnnotationMemberValue familyAttribute =
annotation.findAttributeValue("family");
if (familyAttribute == null) {
return;
}
family[0] = removeQuotes(familyAttribute.getText());
}
});
return family[0];
})
.filter(Objects::nonNull)
.findFirst()
.orElseGet(() -> {
final PsiPackage parent = psiPackage.getParentPackage();
if (parent == null) {
return null;
}
return getFamilyFromPackageInfo(parent, module);
});
}
/**
* Searching for the specific bean name and annotation to find it's {@link PsiClass}
* @param beanName - Name of the bean to search for.
* @param annotation - Type of bean annotation to filter on.
* @param project - Project reference to narrow the search inside.
* @return the {@link PsiClass} matching the bean name and annotation.
*/
public Optional<PsiClass> findBeanClassByName(String beanName, String annotation, Project project) {
for (PsiClass psiClass : getClassesAnnotatedWith(project, annotation)) {
final PsiAnnotation classAnnotation = psiClass.getAnnotation(annotation);
PsiAnnotationMemberValue attribute = classAnnotation.findAttributeValue("value");
if (attribute != null) {
if (attribute instanceof PsiReferenceExpressionImpl) {
//if the attribute value is field reference eg @bean(value = MyClass.BEAN_NAME)
final PsiField psiField = (PsiField) attribute.getReference().resolve();
String staticBeanName = StringUtils.stripDoubleQuotes(PsiTreeUtil.getChildOfAnyType(psiField, PsiLiteralExpression.class).getText());
if (beanName.equals(staticBeanName)) {
return Optional.of(psiClass);
}
} else {
final String value = attribute.getText();
if (beanName.equals(StringUtils.stripDoubleQuotes(value))) {
return Optional.of(psiClass);
}
}
} else {
if (Introspector.decapitalize(psiClass.getName()).equalsIgnoreCase(StringUtils.stripDoubleQuotes(beanName))) {
return Optional.of(psiClass);
}
}
}
return Optional.empty();
}
/**
* Return the bean name for the {@link PsiClass} and the specific bean annotation
* @param clazz - class to return bean name for
* @param annotationFqn - the lookup FQN string for the annotation
* @return the bean name
*/
private Optional<String> getBeanName(PsiClass clazz, String annotationFqn) {
String returnName = null;
final PsiAnnotation annotation = clazz.getAnnotation(annotationFqn);
if (annotation != null) {
final PsiAnnotationMemberValue componentAnnotation = annotation.findAttributeValue("value");
returnName = componentAnnotation != null ? StringUtils.stripDoubleQuotes(componentAnnotation.getText()) : Introspector.decapitalize(clazz.getName());
}
return Optional.ofNullable(returnName);
}
private RemoveAnnotationValueFix( @NotNull PsiAnnotationMemberValue annotationValueToRemove,
@NotNull PsiJavaCodeReferenceElement sideEffectClassReference )
{
super( message( "side.effects.annotation.declared.correctly.fix.remove.class.reference",
sideEffectClassReference.getQualifiedName() ) );
this.annotationValueToRemove = annotationValueToRemove;
}
public RemoveInvalidConcernClassReferenceFix( @NotNull PsiAnnotationMemberValue annotationValueToRemove,
@NotNull PsiJavaCodeReferenceElement concernClassReference )
{
super( message( "concerns.annotation.declared.correctly.fix.remove.concern.class.reference",
concernClassReference.getQualifiedName() ) );
this.concernClassAnnotationValue = annotationValueToRemove;
}
private ProblemDescriptor createProblemDescriptor( @NotNull InspectionManager manager,
@NotNull PsiAnnotationMemberValue mixinAnnotationValue,
@NotNull PsiJavaCodeReferenceElement mixinClassReference,
@NotNull String message )
{
RemoveInvalidMixinClassReferenceFix fix = new RemoveInvalidMixinClassReferenceFix(
mixinAnnotationValue, mixinClassReference
);
return manager.createProblemDescriptor( mixinAnnotationValue, message, fix, GENERIC_ERROR_OR_WARNING );
}
public static Collection<String> getOnX(@NotNull PsiAnnotation psiAnnotation, @NotNull String parameterName) {
PsiAnnotationMemberValue onXValue = psiAnnotation.findAttributeValue(parameterName);
if (!(onXValue instanceof PsiAnnotation)) {
return Collections.emptyList();
}
Collection<PsiAnnotation> annotations = PsiAnnotationUtil.getAnnotationValues((PsiAnnotation) onXValue, "value", PsiAnnotation.class);
Collection<String> annotationStrings = new ArrayList<>();
for (PsiAnnotation annotation : annotations) {
PsiAnnotationParameterList params = annotation.getParameterList();
annotationStrings.add(PsiAnnotationSearchUtil.getSimpleNameOf(annotation) + params.getText());
}
return annotationStrings;
}
public static PsiAnnotationMemberValue findTypeAttributeOfProvidesAnnotation(
PsiElement element ) {
PsiAnnotation annotation = findAnnotation(element, CLASS_PROVIDES);
if (annotation != null) {
return annotation.findAttributeValue(ATTRIBUTE_TYPE);
}
return null;
}
/**
* Return the appropriate return class for a given method element.
*
* @param psiMethod the method to get the return class from.
* @param expandType set this to true if return types annotated with @Provides(type=?)
* should be expanded to the appropriate collection type.
* @return the appropriate return class for the provided method element.
*/
public static PsiClass getReturnClassFromMethod(PsiMethod psiMethod, boolean expandType) {
if (psiMethod.isConstructor()) {
return psiMethod.getContainingClass();
}
PsiClassType returnType = ((PsiClassType) psiMethod.getReturnType());
if (returnType != null) {
// Check if has @Provides annotation and specified type
if (expandType) {
PsiAnnotationMemberValue attribValue = findTypeAttributeOfProvidesAnnotation(psiMethod);
if (attribValue != null) {
if (attribValue.textMatches(SET_TYPE)) {
String typeName = "java.util.Set<" + returnType.getCanonicalText() + ">";
returnType =
((PsiClassType) PsiElementFactory.SERVICE.getInstance(psiMethod.getProject())
.createTypeFromText(typeName, psiMethod));
} else if (attribValue.textMatches(MAP_TYPE)) {
// TODO(radford): Supporting map will require fetching the key type and also validating
// the qualifier for the provided key.
//
// String typeName = "java.util.Map<String, " + returnType.getCanonicalText() + ">";
// returnType = ((PsiClassType) PsiElementFactory.SERVICE.getInstance(psiMethod.getProject())
// .createTypeFromText(typeName, psiMethod));
}
}
}
return returnType.resolve();
}
return null;
}
public static List<PsiType> getTypeParameters(PsiElement psiElement) {
PsiClassType psiClassType = getPsiClassType(psiElement);
if (psiClassType == null) {
return new ArrayList<PsiType>();
}
// Check if @Provides(type=?) pattern (annotation with specified type).
PsiAnnotationMemberValue attribValue = findTypeAttributeOfProvidesAnnotation(psiElement);
if (attribValue != null) {
if (attribValue.textMatches(SET_TYPE)) {
// type = SET. Transform the type parameter to the element type.
ArrayList<PsiType> result = new ArrayList<PsiType>();
result.add(psiClassType);
return result;
} else if (attribValue.textMatches(MAP_TYPE)) {
// TODO(radford): Need to figure out key type for maps.
// type = SET or type = MAP. Transform the type parameter to the element type.
//ArrayList<PsiType> result = new ArrayList<PsiType>();
//result.add(psiKeyType):
//result.add(psiClassType);
//return result;
}
}
if (PsiConsultantImpl.isLazyOrProvider(getClass(psiClassType))) {
psiClassType = extractFirstTypeParameter(psiClassType);
}
Collection<PsiType> typeParameters =
psiClassType.resolveGenerics().getSubstitutor().getSubstitutionMap().values();
return new ArrayList<PsiType>(typeParameters);
}
/** make sure the value is boolean. */
public static boolean getBooleanValue(PsiAnnotationMemberValue value){
return Boolean.valueOf(value.getText());
}
@Override
public final ProblemDescriptor[] checkClass( @NotNull PsiClass psiClass,
@NotNull InspectionManager manager,
boolean isOnTheFly )
{
// If psiClass is not an interface, ignore
if( !psiClass.isInterface() )
{
return null;
}
// If @Mixins annotation is empty, ignore
List<PsiAnnotationMemberValue> mixinAnnotationValues = getMixinsAnnotationValue( psiClass );
if( mixinAnnotationValues.isEmpty() )
{
return null;
}
// Get all valid mixin type
Set<PsiClass> validMixinsType = getAllValidMixinTypes( psiClass );
if( validMixinsType.isEmpty() )
{
return null;
}
// For each mixin
List<ProblemDescriptor> problems = new LinkedList<ProblemDescriptor>();
for( PsiAnnotationMemberValue mixinAnnotationValue : mixinAnnotationValues )
{
PsiJavaCodeReferenceElement mixinClassReference = getMixinClassReference( mixinAnnotationValue );
// If it's not a class reference, ignore
if( mixinClassReference == null )
{
continue;
}
// If class reference can't be resolved, ignore
PsiClass mixinClass = (PsiClass) mixinClassReference.resolve();
if( mixinClass == null )
{
continue;
}
String mixinQualifiedName = mixinClass.getQualifiedName();
boolean isMixinsDeclarationValid = false;
String message = "";
if( mixinClass.isInterface() )
{
// Mixin can't be an interface
message = message( "mixin.implements.mixin.type.error.mixin.is.an.interface", mixinQualifiedName );
}
else if( isAConcern( mixinClass ) )
{
// Mixin can't be a concern
message = message( "mixin.implements.mixin.type.error.mixin.is.a.concern", mixinQualifiedName );
}
else if( isASideEffect( mixinClass ) )
{
// Mixin can't be a side effect
message = message( "mixin.implements.mixin.type.error.mixin.is.a.side.effect", mixinQualifiedName );
}
else
{
// If doesn't implement any mixin type, it's a problem
if( !isImplementValidMixinType( mixinClass, validMixinsType ) )
{
message = message(
"mixin.implements.mixin.type.error.does.not.implement.any.mixin.type",
mixinQualifiedName,
psiClass.getQualifiedName()
);
}
else
{
isMixinsDeclarationValid = true;
}
}
if( !isMixinsDeclarationValid )
{
ProblemDescriptor problemDescriptor = createProblemDescriptor(
manager, mixinAnnotationValue, mixinClassReference, message );
problems.add( problemDescriptor );
}
}
return problems.toArray( new ProblemDescriptor[problems.size()] );
}
public RemoveInvalidMixinClassReferenceFix( @NotNull PsiAnnotationMemberValue mixinClassAnnotationValue,
@NotNull PsiJavaCodeReferenceElement mixinClassReference )
{
super( message( "mixin.implements.mixin.type.fix.remove.class.reference", mixinClassReference.getQualifiedName() ) );
this.mixinClassAnnotationValue = mixinClassAnnotationValue;
}
public RemoveInvalidMixinClassReferenceFix( @NotNull PsiAnnotationMemberValue mixinsAnnotation )
{
super( message( "mixins.annotation.declared.on.mixin.type.fix.remove.mixins.annotation" ) );
this.mixinsAnnotation = mixinsAnnotation;
}