From 8356e5ed8df617329707df7adc5eaf5b41aacf85 Mon Sep 17 00:00:00 2001 From: Kellen Dye Date: Thu, 8 Feb 2024 10:13:47 -0500 Subject: [PATCH] Inline scalafix --- .../src/main/scala/fix/common/Common.scala | 85 ------------------ .../main/scala/fix/v0_14_0/FixAvroCoder.scala | 87 +++++++++++++++++-- .../fix/v0_14_0/FixAvroSchemasPackage.scala | 87 +++++++++++++++++-- 3 files changed, 162 insertions(+), 97 deletions(-) delete mode 100644 scalafix/rules/src/main/scala/fix/common/Common.scala diff --git a/scalafix/rules/src/main/scala/fix/common/Common.scala b/scalafix/rules/src/main/scala/fix/common/Common.scala deleted file mode 100644 index 8e03c2cf40..0000000000 --- a/scalafix/rules/src/main/scala/fix/common/Common.scala +++ /dev/null @@ -1,85 +0,0 @@ -package fix.common - -import scalafix.v1._ -import scala.meta._ - -object Common { - - /** @return true if `sym` is a class whose parents include a type matching `parentMatcher` */ - def hasParentClass(sym: Symbol, parentMatcher: SymbolMatcher)(implicit - sd: SemanticDocument - ): Boolean = { - sym.info.get.signature match { - case ClassSignature(_, parents, _, _) => - parents - .collect { - case TypeRef(_, p, _) if parentMatcher.matches(p) => true - } - .foldLeft(false)(_ || _) - case _ => false - } - } - - /** - * Match a variable declaration, e.g. with `t @ q"..$mods val ..$patsnel: $tpeopt = $expr"` and - * pass `t` to this function. - * - * @return - * The type parameters to the type of `t` if it matches `matcher` - */ - def findMatchingValTypeParams( - t: Tree, - matcher: SymbolMatcher - )(implicit doc: SemanticDocument): List[Symbol] = { - // get the type of the declaration ... - t.symbol.info.get.signature match { - // ... and if it matches, collect all of its type parameters - case MethodSignature(_, _, TypeRef(_, symbol, typeArgs)) if matcher.matches(symbol) => - typeArgs.collect { case TypeRef(_, param, _) => param } - case _ => List.empty - } - } - - /** - * Match a type application with q"$expr[..$tpesnel]". - * - * Given some function call with a context bound e.g. - * - `func[T : ContextBoundType]` or - * - `func[T](cbt: ContextBoundType[T])` or - * - `func[T](..)(implicit cbt:ContextBoundType[T])` or - * - `Class[T : ContextBoundType]` - * - * @return - * The symbols in `tpesnel` which are a type param to the context bound type - */ - def findBoundedTypes( - expr: Term, - tpesnel: Seq[Type], - contextBoundMatcher: SymbolMatcher - )(implicit - doc: SemanticDocument - ): List[Symbol] = { - expr.symbol.info.get.signature match { - case MethodSignature(typeParams, parameterLists, _) => - // find only the types for which the context bound type is required - val contextBoundTypeParameters = parameterLists.flatten - .map(_.signature) - .collect { - case ValueSignature(TypeRef(_, symbol, args)) if contextBoundMatcher.matches(symbol) => - args.collect { case TypeRef(_, schemaSymbol, _) => schemaSymbol } - } - .flatten - - // join the actual params with the positional type params - // and filter for the ones for which the context bound is required - tpesnel - .zip(typeParams) - .collect { - case (tpe, tParam) if contextBoundTypeParameters.contains(tParam.symbol) => - tpe.symbol - } - .toList - case _ => List.empty - } - } -} diff --git a/scalafix/rules/src/main/scala/fix/v0_14_0/FixAvroCoder.scala b/scalafix/rules/src/main/scala/fix/v0_14_0/FixAvroCoder.scala index a3bef09ebb..d3485f1490 100644 --- a/scalafix/rules/src/main/scala/fix/v0_14_0/FixAvroCoder.scala +++ b/scalafix/rules/src/main/scala/fix/v0_14_0/FixAvroCoder.scala @@ -1,6 +1,5 @@ package fix.v0_14_0 -import fix.common.Common import scalafix.v1._ import scala.meta._ @@ -22,8 +21,86 @@ object FixAvroCoder { "org/apache/avro/generic/GenericRecord" ) + /** @return true if `sym` is a class whose parents include a type matching `parentMatcher` */ + def hasParentClass(sym: Symbol, parentMatcher: SymbolMatcher)(implicit + sd: SemanticDocument + ): Boolean = { + sym.info.get.signature match { + case ClassSignature(_, parents, _, _) => + parents + .collect { + case TypeRef(_, p, _) if parentMatcher.matches(p) => true + } + .foldLeft(false)(_ || _) + case _ => false + } + } + + /** + * Match a variable declaration, e.g. with `t @ q"..$mods val ..$patsnel: $tpeopt = $expr"` and + * pass `t` to this function. + * + * @return + * The type parameters to the type of `t` if it matches `matcher` + */ + def findMatchingValTypeParams( + t: Tree, + matcher: SymbolMatcher + )(implicit doc: SemanticDocument): List[Symbol] = { + // get the type of the declaration ... + t.symbol.info.get.signature match { + // ... and if it matches, collect all of its type parameters + case MethodSignature(_, _, TypeRef(_, symbol, typeArgs)) if matcher.matches(symbol) => + typeArgs.collect { case TypeRef(_, param, _) => param } + case _ => List.empty + } + } + + /** + * Match a type application with q"$expr[..$tpesnel]". + * + * Given some function call with a context bound e.g. + * - `func[T : ContextBoundType]` or + * - `func[T](cbt: ContextBoundType[T])` or + * - `func[T](..)(implicit cbt:ContextBoundType[T])` or + * - `Class[T : ContextBoundType]` + * + * @return + * The symbols in `tpesnel` which are a type param to the context bound type + */ + def findBoundedTypes( + expr: Term, + tpesnel: Seq[Type], + contextBoundMatcher: SymbolMatcher + )(implicit + doc: SemanticDocument + ): List[Symbol] = { + expr.symbol.info.get.signature match { + case MethodSignature(typeParams, parameterLists, _) => + // find only the types for which the context bound type is required + val contextBoundTypeParameters = parameterLists.flatten + .map(_.signature) + .collect { + case ValueSignature(TypeRef(_, symbol, args)) if contextBoundMatcher.matches(symbol) => + args.collect { case TypeRef(_, schemaSymbol, _) => schemaSymbol } + } + .flatten + + // join the actual params with the positional type params + // and filter for the ones for which the context bound is required + tpesnel + .zip(typeParams) + .collect { + case (tpe, tParam) if contextBoundTypeParameters.contains(tParam.symbol) => + tpe.symbol + } + .toList + case _ => List.empty + } + } + def isAvroType(sym: Symbol)(implicit sd: SemanticDocument): Boolean = - AvroMatcher.matches(sym) || Common.hasParentClass(sym, AvroMatcher) + AvroMatcher.matches(sym) || hasParentClass(sym, AvroMatcher) } class FixAvroCoder extends SemanticRule("FixAvroCoder") { @@ -34,13 +111,11 @@ class FixAvroCoder extends SemanticRule("FixAvroCoder") { .collect { case q"$expr[..$tpesnel]" => // A method call with a type parameter requires an implicit Coder[T] for our type - Common - .findBoundedTypes(expr, tpesnel, CoderMatcher) + findBoundedTypes(expr, tpesnel, CoderMatcher) .exists(isAvroType) case t @ q"..$mods val ..$patsnel: $tpeopt = $expr" => // Coder[T] is a variable type where T is an avro type - Common - .findMatchingValTypeParams(t, CoderMatcher) + findMatchingValTypeParams(t, CoderMatcher) .exists(isAvroType) } .foldLeft(false)(_ || _) diff --git a/scalafix/rules/src/main/scala/fix/v0_14_0/FixAvroSchemasPackage.scala b/scalafix/rules/src/main/scala/fix/v0_14_0/FixAvroSchemasPackage.scala index 76fd29fccd..6a6627df08 100644 --- a/scalafix/rules/src/main/scala/fix/v0_14_0/FixAvroSchemasPackage.scala +++ b/scalafix/rules/src/main/scala/fix/v0_14_0/FixAvroSchemasPackage.scala @@ -1,6 +1,5 @@ package fix.v0_14_0 -import fix.common.Common import scalafix.v1._ import scala.meta._ @@ -17,8 +16,86 @@ object FixAvroSchemasPackage { "org/apache/avro/specific/SpecificRecord" ) + /** @return true if `sym` is a class whose parents include a type matching `parentMatcher` */ + def hasParentClass(sym: Symbol, parentMatcher: SymbolMatcher)(implicit + sd: SemanticDocument + ): Boolean = { + sym.info.get.signature match { + case ClassSignature(_, parents, _, _) => + parents + .collect { + case TypeRef(_, p, _) if parentMatcher.matches(p) => true + } + .foldLeft(false)(_ || _) + case _ => false + } + } + + /** + * Match a variable declaration, e.g. with `t @ q"..$mods val ..$patsnel: $tpeopt = $expr"` and + * pass `t` to this function. + * + * @return + * The type parameters to the type of `t` if it matches `matcher` + */ + def findMatchingValTypeParams( + t: Tree, + matcher: SymbolMatcher + )(implicit doc: SemanticDocument): List[Symbol] = { + // get the type of the declaration ... + t.symbol.info.get.signature match { + // ... and if it matches, collect all of its type parameters + case MethodSignature(_, _, TypeRef(_, symbol, typeArgs)) if matcher.matches(symbol) => + typeArgs.collect { case TypeRef(_, param, _) => param } + case _ => List.empty + } + } + + /** + * Match a type application with q"$expr[..$tpesnel]". + * + * Given some function call with a context bound e.g. + * - `func[T : ContextBoundType]` or + * - `func[T](cbt: ContextBoundType[T])` or + * - `func[T](..)(implicit cbt:ContextBoundType[T])` or + * - `Class[T : ContextBoundType]` + * + * @return + * The symbols in `tpesnel` which are a type param to the context bound type + */ + def findBoundedTypes( + expr: Term, + tpesnel: Seq[Type], + contextBoundMatcher: SymbolMatcher + )(implicit + doc: SemanticDocument + ): List[Symbol] = { + expr.symbol.info.get.signature match { + case MethodSignature(typeParams, parameterLists, _) => + // find only the types for which the context bound type is required + val contextBoundTypeParameters = parameterLists.flatten + .map(_.signature) + .collect { + case ValueSignature(TypeRef(_, symbol, args)) if contextBoundMatcher.matches(symbol) => + args.collect { case TypeRef(_, schemaSymbol, _) => schemaSymbol } + } + .flatten + + // join the actual params with the positional type params + // and filter for the ones for which the context bound is required + tpesnel + .zip(typeParams) + .collect { + case (tpe, tParam) if contextBoundTypeParameters.contains(tParam.symbol) => + tpe.symbol + } + .toList + case _ => List.empty + } + } + def isSpecificRecord(sym: Symbol)(implicit sd: SemanticDocument) = - Common.hasParentClass(sym, SpecificRecordMatcher) + hasParentClass(sym, SpecificRecordMatcher) def avroImportee(imps: Seq[Importee]): Patch = { imps.collect { case i @ importee"fromAvroSchema" => @@ -35,13 +112,11 @@ class FixAvroSchemasPackage extends SemanticRule("FixAvroSchemasPackage") { .collect { case q"$expr[..$tpesnel]" => // A method call with a type parameter requires an implicit Schema[T] for our type - Common - .findBoundedTypes(expr, tpesnel, SchemaMatcher) + findBoundedTypes(expr, tpesnel, SchemaMatcher) .exists(isSpecificRecord) case t @ q"..$mods val ..$patsnel: $tpeopt = $expr" => // Schema[T] is a variable type where T <: SpecificRecord - Common - .findMatchingValTypeParams(t, SchemaMatcher) + findMatchingValTypeParams(t, SchemaMatcher) .exists(isSpecificRecord) } .foldLeft(false)(_ || _)