@Override public void visitMethod(@NotNull PsiMethod method) { super.visitMethod(method); final PsiCodeBlock body = method.getBody(); if (body == null) { return; } if (method.getNameIdentifier() == null) { return; } final PsiMethod leastConcreteSuperMethod = getLeastConcreteSuperMethod(method); if (leastConcreteSuperMethod == null) { return; } final PsiClass objectClass = ClassUtils.findObjectClass(method); final PsiMethod[] superMethods = method.findSuperMethods(objectClass); if (superMethods.length > 0) { return; } if (ignoreEmptySuperMethods) { final PsiMethod superMethod = (PsiMethod) leastConcreteSuperMethod.getNavigationElement(); if (MethodUtils.isTrivial(superMethod, true)) { return; } } if (onlyReportWhenAnnotated) { if (!AnnotationUtil.isAnnotated(leastConcreteSuperMethod, annotations)) { return; } } if (containsSuperCall(body, leastConcreteSuperMethod)) { return; } registerMethodError(method); }
@Nullable private SiblingInfo findSibling(PsiClass inheritor, PsiClass anInterface, PsiMethod method) { for (PsiMethod superMethod : anInterface.findMethodsByName(method.getName(), true)) { PsiElement navigationElement = superMethod.getNavigationElement(); if (!(navigationElement instanceof PsiMethod)) continue; // Kotlin superMethod = (PsiMethod) navigationElement; ProgressManager.checkCanceled(); PsiClass superInterface = superMethod.getContainingClass(); if (superInterface == null || myContainingClass.isInheritor(superInterface, true)) { // if containingClass implements the superInterface then it's not a sibling inheritance // but a pretty boring the usual one continue; } if (isOverridden(inheritor, method, superMethod, superInterface)) { return new SiblingInfo(superMethod, inheritor); } } return null; }
private static AllowedValues parseBeanInfo(@NotNull PsiModifierListOwner owner) { PsiMethod method = null; if (owner instanceof PsiParameter) { PsiParameter parameter = (PsiParameter) owner; PsiElement scope = parameter.getDeclarationScope(); if (!(scope instanceof PsiMethod)) return null; PsiElement nav = scope.getNavigationElement(); if (!(nav instanceof PsiMethod)) return null; method = (PsiMethod) nav; if (method.isConstructor()) { // not a property, try the @ConstructorProperties({"prop"}) PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, "java.beans.ConstructorProperties"); if (annotation == null) return null; PsiAnnotationMemberValue value = annotation.findAttributeValue("value"); if (!(value instanceof PsiArrayInitializerMemberValue)) return null; PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue) value).getInitializers(); PsiElement parent = parameter.getParent(); if (!(parent instanceof PsiParameterList)) return null; int index = ((PsiParameterList) parent).getParameterIndex(parameter); if (index >= initializers.length) return null; PsiAnnotationMemberValue initializer = initializers[index]; if (!(initializer instanceof PsiLiteralExpression)) return null; Object val = ((PsiLiteralExpression) initializer).getValue(); if (!(val instanceof String)) return null; PsiMethod setter = PropertyUtil.findPropertySetter( method.getContainingClass(), (String) val, false, false); if (setter == null) return null; // try the @beaninfo of the corresponding setter method = (PsiMethod) setter.getNavigationElement(); } } else if (owner instanceof PsiMethod) { PsiElement nav = owner.getNavigationElement(); if (!(nav instanceof PsiMethod)) return null; method = (PsiMethod) nav; } if (method == null) return null; PsiClass aClass = method.getContainingClass(); if (aClass == null) return null; if (PropertyUtil.isSimplePropertyGetter(method)) { List<PsiMethod> setters = PropertyUtil.getSetters(aClass, PropertyUtil.getPropertyNameByGetter(method)); if (setters.size() != 1) return null; method = setters.get(0); } if (!PropertyUtil.isSimplePropertySetter(method)) return null; PsiDocComment doc = method.getDocComment(); if (doc == null) return null; PsiDocTag beaninfo = doc.findTagByName("beaninfo"); if (beaninfo == null) return null; String data = StringUtil.join( beaninfo.getDataElements(), new Function<PsiElement, String>() { @Override public String fun(PsiElement element) { return element.getText(); } }, "\n"); int enumIndex = StringUtil.indexOfSubstringEnd(data, "enum:"); if (enumIndex == -1) return null; data = data.substring(enumIndex); int colon = data.indexOf(":"); int last = colon == -1 ? data.length() : data.substring(0, colon).lastIndexOf("\n"); data = data.substring(0, last); List<PsiAnnotationMemberValue> values = new ArrayList<PsiAnnotationMemberValue>(); for (String line : StringUtil.splitByLines(data)) { List<String> words = StringUtil.split(line, " ", true, true); if (words.size() != 2) continue; String ref = words.get(1); PsiExpression constRef = JavaPsiFacade.getElementFactory(aClass.getProject()) .createExpressionFromText(ref, aClass); if (!(constRef instanceof PsiReferenceExpression)) continue; PsiReferenceExpression expr = (PsiReferenceExpression) constRef; values.add(expr); } if (values.isEmpty()) return null; PsiAnnotationMemberValue[] array = values.toArray(new PsiAnnotationMemberValue[values.size()]); return new AllowedValues(array, false); }
public static PsiMethod generateConstructorPrototype( PsiClass aClass, PsiMethod baseConstructor, boolean copyJavaDoc, PsiField[] fields) throws IncorrectOperationException { PsiManager manager = aClass.getManager(); JVMElementFactory factory = JVMElementFactories.requireFactory(aClass.getLanguage(), aClass.getProject()); CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); PsiMethod constructor = factory.createConstructor(aClass.getName(), aClass); String modifier = PsiUtil.getMaximumModifierForMember(aClass, false); if (modifier != null) { PsiUtil.setModifierProperty(constructor, modifier, true); } if (baseConstructor != null) { PsiJavaCodeReferenceElement[] throwRefs = baseConstructor.getThrowsList().getReferenceElements(); for (PsiJavaCodeReferenceElement ref : throwRefs) { constructor.getThrowsList().add(ref); } if (copyJavaDoc) { final PsiDocComment docComment = ((PsiMethod) baseConstructor.getNavigationElement()).getDocComment(); if (docComment != null) { constructor.addAfter(docComment, null); } } } boolean isNotEnum = false; if (baseConstructor != null) { PsiClass superClass = aClass.getSuperClass(); LOG.assertTrue(superClass != null); if (!CommonClassNames.JAVA_LANG_ENUM.equals(superClass.getQualifiedName())) { isNotEnum = true; if (baseConstructor instanceof PsiCompiledElement) { // to get some parameter names PsiClass dummyClass = JVMElementFactories.requireFactory( baseConstructor.getLanguage(), baseConstructor.getProject()) .createClass("Dummy"); baseConstructor = (PsiMethod) dummyClass.add(baseConstructor); } PsiParameter[] params = baseConstructor.getParameterList().getParameters(); for (PsiParameter param : params) { PsiParameter newParam = factory.createParameter(param.getName(), param.getType(), aClass); GenerateMembersUtil.copyOrReplaceModifierList(param, newParam); constructor.getParameterList().add(newParam); } } } JavaCodeStyleManager javaStyle = JavaCodeStyleManager.getInstance(aClass.getProject()); final PsiMethod dummyConstructor = factory.createConstructor(aClass.getName()); dummyConstructor.getParameterList().replace(constructor.getParameterList().copy()); List<PsiParameter> fieldParams = new ArrayList<PsiParameter>(); for (PsiField field : fields) { String fieldName = field.getName(); String name = javaStyle.variableNameToPropertyName(fieldName, VariableKind.FIELD); String parmName = javaStyle.propertyNameToVariableName(name, VariableKind.PARAMETER); parmName = javaStyle.suggestUniqueVariableName(parmName, dummyConstructor, true); PsiParameter parm = factory.createParameter(parmName, field.getType(), aClass); final NullableNotNullManager nullableManager = NullableNotNullManager.getInstance(field.getProject()); final String notNull = nullableManager.getNotNull(field); if (notNull != null) { parm.getModifierList() .addAfter(factory.createAnnotationFromText("@" + notNull, field), null); } constructor.getParameterList().add(parm); dummyConstructor.getParameterList().add(parm.copy()); fieldParams.add(parm); } ConstructorBodyGenerator generator = ConstructorBodyGenerator.INSTANCE.forLanguage(aClass.getLanguage()); if (generator != null) { @NonNls StringBuilder buffer = new StringBuilder(); generator.start(buffer, constructor.getName(), PsiParameter.EMPTY_ARRAY); if (isNotEnum) { generator.generateSuperCallIfNeeded( buffer, baseConstructor.getParameterList().getParameters()); } generator.generateFieldInitialization( buffer, fields, fieldParams.toArray(new PsiParameter[fieldParams.size()])); generator.finish(buffer); PsiMethod stub = factory.createMethodFromText(buffer.toString(), aClass); constructor.getBody().replace(stub.getBody()); } constructor = (PsiMethod) codeStyleManager.reformat(constructor); return constructor; }
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); }
@Override protected boolean setupConfigurationFromContext( TestNGConfiguration configuration, ConfigurationContext context, Ref<PsiElement> sourceElement) { // TODO: check TestNG Pattern running first, before method/class (see // TestNGInClassConfigurationProducer for logic) // TODO: and PsiClassOwner not handled, which is in TestNGInClassConfigurationProducer Location location = context.getLocation(); if (location == null) { return false; } Project project = context.getProject(); PsiElement leaf = location.getPsiElement(); if (!ProjectRootsUtil.isInProjectOrLibSource(leaf)) { return false; } if (!(leaf.getContainingFile() instanceof KtFile)) { return false; } KtFile jetFile = (KtFile) leaf.getContainingFile(); if (ProjectStructureUtil.isJsKotlinModule(jetFile)) { return false; } KtNamedDeclaration declarationToRun = getDeclarationToRun(leaf); if (declarationToRun instanceof KtNamedFunction) { KtNamedFunction function = (KtNamedFunction) declarationToRun; @SuppressWarnings("unchecked") KtElement owner = PsiTreeUtil.getParentOfType(function, KtFunction.class, KtClass.class); if (owner instanceof KtClass) { PsiClass delegate = LightClassUtil.INSTANCE.getPsiClass((KtClass) owner); if (delegate != null) { for (PsiMethod method : delegate.getMethods()) { if (method.getNavigationElement() == function) { if (TestNGUtil.hasTest(method)) { return configure(configuration, location, context, project, delegate, method); } break; } } } } } if (declarationToRun instanceof KtClass) { PsiClass delegate = LightClassUtil.INSTANCE.getPsiClass((KtClassOrObject) declarationToRun); if (!isTestNGClass(delegate)) { return false; } return configure(configuration, location, context, project, delegate, null); } return false; }