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

Upgrade to scalameta v4.0-M8 #786

Merged
merged 1 commit into from
Aug 9, 2018
Merged
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
2 changes: 1 addition & 1 deletion project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import sbt._
/* scalafmt: { maxColumn = 120 }*/

object Dependencies {
val scalametaV = "4.0.0-M6"
val scalametaV = "4.0.0-M8"
val metaconfigV = "0.8.3"
def dotty = "0.9.0-RC1"
def scala210 = "2.10.6"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import java.io.InputStream
import java.nio.charset.StandardCharsets
import scala.meta.internal.ScalametaInternals
import scala.meta.internal.semanticdb.SymbolInformation
import scala.meta.internal.semanticdb.Accessibility.{Tag => a}
import scala.meta.internal.semanticdb.SymbolInformation.{Property => p}
import scala.meta.internal.semanticdb.SymbolInformation.{Kind => k}
import scala.meta.internal.{semanticdb => s}
Expand All @@ -18,8 +17,8 @@ import scalafix.v1.Sym
import scalafix.v1.SemanticDoc
import scalafix.v0
import scalafix.v0._

import DocSemanticdbIndex._
import scalafix.internal.v0.LegacyCodePrinter

class DocSemanticdbIndex(val doc: SemanticDoc)
extends CrashingSemanticdbIndex
Expand Down Expand Up @@ -133,10 +132,12 @@ object DocSemanticdbIndex {
if (stest(p.STATIC)) dflip(d.STATIC)
if (stest(p.PRIMARY)) dflip(d.PRIMARY)
if (stest(p.ENUM)) dflip(d.ENUM)
info.accessibility.map(_.tag) match {
case Some(a.PRIVATE | a.PRIVATE_THIS | a.PRIVATE_WITHIN) =>
info.access match {
case _: s.PrivateAccess | _: s.PrivateThisAccess |
_: s.PrivateWithinAccess =>
dflip(d.PRIVATE)
case Some(a.PROTECTED | a.PROTECTED_THIS | a.PROTECTED_WITHIN) =>
case _: s.ProtectedAccess | _: s.ProtectedThisAccess |
_: s.ProtectedWithinAccess =>
dflip(d.PROTECTED)
case _ =>
()
Expand Down Expand Up @@ -179,22 +180,7 @@ object DocSemanticdbIndex {
def syntheticToLegacy(doc: SemanticDoc, synthetic: s.Synthetic): Synthetic = {
val pos =
ScalametaInternals.positionFromRange(doc.input, synthetic.range)
val names: List[ResolvedName] = synthetic.text match {
case Some(td) =>
val input = Input.Stream(
InputSynthetic(td.text, doc.input, pos.start, pos.end),
StandardCharsets.UTF_8)
td.occurrences.iterator
.map(o => occurrenceToLegacy(doc, input, o))
.toList
case _ =>
Nil
}
Synthetic(
pos,
synthetic.text.fold("")(_.text),
names
)
new LegacyCodePrinter().toLegacy(synthetic, doc, pos)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import scala.meta.internal.symtab.SymbolTable
import scala.meta.internal.semanticdb.Scala._
import scala.meta.internal.semanticdb.SymbolInformation.{Kind => k}
import scala.meta.internal.semanticdb.SymbolInformation.{Property => p}
import scala.meta.internal.semanticdb.Accessibility.{Tag => a}
import scala.meta.internal.{semanticdb => s}
import scala.util.control.NoStackTrace
import scala.util.control.NonFatal
Expand Down Expand Up @@ -413,9 +412,9 @@ class PrettyType private (
case class TypeToTreeError(msg: String, cause: Option[Throwable] = None)
extends Exception(msg, cause.orNull)
def fail(sig: s.Signature): Nothing =
fail(sig.toSignatureMessage)
fail(sig.asMessage)
def fail(tpe: s.Type): Nothing =
fail(tpe.toTypeMessage)
fail(tpe.asMessage)
def fail(tree: Tree): Nothing =
throw TypeToTreeError(tree.syntax + s"\n\n${tree.structure}")
def fail(any: GeneratedMessage): Nothing =
Expand Down Expand Up @@ -687,22 +686,20 @@ class PrettyType private (

def toMods(info: s.SymbolInformation): List[Mod] = {
val buf = List.newBuilder[Mod]
info.accessibility.foreach { accessibility =>
accessibility.tag match {
case a.PRIVATE =>
buf += Mod.Private(Name.Anonymous())
case a.PRIVATE_WITHIN =>
buf += Mod.Private(accessibility.symbol.toIndeterminateName)
case a.PRIVATE_THIS =>
buf += Mod.Private(Term.This(Name.Anonymous()))
case a.PROTECTED =>
buf += Mod.Protected(Name.Anonymous())
case a.PROTECTED_WITHIN =>
buf += Mod.Protected(accessibility.symbol.toIndeterminateName)
case a.PROTECTED_THIS =>
buf += Mod.Protected(Term.This(Name.Anonymous()))
case _ =>
}
info.access match {
case s.PrivateAccess() =>
buf += Mod.Private(Name.Anonymous())
case s.PrivateWithinAccess(symbol) =>
buf += Mod.Private(symbol.toIndeterminateName)
case s.PrivateThisAccess() =>
buf += Mod.Private(Term.This(Name.Anonymous()))
case s.ProtectedAccess() =>
buf += Mod.Protected(Name.Anonymous())
case s.ProtectedWithinAccess(symbol) =>
buf += Mod.Protected(symbol.toIndeterminateName)
case s.ProtectedThisAccess() =>
buf += Mod.Protected(Term.This(Name.Anonymous()))
case _ =>
}
if (info.is(p.SEALED)) buf += Mod.Sealed()
if (info.kind.isClass && info.is(p.ABSTRACT)) buf += Mod.Abstract()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package scalafix.internal.v0

import java.nio.charset.StandardCharsets
import scala.meta.inputs.Input
import scala.meta.inputs.Position
import scala.meta.internal.semanticdb.Scala._
import scala.meta.internal.{semanticdb => s}
import scalafix.internal.patch.DocSemanticdbIndex.InputSynthetic
import scalafix.v0
import scalafix.v0.ResolvedName
import scalafix.v1.SemanticDoc

class LegacyCodePrinter() {
case class PositionedSymbol(symbol: v0.Symbol, start: Int, end: Int)
private val buf = List.newBuilder[PositionedSymbol]
private val text = new StringBuilder
private def emit(symbol: String): Unit = {
emitCode(symbol.desc.name, symbol)
}
private def emitCode(code: String, sym: String): Unit = {
val start = text.length
text.append(code)
val end = text.length
buf += PositionedSymbol(v0.Symbol(sym), start, end)
}
private def mkString[T](start: String, trees: Seq[T], end: String)(
fn: T => Unit): Unit = {
if (trees.isEmpty) ()
else {
text.append(start)
var first = true
trees.foreach { tree =>
fn(tree)
if (first) {
first = false
} else {
text.append(", ")
}
}
text.append(end)
}
}

private def pprint(sig: s.Signature): Unit = sig match {
case s.ValueSignature(tpe) =>
pprint(tpe)
case _ =>
}
private def pprint(tpe: s.Type): Unit = tpe match {
case s.TypeRef(prefix, symbol, typeArguments) =>
prefix match {
case s.NoType =>
case _ =>
pprint(prefix)
text.append(".")
}
emit(symbol)
mkString("[", typeArguments, "]")(pprint)
// TODO(olafur): Print out more advanced types https://github.com/scalacenter/scalafix/issues/785
case s.SingleType(prefix, symbol) =>
pprint(prefix)
emit(symbol)
case s.ThisType(symbol) =>
emit(symbol)
case s.SuperType(prefix, symbol) =>
pprint(prefix)
emit(symbol)
case s.ConstantType(constant) =>
pprint(constant)
case s.IntersectionType(types) =>
types.foreach(pprint)
case s.UnionType(types) =>
types.foreach(pprint)
case s.WithType(types) =>
types.foreach(pprint)
case s.StructuralType(tpe, declarations) =>
pprint(tpe)
declarations.foreach { s =>
s.symbols.foreach(emit)
s.hardlinks.foreach(info => pprint(info.signature))
}
case s.AnnotatedType(_, tpe) =>
pprint(tpe)
case s.ExistentialType(tpe, declarations) =>
pprint(tpe)
declarations.foreach { s =>
s.symbols.foreach(emit)
s.hardlinks.foreach(info => pprint(info.signature))
}
case s.UniversalType(typeParameters, tpe) =>
typeParameters.foreach { s =>
s.symbols.foreach(emit)
s.hardlinks.foreach(info => pprint(info.signature))
}
pprint(tpe)
case s.ByNameType(tpe) =>
pprint(tpe)
case s.RepeatedType(tpe) =>
pprint(tpe)
case s.NoType =>
}
private def pprint(const: s.Constant): Unit = {
const match {
case s.NoConstant =>
text.append("<?>")
case s.UnitConstant() =>
text.append("()")
case s.BooleanConstant(true) =>
text.append(true)
case s.BooleanConstant(false) =>
text.append(false)
case s.ByteConstant(value) =>
text.append(value.toByte)
case s.ShortConstant(value) =>
text.append(value.toShort)
case s.CharConstant(value) =>
text.append("'" + value.toChar + "'")
case s.IntConstant(value) =>
text.append(value)
case s.LongConstant(value) =>
text.append(value + "L")
case s.FloatConstant(value) =>
text.append(value + "f")
case s.DoubleConstant(value) =>
text.append(value)
case s.StringConstant(value) =>
// TODO: Escape
text.append("\"" + value + "\"")
case s.NullConstant() =>
text.append("null")
}
}
private def loop(tree: s.Tree): Unit = tree match {
case s.NoTree =>
case s.ApplyTree(fn, args) =>
loop(fn)
mkString("(", args, ")")(loop)
case s.FunctionTree(params, term) =>
text.append("{")
mkString("(", params, ") => ")(loop)
loop(term)
text.append("}")
case s.IdTree(sym) =>
emit(sym)
case s.LiteralTree(const) =>
pprint(const)
case s.MacroExpansionTree(_, tpe) =>
text.append("(`macro-expandee` : ")
pprint(tpe)
text.append(")")
case s.OriginalTree(_) =>
emitCode("*", "_star_.")
case s.SelectTree(qual, id) =>
loop(qual)
text.append(".")
id.foreach(loop) // id should be no_box
case s.TypeApplyTree(fn, targs) =>
loop(fn)
mkString("[", targs, "]")(pprint)
}

def toLegacy(
synthetic: s.Synthetic,
doc: SemanticDoc,
pos: Position): v0.Synthetic = {
loop(synthetic.tree)
val input = Input.Stream(
InputSynthetic(text.result(), doc.input, pos.start, pos.end),
StandardCharsets.UTF_8)
val names = buf.result().map { sym =>
val symPos = Position.Range(input, sym.start, sym.end)
ResolvedName(symPos, sym.symbol, isDefinition = false)
}
v0.Synthetic(pos, input.text, names)
}
}
25 changes: 16 additions & 9 deletions scalafix-core/src/main/scala/scalafix/v1/Sym.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ object Sym {
def name: String = info.name
def kind: Kind = new Kind(info)
def props: Properties = new Properties(info.properties)
def access: Accessibility =
new Accessibility(info.accessibility.getOrElse(s.Accessibility()))
def access: Access = new Access(info.access)

override def toString: String = s"Sym.Info(${info.symbol})"
}
Expand Down Expand Up @@ -117,13 +116,21 @@ object Sym {
(props & property.value) != 0
}

final class Accessibility private[Sym] (a: s.Accessibility) {
def isPrivate: Boolean = a.tag.isPrivate
def isPrivateThis: Boolean = a.tag.isPrivateThis
def isProtected: Boolean = a.tag.isProtected
def isProtectedThis: Boolean = a.tag.isProtectedThis
def isPublic: Boolean = a.tag.isPublic
def within: Sym = new Sym(a.symbol)
final class Access private[Sym] (a: s.Access) {
def isPrivate: Boolean = a.isInstanceOf[s.PrivateAccess]
def isPrivateThis: Boolean = a.isInstanceOf[s.PrivateThisAccess]
def privateWithin: Option[Sym] = a match {
case s.PrivateWithinAccess(symbol) => Some(Sym(symbol))
case _ => scala.None
}
def isProtected: Boolean = a.isInstanceOf[s.ProtectedAccess]
def isProtectedThis: Boolean = a.isInstanceOf[s.ProtectedThisAccess]
def protectedWithin: Option[Sym] = a match {
case s.ProtectedWithinAccess(symbol) => Some(Sym(symbol))
case _ => scala.None
}
def isPublic: Boolean = a.isInstanceOf[s.PublicAccess]
def isNone: Boolean = a == s.NoAccess
}

final class Matcher private (doc: SemanticDoc, syms: Seq[Sym]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.SimpleFileVisitor
import java.nio.file.attribute.BasicFileAttributes
import scala.meta.io.AbsolutePath
import scala.meta.Classpath
import scala.meta.metacp
import scala.meta.internal.symtab._
import scala.meta.io.AbsolutePath

object ClasspathOps {

Expand All @@ -25,32 +24,6 @@ object ClasspathOps {
override def write(b: Int): Unit = ()
})

/** Process classpath with metacp to build semanticdbs of global symbols. **/
def toMetaClasspath(
sclasspath: Classpath,
parallel: Boolean = false,
out: PrintStream = devNull
): Option[Classpath] = {
val (processed, toProcess) = sclasspath.entries.partition { path =>
path.isDirectory &&
path.resolve("META-INF").resolve("semanticdb.semanticidx").isFile
}
val withJDK = Classpath(
bootClasspath.fold(sclasspath.entries)(_.entries ::: toProcess)
)
val default = metacp.Settings()
val settings = default
.withClasspath(withJDK)
.withScalaLibrarySynthetics(true)
.withPar(parallel)
val reporter = scala.meta.cli
.Reporter()
.withOut(devNull) // out prints classpath of proccessed classpath, which is not relevant for scalafix.
.withErr(out)
val mclasspath = scala.meta.cli.Metacp.process(settings, reporter)
mclasspath.map(x => Classpath(x.entries ++ processed))
}

def newSymbolTable(
classpath: Classpath,
parallel: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ If you must Option.get, wrap the code block with
val l: ListBuffer[Int] = scala.collection.mutable.ListBuffer.empty[Int] // assert: Disable.mutable
List(1) + "any2stringadd" /* assert: Disable.any2stringadd
^
any2stringadd is disabled and it got inferred as `scala.Predef.any2stringadd[List[Int]](*)`
any2stringadd is disabled and it got inferred as `any2stringadd[List[Int]](*)`
*/

@SuppressWarnings(Array("Disable.drop", "Disable.length"))
Expand Down