diff options
author | Martin Odersky <odersky@gmail.com> | 2012-04-13 12:40:59 -0700 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2012-04-13 12:40:59 -0700 |
commit | cc764e944817628cbca3f7b5a195cdb495ca8f38 (patch) | |
tree | 3508dd2fe98420f9f33fc5a4b1985e926dc12561 /src | |
parent | 381c0e12bf5a72df6f3b3ac8eaca1cac28263154 (diff) | |
download | scala-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')
5 files changed, 69 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." diff --git a/src/library/scala/annotation/meta/languageFeature.scala b/src/library/scala/annotation/meta/languageFeature.scala new file mode 100644 index 0000000000..23acc01b51 --- /dev/null +++ b/src/library/scala/annotation/meta/languageFeature.scala @@ -0,0 +1,13 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ +package scala.annotation.meta + +/** + * An annotation giving particulars for a language feature in object `scala.language`. + */ +final class languageFeature(feature: String, enableRequired: Boolean) extends annotation.StaticAnnotation |