in scala/scala-impl/src/org/jetbrains/plugins/scala/lang/formatting/ScalaBlockBuilder.scala [177:278]
private def calcChildAlignment(parent: ASTNode, child: ASTNode, sharedAlignment: Alignment): Alignment =
parent.getPsi match {
case params: ScParameters =>
child.getElementType match {
case ScalaElementType.TYPE_PARAM_CLAUSE =>
NullSafe(params.getContext.getUserData(typeParameterClauseAlignmentKey))
.getOrElse(sharedAlignment)
case _ =>
val firstParameterStartsFromNewLine =
commonSettings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE ||
params.clauses.headOption.flatMap(_.parameters.headOption).forall(_.startsFromNewLine())
if (firstParameterStartsFromNewLine && !scalaSettings.INDENT_FIRST_PARAMETER) null
else {
@Nullable
def lastParamClauseAlignment = params.getUserData(parameterClauseAlignmentKey)
@Nullable
def typeParamAlignment = params.getContext.getUserData(typeParameterClauseAlignmentKey)
val childPsi = child.getPsi()
def isOnNewLine = childPsi.startsFromNewLine()
val prev = childPsi.getPrevSiblingNotWhitespaceComment
if (prev == null) {
params.putUserData(parameterClauseAlignmentKey, null)
}
if (prev == null || prev.is[ScTypeParamClause]) {
val alignment = typeParamAlignment match {
case null => sharedAlignment
case _ if isOnNewLine => NullSafe(lastParamClauseAlignment).getOrElse(typeParamAlignment)
case _ => Alignment.createAlignment()
}
params.putUserData(parameterClauseAlignmentKey, alignment)
alignment
} else {
NullSafe(lastParamClauseAlignment)
.orElse(NullSafe(typeParamAlignment))
.getOrElse(sharedAlignment)
}
}
}
case typeParameterOwner: ScTypeParametersOwner if child.getElementType == ScalaElementType.TYPE_PARAM_CLAUSE =>
// if type param clauses are over multiple lines, do not align multiple param clauses
if (child.textContains('\n')) {
sharedAlignment
} else {
val alignment = Alignment.createAlignment(true)
typeParameterOwner.putUserData(typeParameterClauseAlignmentKey, alignment)
alignment
}
case _: ScParameterClause =>
child.getElementType match {
case `tRPARENTHESIS` | `tLPARENTHESIS` => null
case _ => sharedAlignment
}
case _: ScArgumentExprList =>
child.getElementType match {
case `tRPARENTHESIS` if cs.ALIGN_MULTILINE_PARAMETERS_IN_CALLS => sharedAlignment
case `tRPARENTHESIS` | `tLPARENTHESIS` => null
case ScCodeBlockElementType.BlockExpression if ss.DO_NOT_ALIGN_BLOCK_EXPR_PARAMS => null
case _ if cs.ALIGN_MULTILINE_PARAMETERS_IN_CALLS => sharedAlignment
case _ => null
}
case patt: ScPatternArgumentList =>
child.getElementType match {
case `tRPARENTHESIS` if cs.ALIGN_MULTILINE_PARAMETERS_IN_CALLS && patt.missedLastExpr => sharedAlignment
case `tRPARENTHESIS` | `tLPARENTHESIS` => null
case ScCodeBlockElementType.BlockExpression if ss.DO_NOT_ALIGN_BLOCK_EXPR_PARAMS => null
case _ if cs.ALIGN_MULTILINE_PARAMETERS_IN_CALLS => sharedAlignment
case _ => null
}
case _: ScMethodCall | _: ScReferenceExpression =>
if (child.getElementType == tIDENTIFIER &&
child.getPsi.getParent.is[ScReferenceExpression] &&
child.getPsi.getParent.asInstanceOf[ScReferenceExpression].qualifier.isEmpty) null
else if (child.getPsi.is[ScExpression]) null
else sharedAlignment
case _: ScXmlStartTag | _: ScXmlEmptyTag =>
child.getElementType match {
case ScalaElementType.XML_ATTRIBUTE => sharedAlignment
case _ => null
}
case _: ScXmlElement =>
child.getElementType match {
case ScalaElementType.XML_START_TAG | ScalaElementType.XML_END_TAG => sharedAlignment
case _ => null
}
case param: ScParameter =>
import ScalaCodeStyleSettings._
val addAlignmentToChild = ss.ALIGN_PARAMETER_TYPES_IN_MULTILINE_DECLARATIONS match {
case ALIGN_ON_COLON => child.getElementType == tCOLON
case ALIGN_ON_TYPE => child.getElementType == ScalaElementType.PARAM_TYPE
case _ => false
}
if (addAlignmentToChild) {
val parameterClause = Option(PsiTreeUtil.getParentOfType(param, classOf[ScParameterClause], false))
val alignmentOpt = parameterClause.flatMap(cachedParameterTypeAnnotationAlignment)
alignmentOpt.getOrElse(sharedAlignment)
}
else sharedAlignment
case literal: ScInterpolatedStringLiteral if child.getElementType == tINTERPOLATED_STRING_END =>
cachedAlignment(literal).map(_.quotes).orNull
case _ =>
sharedAlignment
}