Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Made "mode" into a value class.

This is an obvious place to apply value class goodness and
collect some safety/sanity in typing modes. It does show off
a challenge in introducing value classes without disruption:
there's no way to deprecate the old signature of 'typed',
'adapt', etc. because they erase the same.

  class Bippy(val x: Int) extends AnyVal
  class A {
    @deprecated("Use a bippy") def f(x: Int): Int = 5
    def f(x: Bippy): Int = x.x
  }

  ./a.scala:5: error: double definition:
  method f:(x: Bippy)Int and
  method f:(x: Int)Int at line 4
  have same type after erasure: (x: Int)Int

An Int => Mode implicit handles most uses, but nothing can
be done to avoid breaking anything which e.g. extends Typer
and overrides typed.
  • Loading branch information...
commit 198d5229967367493960a6b4e0f9c382d7122a25 1 parent 816bcdf
Paul Phillips paulp authored
6 src/compiler/scala/reflect/macros/runtime/Typers.scala
View
@@ -1,6 +1,8 @@
package scala.reflect.macros
package runtime
+import scala.reflect.internal.Mode
+
trait Typers {
self: Context =>
@@ -22,7 +24,7 @@ trait Typers {
// typechecking uses silent anyways (e.g. in typedSelect), so you'll only waste your time
// I'd advise fixing the root cause: finding why the context is not set to report errors
// (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you)
- wrapper(callsiteTyper.silent(_.typed(tree, universe.analyzer.EXPRmode, pt)) match {
+ wrapper(callsiteTyper.silent(_.typed(tree, Mode.EXPRmode, pt)) match {
case universe.analyzer.SilentResultValue(result) =>
macroLogVerbose(result)
result
@@ -62,4 +64,4 @@ trait Typers {
def resetAllAttrs(tree: Tree): Tree = universe.resetAllAttrs(tree)
def resetLocalAttrs(tree: Tree): Tree = universe.resetLocalAttrs(tree)
-}
+}
2  src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
View
@@ -170,7 +170,7 @@ trait ModelFactoryImplicitSupport {
val newContext = context.makeImplicit(context.ambiguousErrors)
newContext.macrosEnabled = false
val newTyper = global.analyzer.newTyper(newContext)
- newTyper.silent(_.typed(appliedTree, global.analyzer.EXPRmode, WildcardType), false) match {
+ newTyper.silent(_.typed(appliedTree, EXPRmode, WildcardType), false) match {
case global.analyzer.SilentResultValue(t: Tree) => t
case global.analyzer.SilentTypeError(err) =>
2  src/compiler/scala/tools/nsc/interpreter/ReplGlobal.scala
View
@@ -24,7 +24,7 @@ trait ReplGlobal extends Global {
val global: ReplGlobal.this.type = ReplGlobal.this
} with Analyzer {
override def newTyper(context: Context): Typer = new Typer(context) {
- override def typed(tree: Tree, mode: Int, pt: Type): Tree = {
+ override def typed(tree: Tree, mode: Mode, pt: Type): Tree = {
val res = super.typed(tree, mode, pt)
tree match {
case Ident(name) if !tree.symbol.hasPackageFlag && !name.toString.startsWith("$") =>
9 src/compiler/scala/tools/nsc/package.scala
View
@@ -6,6 +6,15 @@
package scala.tools
package object nsc {
+ type Mode = scala.reflect.internal.Mode
+ val Mode = scala.reflect.internal.Mode
+
+ def EXPRmode = Mode.EXPRmode
+ def BYVALmode = Mode.BYVALmode
+ def POLYmode = Mode.POLYmode
+ def TAPPmode = Mode.TAPPmode
+ def FUNmode = Mode.FUNmode
+
type Phase = scala.reflect.internal.Phase
val NoPhase = scala.reflect.internal.NoPhase
5 src/compiler/scala/tools/nsc/transform/Erasure.scala
View
@@ -10,6 +10,7 @@ import scala.reflect.internal.ClassfileConstants._
import scala.collection.{ mutable, immutable }
import symtab._
import Flags._
+import scala.reflect.internal.Mode._
abstract class Erasure extends AddInterfaces
with scala.reflect.internal.transform.Erasure
@@ -801,12 +802,12 @@ abstract class Erasure extends AddInterfaces
/** A replacement for the standard typer's adapt method.
*/
- override protected def adapt(tree: Tree, mode: Int, pt: Type, original: Tree = EmptyTree): Tree =
+ override protected def adapt(tree: Tree, mode: Mode, pt: Type, original: Tree = EmptyTree): Tree =
adaptToType(tree, pt)
/** A replacement for the standard typer's `typed1` method.
*/
- override def typed1(tree: Tree, mode: Int, pt: Type): Tree = {
+ override def typed1(tree: Tree, mode: Mode, pt: Type): Tree = {
val tree1 = try {
tree match {
case InjectDerivedValue(arg) =>
2  src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
View
@@ -197,7 +197,7 @@ abstract class Duplicators extends Analyzer {
* their symbols are recreated ad-hoc and their types are fixed inline, instead of letting the
* namer/typer handle them, or Idents that refer to them.
*/
- override def typed(tree: Tree, mode: Int, pt: Type): Tree = {
+ override def typed(tree: Tree, mode: Mode, pt: Type): Tree = {
debuglog("typing " + tree + ": " + tree.tpe + ", " + tree.getClass)
val origtreesym = tree.symbol
if (tree.hasSymbolField && tree.symbol != NoSymbol
2  src/compiler/scala/tools/nsc/typechecker/Macros.scala
View
@@ -676,7 +676,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
* the expandee with an error marker set if the expansion has been cancelled due malformed arguments or implementation
* the expandee with an error marker set if there has been an error
*/
- def macroExpand(typer: Typer, expandee: Tree, mode: Int = EXPRmode, pt: Type = WildcardType): Tree = {
+ def macroExpand(typer: Typer, expandee: Tree, mode: Mode = EXPRmode, pt: Type = WildcardType): Tree = {
val start = if (Statistics.canEnable) Statistics.startTimer(macroExpandNanos) else null
if (Statistics.canEnable) Statistics.incCounter(macroExpandCount)
try {
2  src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
View
@@ -104,7 +104,7 @@ trait NamesDefaults { self: Analyzer =>
* @return the transformed application (a Block) together with the NamedApplyInfo.
* if isNamedApplyBlock(tree), returns the existing context.namedApplyBlockInfo
*/
- def transformNamedApplication(typer: Typer, mode: Int, pt: Type)
+ def transformNamedApplication(typer: Typer, mode: Mode, pt: Type)
(tree: Tree, argPos: Int => Int): Tree = {
import typer._
import typer.infer._
2  src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
View
@@ -189,7 +189,7 @@ abstract class TreeCheckers extends Analyzer {
if (t.symbol == NoSymbol)
errorFn(t.pos, "no symbol: " + treestr(t))
- override def typed(tree: Tree, mode: Int, pt: Type): Tree = returning(tree) {
+ override def typed(tree: Tree, mode: Mode, pt: Type): Tree = returning(tree) {
case EmptyTree | TypeTree() => ()
case _ if tree.tpe != null =>
tpeOfTree.getOrElseUpdate(tree, try tree.tpe finally tree.clearType())
2  src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
View
@@ -552,7 +552,7 @@ trait TypeDiagnostics {
}
// The checkDead call from typedArg is more selective.
- def inMode(mode: Int, tree: Tree): Tree = {
+ def inMode(mode: Mode, tree: Tree): Tree = {
val modeOK = (mode & (EXPRmode | BYVALmode | POLYmode)) == (EXPRmode | BYVALmode)
if (modeOK) apply(tree)
else tree
195 src/compiler/scala/tools/nsc/typechecker/Typers.scala
View
@@ -16,6 +16,7 @@ import scala.collection.mutable
import scala.reflect.internal.util.{ BatchSourceFile, Statistics, shortClassOfInstance }
import mutable.ListBuffer
import symtab.Flags._
+import Mode._
// Suggestion check whether we can do without priming scopes with symbols of outer scopes,
// like the IDE does.
@@ -24,7 +25,7 @@ import symtab.Flags._
* @author Martin Odersky
* @version 1.0
*/
-trait Typers extends Modes with Adaptations with Tags {
+trait Typers extends Adaptations with Tags {
self: Analyzer =>
import global._
@@ -32,7 +33,7 @@ trait Typers extends Modes with Adaptations with Tags {
import TypersStats._
import patmat.DefaultOverrideMatchAttachment
- final def forArgMode(fun: Tree, mode: Int) =
+ final def forArgMode(fun: Tree, mode: Mode) =
if (treeInfo.isSelfOrSuperConstrCall(fun)) mode | SCCmode
else mode
@@ -525,11 +526,11 @@ trait Typers extends Modes with Adaptations with Tags {
/** Does the context of tree `tree` require a stable type?
*/
- private def isStableContext(tree: Tree, mode: Int, pt: Type) =
- isNarrowable(tree.tpe) && ((mode & (EXPRmode | LHSmode)) == EXPRmode) &&
+ private def isStableContext(tree: Tree, mode: Mode, pt: Type) =
+ isNarrowable(tree.tpe) && mode.inExprMode && mode.inNone(LHSmode) &&
(xtypes ||
(pt.isStable ||
- (mode & QUALmode) != 0 && !tree.symbol.isConstant ||
+ mode.inAll(QUALmode) && !tree.symbol.isConstant ||
pt.typeSymbol.isAbstractType && pt.bounds.lo.isStable && !(tree.tpe <:< pt)) ||
pt.typeSymbol.isRefinementClass && !(tree.tpe <:< pt))
@@ -583,15 +584,15 @@ trait Typers extends Modes with Adaptations with Tags {
* 3. Turn tree type into stable type if possible and required by context.
* 4. Give getClass calls a more precise type based on the type of the target of the call.
*/
- private def stabilize(tree: Tree, pre: Type, mode: Int, pt: Type): Tree = {
- if (tree.symbol.isOverloaded && !inFunMode(mode))
+ private def stabilize(tree: Tree, pre: Type, mode: Mode, pt: Type): Tree = {
+ if (tree.symbol.isOverloaded && !mode.inFunMode)
inferExprAlternative(tree, pt)
val sym = tree.symbol
def fail() = NotAValueError(tree, sym)
if (tree.isErrorTyped) tree
- else if (inPatternNotFunMode(mode) && tree.isTerm) { // (1)
+ else if (mode.inPatternNotFunMode && tree.isTerm) { // (1)
if (sym.isValue) {
val tree1 = checkStable(tree)
// A module reference in a pattern has type Foo.type, not "object Foo"
@@ -625,7 +626,7 @@ trait Typers extends Modes with Adaptations with Tags {
case _ => !phase.erasedTypes
}
- def stabilizeFun(tree: Tree, mode: Int, pt: Type): Tree = {
+ def stabilizeFun(tree: Tree, mode: Mode, pt: Type): Tree = {
val sym = tree.symbol
val pre = tree match {
case Select(qual, _) => qual.tpe
@@ -785,7 +786,7 @@ trait Typers extends Modes with Adaptations with Tags {
* (14) When in mode EXPRmode, apply a view
* If all this fails, error
*/
- protected def adapt(tree: Tree, mode: Int, pt: Type, original: Tree = EmptyTree): Tree = {
+ protected def adapt(tree: Tree, mode: Mode, pt: Type, original: Tree = EmptyTree): Tree = {
def adaptToImplicitMethod(mt: MethodType): Tree = {
if (context.undetparams.nonEmpty) { // (9) -- should revisit dropped condition `(mode & POLYmode) == 0`
@@ -854,13 +855,13 @@ trait Typers extends Modes with Adaptations with Tags {
}
def adaptType(): Tree = {
- if (inFunMode(mode)) {
+ if (mode.inFunMode) {
// todo. the commented line below makes sense for typechecking, say, TypeApply(Ident(`some abstract type symbol`), List(...))
// because otherwise Ident will have its tpe set to a TypeRef, not to a PolyType, and `typedTypeApply` will fail
// but this needs additional investigation, because it crashes t5228, gadts1 and maybe something else
// tree setType tree.tpe.normalize
tree
- } else if (tree.hasSymbolField && !tree.symbol.typeParams.isEmpty && !inHKMode(mode) &&
+ } else if (tree.hasSymbolField && !tree.symbol.typeParams.isEmpty && !mode.inHKMode &&
!(tree.symbol.isJavaDefined && context.unit.isJava)) { // (7)
// @M When not typing a higher-kinded type ((mode & HKmode) == 0)
// or raw type (tree.symbol.isJavaDefined && context.unit.isJava), types must be of kind *,
@@ -869,7 +870,7 @@ trait Typers extends Modes with Adaptations with Tags {
MissingTypeParametersError(tree)
} else if ( // (7.1) @M: check kind-arity
// @M: removed check for tree.hasSymbolField and replace tree.symbol by tree.tpe.symbol (TypeTree's must also be checked here, and they don't directly have a symbol)
- (inHKMode(mode)) &&
+ mode.inHKMode &&
// @M: don't check tree.tpe.symbol.typeParams. check tree.tpe.typeParams!!!
// (e.g., m[Int] --> tree.tpe.symbol.typeParams.length == 1, tree.tpe.typeParams.length == 0!)
!sameLength(tree.tpe.typeParams, pt.typeParams) &&
@@ -991,7 +992,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
def insertApply(): Tree = {
- assert(!inHKMode(mode), modeString(mode)) //@M
+ assert(!mode.inHKMode, mode) //@M
val adapted = adaptToName(tree, nme.apply)
def stabilize0(pre: Type): Tree = stabilize(adapted, pre, EXPRmode | QUALmode, WildcardType)
// TODO reconcile the overlap between Typers#stablize and TreeGen.stabilize
@@ -1019,26 +1020,26 @@ trait Typers extends Modes with Adaptations with Tags {
tree.tpe match {
case atp @ AnnotatedType(_, _, _) if canAdaptAnnotations(tree, mode, pt) => // (-1)
adaptAnnotations(tree, mode, pt)
- case ct @ ConstantType(value) if inNoModes(mode, TYPEmode | FUNmode) && (ct <:< pt) && !forScaladoc && !forInteractive => // (0)
+ case ct @ ConstantType(value) if mode.inNone(TYPEmode | FUNmode) && (ct <:< pt) && !forScaladoc && !forInteractive => // (0)
val sym = tree.symbol
if (sym != null && sym.isDeprecated) {
val msg = sym.toString + sym.locationString + " is deprecated: " + sym.deprecationMessage.getOrElse("")
unit.deprecationWarning(tree.pos, msg)
}
treeCopy.Literal(tree, value)
- case OverloadedType(pre, alts) if !inFunMode(mode) => // (1)
+ case OverloadedType(pre, alts) if !mode.inFunMode => // (1)
inferExprAlternative(tree, pt)
adapt(tree, mode, pt, original)
case NullaryMethodType(restpe) => // (2)
adapt(tree setType restpe, mode, pt, original)
- case TypeRef(_, ByNameParamClass, List(arg)) if ((mode & EXPRmode) != 0) => // (2)
+ case TypeRef(_, ByNameParamClass, List(arg)) if mode.inExprMode => // (2)
adapt(tree setType arg, mode, pt, original)
case tr @ TypeRef(_, sym, _) if sym.isAliasType && tr.dealias.isInstanceOf[ExistentialType] &&
((mode & (EXPRmode | LHSmode)) == EXPRmode) =>
adapt(tree setType tr.dealias.skolemizeExistential(context.owner, tree), mode, pt, original)
case et @ ExistentialType(_, _) if ((mode & (EXPRmode | LHSmode)) == EXPRmode) =>
adapt(tree setType et.skolemizeExistential(context.owner, tree), mode, pt, original)
- case PolyType(tparams, restpe) if inNoModes(mode, TAPPmode | PATTERNmode | HKmode) => // (3)
+ case PolyType(tparams, restpe) if mode.inNone(TAPPmode | PATTERNmode | HKmode) => // (3)
// assert((mode & HKmode) == 0) //@M a PolyType in HKmode represents an anonymous type function,
// we're in HKmode since a higher-kinded type is expected --> hence, don't implicitly apply it to type params!
// ticket #2197 triggered turning the assert into a guard
@@ -1057,18 +1058,18 @@ trait Typers extends Modes with Adaptations with Tags {
adaptToImplicitMethod(mt)
case mt: MethodType if (((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) &&
- (context.undetparams.isEmpty || inPolyMode(mode))) && !(tree.symbol != null && tree.symbol.isTermMacro) =>
+ (context.undetparams.isEmpty || mode.inPolyMode)) && !(tree.symbol != null && tree.symbol.isTermMacro) =>
instantiateToMethodType(mt)
case _ =>
- def shouldInsertApply(tree: Tree) = inAllModes(mode, EXPRmode | FUNmode) && (tree.tpe match {
+ def shouldInsertApply(tree: Tree) = mode.inAll(EXPRmode | FUNmode) && (tree.tpe match {
case _: MethodType | _: OverloadedType | _: PolyType => false
case _ => applyPossible
})
def applyPossible = {
def applyMeth = member(adaptToName(tree, nme.apply), nme.apply)
dyna.acceptsApplyDynamic(tree.tpe) || (
- if ((mode & TAPPmode) != 0)
+ if (mode.inAll(TAPPmode))
tree.tpe.typeParams.isEmpty && applyMeth.filter(!_.tpe.typeParams.isEmpty) != NoSymbol
else
applyMeth.filter(_.tpe.paramSectionCount > 0) != NoSymbol
@@ -1077,17 +1078,17 @@ trait Typers extends Modes with Adaptations with Tags {
if (tree.isType)
adaptType()
else if (
- inExprModeButNot(mode, FUNmode) && !tree.isDef && // typechecking application
+ mode.inExprModeButNot(FUNmode) && !tree.isDef && // typechecking application
tree.symbol != null && tree.symbol.isTermMacro && // of a macro
!tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined)
macroExpand(this, tree, mode, pt)
- else if (inAllModes(mode, PATTERNmode | FUNmode))
+ else if (mode.inAll(PATTERNmode | FUNmode))
adaptConstrPattern()
else if (shouldInsertApply(tree))
insertApply()
- else if (!context.undetparams.isEmpty && !inPolyMode(mode)) { // (9)
- assert(!inHKMode(mode), modeString(mode)) //@M
- if (inExprModeButNot(mode, FUNmode) && pt.typeSymbol == UnitClass)
+ else if (!context.undetparams.isEmpty && !mode.inPolyMode) { // (9)
+ assert(!mode.inHKMode, mode) //@M
+ if (mode.inExprModeButNot(FUNmode) && pt.typeSymbol == UnitClass)
instantiateExpectingUnit(tree, mode)
else
instantiate(tree, mode, pt)
@@ -1095,7 +1096,7 @@ trait Typers extends Modes with Adaptations with Tags {
tree
} else {
def fallBack: Tree = {
- if (inPatternMode(mode)) {
+ if (mode.inPatternMode) {
if ((tree.symbol ne null) && tree.symbol.isModule)
inferModulePattern(tree, pt)
if (isPopulated(tree.tpe, approximateAbstracts(pt)))
@@ -1104,7 +1105,7 @@ trait Typers extends Modes with Adaptations with Tags {
val tree1 = constfold(tree, pt) // (10) (11)
if (tree1.tpe <:< pt) adapt(tree1, mode, pt, original)
else {
- if (inExprModeButNot(mode, FUNmode)) {
+ if (mode.inExprModeButNot(FUNmode)) {
pt.dealias match {
case TypeRef(_, sym, _) =>
// note: was if (pt.typeSymbol == UnitClass) but this leads to a potentially
@@ -1212,7 +1213,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
}
- def instantiate(tree: Tree, mode: Int, pt: Type): Tree = {
+ def instantiate(tree: Tree, mode: Mode, pt: Type): Tree = {
inferExprInstance(tree, context.extractUndetparams(), pt)
adapt(tree, mode, pt)
}
@@ -1220,7 +1221,7 @@ trait Typers extends Modes with Adaptations with Tags {
* with expected type Unit, but if that fails, try again with pt = WildcardType
* and discard the expression.
*/
- def instantiateExpectingUnit(tree: Tree, mode: Int): Tree = {
+ def instantiateExpectingUnit(tree: Tree, mode: Mode): Tree = {
val savedUndetparams = context.undetparams
silent(_.instantiate(tree, mode, UnitClass.tpe)) orElse { _ =>
context.undetparams = savedUndetparams
@@ -1294,7 +1295,7 @@ trait Typers extends Modes with Adaptations with Tags {
* a method `name`. If that's ambiguous try taking arguments into
* account using `adaptToArguments`.
*/
- def adaptToMemberWithArgs(tree: Tree, qual: Tree, name: Name, mode: Int, reportAmbiguous: Boolean, saveErrors: Boolean): Tree = {
+ def adaptToMemberWithArgs(tree: Tree, qual: Tree, name: Name, mode: Mode, reportAmbiguous: Boolean, saveErrors: Boolean): Tree = {
def onError(reportError: => Tree): Tree = context.tree match {
case Apply(tree1, args) if (tree1 eq tree) && args.nonEmpty =>
( silent (_.typedArgs(args, mode))
@@ -2296,7 +2297,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
}
- def typedBlock(block: Block, mode: Int, pt: Type): Block = {
+ def typedBlock(block: Block, mode: Mode, pt: Type): Block = {
val syntheticPrivates = new ListBuffer[Symbol]
try {
namer.enterSyms(block.stats)
@@ -2358,7 +2359,7 @@ trait Typers extends Modes with Adaptations with Tags {
case _ => stat::Nil
})
val stats2 = typedStats(stats1, context.owner)
- val expr1 = typed(block.expr, mode & ~(FUNmode | QUALmode), pt)
+ val expr1 = typed(block.expr, mode &~ (FUNmode | QUALmode), pt)
treeCopy.Block(block, stats2, expr1)
.setType(if (treeInfo.isExprSafeToInline(block)) expr1.tpe else expr1.tpe.deconst)
} finally {
@@ -2429,13 +2430,13 @@ trait Typers extends Modes with Adaptations with Tags {
newTyper(context.makeNewScope(cdef, context.owner)).typedCase(cdef, pattp, pt)
}
- def adaptCase(cdef: CaseDef, mode: Int, tpe: Type): CaseDef = deriveCaseDef(cdef)(adapt(_, mode, tpe))
+ def adaptCase(cdef: CaseDef, mode: Mode, tpe: Type): CaseDef = deriveCaseDef(cdef)(adapt(_, mode, tpe))
def ptOrLub(tps: List[Type], pt: Type ) = if (isFullyDefined(pt)) (pt, false) else weakLub(tps map (_.deconst))
def ptOrLubPacked(trees: List[Tree], pt: Type) = if (isFullyDefined(pt)) (pt, false) else weakLub(trees map (c => packedType(c, context.owner).deconst))
// takes untyped sub-trees of a match and type checks them
- def typedMatch(selector: Tree, cases: List[CaseDef], mode: Int, pt: Type, tree: Tree = EmptyTree): Match = {
+ def typedMatch(selector: Tree, cases: List[CaseDef], mode: Mode, pt: Type, tree: Tree = EmptyTree): Match = {
val selector1 = checkDead(typed(selector, EXPRmode | BYVALmode, WildcardType))
val selectorTp = packCaptured(selector1.tpe.widen).skolemizeExistential(context.owner, selector)
val casesTyped = typedCases(cases, selectorTp, pt)
@@ -2448,7 +2449,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
// match has been typed -- virtualize it during type checking so the full context is available
- def virtualizedMatch(match_ : Match, mode: Int, pt: Type) = {
+ def virtualizedMatch(match_ : Match, mode: Mode, pt: Type) = {
import patmat.{ vpmName, PureMatchTranslator }
// TODO: add fallback __match sentinel to predef
@@ -2466,7 +2467,7 @@ trait Typers extends Modes with Adaptations with Tags {
// Match(EmptyTree, cases) ==> new PartialFunction { def apply<OrElse>(params) = `translateMatch('`(param1,...,paramN)` match { cases }')` }
// for fresh params, the selector of the match we'll translated simply gathers those in a tuple
// NOTE: restricted to PartialFunction -- leave Function trees if the expected type does not demand a partial function
- class MatchFunTyper(tree: Tree, cases: List[CaseDef], mode: Int, pt0: Type) {
+ class MatchFunTyper(tree: Tree, cases: List[CaseDef], mode: Mode, pt0: Type) {
// TODO: remove FunctionN support -- this is currently designed so that it can emit FunctionN and PartialFunction subclasses
// however, we should leave Function nodes until Uncurry so phases after typer can still detect normal Function trees
// we need to synthesize PartialFunction impls, though, to avoid nastiness in Uncurry in transforming&duplicating generated pattern matcher trees
@@ -2616,7 +2617,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
// Function(params, Match(sel, cases)) ==> new <Partial>Function { def apply<OrElse>(params) = `translateMatch('sel match { cases }')` }
- class MatchFunTyperBetaReduced(fun: Function, sel: Tree, cases: List[CaseDef], mode: Int, pt: Type) extends MatchFunTyper(fun, cases, mode, pt) {
+ class MatchFunTyperBetaReduced(fun: Function, sel: Tree, cases: List[CaseDef], mode: Mode, pt: Type) extends MatchFunTyper(fun, cases, mode, pt) {
override def deriveFormals =
fun.vparams map { p => if(p.tpt.tpe == null) typedType(p.tpt).tpe else p.tpt.tpe }
@@ -2629,7 +2630,7 @@ trait Typers extends Modes with Adaptations with Tags {
override def mkSel(params: List[Symbol]) = sel.duplicate
}
- private def typedFunction(fun: Function, mode: Int, pt: Type): Tree = {
+ private def typedFunction(fun: Function, mode: Mode, pt: Type): Tree = {
val numVparams = fun.vparams.length
if (numVparams > definitions.MaxFunctionArity)
return MaxFunctionArityError(fun)
@@ -2654,7 +2655,7 @@ trait Typers extends Modes with Adaptations with Tags {
else {
fun match {
case etaExpansion(vparams, fn, args) =>
- silent(_.typed(fn, forFunMode(mode), pt)) filter (_ => context.undetparams.isEmpty) map { fn1 =>
+ silent(_.typed(fn, mode.forFunMode, pt)) filter (_ => context.undetparams.isEmpty) map { fn1 =>
// if context,undetparams is not empty, the function was polymorphic,
// so we need the missing arguments to infer its type. See #871
//println("typing eta "+fun+":"+fn1.tpe+"/"+context.undetparams)
@@ -2859,14 +2860,14 @@ trait Typers extends Modes with Adaptations with Tags {
}
}
- def typedArg(arg: Tree, mode: Int, newmode: Int, pt: Type): Tree = {
- val typedMode = onlyStickyModes(mode) | newmode
- val t = withCondConstrTyper((mode & SCCmode) != 0)(_.typed(arg, typedMode, pt))
+ def typedArg(arg: Tree, mode: Mode, newmode: Mode, pt: Type): Tree = {
+ val typedMode = mode.onlySticky | newmode
+ val t = withCondConstrTyper((mode & SCCmode) != NOmode)(_.typed(arg, typedMode, pt))
checkDead.inMode(typedMode, t)
}
- def typedArgs(args: List[Tree], mode: Int) =
- args mapConserve (arg => typedArg(arg, mode, 0, WildcardType))
+ def typedArgs(args: List[Tree], mode: Mode) =
+ args mapConserve (arg => typedArg(arg, mode, NOmode, WildcardType))
/** Type trees in `args0` against corresponding expected type in `adapted0`.
*
@@ -2876,8 +2877,8 @@ trait Typers extends Modes with Adaptations with Tags {
*
* (docs reverse-engineered -- AM)
*/
- def typedArgs(args0: List[Tree], mode: Int, formals0: List[Type], adapted0: List[Type]): List[Tree] = {
- val sticky = onlyStickyModes(mode)
+ def typedArgs(args0: List[Tree], mode: Mode, formals0: List[Type], adapted0: List[Type]): List[Tree] = {
+ val sticky = mode.onlySticky
def loop(args: List[Tree], formals: List[Type], adapted: List[Type]): List[Tree] = {
if (args.isEmpty || adapted.isEmpty) Nil
else {
@@ -2885,7 +2886,7 @@ trait Typers extends Modes with Adaptations with Tags {
val isVarArgs = formals.isEmpty || formals.tail.isEmpty && isRepeatedParamType(formals.head)
val typedMode = sticky | (
if (isVarArgs) STARmode | BYVALmode
- else if (isByNameParamType(formals.head)) 0
+ else if (isByNameParamType(formals.head)) NOmode
else BYVALmode
)
var tree = typedArg(args.head, mode, typedMode, adapted.head)
@@ -2937,7 +2938,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
}
- def doTypedApply(tree: Tree, fun0: Tree, args: List[Tree], mode: Int, pt: Type): Tree = {
+ def doTypedApply(tree: Tree, fun0: Tree, args: List[Tree], mode: Mode, pt: Type): Tree = {
// TODO_NMT: check the assumption that args nonEmpty
def duplErrTree = setError(treeCopy.Apply(tree, fun0, args))
def duplErrorTree(err: AbsTypeError) = { issue(err); duplErrTree }
@@ -2979,7 +2980,7 @@ trait Typers extends Modes with Adaptations with Tags {
if (sym1 != NoSymbol) sym = sym1
}
if (sym == NoSymbol) fun
- else adapt(fun setSymbol sym setType pre.memberType(sym), forFunMode(mode), WildcardType)
+ else adapt(fun setSymbol sym setType pre.memberType(sym), mode.forFunMode, WildcardType)
} else fun
}
@@ -3012,7 +3013,7 @@ trait Typers extends Modes with Adaptations with Tags {
setError(tree)
else {
inferMethodAlternative(fun, undetparams, argtpes.toList, pt)
- doTypedApply(tree, adapt(fun, forFunMode(mode), WildcardType), args1, mode, pt)
+ doTypedApply(tree, adapt(fun, mode.forFunMode, WildcardType), args1, mode, pt)
}
}
handleOverloaded
@@ -3037,7 +3038,7 @@ trait Typers extends Modes with Adaptations with Tags {
// Depending on user options, may warn or error here if
// a Unit or tuple was inserted.
Some(t) filter (tupledTree =>
- !inExprModeButNot(mode, FUNmode)
+ !mode.inExprModeButNot(FUNmode)
|| tupledTree.symbol == null
|| checkValidAdaptation(tupledTree, args)
)
@@ -3060,7 +3061,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
if (mt.isErroneous) duplErrTree
- else if (inPatternMode(mode)) {
+ else if (mode.inPatternMode) {
// #2064
duplErrorTree(WrongNumberOfArgsError(tree, fun))
} else if (lencmp > 0) {
@@ -3157,7 +3158,7 @@ trait Typers extends Modes with Adaptations with Tags {
// precise(foo) : foo.type => foo.type
val restpe = mt.resultType(args1 map (arg => gen.stableTypeFor(arg) getOrElse arg.tpe))
def ifPatternSkipFormals(tp: Type) = tp match {
- case MethodType(_, rtp) if (inPatternMode(mode)) => rtp
+ case MethodType(_, rtp) if (mode.inPatternMode) => rtp
case _ => tp
}
@@ -3181,7 +3182,7 @@ trait Typers extends Modes with Adaptations with Tags {
doTypedApply(tree, fun, args, mode, pt)
} else {
def handlePolymorphicCall = {
- assert(!inPatternMode(mode), modeString(mode)) // this case cannot arise for patterns
+ assert(!mode.inPatternMode, mode) // this case cannot arise for patterns
val lenientTargs = protoTypeArgs(tparams, formals, mt.resultApprox, pt)
val strictTargs = map2(lenientTargs, tparams)((targ, tparam) =>
if (targ == WildcardType) tparam.tpeHK else targ)
@@ -3222,7 +3223,7 @@ trait Typers extends Modes with Adaptations with Tags {
if (!tree.isErrorTyped) setError(tree) else tree
// @H change to setError(treeCopy.Apply(tree, fun, args))
- case otpe if inPatternMode(mode) && unapplyMember(otpe).exists =>
+ case otpe if mode.inPatternMode && unapplyMember(otpe).exists =>
doTypedUnapply(tree, fun0, fun, args, mode, pt)
case _ =>
@@ -3230,7 +3231,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
}
- def doTypedUnapply(tree: Tree, fun0: Tree, fun: Tree, args: List[Tree], mode: Int, pt: Type): Tree = {
+ def doTypedUnapply(tree: Tree, fun0: Tree, fun: Tree, args: List[Tree], mode: Mode, pt: Type): Tree = {
def duplErrTree = setError(treeCopy.Apply(tree, fun0, args))
def duplErrorTree(err: AbsTypeError) = { issue(err); duplErrTree }
@@ -3354,7 +3355,7 @@ trait Typers extends Modes with Adaptations with Tags {
*
* @param annClass the expected annotation class
*/
- def typedAnnotation(ann: Tree, mode: Int = EXPRmode, selfsym: Symbol = NoSymbol, annClass: Symbol = AnnotationClass, requireJava: Boolean = false): AnnotationInfo = {
+ def typedAnnotation(ann: Tree, mode: Mode = EXPRmode, selfsym: Symbol = NoSymbol, annClass: Symbol = AnnotationClass, requireJava: Boolean = false): AnnotationInfo = {
var hasError: Boolean = false
val pending = ListBuffer[AbsTypeError]()
@@ -3399,7 +3400,7 @@ trait Typers extends Modes with Adaptations with Tags {
// use of Array.apply[T: ClassTag](xs: T*): Array[T]
// and Array.apply(x: Int, xs: Int*): Array[Int] (and similar)
case Apply(fun, args) =>
- val typedFun = typed(fun, forFunMode(mode), WildcardType)
+ val typedFun = typed(fun, mode.forFunMode, WildcardType)
if (typedFun.symbol.owner == ArrayModule.moduleClass && typedFun.symbol.name == nme.apply)
pt match {
case TypeRef(_, ArrayClass, targ :: _) =>
@@ -3443,7 +3444,7 @@ trait Typers extends Modes with Adaptations with Tags {
val res = if (fun.isErroneous) ErroneousAnnotation
else {
- val typedFun @ Select(New(tpt), _) = typed(fun, forFunMode(mode), WildcardType)
+ val typedFun @ Select(New(tpt), _) = typed(fun, mode.forFunMode, WildcardType)
val annType = tpt.tpe
if (typedFun.isErroneous) ErroneousAnnotation
@@ -3733,7 +3734,7 @@ trait Typers extends Modes with Adaptations with Tags {
if (!checkClassType(tpt) && noGen) tpt
else atPos(tree.pos)(gen.mkClassOf(tpt.tpe))
- protected def typedExistentialTypeTree(tree: ExistentialTypeTree, mode: Int): Tree = {
+ protected def typedExistentialTypeTree(tree: ExistentialTypeTree, mode: Mode): Tree = {
for (wc <- tree.whereClauses)
if (wc.symbol == NoSymbol) { namer.enterSym(wc); wc.symbol setFlag EXISTENTIAL }
else context.scope enter wc.symbol
@@ -3748,7 +3749,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
// lifted out of typed1 because it's needed in typedImplicit0
- protected def typedTypeApply(tree: Tree, mode: Int, fun: Tree, args: List[Tree]): Tree = fun.tpe match {
+ protected def typedTypeApply(tree: Tree, mode: Mode, fun: Tree, args: List[Tree]): Tree = fun.tpe match {
case OverloadedType(pre, alts) =>
inferPolyAlternatives(fun, args map (_.tpe))
val tparams = fun.symbol.typeParams //@M TODO: fun.symbol.info.typeParams ? (as in typedAppliedTypeTree)
@@ -3837,7 +3838,7 @@ trait Typers extends Modes with Adaptations with Tags {
// else false
}
- def typedNamedApply(orig: Tree, fun: Tree, args: List[Tree], mode: Int, pt: Type): Tree = {
+ def typedNamedApply(orig: Tree, fun: Tree, args: List[Tree], mode: Mode, pt: Type): Tree = {
def argToBinding(arg: Tree): Tree = arg match {
case AssignOrNamedArg(Ident(name), rhs) => gen.mkTuple(List(CODE.LIT(name.toString), rhs))
case _ => gen.mkTuple(List(CODE.LIT(""), arg))
@@ -3922,10 +3923,10 @@ trait Typers extends Modes with Adaptations with Tags {
println(s)
}
- def typed1(tree: Tree, mode: Int, pt: Type): Tree = {
- def isPatternMode = inPatternMode(mode)
- def inPatternConstructor = inAllModes(mode, PATTERNmode | FUNmode)
- def isQualifierMode = (mode & QUALmode) != 0
+ def typed1(tree: Tree, mode: Mode, pt: Type): Tree = {
+ def isPatternMode = mode.inPatternMode
+ def inPatternConstructor = mode.inAll(PATTERNmode | FUNmode)
+ def isQualifierMode = mode.inAll(QUALmode)
// Lookup in the given class using the root mirror.
def lookupInOwner(owner: Symbol, name: Name): Symbol =
@@ -3947,7 +3948,7 @@ trait Typers extends Modes with Adaptations with Tags {
val ann = atd.annot
val arg1 = typed(atd.arg, mode, pt)
/** mode for typing the annotation itself */
- val annotMode = mode & ~TYPEmode | EXPRmode
+ val annotMode = (mode &~ TYPEmode) | EXPRmode
def resultingTypeTree(tpe: Type) = {
// we need symbol-ful originals for reification
@@ -4049,7 +4050,7 @@ trait Typers extends Modes with Adaptations with Tags {
else context.owner.newValue(name, tree.pos)
if (name != nme.WILDCARD) {
- if ((mode & ALTmode) != 0) VariableInPatternAlternativeError(tree)
+ if (mode.inAll(ALTmode)) VariableInPatternAlternativeError(tree)
namer.enterInScope(sym)
}
@@ -4276,7 +4277,7 @@ trait Typers extends Modes with Adaptations with Tags {
UnderscoreEtaError(expr1)
}
- def tryTypedArgs(args: List[Tree], mode: Int): Option[List[Tree]] = {
+ def tryTypedArgs(args: List[Tree], mode: Mode): Option[List[Tree]] = {
val c = context.makeSilent(false)
c.retyping = true
try {
@@ -4356,7 +4357,7 @@ trait Typers extends Modes with Adaptations with Tags {
val stableApplication = (fun.symbol ne null) && fun.symbol.isMethod && fun.symbol.isStable
if (stableApplication && isPatternMode) {
// treat stable function applications f() as expressions.
- typed1(tree, mode & ~PATTERNmode | EXPRmode, pt)
+ typed1(tree, (mode &~ PATTERNmode) | EXPRmode, pt)
} else {
val funpt = if (isPatternMode) pt else WildcardType
val appStart = if (Statistics.canEnable) Statistics.startTimer(failedApplyNanos) else null
@@ -4379,9 +4380,9 @@ trait Typers extends Modes with Adaptations with Tags {
reportError
}
}
- silent(_.typed(fun, forFunMode(mode), funpt),
- if ((mode & EXPRmode) != 0) false else context.ambiguousErrors,
- if ((mode & EXPRmode) != 0) tree else context.tree) match {
+ silent(_.typed(fun, mode.forFunMode, funpt),
+ if (mode.inExprMode) false else context.ambiguousErrors,
+ if (mode.inExprMode) tree else context.tree) match {
case SilentResultValue(fun1) =>
val fun2 = if (stableApplication) stabilizeFun(fun1, mode, pt) else fun1
if (Statistics.canEnable) Statistics.incCounter(typedApplyCount)
@@ -4521,7 +4522,7 @@ trait Typers extends Modes with Adaptations with Tags {
val owntype = (
if (!mix.isEmpty) findMixinSuper(clazz.tpe)
- else if ((mode & SUPERCONSTRmode) != 0) clazz.info.firstParent
+ else if (mode.inAll(SUPERCONSTRmode)) clazz.info.firstParent
else intersectionType(clazz.info.parents)
)
treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype)
@@ -4565,7 +4566,7 @@ trait Typers extends Modes with Adaptations with Tags {
// symbol not found? --> try to convert implicitly to a type that does have the required
// member. Added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an
// xml member to StringContext, which in turn has an unapply[Seq] method)
- if (name != nme.CONSTRUCTOR && inExprModeOr(mode, PATTERNmode)) {
+ if (name != nme.CONSTRUCTOR && mode.inExprModeOr(PATTERNmode)) {
val qual1 = adaptToMemberWithArgs(tree, qual, name, mode, true, true)
if ((qual1 ne qual) && !qual1.isErrorTyped)
return typed(treeCopy.Select(tree, qual1, name), mode, pt)
@@ -4738,7 +4739,7 @@ trait Typers extends Modes with Adaptations with Tags {
setError(tree)
}
// ignore current variable scope in patterns to enforce linearity
- val startContext = if (inNoModes(mode, PATTERNmode | TYPEPATmode)) context else context.outer
+ val startContext = if (mode.inNone(PATTERNmode | TYPEPATmode)) context else context.outer
val nameLookup = tree.symbol match {
case NoSymbol => startContext.lookupSymbol(name, qualifies)
case sym => LookupSucceeded(EmptyTree, sym)
@@ -4774,8 +4775,8 @@ trait Typers extends Modes with Adaptations with Tags {
def typedIdentOrWildcard(tree: Ident) = {
val name = tree.name
if (Statistics.canEnable) Statistics.incCounter(typedIdentCount)
- if ((name == nme.WILDCARD && (mode & (PATTERNmode | FUNmode)) == PATTERNmode) ||
- (name == tpnme.WILDCARD && (mode & TYPEmode) != 0))
+ if ((name == nme.WILDCARD && mode.inPatternNotFunMode) ||
+ (name == tpnme.WILDCARD && mode.inAll(TYPEmode)))
tree setType makeFullyDefined(pt)
else
typedIdent(tree, name)
@@ -4898,7 +4899,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
def typedStar(tree: Star) = {
- if ((mode & STARmode) == 0 && !isPastTyper)
+ if (mode.inNone(STARmode) && !isPastTyper)
StarPatternWithVarargParametersError(tree)
treeCopy.Star(tree, typed(tree.elem, mode, pt)) setType makeFullyDefined(pt)
}
@@ -4958,7 +4959,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
case Ident(tpnme.WILDCARD_STAR) =>
- val exprTyped = typed(expr, onlyStickyModes(mode), WildcardType)
+ val exprTyped = typed(expr, mode.onlySticky, WildcardType)
def subArrayType(pt: Type) =
if (isPrimitiveValueClass(pt.typeSymbol) || !isFullyDefined(pt)) arrayType(pt)
else {
@@ -4967,8 +4968,8 @@ trait Typers extends Modes with Adaptations with Tags {
}
val (exprAdapted, baseClass) = exprTyped.tpe.typeSymbol match {
- case ArrayClass => (adapt(exprTyped, onlyStickyModes(mode), subArrayType(pt)), ArrayClass)
- case _ => (adapt(exprTyped, onlyStickyModes(mode), seqType(pt)), SeqClass)
+ case ArrayClass => (adapt(exprTyped, mode.onlySticky, subArrayType(pt)), ArrayClass)
+ case _ => (adapt(exprTyped, mode.onlySticky, seqType(pt)), SeqClass)
}
exprAdapted.tpe.baseType(baseClass) match {
case TypeRef(_, _, List(elemtp)) =>
@@ -4979,7 +4980,7 @@ trait Typers extends Modes with Adaptations with Tags {
case _ =>
val tptTyped = typedType(tpt, mode)
- val exprTyped = typed(expr, onlyStickyModes(mode), tptTyped.tpe.deconst)
+ val exprTyped = typed(expr, mode.onlySticky, tptTyped.tpe.deconst)
val treeTyped = treeCopy.Typed(tree, exprTyped, tptTyped)
if (isPatternMode) {
@@ -5011,7 +5012,7 @@ trait Typers extends Modes with Adaptations with Tags {
//val undets = context.undetparams
// @M: fun is typed in TAPPmode because it is being applied to its actual type parameters
- val fun1 = typed(fun, forFunMode(mode) | TAPPmode, WildcardType)
+ val fun1 = typed(fun, mode.forFunMode | TAPPmode, WildcardType)
val tparams = fun1.symbol.typeParams
//@M TODO: val undets_fun = context.undetparams ?
@@ -5164,7 +5165,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
}
- def typed(tree: Tree, mode: Int, pt: Type): Tree = {
+ def typed(tree: Tree, mode: Mode, pt: Type): Tree = {
lastTreeToTyper = tree
indentTyping()
@@ -5184,7 +5185,7 @@ trait Typers extends Modes with Adaptations with Tags {
"undetparams" -> context.undetparams,
"implicitsEnabled" -> context.implicitsEnabled,
"enrichmentEnabled" -> context.enrichmentEnabled,
- "mode" -> modeString(mode),
+ "mode" -> mode,
"silent" -> context.bufferErrors,
"context.owner" -> context.owner
)
@@ -5247,7 +5248,7 @@ trait Typers extends Modes with Adaptations with Tags {
ret
}
- def typedPos(pos: Position, mode: Int, pt: Type)(tree: Tree) = typed(atPos(pos)(tree), mode, pt)
+ def typedPos(pos: Position, mode: Mode, pt: Type)(tree: Tree) = typed(atPos(pos)(tree), mode, pt)
def typedPos(pos: Position)(tree: Tree) = typed(atPos(pos)(tree))
// TODO: see if this formulation would impose any penalty, since
// it makes for a lot less casting.
@@ -5261,13 +5262,13 @@ trait Typers extends Modes with Adaptations with Tags {
/** Types qualifier `tree` of a select node.
* E.g. is tree occurs in a context like `tree.m`.
*/
- def typedQualifier(tree: Tree, mode: Int, pt: Type): Tree =
+ def typedQualifier(tree: Tree, mode: Mode, pt: Type): Tree =
typed(tree, EXPRmode | QUALmode | POLYmode | mode & TYPEPATmode, pt) // TR: don't set BYVALmode, since qualifier might end up as by-name param to an implicit
/** Types qualifier `tree` of a select node.
* E.g. is tree occurs in a context like `tree.m`.
*/
- def typedQualifier(tree: Tree, mode: Int): Tree =
+ def typedQualifier(tree: Tree, mode: Mode): Tree =
typedQualifier(tree, mode, WildcardType)
def typedQualifier(tree: Tree): Tree = typedQualifier(tree, NOmode, WildcardType)
@@ -5300,23 +5301,23 @@ trait Typers extends Modes with Adaptations with Tags {
}
/** Types a (fully parameterized) type tree */
- def typedType(tree: Tree, mode: Int): Tree =
- typed(tree, forTypeMode(mode), WildcardType)
+ def typedType(tree: Tree, mode: Mode): Tree =
+ typed(tree, mode.forTypeMode, WildcardType)
/** Types a (fully parameterized) type tree */
def typedType(tree: Tree): Tree = typedType(tree, NOmode)
/** Types a higher-kinded type tree -- pt denotes the expected kind*/
- def typedHigherKindedType(tree: Tree, mode: Int, pt: Type): Tree =
+ def typedHigherKindedType(tree: Tree, mode: Mode, pt: Type): Tree =
if (pt.typeParams.isEmpty) typedType(tree, mode) // kind is known and it's *
else typed(tree, HKmode, pt)
- def typedHigherKindedType(tree: Tree, mode: Int): Tree =
+ def typedHigherKindedType(tree: Tree, mode: Mode): Tree =
typed(tree, HKmode, WildcardType)
/** Types a type constructor tree used in a new or supertype */
- def typedTypeConstructor(tree: Tree, mode: Int): Tree = {
- val result = typed(tree, forTypeMode(mode) | FUNmode, WildcardType)
+ def typedTypeConstructor(tree: Tree, mode: Mode): Tree = {
+ val result = typed(tree, mode.forTypeMode | FUNmode, WildcardType)
// get rid of type aliases for the following check (#1241)
result.tpe.dealias match {
@@ -5373,7 +5374,7 @@ trait Typers extends Modes with Adaptations with Tags {
case None => op
}
- def transformedOrTyped(tree: Tree, mode: Int, pt: Type): Tree = transformed.get(tree) match {
+ def transformedOrTyped(tree: Tree, mode: Mode, pt: Type): Tree = transformed.get(tree) match {
case Some(tree1) => transformed -= tree; tree1
case None => typed(tree, mode, pt)
}
3  src/compiler/scala/tools/reflect/ToolBoxFactory.scala
View
@@ -1,6 +1,7 @@
package scala.tools
package reflect
+import scala.tools.nsc.EXPRmode
import scala.tools.nsc.reporters._
import scala.tools.nsc.CompilerCommand
import scala.tools.nsc.io.VirtualDirectory
@@ -163,7 +164,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
transformDuringTyper(expr, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)(
(currentTyper, expr) => {
trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value))
- currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt)) match {
+ currentTyper.silent(_.typed(expr, EXPRmode, pt)) match {
case analyzer.SilentResultValue(result) =>
trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value))
result
37 src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
View
@@ -2,11 +2,10 @@
package scala.tools.selectivecps
-import scala.tools.nsc.Global
-import scala.tools.nsc.typechecker.Modes
+import scala.tools.nsc.{ Global, Mode }
import scala.tools.nsc.MissingRequirementError
-abstract class CPSAnnotationChecker extends CPSUtils with Modes {
+abstract class CPSAnnotationChecker extends CPSUtils {
val global: Global
import global._
import definitions._
@@ -117,14 +116,14 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
bounds
}
- override def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = {
+ override def canAdaptAnnotations(tree: Tree, mode: Mode, pt: Type): Boolean = {
if (!cpsEnabled) return false
- vprintln("can adapt annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt)
+ vprintln("can adapt annotations? " + tree + " / " + tree.tpe + " / " + mode + " / " + pt)
val annots1 = cpsParamAnnotation(tree.tpe)
val annots2 = cpsParamAnnotation(pt)
- if ((mode & global.analyzer.PATTERNmode) != 0) {
+ if (mode.inPatternMode) {
//println("can adapt pattern annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt)
if (!annots1.isEmpty) {
return true
@@ -133,7 +132,7 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
/*
// not precise enough -- still relying on addAnnotations to remove things from ValDef symbols
- if ((mode & global.analyzer.TYPEmode) != 0 && (mode & global.analyzer.BYVALmode) != 0) {
+ if ((mode & TYPEmode) != 0 && (mode & BYVALmode) != 0) {
if (!annots1.isEmpty) {
return true
}
@@ -142,16 +141,16 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
/*
this interferes with overloading resolution
- if ((mode & global.analyzer.BYVALmode) != 0 && tree.tpe <:< pt) {
+ if ((mode & BYVALmode) != 0 && tree.tpe <:< pt) {
vprintln("already compatible, can't adapt further")
return false
}
*/
- if ((mode & global.analyzer.EXPRmode) != 0) {
+ if (mode.inExprMode) {
if ((annots1 corresponds annots2)(_.atp <:< _.atp)) {
vprintln("already same, can't adapt further")
false
- } else if (annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.BYVALmode) == 0)) {
+ } else if (annots1.isEmpty && !annots2.isEmpty && !mode.inByValMode) {
//println("can adapt annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt)
if (!hasPlusMarker(tree.tpe)) {
// val base = tree.tpe <:< removeAllCPSAnnotations(pt)
@@ -164,10 +163,10 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
true
//}
} else false
- } else if (!hasPlusMarker(tree.tpe) && annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.RETmode) != 0)) {
+ } else if (!hasPlusMarker(tree.tpe) && annots1.isEmpty && !annots2.isEmpty && mode.inRetMode) {
vprintln("checking enclosing method's result type without annotations")
tree.tpe <:< pt.withoutAnnotations
- } else if (!hasMinusMarker(tree.tpe) && !annots1.isEmpty && ((mode & global.analyzer.BYVALmode) != 0)) {
+ } else if (!hasMinusMarker(tree.tpe) && !annots1.isEmpty && mode.inByValMode) {
val optCpsTypes: Option[(Type, Type)] = cpsParamTypes(tree.tpe)
val optExpectedCpsTypes: Option[(Type, Type)] = cpsParamTypes(pt)
if (optCpsTypes.isEmpty || optExpectedCpsTypes.isEmpty) {
@@ -183,21 +182,21 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
} else false
}
- override def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = {
+ override def adaptAnnotations(tree: Tree, mode: Mode, pt: Type): Tree = {
if (!cpsEnabled) return tree
- vprintln("adapt annotations " + tree + " / " + tree.tpe + " / " + modeString(mode) + " / " + pt)
+ vprintln("adapt annotations " + tree + " / " + tree.tpe + " / " + mode + " / " + pt)
- val patMode = (mode & global.analyzer.PATTERNmode) != 0
- val exprMode = (mode & global.analyzer.EXPRmode) != 0
- val byValMode = (mode & global.analyzer.BYVALmode) != 0
- val retMode = (mode & global.analyzer.RETmode) != 0
+ val patMode = mode.inPatternMode
+ val exprMode = mode.inExprMode
+ val byValMode = mode.inByValMode
+ val retMode = mode.inRetMode
val annotsTree = cpsParamAnnotation(tree.tpe)
val annotsExpected = cpsParamAnnotation(pt)
// not sure I rephrased this comment correctly:
- // replacing `patMode` in the condition below by `patMode || ((mode & global.analyzer.TYPEmode) != 0 && (mode & global.analyzer.BYVALmode))`
+ // replacing `patMode` in the condition below by `patMode || ((mode & TYPEmode) != 0 && (mode & BYVALmode))`
// doesn't work correctly -- still relying on addAnnotations to remove things from ValDef symbols
if (patMode && !annotsTree.isEmpty) tree modifyType removeAllCPSAnnotations
else if (exprMode && !byValMode && !hasPlusMarker(tree.tpe) && annotsTree.isEmpty && annotsExpected.nonEmpty) { // shiftUnit
10 src/reflect/scala/reflect/internal/AnnotationCheckers.scala
View
@@ -39,14 +39,14 @@ trait AnnotationCheckers {
/** Decide whether this annotation checker can adapt a tree
* that has an annotated type to the given type tp, taking
* into account the given mode (see method adapt in trait Typers).*/
- def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = false
+ def canAdaptAnnotations(tree: Tree, mode: Mode, pt: Type): Boolean = false
/** Adapt a tree that has an annotated type to the given type tp,
* taking into account the given mode (see method adapt in trait Typers).
* An implementation cannot rely on canAdaptAnnotations being called
* before. If the implementing class cannot do the adaptiong, it
* should return the tree unchanged.*/
- def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = tree
+ def adaptAnnotations(tree: Tree, mode: Mode, pt: Type): Tree = tree
/** Adapt the type of a return expression. The decision of an annotation checker
* whether the type should be adapted is based on the type of the expression
@@ -113,7 +113,7 @@ trait AnnotationCheckers {
/** Find out whether any annotation checker can adapt a tree
* to a given type. Called by Typers.adapt. */
- def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = {
+ def canAdaptAnnotations(tree: Tree, mode: Mode, pt: Type): Boolean = {
annotationCheckers.exists(_.canAdaptAnnotations(tree, mode, pt))
}
@@ -121,7 +121,7 @@ trait AnnotationCheckers {
* to a given type (called by Typers.adapt). Annotation checkers
* that cannot do the adaption should pass the tree through
* unchanged. */
- def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = {
+ def adaptAnnotations(tree: Tree, mode: Mode, pt: Type): Tree = {
annotationCheckers.foldLeft(tree)((tree, checker) =>
checker.adaptAnnotations(tree, mode, pt))
}
@@ -129,7 +129,7 @@ trait AnnotationCheckers {
/** Let a registered annotation checker adapt the type of a return expression.
* Annotation checkers that cannot do the adaptation should simply return
* the `default` argument.
- *
+ *
* Note that the result is undefined if more than one annotation checker
* returns an adapted type which is not a subtype of `default`.
*/
108 src/compiler/scala/tools/nsc/typechecker/Modes.scala → src/reflect/scala/reflect/internal/Mode.scala
View
@@ -3,75 +3,76 @@
* @author Martin Odersky
*/
-package scala.tools.nsc
-package typechecker
+package scala.reflect
+package internal
+
+object Mode {
+ private implicit def liftIntBitsToMode(bits: Int): Mode = apply(bits)
+ def apply(bits: Int): Mode = new Mode(bits)
-/** Mode constants.
- */
-trait Modes {
/** NOmode, EXPRmode and PATTERNmode are mutually exclusive.
*/
- final val NOmode = 0x000
- final val EXPRmode = 0x001
- final val PATTERNmode = 0x002
+ final val NOmode: Mode = 0x000
+ final val EXPRmode: Mode = 0x001
+ final val PATTERNmode: Mode = 0x002
/** TYPEmode needs a comment. <-- XXX.
*/
- final val TYPEmode = 0x004
+ final val TYPEmode: Mode = 0x004
/** SCCmode is orthogonal to above. When set we are
* in the this or super constructor call of a constructor.
*/
- final val SCCmode = 0x008
+ final val SCCmode: Mode = 0x008
/** FUNmode is orthogonal to above.
* When set we are looking for a method or constructor.
*/
- final val FUNmode = 0x010
+ final val FUNmode: Mode = 0x010
/** POLYmode is orthogonal to above.
* When set expression types can be polymorphic.
*/
- final val POLYmode = 0x020
+ final val POLYmode: Mode = 0x020
/** QUALmode is orthogonal to above. When set
* expressions may be packages and Java statics modules.
*/
- final val QUALmode = 0x040
+ final val QUALmode: Mode = 0x040
/** TAPPmode is set for the function/type constructor
* part of a type application. When set we do not decompose PolyTypes.
*/
- final val TAPPmode = 0x080
+ final val TAPPmode: Mode = 0x080
/** SUPERCONSTRmode is set for the super
* in a superclass constructor call super.<init>.
*/
- final val SUPERCONSTRmode = 0x100
+ final val SUPERCONSTRmode: Mode = 0x100
/** SNDTRYmode indicates that an application is typed for the 2nd time.
* In that case functions may no longer be coerced with implicit views.
*/
- final val SNDTRYmode = 0x200
+ final val SNDTRYmode: Mode = 0x200
/** LHSmode is set for the left-hand side of an assignment.
*/
- final val LHSmode = 0x400
+ final val LHSmode: Mode = 0x400
/** STARmode is set when star patterns are allowed.
* (This was formerly called REGPATmode.)
*/
- final val STARmode = 0x1000
+ final val STARmode: Mode = 0x1000
/** ALTmode is set when we are under a pattern alternative.
*/
- final val ALTmode = 0x2000
+ final val ALTmode: Mode = 0x2000
/** HKmode is set when we are typing a higher-kinded type.
* adapt should then check kind-arity based on the prototypical type's
* kind arity. Type arguments should not be inferred.
*/
- final val HKmode = 0x4000 // @M: could also use POLYmode | TAPPmode
+ final val HKmode: Mode = 0x4000 // @M: could also use POLYmode | TAPPmode
/** BYVALmode is set when we are typing an expression
* that occurs in a by-value position. An expression e1 is in by-value
@@ -80,39 +81,17 @@ trait Modes {
* arguments or the conditional of an if-then-else clause.
* This mode has been added to support continuations.
*/
- final val BYVALmode = 0x8000
+ final val BYVALmode: Mode = 0x8000
/** TYPEPATmode is set when we are typing a type in a pattern.
*/
- final val TYPEPATmode = 0x10000
+ final val TYPEPATmode: Mode = 0x10000
/** RETmode is set when we are typing a return expression.
*/
- final val RETmode = 0x20000
-
- final private val StickyModes = EXPRmode | PATTERNmode | TYPEmode | ALTmode
-
- final def onlyStickyModes(mode: Int) =
- mode & StickyModes
-
- final def forFunMode(mode: Int) =
- mode & (StickyModes | SCCmode) | FUNmode | POLYmode | BYVALmode
-
- final def forTypeMode(mode: Int) =
- if (inAnyMode(mode, PATTERNmode | TYPEPATmode)) TYPEmode | TYPEPATmode
- else TYPEmode
+ final val RETmode: Mode = 0x20000
- final def inAllModes(mode: Int, required: Int) = (mode & required) == required
- final def inAnyMode(mode: Int, required: Int) = (mode & required) != 0
- final def inNoModes(mode: Int, prohibited: Int) = (mode & prohibited) == 0
- final def inHKMode(mode: Int) = (mode & HKmode) != 0
- final def inFunMode(mode: Int) = (mode & FUNmode) != 0
- final def inPolyMode(mode: Int) = (mode & POLYmode) != 0
- final def inPatternMode(mode: Int) = (mode & PATTERNmode) != 0
- final def inPatternNotFunMode(mode: Int) = inPatternMode(mode) && !inFunMode(mode)
- final def inExprModeOr(mode: Int, others: Int) = (mode & (EXPRmode | others)) != 0
- final def inExprModeButNot(mode: Int, prohibited: Int) =
- (mode & (EXPRmode | prohibited)) == EXPRmode
+ final private val StickyModes: Mode = EXPRmode | PATTERNmode | TYPEmode | ALTmode
/** Translates a mask of mode flags into something readable.
*/
@@ -134,8 +113,37 @@ trait Modes {
(1 << 14) -> "HKmode",
(1 << 15) -> "BYVALmode",
(1 << 16) -> "TYPEPATmode"
- )
- def modeString(mode: Int): String =
- if (mode == 0) "NOmode"
- else (modeNameMap filterKeys (bit => inAllModes(mode, bit))).values mkString " "
+ ).map({ case (k, v) => Mode(k) -> v })
+}
+import Mode._
+
+final class Mode private (val bits: Int) extends AnyVal {
+ def &(other: Mode): Mode = new Mode(bits & other.bits)
+ def |(other: Mode): Mode = new Mode(bits | other.bits)
+ def &~(other: Mode): Mode = new Mode(bits & ~(other.bits))
+
+ def onlySticky = this & Mode.StickyModes
+ def forFunMode = this & (Mode.StickyModes | SCCmode) | FUNmode | POLYmode | BYVALmode
+ def forTypeMode =
+ if (inAny(PATTERNmode | TYPEPATmode)) TYPEmode | TYPEPATmode
+ else TYPEmode
+
+ def inAll(required: Mode) = (this & required) == required
+ def inAny(required: Mode) = (this & required) !=NOmode
+ def inNone(prohibited: Mode) = (this & prohibited) == NOmode
+ def inHKMode = inAll(HKmode)
+ def inFunMode = inAll(FUNmode)
+ def inPolyMode = inAll(POLYmode)
+ def inPatternMode = inAll(PATTERNmode)
+ def inExprMode = inAll(EXPRmode)
+ def inByValMode = inAll(BYVALmode)
+ def inRetMode = inAll(RETmode)
+
+ def inPatternNotFunMode = inPatternMode && !inFunMode
+ def inExprModeOr(others: Mode) = inAny(EXPRmode | others)
+ def inExprModeButNot(prohibited: Mode) = inAll(EXPRmode) && inNone(prohibited)
+
+ override def toString =
+ if (bits == 0) "NOmode"
+ else (modeNameMap filterKeys inAll).values.toList.sorted mkString " "
}
2  test/files/pos/CustomGlobal.scala
View
@@ -22,7 +22,7 @@ class CustomGlobal(currentSettings: Settings, reporter: Reporter) extends Global
override def newTyper(context: Context): Typer = new CustomTyper(context)
class CustomTyper(context : Context) extends Typer(context) {
- override def typed(tree: Tree, mode: Int, pt: Type): Tree = {
+ override def typed(tree: Tree, mode: Mode, pt: Type): Tree = {
if (tree.summaryString contains "Bippy")
println("I'm typing a Bippy! It's a " + tree.shortClass + ".")
Please sign in to comment.
Something went wrong with that request. Please try again.