override fun getS4ContextWithoutCaching()

in psi/src/com/intellij/r/psi/classes/s4/context/setClass/RS4SetClassContextProvider.kt [44:106]


  override fun getS4ContextWithoutCaching(element: RPsiElement): RS4SetClassTypeContext? {
    val parentCall = PsiTreeUtil.getParentOfType(element, RCallExpression::class.java) ?: return null
    return if (parentCall.isFunctionFromLibrarySoft("setClass", "methods")) {
      val parentArgumentInfo = RArgumentInfo.getArgumentInfo(parentCall) ?: return null
      when (element) {
        parentArgumentInfo.getArgumentPassedToParameter("Class") -> {
          // setClass("<caret>")
          if (element is RStringLiteralExpression) RS4SetClassClassNameContext(element, parentCall)
          else null
        }
        parentArgumentInfo.getArgumentPassedToParameter("representation") -> {
          // setClass("MyClass", "<caret>")
          RS4SetClassRepresentationContext(element, parentCall)
        }
        parentArgumentInfo.getArgumentPassedToParameter("contains") -> {
          // setClass("MyClass", , , "<caret>")
          RS4SetClassContainsContext(element, parentCall)
        }
        else -> null
      }
    }
    else {
      val grandParentCall = PsiTreeUtil.getParentOfType(parentCall, RCallExpression::class.java) ?: return null
      if (grandParentCall.isFunctionFromLibrarySoft("setClass", "methods")) {
        val grandParentArgumentInfo = RArgumentInfo.getArgumentInfo(grandParentCall) ?: return null
        return when {
          // setClass("MyClass", contains = "<caret>")
          // setClass("MyClass", contains = c("<caret>"))
          // setClass("MyClass", contains = c(smt = "<caret>")
          // setClass("MyClass", representation = representation(smt = "<caret>")
          // setClass("MyClass", representation = representation("<caret>")
          PsiTreeUtil.isAncestor(grandParentArgumentInfo.getArgumentPassedToParameter("contains"), element, false) ||
          PsiTreeUtil.isAncestor(grandParentArgumentInfo.getArgumentPassedToParameter("representation"), element, false) -> {
            val parent = element.parent
            if (parent is RNamedArgument && parent.nameIdentifier == element) null
            else RS4SetClassDependencyClassNameContext(element, grandParentCall)
          }

          // setClass("MyClass", slots = c(name = "<caret>"))
          PsiTreeUtil.isAncestor(grandParentArgumentInfo.getArgumentPassedToParameter("slots"), element, false) -> {
            val parent = element.parent
            if (parent !is RNamedArgument || parent.assignedValue != element) null
            else RS4SetClassDependencyClassNameContext(element, grandParentCall)
          }
          else -> null
        }
      }
      else {
        val grandGrandParentCall = PsiTreeUtil.getParentOfType(grandParentCall, RCallExpression::class.java) ?: return null
        if (!grandGrandParentCall.isFunctionFromLibrarySoft("setClass", "methods")) return null
        val grandGrandParentArgumentInfo = RArgumentInfo.getArgumentInfo(grandGrandParentCall) ?: return null

        // setClass("MyClass", slots = c(name = c("<caret>")))
        // setClass("MyClass", slots = c(name = c(ext = "<caret>")))
        if (PsiTreeUtil.isAncestor(grandGrandParentArgumentInfo.getArgumentPassedToParameter("slots"), element, false)) {
          val parent = element.parent
          if (parent is RNamedArgument && parent.nameIdentifier == element) null
          else RS4SetClassDependencyClassNameContext(element, grandGrandParentCall)
        }
        else null
      }
    }
  }