in scala/scala-impl/src/org/jetbrains/plugins/scala/lang/formatting/ScalaBlockChildAttributes.scala [99:232]
private def getChildAttributesIntellijInner(block: ScalaBlock, newChildIndex: Int, scalaSettings: ScalaCodeStyleSettings): ChildAttributes = {
val blockFirstNode = block.getNode.getPsi
val indentSize = block.settings.getIndentSize(ScalaFileType.INSTANCE)
val braceShifted = block.settings.BRACE_STYLE == CommonCodeStyleSettings.NEXT_LINE_SHIFTED
object ElementType {
def unapply(psi: PsiElement): Some[IElementType] =
Some(psi.getNode.getElementType)
}
blockFirstNode match {
case m: ScMatch =>
val isAfterLastCaseClause = m.clauses.nonEmpty
val indent =
if (isAfterLastCaseClause)
if (shouldIndentAfterCaseClause(newChildIndex, block.getSubBlocks))
Indent.getSpaceIndent(2 * indentSize)
else
Indent.getNormalIndent // we still need to indent to the `case`
else if (braceShifted) Indent.getNoneIndent
else Indent.getNormalIndent
new ChildAttributes(indent, null)
case _: ScCaseClauses =>
// used when Enter / Backspace is pressed after case clause body, in the trailing whitespace
// note: when the caret is located after the last case clause, this branch is not triggered,
// because parent of the last whitespace is ScMatch
val indent = if (shouldIndentAfterCaseClause(newChildIndex, block.getSubBlocks)) Indent.getNormalIndent else Indent.getNoneIndent
new ChildAttributes(indent, null)
case _: ScCaseClause =>
// used when Enter / Backspace is pressed inside case clause body (not in the trailing space)
new ChildAttributes(Indent.getNormalIndent, null)
case l: ScStringLiteral if l.isMultiLineString && scalaSettings.supportMultilineString =>
new ChildAttributes(Indent.getSpaceIndent(3, true), null)
case b: ScBlockExpr if b.resultExpression.exists(_.is[ScFunctionExpr]) || b.caseClauses.isDefined =>
val indent = {
val nodeBeforeLast = b.resultExpression.orElse(b.caseClauses).get.getNode.getTreePrev
val isLineBreak = nodeBeforeLast.getElementType == TokenType.WHITE_SPACE && nodeBeforeLast.textContains('\n')
val extraIndent =
if (b.isEnclosedByBraces && isLineBreak && block.getSubBlocks().size - 1 == newChildIndex) 1
else 0
val indentsCount = extraIndent + (if (braceShifted) 0 else 1)
Indent.getSpaceIndent(indentsCount * indentSize)
}
new ChildAttributes(indent, null)
case _: ScBlockExpr | _: ScEarlyDefinitions | _: ScTemplateBody | _: ScExtensionBody |
_: ScFor | _: ScWhile | _: ScCatchBlock | ElementType(ScalaTokenTypes.kYIELD | ScalaTokenTypes.kDO) =>
val indent =
if (braceShifted) {
Indent.getNoneIndent
} else {
Indent.getNormalIndent
}
new ChildAttributes(indent, null)
case scope if isBlockOnlyScope(block, scope) =>
val indent =
if (scope.getNode.getElementType == ScalaTokenTypes.tLBRACE && braceShifted) Indent.getNoneIndent
else Indent.getNormalIndent
new ChildAttributes(indent, null)
case p: ScPackaging if p.isExplicit =>
new ChildAttributes(Indent.getNormalIndent, null)
case ElementType(ScalaTokenTypes.tCOLON) if blockFirstNode.getParent.is[ScPackaging] =>
// The ScalaBlock of a packaging block starts with a ':' token
new ChildAttributes(Indent.getNormalIndent, null)
case _: ScBlock =>
val indent = blockFirstNode.getParent match {
case _: ScCaseClause | _: ScFunctionExpr => Indent.getNormalIndent
case _ => Indent.getNoneIndent
}
new ChildAttributes(indent, null)
case _: ScIf =>
new ChildAttributes(Indent.getNormalIndent(scalaSettings.ALIGN_IF_ELSE), block.getAlignment)
case x: ScDo =>
val indent =
if (x.body.isDefined) Indent.getNoneIndent
else if (block.settings.BRACE_STYLE == CommonCodeStyleSettings.NEXT_LINE_SHIFTED) Indent.getNoneIndent
else Indent.getNormalIndent
new ChildAttributes(indent, null)
case _: ScXmlElement =>
new ChildAttributes(Indent.getNormalIndent, null)
case _: ScalaFile =>
new ChildAttributes(Indent.getNoneIndent, null)
case _: ScMethodCall if newChildIndex > 0 =>
val prevChildBlock = block.getSubBlocks.get(newChildIndex - 1)
new ChildAttributes(prevChildBlock.getIndent, prevChildBlock.getAlignment)
case _: ScExpression | _: ScPattern | _: ScParameters =>
new ChildAttributes(Indent.getContinuationWithoutFirstIndent, block.getAlignment)
case _: ScDocComment =>
val indent = Indent.getSpaceIndent(if (scalaSettings.USE_SCALADOC2_FORMATTING) 2 else 1)
new ChildAttributes(indent, null)
case ElementType(ScalaTokenTypes.kIF) =>
new ChildAttributes(Indent.getNormalIndent, null)
case ElementType(ScalaTokenTypes.kELSE) =>
new ChildAttributes(Indent.getNormalIndent, null)
case p: ScParameterClause
if scalaSettings.USE_ALTERNATE_CONTINUATION_INDENT_FOR_PARAMS && isConstructorArgOrMemberFunctionParameter(p) =>
val indent = Indent.getSpaceIndent(scalaSettings.ALTERNATE_CONTINUATION_INDENT_FOR_PARAMS, false)
new ChildAttributes(indent, null)
case _: ScParameterClause =>
val indent =
if (scalaSettings.NOT_CONTINUATION_INDENT_FOR_PARAMS) Indent.getNormalIndent
else Indent.getContinuationWithoutFirstIndent
new ChildAttributes(indent, block.getAlignment)
case _: ScArgumentExprList =>
new ChildAttributes(Indent.getNormalIndent, block.getAlignment)
case _: ScFunctionalTypeElement =>
new ChildAttributes(Indent.getNormalIndent, null)
// def, var, val, type, given + `=`
case _: ScDefinitionWithAssignment =>
new ChildAttributes(Indent.getNormalIndent, null)
// extension (ss: Seq[String]) ...
case _: ScExtension =>
new ChildAttributes(Indent.getNormalIndent, null)
// given intOrd: Ord[Int] with <caret+Enter>
case (_: ScExtendsBlock) & Parent(_: ScGivenDefinition) =>
new ChildAttributes(Indent.getNormalIndent, block.getAlignment)
// given intOrd: Ord[Int] with <caret+Enter> (top level definition, as a last element in file)
// in this case `com.intellij.formatting.FormatProcessor.getParentFor` doesn't select ScExtendsBlock
case (_: ScTemplateParents) & Parent((_: ScExtendsBlock) & Parent(_: ScGivenDefinition)) if block.lastNode.getElementType == ScalaTokenTypes.kWITH =>
new ChildAttributes(Indent.getNormalIndent, null)
case ElementType(ScalaTokenTypes.kEXTENDS) =>
if (scalaSettings.ALIGN_EXTENDS_WITH == ScalaCodeStyleSettings.ALIGN_TO_EXTENDS)
new ChildAttributes(Indent.getNoneIndent, null)
else
new ChildAttributes(Indent.getNormalIndent, null)
case _: ScEnumerator =>
new ChildAttributes(Indent.getNormalIndent, null)
case _: ScImportSelectors =>
new ChildAttributes(Indent.getNormalIndent, null)
case _ =>
new ChildAttributes(Indent.getNoneIndent, null)
}
}