in scala/scala-impl/src/org/jetbrains/plugins/scala/lang/psi/impl/toplevel/typedef/ScTemplateDefinitionImpl.scala [295:412]
def processDeclarationsForTemplateBody(processor: PsiScopeProcessor,
oldState: ResolveState,
@Nullable lastParent: PsiElement,
place: PsiElement): Boolean = {
if (DumbService.getInstance(getProject).isDumb) return true
//exception cases
this match {
case s: ScTypeParametersOwner => s.typeParametersClause match {
case Some(tpc) if isContextAncestor(tpc, place, false) => return true
case _ =>
}
case _ =>
}
// Process selftype reference
selfTypeElement match {
case Some(se) if se.name != "_" => if (!processor.execute(se, oldState))
return false
case _ =>
}
val fromType =
if (ScalaPsiUtil.isPlaceTdAncestor(this, place)) ScThisType(this)
else ScalaType.designator(this)
val state = oldState.withFromType(fromType)
this match {
case constructorOwner: ScConstructorOwner =>
constructorOwner.constructor match {
case Some(constr) if place != null && PsiTreeUtil.isContextAncestor(constr, place, false) =>
//ignore, should be processed in ScParameters
case _ =>
for (p <- constructorOwner.parameters) {
ProgressManager.checkCanceled()
if (processor.is[BaseProcessor]) {
// don't expose class parameters to Java.
if (!processor.execute(p, state))
return false
}
}
}
case _ =>
}
val eb = extendsBlock
eb.templateParents match {
case Some(p) if isContextAncestor(p, place, false) =>
eb.earlyDefinitions match {
case Some(ed) => for (m <- ed.members) {
ProgressManager.checkCanceled()
m match {
case _var: ScVariable => for (declared <- _var.declaredElements) {
ProgressManager.checkCanceled()
if (!processor.execute(declared, state))
return false
}
case _val: ScValue => for (declared <- _val.declaredElements) {
ProgressManager.checkCanceled()
if (!processor.execute(declared, state))
return false
}
}
}
case None =>
}
true
case _ =>
eb.earlyDefinitions match {
case Some(ed) if isContextAncestor(ed, place, true) =>
case _ =>
extendsBlock match {
case e: ScExtendsBlock if e != null =>
val isUnderExtendsBlock =
isContextAncestor(e, place, true) || {
val enclosingMember = place.parentOfType[ScMember]
if (enclosingMember.exists(_.isSynthetic)) isContextAncestor(this, place, true)
else false
}
if (isUnderExtendsBlock ||
ScalaPsiUtil.isSyntheticContextAncestor(e, place) ||
!isContextAncestor(this, place, true) ||
//This is a workaround for referencing type definition member from a link in the ScalaDoc of that type definition:
///** [[Example.myMethod]] */class Example { def myMethod: Int = 42 }
//The issue is that ScalaDoc element is attached to the definition
//so `isContextAncestor(this, place, true)` returns true and magicCondition1 becomes false
place.is[ScDocResolvableCodeReference]) {
this match {
case t: ScTypeDefinition =>
selfTypeElement match {
case Some(selfTypeElementValue) =>
val magicCondition2 =
!isContextAncestor(selfTypeElementValue, place, true) &&
isContextAncestor(e.templateBody.orNull, place, true) &&
!t.isInstanceOf[ScObject]
if (magicCondition2) {
processor match {
case baseProcessor: BaseProcessor =>
baseProcessor.processType(ScThisType(t), place, state)
return true
case _ =>
}
}
case _ =>
}
case _ =>
}
if (!processClassDeclarations(this, processor, state, lastParent, place))
return false
}
case _ =>
}
}
true
}
}