String (@NotNull PsiElement reference, @NotNull PsiClass referencedClass, @NotNull PsiClass outerClass, @NotNull PsiMethodCallExpression generatedCall, @NotNull PsiElementFactory elementFactory) { String qualifiedName = referencedClass.getName(); if (qualifiedName == null) { // TODO: handle this case as well LOG.warn("Anonymous and local classes are not supported yet"); } else { if (!PsiTreeUtil.isAncestor(outerClass, referencedClass, false)) { PsiType accessibleType = PsiReflectionAccessUtil.nearestAccessibleType(PsiTypesUtil.getClassType(referencedClass)); PsiMethod generatedMethod = (PsiMethod)PsiTreeUtil .findFirstParent(reference, x -> x instanceof PsiMethod && "invoke".equals(((PsiMethod)x).getName())); if (generatedMethod == null) { // TODO: provide this generated method somehow outside! LOG.warn("Could not find method 'invoke' in the generated class"); return "this"; } PsiParameterList parameterList = generatedMethod.getParameterList(); String referredObjectName = "outerContext" + parameterList.getParametersCount(); parameterList.add(elementFactory.createParameter(referredObjectName, accessibleType)); generatedCall.getArgumentList().add(elementFactory.createExpressionFromText(qualifiedName + ".this", null)); return referredObjectName; } } return "this"; }