summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-04-13 12:40:59 -0700
committerMartin Odersky <odersky@gmail.com>2012-04-13 12:40:59 -0700
commitcc764e944817628cbca3f7b5a195cdb495ca8f38 (patch)
tree3508dd2fe98420f9f33fc5a4b1985e926dc12561 /src/compiler
parent381c0e12bf5a72df6f3b3ac8eaca1cac28263154 (diff)
downloadscala-cc764e944817628cbca3f7b5a195cdb495ca8f38.tar.gz
scala-cc764e944817628cbca3f7b5a195cdb495ca8f38.tar.bz2
scala-cc764e944817628cbca3f7b5a195cdb495ca8f38.zip
Added languageFeature annotation (was missing before). Resolved problem with late loading of nested classes in Definitions. Resolved handling of deprecated idents `then` and `macro`. Massaged test flags.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala30
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala75
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala38
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
4 files changed, 56 insertions, 89 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 6689a9dbb8..72fca5da12 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -924,17 +924,18 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val ClassTargetClass = getMetaAnnotation("companionClass")
lazy val ObjectTargetClass = getMetaAnnotation("companionObject")
lazy val MethodTargetClass = getMetaAnnotation("companionMethod") // TODO: module, moduleClass? package, packageObject?
- lazy val LanguageFeatureClass = getMetaAnnotation("languageFeature")
+ lazy val LanguageFeatureAnnot = getMetaAnnotation("languageFeature")
// Language features
lazy val languageFeatureModule = getRequiredModule("scala.languageFeature")
- lazy val MacrosFeature = getRequiredClass("scala.languageFeature.experimental.macros")
- lazy val DynamicsFeature = getRequiredClass("scala.languageFeature.dynamics")
- lazy val PostfixOpsFeature = getRequiredClass("scala.languageFeature.postfixOps")
- lazy val ReflectiveCallsFeature = getRequiredClass("scala.languageFeature.reflectiveCalls")
- lazy val ImplicitConversionsFeature = getRequiredClass("scala.languageFeature.implicitConversions")
- lazy val HigherKindsFeature = getRequiredClass("scala.languageFeature.higherKinds")
- lazy val ExistentialsFeature = getRequiredClass("scala.languageFeature.existentials")
+ lazy val experimentalModule = getMember(languageFeatureModule, newTermName("experimental"))
+ lazy val MacrosFeature = getLanguageFeature("macros", experimentalModule)
+ lazy val DynamicsFeature = getLanguageFeature("dynamics")
+ lazy val PostfixOpsFeature = getLanguageFeature("postfixOps")
+ lazy val ReflectiveCallsFeature = getLanguageFeature("reflectiveCalls")
+ lazy val ImplicitConversionsFeature = getLanguageFeature("implicitConversions")
+ lazy val HigherKindsFeature = getLanguageFeature("higherKinds")
+ lazy val ExistentialsFeature = getLanguageFeature("existentials")
private def getMetaAnnotation(name: String) = getRequiredClass("scala.annotation.meta." + name)
def isMetaAnnotation(sym: Symbol): Boolean = metaAnnotations(sym) || (
@@ -986,6 +987,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
try getModule(fullname.toTermName)
catch { case _: MissingRequirementError => NoSymbol }
+ def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule) =
+ getMember(owner, newTypeName(name))
+
def termMember(owner: Symbol, name: String): Symbol = owner.info.member(newTermName(name))
def typeMember(owner: Symbol, name: String): Symbol = owner.info.member(newTypeName(name))
@@ -1005,7 +1009,13 @@ trait Definitions extends reflect.api.StandardDefinitions {
def getMember(owner: Symbol, name: Name): Symbol = {
getMemberIfDefined(owner, name) orElse {
- throw new FatalError(owner + " does not have a member " + name)
+ if (phase.flatClasses && name.isTypeName && !owner.isPackageObjectOrClass) {
+ val pkg = owner.owner
+ val flatname = nme.flattenedName(owner.name, name)
+ getMember(pkg, flatname)
+ } else {
+ throw new FatalError(owner + " does not have a member " + name)
+ }
}
}
def getMemberIfDefined(owner: Symbol, name: Name): Symbol =
@@ -1022,7 +1032,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
def getDeclIfDefined(owner: Symbol, name: Name): Symbol =
owner.info.nonPrivateDecl(name)
-
+
def packageExists(packageName: String): Boolean =
getModuleIfDefined(packageName).isPackage
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index ef11427677..65225b185b 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1773,21 +1773,7 @@ self =>
*/
def pattern2(): Tree = {
val nameOffset = in.offset
- def warnIfMacro(tree: Tree): Unit = {
- def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString)
- warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.")
- tree match {
- case _: BackQuotedIdent =>
- ;
- case Ident(name) =>
- check(name)
- case _ =>
- ;
- }
- }
-
val p = pattern3()
- warnIfMacro(p)
if (in.token != AT) p
else p match {
@@ -2463,8 +2449,6 @@ self =>
val nameOffset = in.offset
val isBackquoted = in.token == BACKQUOTED_IDENT
val name = ident()
- if (name.toString == nme.MACROkw.toString && !isBackquoted)
- warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.")
funDefRest(start, nameOffset, mods, name)
}
}
@@ -2480,7 +2464,7 @@ self =>
val vparamss = paramClauses(name, contextBoundBuf.toList, false)
newLineOptWhenFollowedBy(LBRACE)
var restype = fromWithinReturnType(typedOpt())
- val rhs =
+ val rhs =
if (isStatSep || in.token == RBRACE) {
if (restype.isEmpty) restype = scalaUnitConstr
newmods |= Flags.DEFERRED
@@ -2489,11 +2473,15 @@ self =>
restype = scalaUnitConstr
blockExpr()
} else {
- accept(EQUALS)
- if (settings.Xmacros.value && in.token == MACRO || // [Martin] Xmacros can be retired now
- in.token == IDENTIFIER && in.name == nme.MACROkw) {
- in.nextToken()
- newmods |= Flags.MACRO
+ if (in.token == EQUALS) {
+ in.nextTokenAllow(nme.MACROkw)
+ if (settings.Xmacros.value && in.token == MACRO || // [Martin] Xmacros can be retired now
+ in.token == IDENTIFIER && in.name == nme.MACROkw) {
+ in.nextToken()
+ newmods |= Flags.MACRO
+ }
+ } else {
+ accept(EQUALS)
}
expr()
}
@@ -2556,8 +2544,6 @@ self =>
val nameOffset = in.offset
val isBackquoted = in.token == BACKQUOTED_IDENT
val name = identForType()
- if (name.toString == nme.MACROkw.toString && !isBackquoted)
- warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.")
// @M! a type alias as well as an abstract type may declare type parameters
val tparams = typeParamClauseOpt(name, null)
in.token match {
@@ -2617,9 +2603,6 @@ self =>
val nameOffset = in.offset
val isBackquoted = in.token == BACKQUOTED_IDENT
val name = identForType()
- if (name.toString == nme.MACROkw.toString && !isBackquoted)
- warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.")
-
atPos(start, if (name == tpnme.ERROR) start else nameOffset) {
savingClassContextBounds {
val contextBoundBuf = new ListBuffer[Tree]
@@ -2661,8 +2644,6 @@ self =>
val nameOffset = in.offset
val isBackquoted = in.token == BACKQUOTED_IDENT
val name = ident()
- if (name.toString == nme.MACROkw.toString && !isBackquoted)
- warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.")
val tstart = in.offset
atPos(start, if (name == nme.ERROR) start else nameOffset) {
val mods1 = if (in.token == SUBTYPE) mods | Flags.DEFERRED else mods
@@ -2841,24 +2822,7 @@ self =>
*/
def packaging(start: Int): Tree = {
val nameOffset = in.offset
- def warnIfMacro(tree: Tree): Unit = {
- def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString)
- warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.")
- tree match {
- case _: BackQuotedIdent =>
- ;
- case Ident(name) =>
- check(name)
- case Select(qual, name) =>
- warnIfMacro(qual)
- check(name)
- case _ =>
- ;
- }
- }
-
val pkg = pkgQualId()
- warnIfMacro(pkg)
val stats = inBracesOrNil(topStatSeq())
makePackaging(start, pkg, stats)
}
@@ -3061,27 +3025,8 @@ self =>
}
} else {
val nameOffset = in.offset
- def warnIfMacro(tree: Tree): Unit = {
- def check(name: Name): Unit = if (name.toString == nme.MACROkw.toString)
- warning(nameOffset, "in future versions of Scala \"macro\" will be a keyword. consider using a different name.")
- tree match {
- // [Eugene] pkgQualId never returns BackQuotedIdents
- // this means that we'll get spurious warnings even if we wrap macro package name in backquotes
- case _: BackQuotedIdent =>
- ;
- case Ident(name) =>
- check(name)
- case Select(qual, name) =>
- warnIfMacro(qual)
- check(name)
- case _ =>
- ;
- }
- }
-
in.flushDoc
val pkg = pkgQualId()
- warnIfMacro(pkg)
if (in.token == EOF) {
ts += makePackaging(start, pkg, List())
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index c75e806b2a..105db805d8 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -113,20 +113,19 @@ trait Scanners extends ScannersCommon {
}
/** Clear buffer and set name and token */
- private def finishNamed() {
+ private def finishNamed(idtoken: Int = IDENTIFIER) {
name = newTermName(cbuf.toString)
- token = name2token(name)
- cbuf.clear()
- }
-
- /** Convert name to token */
- private def name2token(name: Name) = {
+ token = idtoken
val idx = name.start - kwOffset
if (idx >= 0 && idx < kwArray.length) {
- val token = kwArray(idx)
- if (token == IDENTIFIER) deprecationWarning(name+" is now a reserved word; usage as an identifier is deprecated")
- token
- } else IDENTIFIER
+ token = kwArray(idx)
+ if (token == IDENTIFIER) {
+ if (idtoken == IDENTIFIER && allowIdent != name)
+ deprecationWarning(name+" is now a reserved word; usage as an identifier is deprecated")
+ token = idtoken
+ }
+ }
+ cbuf.clear()
}
/** Clear buffer and set string */
@@ -200,6 +199,20 @@ trait Scanners extends ScannersCommon {
off
}
+ /** Allow an otherwise deprecated ident here */
+ private var allowIdent: Name = nme.EMPTY
+
+ /** Get next token, and allow the otherwise deprecated ident `name` */
+ def nextTokenAllow(name: Name) = {
+ val prev = allowIdent
+ allowIdent = name
+ try {
+ nextToken()
+ } finally {
+ allowIdent = prev
+ }
+ }
+
/** Produce next token, filling TokenData fields of Scanner.
*/
def nextToken() {
@@ -572,9 +585,8 @@ trait Scanners extends ScannersCommon {
getLitChars('`')
if (ch == '`') {
nextChar()
- finishNamed()
+ finishNamed(BACKQUOTED_IDENT)
if (name.length == 0) syntaxError("empty quoted identifier")
- token = BACKQUOTED_IDENT
}
else syntaxError("unclosed quoted identifier")
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index b1cbc53044..1425cd4755 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -743,7 +743,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def hasOption = settings.language.value contains featureName
if (!hasImport && !hasOption) {
val Some(AnnotationInfo(_, List(Literal(Constant(featureDesc: String)), Literal(Constant(required: Boolean))), _)) =
- featureTrait getAnnotation LanguageFeatureClass
+ featureTrait getAnnotation LanguageFeatureAnnot
val req = if (required) "needs to" else "should"
var raw = featureDesc + " " + req + " be enabled\n" +
"by making the implicit value language." + featureName + " visible."