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
}
}
}