Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update scalafmt-core to 3.8.4 #265

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ f3e9d962fa8ceb0db3cec08bac9e4d05635f0908

# Scala Steward: Reformat with scalafmt 3.8.3
3f51dc7447fca7c4a49087ff4255387e31ad3b0d

# Scala Steward: Reformat with scalafmt 3.8.4
d441a11f4af59b626fe6681f2d1a307c9465af83
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = 3.8.3
version = 3.8.4
maxColumn = 120
runner.dialect = scala3
fileOverride {
Expand Down
6 changes: 5 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ excludeLintKeys in Global ++= Set(ideSkipProject)
val commonSettings = commonSmlBuildSettings ++ ossPublishSettings ++ Seq(
organization := "com.softwaremill.quicklens",
updateDocs := UpdateVersionInDocs(sLog.value, organization.value, version.value, List(file("README.md"))),
scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked"), // useful for debugging macros: "-Ycheck:all", "-Xcheck-macros"
scalacOptions ++= Seq(
"-deprecation",
"-feature",
"-unchecked"
), // useful for debugging macros: "-Ycheck:all", "-Xcheck-macros"
ideSkipProject := (scalaVersion.value != scalaIdeaVersion)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ object QuicklensMacros {
def name: String

def equiv(other: Any): Boolean = (this, other) match
case (Field(name1), Field(name2)) => name1 == name2
case (Field(name1), Field(name2)) => name1 == name2
case (Extension(term1, name1), Extension(term2, name2)) => term1 == term2 && name1 == name2
case (FunctionDelegate(name1, _, typeTree1, args1), FunctionDelegate(name2, _, typeTree2, args2)) =>
name1 == name2 && typeTree1.tpe == typeTree2.tpe && args1 == args2
Expand All @@ -127,24 +127,31 @@ object QuicklensMacros {

def toPath(tree: Tree, focus: Expr[S => A]): Seq[PathSymbol] = {
tree match {

/** Field access */
case Select(deep, ident) =>
toPath(deep, focus) :+ PathSymbol.Field(ident)

/** Method call with arguments and using clause */
case Apply(Apply(Apply(TypeApply(Ident(s), typeTrees), idents), args), List(givn)) if methodSupported(s) =>
idents.flatMap(toPath(_, focus)) :+ PathSymbol.FunctionDelegate(s, givn, typeTrees.last, args)

/** Method call with no arguments and using clause */
case Apply(Apply(TypeApply(Ident(s), typeTrees), idents), List(givn)) if methodSupported(s) =>
idents.flatMap(toPath(_, focus)) :+ PathSymbol.FunctionDelegate(s, givn, typeTrees.last, List.empty)

/** Method call with one type parameter and using clause */
case a @ Apply(TypeApply(Apply(TypeApply(Ident(s), _), idents), typeTrees), List(givn)) if methodSupported(s) =>
idents.flatMap(toPath(_, focus)) :+ PathSymbol.FunctionDelegate(s, givn, typeTrees.last, List.empty)

/** Extension method, which is called e.g. as x(_$1) */
case Apply(obj@Select(term, member), Seq(deep)) if obj.symbol.flags.is(Flags.ExtensionMethod) =>
case Apply(obj @ Select(term, member), Seq(deep)) if obj.symbol.flags.is(Flags.ExtensionMethod) =>
toPath(deep, focus) :+ PathSymbol.Extension(term, member)

/** Field access */
case Apply(deep, idents) =>
toPath(deep, focus) ++ idents.flatMap(toPath(_, focus))

/** Wild card from path */
case i: Ident if i.name.startsWith("_") =>
Seq.empty
Expand Down Expand Up @@ -182,8 +189,7 @@ object QuicklensMacros {
val objSymbol = objTpe.matchingTypeSymbol
// opaque types can find members of underlying types - ignore them (see https://github.com/scala/scala3/issues/22143)
val fieldMemberSym = objSymbol.fieldMember(name)
if !objSymbol.flags.is(Flags.Deferred) && fieldMemberSym.exists then
Select(obj, fieldMemberSym)
if !objSymbol.flags.is(Flags.Deferred) && fieldMemberSym.exists then Select(obj, fieldMemberSym)
else
objSymbol.methodMember(name) match
case List(m) =>
Expand All @@ -192,10 +198,15 @@ object QuicklensMacros {
report.errorAndAbort(reportMethodError(objSymbol, name, lst))
}

def reportMethodError(sym: Symbol, name: String, lst: List[Symbol], maybeArgNames: Option[Iterable[String]] = None): String = {
def reportMethodError(
sym: Symbol,
name: String,
lst: List[Symbol],
maybeArgNames: Option[Iterable[String]] = None
): String = {
(lst, maybeArgNames) match
case (Nil, _) => noSuchMember(sym.name, name)
case (lst, None) => multipleMatchingMethods(sym.name, name, lst)
case (Nil, _) => noSuchMember(sym.name, name)
case (lst, None) => multipleMatchingMethods(sym.name, name, lst)
case (lst, Some(argNames)) => noSuitableMember(sym.name, name, argNames)
}

Expand All @@ -212,14 +223,14 @@ object QuicklensMacros {
val paramNames = msym.paramSymss.flatten.filter(_.isTerm).map(_.name)
argNames.forall(paramNames.contains)
} match
case List(m) => Some(m)
case Nil => None
case lst@(m :: _) =>
case List(m) => Some(m)
case Nil => None
case lst @ (m :: _) =>
// if we have multiple matching copy methods, pick the synthetic one, if it exists, otherwise, pick any method
val syntheticCopies = lst.filter(_.flags.is(Flags.Synthetic))
syntheticCopies match
case List(mSynth) => Some(mSynth)
case _ => Some(m)
case _ => Some(m)
}

def methodSymbolByNameAndArgs(sym: Symbol, name: String, argsMap: Map[String, Term]): Either[String, Symbol] = {
Expand All @@ -230,20 +241,25 @@ object QuicklensMacros {
else Left(s"Deferred type ${sym.name}")
}

/**
* @param argsMap normal methods receive one parameter list, extensions methods two, the first one contains the value
* on which the extension is called
* */
/** @param argsMap
* normal methods receive one parameter list, extensions methods two, the first one contains the value on which
* the extension is called
*/
def callMethod(obj: Term, copy: Symbol, argsMap: List[Map[String, Term]]) = {
require(argsMap.size == 1 || argsMap.size == 2, s"argsMap.size should be either 1 or 2, got: ${argsMap.size} ($argsMap)")
require(
argsMap.size == 1 || argsMap.size == 2,
s"argsMap.size should be either 1 or 2, got: ${argsMap.size} ($argsMap)"
)
val objTpe = obj.tpe.widenAll
val objSymbol = objTpe.matchingTypeSymbol

val typeParams = objTpe.typeArgs
val copyTree: DefDef = copy.tree.asInstanceOf[DefDef]
val copyParams: List[(String, Option[Term])] = copyTree.termParamss.zip(argsMap)
val copyParams: List[(String, Option[Term])] = copyTree.termParamss
.zip(argsMap)
.map((params, args) => params.params.map(_.name).map(name => name -> args.get(name)))
.flatten.toList
.flatten
.toList

val args = copyParams.zipWithIndex.map { case ((n, v), _i) =>
val i = _i + 1
Expand All @@ -255,7 +271,8 @@ object QuicklensMacros {
n -> v.getOrElse(defaultMethod)
}.toMap

val argLists: List[List[Term]] = copyTree.termParamss.take(argsMap.size).map(list => list.params.map(p => args(p.name)))
val argLists: List[List[Term]] =
copyTree.termParamss.take(argsMap.size).map(list => list.params.map(p => args(p.name)))

if copyTree.termParamss.drop(argLists.size).exists(_.params.exists(!_.symbol.flags.is(Flags.Implicit))) then
report.errorAndAbort(
Expand All @@ -281,8 +298,7 @@ object QuicklensMacros {
}

def findCompanionLikeObject(objSymbol: Symbol): Symbol = {
if objSymbol.companionModule.exists then
objSymbol.companionModule
if objSymbol.companionModule.exists then objSymbol.companionModule
else
val namedFromOwnerScope = objSymbol.owner.fieldMember(objSymbol.name)
if namedFromOwnerScope.flags.is(Flags.Module) then namedFromOwnerScope
Expand All @@ -293,8 +309,7 @@ object QuicklensMacros {
val companionSymbol = findCompanionLikeObject(sym)
if companionSymbol.exists then
companionSymbol.methodMember(methodName).filter(s => s.name == methodName && s.flags.is(Flags.ExtensionMethod))
else
Nil
else Nil
}

def isProductLike(sym: Symbol): Boolean = {
Expand Down Expand Up @@ -367,7 +382,9 @@ object QuicklensMacros {
callMethod(Ref(objCompanion), copy, argsWithObj)
case None => report.errorAndAbort(error)
} else
report.errorAndAbort(s"Unsupported source object: must be a case class, sealed trait or class with copy method, but got: $objSymbol of type ${objTpe.show} (${obj.show})")
report.errorAndAbort(
s"Unsupported source object: must be a case class, sealed trait or class with copy method, but got: $objSymbol of type ${objTpe.show} (${obj.show})"
)
}

def applyFunctionDelegate(
Expand Down Expand Up @@ -408,7 +425,8 @@ object QuicklensMacros {
objTerm

case (_: (PathSymbol.Field | PathSymbol.Extension), _) :: _ =>
val (fs, funs) = pathSymbols.span((ps, _) => ps.isInstanceOf[PathSymbol.Field] || ps.isInstanceOf[PathSymbol.Extension])
val (fs, funs) =
pathSymbols.span((ps, _) => ps.isInstanceOf[PathSymbol.Field] || ps.isInstanceOf[PathSymbol.Extension])
val fields = fs.collect { case (p: (PathSymbol.Field | PathSymbol.Extension), trees) => p -> trees }
val withCopiedFields: Term = caseClassCopy(owner, mod, objTerm, fields)
accumulateToCopy(owner, mod, withCopiedFields, funs)
Expand All @@ -433,9 +451,11 @@ object QuicklensMacros {
}

def extractFocus(tree: Tree): Tree = tree match {

/** Single inlined path */
case Inlined(_, _, p) =>
extractFocus(p)

/** One of paths from modifyAll */
case Block(List(DefDef(_, _, _, Some(p))), _) =>
p
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ package object quicklens {
def map[A](fa: M[A], f: A => A): M[A] = {
val mapped = fa.view.mapValues(f)
(fa match {
case sfa: SortedMap[K, A]@unchecked => sfa.sortedMapFactory.from(mapped)(using sfa.ordering)
case _ => mapped.to(fa.mapFactory)
case sfa: SortedMap[K, A] @unchecked => sfa.sortedMapFactory.from(mapped)(using sfa.ordering)
case _ => mapped.to(fa.mapFactory)
}).asInstanceOf[M[A]]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ class ExplicitCopyTest extends AnyFlatSpec with Matchers {
it should "modify a class that has a method with the same name as a field" in {
final case class PathItem()
final case class Paths(
pathItems: Map[String, PathItem] = Map.empty
pathItems: Map[String, PathItem] = Map.empty
)
final case class Docs(
paths: Paths = Paths()
paths: Paths = Paths()
) {
def paths(paths: Paths): Docs = copy(paths = paths)
}
val docs = Docs()
val r = docs.modify(_.paths.pathItems).using(m => m + ("a" -> PathItem()))
r.paths.pathItems should contain ("a" -> PathItem())
r.paths.pathItems should contain("a" -> PathItem())
}

it should "modify a case class with an additional explicit copy" in {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class ExtensionCopyTest extends AnyFlatSpec with Matchers {
val a = VecSimple(1, 2)
val b = a.modify(_.xMember).using(_ + 10)
b.xMember shouldEqual 11
*/
*/
}

it should "modify a simple class with an extension copy method in companion" in {
Expand Down