Skip to content

Commit 3ed96b8

Browse files
committed
Merge remote-tracking branch 'origin/master' into batch-files
2 parents 3a00a89 + f66225c commit 3ed96b8

File tree

246 files changed

+8156
-1376
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

246 files changed

+8156
-1376
lines changed

build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ val `dotty-language-server` = Build.`dotty-language-server`
1313
val `dotty-bench` = Build.`dotty-bench`
1414
val `dotty-bench-bootstrapped` = Build.`dotty-bench-bootstrapped`
1515
val `dotty-semanticdb` = Build.`dotty-semanticdb`
16+
val `dotty-semanticdb-input` = Build.`dotty-semanticdb-input`
1617
val `scala-library` = Build.`scala-library`
1718
val `scala-compiler` = Build.`scala-compiler`
1819
val `scala-reflect` = Build.`scala-reflect`

compiler/src/dotty/tools/dotc/Driver.scala

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package dotty.tools.dotc
22

3+
import java.nio.file.{Files, Paths}
4+
35
import dotty.tools.FatalError
46
import config.CompilerCommand
57
import core.Comments.{ContextDoc, ContextDocstrings}
68
import core.Contexts.{Context, ContextBase}
79
import core.Mode
810
import reporting._
11+
912
import scala.util.control.NonFatal
10-
import fromtasty.TASTYCompiler
13+
import fromtasty.{TASTYCompiler, TastyFileUtil}
1114

1215
/** Run the Dotty compiler.
1316
*
@@ -54,7 +57,34 @@ class Driver {
5457
}
5558

5659
val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)(ctx)
57-
(fileNames, ctx)
60+
fromTastySetup(fileNames, ctx)
61+
}
62+
63+
/** Setup extra classpath and figure out class names for tasty file inputs */
64+
private def fromTastySetup(fileNames0: List[String], ctx0: Context) = {
65+
if (ctx0.settings.fromTasty.value(ctx0)) {
66+
// Resolve classpath and class names of tasty files
67+
val (classPaths, classNames) = fileNames0.map { name =>
68+
val path = Paths.get(name)
69+
if (!name.endsWith(".tasty")) ("", name)
70+
else if (Files.exists(path)) {
71+
TastyFileUtil.getClassName(path) match {
72+
case Some(res) => res
73+
case _ =>
74+
ctx0.error(s"Could not load classname from $name.")
75+
("", name)
76+
}
77+
} else {
78+
ctx0.error(s"File $name does not exist.")
79+
("", name)
80+
}
81+
}.unzip
82+
val ctx1 = ctx0.fresh
83+
val classPaths1 = classPaths.distinct.filter(_ != "")
84+
val fullClassPath = (classPaths1 :+ ctx1.settings.classpath.value(ctx1)).mkString(java.io.File.pathSeparator)
85+
ctx1.setSetting(ctx1.settings.classpath, fullClassPath)
86+
(classNames, ctx1)
87+
} else (fileNames0, ctx0)
5888
}
5989

6090
/** Entry point to the compiler that can be conveniently used with Java reflection.

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Symbols._, StdNames._, Trees._
88
import Decorators._, transform.SymUtils._
99
import NameKinds.{UniqueName, EvidenceParamName, DefaultGetterName}
1010
import typer.FrontEnd
11+
import util.Property
1112
import collection.mutable.ListBuffer
1213
import reporting.diagnostic.messages._
1314
import reporting.trace
@@ -18,6 +19,11 @@ object desugar {
1819
import untpd._
1920
import DesugarEnums._
2021

22+
/** If a Select node carries this attachment, suppress the check
23+
* that its type refers to an acessible symbol.
24+
*/
25+
val SuppressAccessCheck = new Property.Key[Unit]
26+
2127
/** Info of a variable in a pattern: The named tree and its type */
2228
private type VarInfo = (NameTree, Tree)
2329

