def processDeclarationsForTemplateBody()

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