private static PsiAnnotationMemberValue[] readFromClass( @NonNls String attributeName, @NotNull PsiAnnotation magic, PsiType type) { PsiAnnotationMemberValue fromClassAttr = magic.findAttributeValue(attributeName); PsiType fromClassType = fromClassAttr instanceof PsiClassObjectAccessExpression ? ((PsiClassObjectAccessExpression) fromClassAttr).getOperand().getType() : null; PsiClass fromClass = fromClassType instanceof PsiClassType ? ((PsiClassType) fromClassType).resolve() : null; if (fromClass == null) return null; String fqn = fromClass.getQualifiedName(); if (fqn == null) return null; List<PsiAnnotationMemberValue> constants = new ArrayList<PsiAnnotationMemberValue>(); for (PsiField field : fromClass.getFields()) { if (!field.hasModifierProperty(PsiModifier.PUBLIC) || !field.hasModifierProperty(PsiModifier.STATIC) || !field.hasModifierProperty(PsiModifier.FINAL)) continue; PsiType fieldType = field.getType(); if (!Comparing.equal(fieldType, type)) continue; PsiAssignmentExpression e = (PsiAssignmentExpression) JavaPsiFacade.getElementFactory(field.getProject()) .createExpressionFromText("x=" + fqn + "." + field.getName(), field); PsiReferenceExpression refToField = (PsiReferenceExpression) e.getRExpression(); constants.add(refToField); } if (constants.isEmpty()) return null; return constants.toArray(new PsiAnnotationMemberValue[constants.size()]); }
private static boolean visitAnnotatedElementInner( PsiElement element, AnnotatedElementVisitor visitor) { final PsiElement parent = element.getParent(); if (element instanceof PsiReferenceExpression) { if (!visitor.visitReference((PsiReferenceExpression) element)) return false; } else if (element instanceof PsiNameValuePair && parent != null && parent.getParent() instanceof PsiAnnotation) { return visitor.visitAnnotationParameter( (PsiNameValuePair) element, (PsiAnnotation) parent.getParent()); } if (parent instanceof PsiAssignmentExpression) { final PsiAssignmentExpression p = (PsiAssignmentExpression) parent; if (p.getRExpression() == element || p.getOperationTokenType() == JavaTokenType.PLUSEQ) { final PsiExpression left = p.getLExpression(); if (left instanceof PsiReferenceExpression) { if (!visitor.visitReference((PsiReferenceExpression) left)) return false; } } } else if (parent instanceof PsiConditionalExpression && ((PsiConditionalExpression) parent).getCondition() == element) { return false; } else if (parent instanceof PsiReturnStatement) { final PsiMethod m = PsiTreeUtil.getParentOfType(parent, PsiMethod.class); if (m != null) { if (!visitor.visitMethodReturnStatement((PsiReturnStatement) parent, m)) return false; } } else if (parent instanceof PsiVariable) { return visitor.visitVariable((PsiVariable) parent); } else if (parent instanceof PsiModifierListOwner) { return false; // PsiClass/PsiClassInitializer/PsiCodeBlock } else if (parent instanceof PsiArrayInitializerMemberValue || parent instanceof PsiNameValuePair) { return true; } else if (parent instanceof PsiExpressionList && parent.getParent() instanceof PsiCallExpression) { return visitor.visitMethodParameter( (PsiExpression) element, (PsiCallExpression) parent.getParent()); } return true; }
private NamesByExprInfo suggestVariableNameByExpressionPlace( PsiExpression expr, final VariableKind variableKind, boolean correctKeywords) { if (expr.getParent() instanceof PsiExpressionList) { PsiExpressionList list = (PsiExpressionList) expr.getParent(); PsiElement listParent = list.getParent(); PsiSubstitutor subst = PsiSubstitutor.EMPTY; PsiMethod method = null; if (listParent instanceof PsiMethodCallExpression) { final JavaResolveResult resolveResult = ((PsiMethodCallExpression) listParent).getMethodExpression().advancedResolve(false); method = (PsiMethod) resolveResult.getElement(); subst = resolveResult.getSubstitutor(); } else { if (listParent instanceof PsiAnonymousClass) { listParent = listParent.getParent(); } if (listParent instanceof PsiNewExpression) { method = ((PsiNewExpression) listParent).resolveConstructor(); } } if (method != null) { final PsiElement navElement = method.getNavigationElement(); if (navElement instanceof PsiMethod) { method = (PsiMethod) navElement; } PsiExpression[] expressions = list.getExpressions(); int index = -1; for (int i = 0; i < expressions.length; i++) { if (expressions[i] == expr) { index = i; break; } } PsiParameter[] parameters = method.getParameterList().getParameters(); if (index < parameters.length) { String name = parameters[index].getName(); if (name != null && TypeConversionUtil.areTypesAssignmentCompatible( subst.substitute(parameters[index].getType()), expr)) { name = variableNameToPropertyName(name, VariableKind.PARAMETER); String[] names = getSuggestionsByName(name, variableKind, false, correctKeywords); if (expressions.length == 1) { final String methodName = method.getName(); String[] words = NameUtil.nameToWords(methodName); if (words.length > 0) { final String firstWord = words[0]; if (SET_PREFIX.equals(firstWord)) { final String propertyName = methodName.substring(firstWord.length()); final String[] setterNames = getSuggestionsByName(propertyName, variableKind, false, correctKeywords); names = ArrayUtil.mergeArrays(names, setterNames); } } } return new NamesByExprInfo(name, names); } } } } else if (expr.getParent() instanceof PsiAssignmentExpression && variableKind == VariableKind.PARAMETER) { final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression) expr.getParent(); if (expr == assignmentExpression.getRExpression()) { final PsiExpression leftExpression = assignmentExpression.getLExpression(); if (leftExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression) leftExpression).getQualifier() == null) { String name = leftExpression.getText(); if (name != null) { final PsiElement resolve = ((PsiReferenceExpression) leftExpression).resolve(); if (resolve instanceof PsiVariable) { name = variableNameToPropertyName(name, getVariableKind((PsiVariable) resolve)); } String[] names = getSuggestionsByName(name, variableKind, false, correctKeywords); return new NamesByExprInfo(name, names); } } } } return new NamesByExprInfo(null, ArrayUtil.EMPTY_STRING_ARRAY); }
/** * Determines the PsiModifierListOwner for the passed element depending of the specified * LookupType. The LookupType decides whether to prefer the element a reference expressions * resolves to, or the element that is implied by the usage context ("expected type"). */ @Nullable public static PsiModifierListOwner getAnnotatedElementFor( @Nullable PsiElement element, LookupType type) { while (element != null) { if (type == LookupType.PREFER_DECLARATION || type == LookupType.DECLARATION_ONLY) { if (element instanceof PsiReferenceExpression) { final PsiElement e = ((PsiReferenceExpression) element).resolve(); if (e instanceof PsiModifierListOwner) { return (PsiModifierListOwner) e; } if (type == LookupType.DECLARATION_ONLY) { return null; } } } element = ContextComputationProcessor.getTopLevelInjectionTarget(element); final PsiElement parent = element.getParent(); if (element instanceof PsiAssignmentExpression && ((PsiAssignmentExpression) element).getOperationTokenType() == JavaTokenType.PLUSEQ) { element = ((PsiAssignmentExpression) element).getLExpression(); continue; } else if (parent instanceof PsiAssignmentExpression) { final PsiAssignmentExpression p = (PsiAssignmentExpression) parent; if (p.getRExpression() == element) { element = p.getLExpression(); continue; } } else if (parent instanceof PsiReturnStatement) { final PsiMethod m = PsiTreeUtil.getParentOfType(parent, PsiMethod.class); if (m != null) { return m; } } else if (parent instanceof PsiModifierListOwner) { return (PsiModifierListOwner) parent; } else if (parent instanceof PsiArrayInitializerMemberValue) { final PsiArrayInitializerMemberValue value = (PsiArrayInitializerMemberValue) parent; final PsiElement pair = value.getParent(); if (pair instanceof PsiNameValuePair) { return AnnotationUtil.getAnnotationMethod((PsiNameValuePair) pair); } } else if (parent instanceof PsiNameValuePair) { return AnnotationUtil.getAnnotationMethod((PsiNameValuePair) parent); } else { return PsiUtilEx.getParameterForArgument(element); } // If no annotation has been found through the usage context, check if the element // (i.e. the element the reference refers to) is annotated itself if (type != LookupType.DECLARATION_ONLY) { if (element instanceof PsiReferenceExpression) { final PsiElement e = ((PsiReferenceExpression) element).resolve(); if (e instanceof PsiModifierListOwner) { return (PsiModifierListOwner) e; } } } return null; } return null; }