@@ -293,7 +299,7 @@ object desugar {
293299
val impl @ Template(constr0, parents, self, _) = cdef.rhs
294300
val mods = cdef.mods
295301
val companionMods = mods
296-
.withFlags((mods.flags & AccessFlags).toCommonFlags)
302+
.withFlags((mods.flags & (AccessFlags | Final)).toCommonFlags)
297303
.withMods(Nil)
298304

299305
var defaultGetters: List[Tree] = Nil
@@ -430,6 +436,8 @@ object desugar {
430436
// new C[Ts](paramss)
431437
lazy val creatorExpr = New(classTypeRef, constrVparamss nestedMap refOfDef)
432438

439+
val copiedAccessFlags = if (ctx.scala2Setting) EmptyFlags else AccessFlags
440+
433441
// Methods to add to a case class C[..](p1: T1, ..., pN: Tn)(moreParams)
434442
// def _1: T1 = this.p1
435443
// ...
@@ -469,7 +477,7 @@ object desugar {
469477
val copyRestParamss = derivedVparamss.tail.nestedMap(vparam =>
470478
cpy.ValDef(vparam)(rhs = EmptyTree))
471479
DefDef(nme.copy, derivedTparams, copyFirstParams :: copyRestParamss, TypeTree(), creatorExpr)
472-
.withMods(synthetic) :: Nil
480+
.withFlags(Synthetic | constr1.mods.flags & copiedAccessFlags) :: Nil
473481
}
474482
}
475483

@@ -574,7 +582,7 @@ object desugar {
574582
if (mods is Abstract) Nil
575583
else
576584
DefDef(nme.apply, derivedTparams, derivedVparamss, applyResultTpt, widenedCreatorExpr)
577-
.withFlags(Synthetic | (constr1.mods.flags & DefaultParameterized)) :: widenDefs
585+
.withFlags(Synthetic | constr1.mods.flags & (DefaultParameterized | copiedAccessFlags)) :: widenDefs
578586
val unapplyMeth = {
579587
val unapplyParam = makeSyntheticParameter(tpt = classTypeRef)
580588
val unapplyRHS = if (arity == 0) Literal(Constant(true)) else Ident(unapplyParam.name)
@@ -658,8 +666,6 @@ object desugar {
658666
flatTree(cdef1 :: companions ::: implicitWrappers)
659667
}
660668

661-
val AccessOrSynthetic: FlagSet = AccessFlags | Synthetic
662-
663669
/** Expand
664670
*
665671
* object name extends parents { self => body }
@@ -727,9 +733,11 @@ object desugar {
727733
fwd
728734
}
729735
val moduleName = tdef.name.toTermName
730-
val aliasType = cpy.TypeDef(tdef)(
731-
rhs = completeForwarder(Select(Ident(moduleName), tdef.name)))
732-
val localType = tdef.withFlags(Synthetic | Opaque)
736+
val localRef = Select(Ident(moduleName), tdef.name)
737+
localRef.pushAttachment(SuppressAccessCheck, ())
738+
val aliasType = cpy.TypeDef(tdef)(rhs = completeForwarder(localRef))
739+
val localType = tdef.withMods(Modifiers(Synthetic | Opaque).withPrivateWithin(tdef.name))
740+
733741
val companions = moduleDef(ModuleDef(
734742
moduleName, Template(emptyConstructor, Nil, EmptyValDef, localType :: Nil))
735743
.withFlags(Synthetic | Opaque))

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,9 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
399399
case Apply(fn, args) =>
400400
def isKnownPureOp(sym: Symbol) =
401401
sym.owner.isPrimitiveValueClass || sym.owner == defn.StringClass
402-
if (tree.tpe.isInstanceOf[ConstantType] && isKnownPureOp(tree.symbol)
403-
// A constant expression with pure arguments is pure.
404-
|| fn.symbol.isStable)
402+
if (tree.tpe.isInstanceOf[ConstantType] && isKnownPureOp(tree.symbol) // A constant expression with pure arguments is pure.
403+
|| fn.symbol.isStable
404+
|| fn.symbol.isPrimaryConstructor && fn.symbol.owner.isNoInitsClass) // TODO: include in isStable?
405405
minOf(exprPurity(fn), args.map(exprPurity)) `min` Pure
406406
else if (fn.symbol.is(Erased)) Pure
407407
else Impure
@@ -449,7 +449,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
449449
def isIdempotentRef(tree: Tree)(implicit ctx: Context): Boolean =
450450
refPurity(tree) >= Idempotent
451451

452-
/** If `tree` is a constant expression, its value as a Literal,
452+
/** (1) If `tree` is a constant expression, its value as a Literal,
453453
* or `tree` itself otherwise.
454454
*
455455
* Note: Demanding idempotency instead of purity in literalize is strictly speaking too loose.
@@ -485,11 +485,27 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
485485
* Ident
486486
* Select
487487
* TypeApply
488+
*
489+
* (2) A primitive unary operator expression `pre.op` where `op` is one of `+`, `-`, `~`, `!`
490+
* that has a constant type `ConstantType(v)` but that is not a constant expression
491+
* (i.e. `pre` has side-effects) is translated to
492+
*
493+
* { pre; v }
494+
*
495+
* This avoids the situation where we have a Select node that does not have a symbol.
488496
*/
489497
def constToLiteral(tree: Tree)(implicit ctx: Context): Tree = {
490498
val tree1 = ConstFold(tree)
491499
tree1.tpe.widenTermRefExpr match {
492-
case ConstantType(value) if isIdempotentExpr(tree1) => Literal(value)
500+
case ConstantType(value) =>
501+
if (isIdempotentExpr(tree1)) Literal(value)
502+
else tree1 match {
503+
case Select(qual, _) if tree1.tpe.isInstanceOf[ConstantType] =>
504+
// it's a primitive unary operator; Simplify `pre.op` to `{ pre; v }` where `v` is the value of `pre.op`
505+
Block(qual :: Nil, Literal(value))
506+
case _ =>
507+
tree1
508+
}
493509
case _ => tree1
494510
}
495511
}

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,12 @@ object Trees {
495495
case class If[-T >: Untyped] private[ast] (cond: Tree[T], thenp: Tree[T], elsep: Tree[T])
496496
extends TermTree[T] {
497497
type ThisTree[-T >: Untyped] = If[T]
498+
def isInline = false
499+
}
500+
class InlineIf[T >: Untyped] private[ast] (cond: Tree[T], thenp: Tree[T], elsep: Tree[T])
501+
extends If(cond, thenp, elsep) {
502+
override def isInline = true
503+
override def toString = s"InlineIf($cond, $thenp, $elsep)"
498504
}
499505

500506
/** A closure with an environment and a reference to a method.
@@ -515,6 +521,12 @@ object Trees {
515521
case class Match[-T >: Untyped] private[ast] (selector: Tree[T], cases: List[CaseDef[T]])
516522
extends TermTree[T] {
517523
type ThisTree[-T >: Untyped] = Match[T]
524+
def isInline = false
525+
}
526+
class InlineMatch[T >: Untyped] private[ast] (selector: Tree[T], cases: List[CaseDef[T]])
527+
extends Match(selector, cases) {
528+
override def isInline = true
529+
override def toString = s"InlineMatch($selector, $cases)"
518530
}
519531

520532
/** case pat if guard => body; only appears as child of a Match */
@@ -901,8 +913,10 @@ object Trees {
901913
type Assign = Trees.Assign[T]
902914
type Block = Trees.Block[T]
903915
type If = Trees.If[T]
916+
type InlineIf = Trees.InlineIf[T]
904917
type Closure = Trees.Closure[T]
905918
type Match = Trees.Match[T]
919+
type InlineMatch = Trees.InlineMatch[T]
906920
type CaseDef = Trees.CaseDef[T]
907921
type Labeled = Trees.Labeled[T]
908922
type Return = Trees.Return[T]
@@ -1030,6 +1044,7 @@ object Trees {
10301044
}
10311045
def If(tree: Tree)(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If = tree match {
10321046
case tree: If if (cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep) => tree
1047+
case tree: InlineIf => finalize(tree, untpd.InlineIf(cond, thenp, elsep))
10331048
case _ => finalize(tree, untpd.If(cond, thenp, elsep))
10341049
}
10351050
def Closure(tree: Tree)(env: List[Tree], meth: Tree, tpt: Tree)(implicit ctx: Context): Closure = tree match {
@@ -1038,6 +1053,7 @@ object Trees {
10381053
}
10391054
def Match(tree: Tree)(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match = tree match {
10401055
case tree: Match if (selector eq tree.selector) && (cases eq tree.cases) => tree
1056+
case tree: InlineMatch => finalize(tree, untpd.InlineMatch(selector, cases))
10411057
case _ => finalize(tree, untpd.Match(selector, cases))
10421058
}
10431059
def CaseDef(tree: Tree)(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef = tree match {

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Decorators._, DenotTransformers._
1313
import collection.mutable
1414
import util.{Property, SourceFile, NoSource}
1515
import NameKinds.{TempResultName, OuterSelectName}
16+
import typer.ConstFold
1617

1718
import scala.annotation.tailrec
1819
import scala.io.Codec
@@ -85,6 +86,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
8586
def If(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If =
8687
ta.assignType(untpd.If(cond, thenp, elsep), thenp, elsep)
8788

89+
def InlineIf(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If =
90+
ta.assignType(untpd.InlineIf(cond, thenp, elsep), thenp, elsep)
91+
8892
def Closure(env: List[Tree], meth: Tree, tpt: Tree)(implicit ctx: Context): Closure =
8993
ta.assignType(untpd.Closure(env, meth, tpt), meth, tpt)
9094

@@ -121,6 +125,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
121125
def Match(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match =
122126
ta.assignType(untpd.Match(selector, cases), selector, cases)
123127

128+
def InlineMatch(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match =
129+
ta.assignType(untpd.InlineMatch(selector, cases), selector, cases)
130+
124131
def Labeled(bind: Bind, expr: Tree)(implicit ctx: Context): Labeled =
125132
ta.assignType(untpd.Labeled(bind, expr))
126133

@@ -519,10 +526,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
519526
tree match {
520527
case tree: Select if qualifier.tpe eq tree.qualifier.tpe =>
521528
tree1.withTypeUnchecked(tree.tpe)
522-
case _ => tree.tpe match {
523-
case tpe: NamedType => tree1.withType(tpe.derivedSelect(qualifier.tpe.widenIfUnstable))
524-
case _ => tree1.withTypeUnchecked(tree.tpe)
525-
}
529+
case _ =>
530+
val tree2 = tree.tpe match {
531+
case tpe: NamedType => tree1.withType(tpe.derivedSelect(qualifier.tpe.widenIfUnstable))
532+
case _ => tree1.withTypeUnchecked(tree.tpe)
533+
}
534+
ConstFold(tree2)
526535
}
527536
}
528537

@@ -1147,5 +1156,91 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
11471156
case _ =>
11481157
EmptyTree
11491158
}
1159+
1160+
/**
1161+
* The symbols that are imported with `expr.name`
1162+
*
1163+
* @param expr The base of the import statement
1164+
* @param name The name that is being imported.
1165+
* @return All the symbols that would be imported with `expr.name`.
1166+
*/
1167+
def importedSymbols(expr: Tree, name: Name)(implicit ctx: Context): List[Symbol] = {
1168+
def lookup(name: Name): Symbol = expr.tpe.member(name).symbol
1169+
val symbols =
1170+
List(lookup(name.toTermName),
1171+
lookup(name.toTypeName),
1172+
lookup(name.moduleClassName),
1173+
lookup(name.sourceModuleName))
1174+
1175+
symbols.map(_.sourceSymbol).filter(_.exists).distinct
1176+
}
1177+
1178+
/**
1179+
* All the symbols that are imported by the first selector of `imp` that matches
1180+
* `selectorPredicate`.
1181+
*
1182+
* @param imp The import statement to analyze
1183+
* @param selectorPredicate A test to find the selector to use.
1184+
* @return The symbols imported.
1185+
*/
1186+
def importedSymbols(imp: Import,
1187+
selectorPredicate: untpd.Tree => Boolean = util.common.alwaysTrue)
1188+
(implicit ctx: Context): List[Symbol] = {
1189+
imp.selectors.find(selectorPredicate) match {
1190+
case Some(id: untpd.Ident) =>
1191+
importedSymbols(imp.expr, id.name)
1192+
case Some(Thicket((id: untpd.Ident) :: (_: untpd.Ident) :: Nil)) =>
1193+
importedSymbols(imp.expr, id.name)
1194+
case _ =>
1195+
Nil
1196+
}
1197+
}
1198+
1199+
/**
1200+
* The list of select trees that resolve to the same symbols as the ones that are imported
1201+
* by `imp`.
1202+
*/
1203+
def importSelections(imp: Import)(implicit ctx: Context): List[Select] = {
1204+
def imported(sym: Symbol, id: untpd.Ident, rename: Option[untpd.Ident]): List[Select] = {
1205+
// Give a zero-extent position to the qualifier to prevent it from being included several
1206+
// times in results in the language server.
1207+
val noPosExpr = focusPositions(imp.expr)
1208+
val selectTree = Select(noPosExpr, sym.name).withPos(id.pos)
1209+
rename match {
1210+
case None =>
1211+
selectTree :: Nil
1212+
case Some(rename) =>
1213+
// Get the type of the symbol that is actually selected, and construct a select
1214+
// node with the new name and the type of the real symbol.
1215+
val name = if (sym.name.isTypeName) rename.name.toTypeName else rename.name
1216+
val actual = Select(noPosExpr, sym.name)
1217+
val renameTree = Select(noPosExpr, name).withPos(rename.pos).withType(actual.tpe)
1218+
selectTree :: renameTree :: Nil
1219+
}
1220+
}
1221+
1222+
imp.selectors.flatMap {
1223+
case Ident(nme.WILDCARD) =>
1224+
Nil
1225+
case id: untpd.Ident =>
1226+
importedSymbols(imp.expr, id.name).flatMap { sym =>
1227+
imported(sym, id, None)
1228+
}
1229+
case Thicket((id: untpd.Ident) :: (newName: untpd.Ident) :: Nil) =>
1230+
importedSymbols(imp.expr, id.name).flatMap { sym =>
1231+
imported(sym, id, Some(newName))
1232+
}
1233+
}
1234+
}
1235+
1236+
/** Replaces all positions in `tree` with zero-extent positions */
1237+
private def focusPositions(tree: Tree)(implicit ctx: Context): Tree = {
1238+
val transformer = new tpd.TreeMap {
1239+
override def transform(tree: Tree)(implicit ctx: Context): Tree = {
1240+
super.transform(tree).withPos(tree.pos.focus)
1241+
}
1242+
}
1243+
transformer.transform(tree)
1244+
}
11501245
}
11511246

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
271271
def Assign(lhs: Tree, rhs: Tree): Assign = new Assign(lhs, rhs)
272272
def Block(stats: List[Tree], expr: Tree): Block = new Block(stats, expr)
273273
def If(cond: Tree, thenp: Tree, elsep: Tree): If = new If(cond, thenp, elsep)
274+
def InlineIf(cond: Tree, thenp: Tree, elsep: Tree): If = new InlineIf(cond, thenp, elsep)
274275
def Closure(env: List[Tree], meth: Tree, tpt: Tree): Closure = new Closure(env, meth, tpt)
275276
def Match(selector: Tree, cases: List[CaseDef]): Match = new Match(selector, cases)
277+
def InlineMatch(selector: Tree, cases: List[CaseDef]): Match = new InlineMatch(selector, cases)
276278
def CaseDef(pat: Tree, guard: Tree, body: Tree): CaseDef = new CaseDef(pat, guard, body)
277279
def Labeled(bind: Bind, expr: Tree): Labeled = new Labeled(bind, expr)
278280
def Return(expr: Tree, from: Tree): Return = new Return(expr, from)

0 commit comments

Comments
 (0)