Skip to content

Outline Typing #44

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

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2d2b895
Improve hash code of Names
retronym Oct 21, 2016
50ff821
Limit string interpolation intrinsic avoid compiler SOE
retronym Apr 23, 2019
86c5a03
correct jansi version in intellij setup
SethTisue Apr 25, 2019
ee27195
fix XSS vulnerability in scaladoc search
mpollmeier Apr 30, 2019
fa355d0
Optimize importedSymbol
retronym Apr 30, 2019
5e8355a
fix xss by writing the input parameter properly to the dom
mpollmeier May 2, 2019
1ad22f1
four space indentation
mpollmeier May 2, 2019
2dbf5c1
Merge pull request #8018 from mpollmeier/scaladoc-rss-fix
lrytz May 3, 2019
a09ca5b
Merge pull request #7999 from SethTisue/jansi
SethTisue May 4, 2019
f07f779
Merge pull request #7995 from retronym/ticket/10870
diesalbla May 5, 2019
3347caa
Remove unused, duplicated copy of findMacroClassLoader
retronym Apr 29, 2019
e4406b9
Improve timer-based eviction of classloader caches
retronym Apr 29, 2019
24e1365
Merge pull request #8019 from retronym/faster/imported-symbol
retronym May 8, 2019
92f6515
Merge pull request #5474 from retronym/topic/name-hash
retronym May 8, 2019
e5dab49
Rationalize subclasses of Name
retronym May 8, 2019
3b57788
Avoid direct use of Names.chrs from Symbols
retronym May 8, 2019
22f6779
Deprecate external access to Names.chrs
retronym May 8, 2019
3e468a0
Merge pull request #8021 from retronym/topic/classloader-cache-cleanup
retronym May 9, 2019
f3901f0
Fix regression in import name comparison
retronym May 11, 2019
8257b83
[nomerge] merge pull request #8051 from retronym/topic/sameName
lrytz May 13, 2019
ae27fe9
Merge pull request #8044 from retronym/topic/rationalize-names
retronym May 14, 2019
0b28d2f
Fix scalap parsing/printing of enum and class constant types
retronym May 17, 2019
d28a129
Merge pull request #8066 from retronym/topic/scalap-constant
lrytz May 17, 2019
7806650
Avoid typechecking val and def tpt-s twice
retronym Oct 29, 2018
07fafa7
Merge pull request #8075 from retronym/topic/tpt-tpe-tapestry
retronym May 21, 2019
786c657
PipelineMain: add test, make it more testable and less buggy.
retronym May 22, 2019
3cfb31c
Add experimental support for outline typing
retronym May 22, 2019
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
275 changes: 194 additions & 81 deletions src/compiler/scala/tools/nsc/PipelineMain.scala

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -197,35 +197,49 @@ final class FileBasedCache[T] {
private case class Stamp(lastModified: FileTime, size: Long, fileKey: Object)
private case class Entry(stamps: Seq[Stamp], t: T) {
val referenceCount: AtomicInteger = new AtomicInteger(1)
var timerTask: TimerTask = null
def cancelTimer(): Unit = {
timerTask match {
case null =>
case t => t.cancel()
}
}
}
private val cache = collection.mutable.Map.empty[Seq[Path], Entry]

private def referenceCountDecrementer(e: Entry, paths: Seq[Path]): Closeable = new Closeable {
var closed = false
override def close(): Unit = {
if (!closed) {
closed = true
val count = e.referenceCount.decrementAndGet()
if (count == 0) {
e.t match {
case cl: Closeable =>
FileBasedCache.timer match {
case Some(timer) =>
val task = new TimerTask {
override def run(): Unit = {
cache.synchronized {
if (e.referenceCount.compareAndSet(0, -1)) {
cache.remove(paths)
cl.close()
private def referenceCountDecrementer(e: Entry, paths: Seq[Path]): Closeable = {
// Cancel the deferred close timer (if any) that was started when the reference count
// last dropped to zero.
e.cancelTimer()

new Closeable {
var closed = false
override def close(): Unit = {
if (!closed) {
closed = true
val count = e.referenceCount.decrementAndGet()
if (count == 0) {
e.t match {
case cl: Closeable =>
FileBasedCache.timer match {
case Some(timer) =>
val task = new TimerTask {
override def run(): Unit = {
cache.synchronized {
if (e.referenceCount.compareAndSet(0, -1)) {
cache.remove(paths)
cl.close()
}
}
}
}
}
timer.schedule(task, FileBasedCache.deferCloseMs.toLong)
case None =>
cl.close()
}
case _ =>
e.timerTask = task
timer.schedule(task, FileBasedCache.deferCloseMs.toLong)
case None =>
cl.close()
}
case _ =>
}
}
}
}
Expand Down
34 changes: 0 additions & 34 deletions src/compiler/scala/tools/nsc/plugins/Plugins.scala
Original file line number Diff line number Diff line change
Expand Up @@ -167,38 +167,4 @@ trait Plugins { global: Global =>
(for (plug <- roughPluginsList ; help <- plug.optionsHelp) yield {
"\nOptions for plugin '%s':\n%s\n".format(plug.name, help)
}).mkString

/** Obtains a `ClassLoader` instance used for macro expansion.
*
* By default a new `ScalaClassLoader` is created using the classpath
* from global and the classloader of self as parent.
*
* Mirrors with runtime definitions (e.g. Repl) need to adjust this method.
*/
protected def findMacroClassLoader(): ClassLoader = {
val classpath: Seq[URL] = if (settings.YmacroClasspath.isSetByUser) {
for {
file <- scala.tools.nsc.util.ClassPath.expandPath(settings.YmacroClasspath.value, true)
af <- Option(nsc.io.AbstractFile getDirectory file)
} yield af.file.toURI.toURL
} else global.classPath.asURLs
def newLoader: () => ScalaClassLoader.URLClassLoader = () => {
analyzer.macroLogVerbose("macro classloader: initializing from -cp: %s".format(classpath))
ScalaClassLoader.fromURLs(classpath, getClass.getClassLoader)
}

val policy = settings.YcacheMacroClassLoader.value
val cache = Macros.macroClassLoadersCache
val disableCache = policy == settings.CachePolicy.None.name
val checkStamps = policy == settings.CachePolicy.LastModified.name
cache.checkCacheability(classpath, checkStamps, disableCache) match {
case Left(msg) =>
analyzer.macroLogVerbose(s"macro classloader: $msg.")
val loader = newLoader()
closeableRegistry.registerClosable(loader)
loader
case Right(paths) =>
cache.getOrCreate(paths, newLoader, closeableRegistry, checkStamps)
}
}
}
12 changes: 7 additions & 5 deletions src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,13 @@ trait Analyzer extends AnyRef
try {
val typer = newTyper(rootContext(unit))
unit.body = typer.typed(unit.body)
for (workItem <- unit.toCheck) workItem()
if (settings.warnUnusedImport)
warnUnusedImports(unit)
if (settings.warnUnused.isSetByUser)
new checkUnused(typer).apply(unit)
if (!settings.Youtline.value) {
for (workItem <- unit.toCheck) workItem()
if (settings.warnUnusedImport)
warnUnusedImports(unit)
if (settings.warnUnused.isSetByUser)
new checkUnused(typer).apply(unit)
}
}
finally {
unit.toCheck.clear()
Expand Down
7 changes: 5 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1532,10 +1532,13 @@ trait Contexts { self: Analyzer =>
var selectors = tree.selectors
@inline def current = selectors.head
while ((selectors ne Nil) && result == NoSymbol) {
if (current.rename == name.toTermName)
def sameName(name: Name, other: Name) = {
(name eq other) || (name ne null) && name.start == other.start && name.length == other.length
}
if (sameName(current.rename, name))
result = qual.tpe.nonLocalMember( // new to address #2733: consider only non-local members for imports
if (name.isTypeName) current.name.toTypeName else current.name)
else if (current.name == name.toTermName)
else if (sameName(current.name, name))
renamed = true
else if (current.name == nme.WILDCARD && !renamed && !requireExplicit)
result = qual.tpe.nonLocalMember(name)
Expand Down
12 changes: 10 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/Namers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,11 @@ trait Namers extends MethodSynthesis {

val resTpGiven =
if (tpt.isEmpty) WildcardType
else typer.typedType(tpt).tpe
else {
val tptTyped = typer.typedType(tpt)
context.unit.transformed(tpt) = tptTyped
tptTyped.tpe
}


// ignore missing types unless we can look to overridden method to recover the missing information
Expand Down Expand Up @@ -1723,7 +1727,11 @@ trait Namers extends MethodSynthesis {

tptFromRhsUnderPt
}
} else typer.typedType(tpt).tpe
} else {
val tptTyped = typer.typedType(tpt)
context.unit.transformed(tpt) = tptTyped
tptTyped.tpe
}

// println(s"val: $result / ${vdef.tpt.tpe} / ")

Expand Down
3 changes: 2 additions & 1 deletion src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1604,7 +1604,8 @@ abstract class RefChecks extends Transform {
if qual1.symbol == rd.StringContext_apply &&
treeInfo.isQualifierSafeToElide(qual) &&
lits.forall(lit => treeInfo.isLiteralString(lit)) &&
lits.length == (args.length + 1) =>
lits.length == (args.length + 1) &&
args.lengthCompare(64) <= 0 => // TODO make more robust to large input so that we can drop this condition, chunk the concatenations in manageable batches
val isRaw = sym == rd.StringContext_raw
if (isRaw) Some((lits, args))
else {
Expand Down
16 changes: 12 additions & 4 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2087,7 +2087,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
} else typedModifiers(vdef.mods)

sym.annotations.map(_.completeInfo())
val tpt1 = checkNoEscaping.privates(this, sym, typedType(vdef.tpt))
val tpt1 = checkNoEscaping.privates(this, sym, transformedOr(vdef.tpt, typedType(vdef.tpt)))
checkNonCyclic(vdef, tpt1)

// allow trait accessors: it's the only vehicle we have to hang on to annotations that must be passed down to
Expand Down Expand Up @@ -2315,7 +2315,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (isRepeatedParamType(vparam1.symbol.tpe))
StarParamNotLastError(vparam1)

val tpt1 = checkNoEscaping.privates(this, meth, typedType(ddef.tpt))
val tpt1 = checkNoEscaping.privates(this, meth, transformedOr(ddef.tpt, typedType(ddef.tpt)))
checkNonCyclic(ddef, tpt1)
ddef.tpt.setType(tpt1.tpe)
val typedMods = typedModifiers(ddef.mods)
Expand Down Expand Up @@ -5945,14 +5945,21 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
final def transformedOrTyped(tree: Tree, mode: Mode, pt: Type): Tree = {
lookupTransformed(tree) match {
case Some(tree1) => tree1
case _ => typed(tree, mode, pt)
case _ => if (canSkipRhs(tree)) EmptyTree else typed(tree, mode, pt)
}
}
final def lookupTransformed(tree: Tree): Option[Tree] =
if (phase.erasedTypes) None // OPT save the hashmap lookup in erasure type and beyond
else transformed remove tree
}

private final def canSkipRhs(tree: Tree) = settings.Youtline.value && !tree.exists {
case Super(qual, mix) =>
// conservative approximation of method bodies that may give rise to super accessors which must be
// stored in pickle.
context.owner.enclClass.isTrait || mix != tpnme.EMPTY
case _ => false
}
}

/** Finish computation of param aliases after typechecking is completed */
final def finishComputeParamAlias(): Unit = {
Expand Down Expand Up @@ -5981,6 +5988,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
superConstructorCalls.clear()
}

}

trait TypersStats {
Expand Down
2 changes: 1 addition & 1 deletion src/intellij/scala.ipr.SAMPLE
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@
<root url="jar://$USER_HOME$/.ivy2/cache/org.scala-sbt/completion/jars/completion-0.13.18.jar!/" />
<root url="jar://$USER_HOME$/.ivy2/cache/org.scala-sbt/collections/jars/collections-0.13.18.jar!/" />
<root url="jar://$USER_HOME$/.ivy2/cache/jline/jline/jars/jline-2.13.jar!/" />
<root url="jar://$USER_HOME$/.ivy2/cache/org.fusesource.jansi/jansi/jars/jansi-1.11.jar!/" />
<root url="jar://$USER_HOME$/.ivy2/cache/org.fusesource.jansi/jansi/jars/jansi-1.12.jar!/" />
<root url="jar://$USER_HOME$/.ivy2/cache/org.scala-sbt/api/jars/api-0.13.18.jar!/" />
<root url="jar://$USER_HOME$/.ivy2/cache/org.scala-sbt/classfile/jars/classfile-0.13.18.jar!/" />
<root url="jar://$USER_HOME$/.ivy2/cache/org.scala-sbt/logging/jars/logging-0.13.18.jar!/" />
Expand Down
Loading