diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2012-11-16 14:56:55 -0800 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2012-11-16 14:56:55 -0800 |
commit | 6645fec23ab3ee7d12f5cfc7c474a42f0eb7ec15 (patch) | |
tree | a4f4cd998a558990315530e67fb06068b836d8ad /src/reflect | |
parent | b091cbda7e3a22f0d4554159b27b1bb30cf4a3a9 (diff) | |
parent | ed44df6c85e82bc6d4731ed232de53bdbeadb2e1 (diff) | |
download | scala-6645fec23ab3ee7d12f5cfc7c474a42f0eb7ec15.tar.gz scala-6645fec23ab3ee7d12f5cfc7c474a42f0eb7ec15.tar.bz2 scala-6645fec23ab3ee7d12f5cfc7c474a42f0eb7ec15.zip |
Merge pull request #1623 from paulp/merge-2.10.x
Merge 2.10.0-wip/.x into master
Diffstat (limited to 'src/reflect')
6 files changed, 91 insertions, 18 deletions
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index ed45010091..8e406b6f62 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -981,6 +981,7 @@ trait Definitions extends api.StandardDefinitions { lazy val BeanPropertyAttr = requiredClass[scala.beans.BeanProperty] lazy val BooleanBeanPropertyAttr = requiredClass[scala.beans.BooleanBeanProperty] lazy val CloneableAttr = requiredClass[scala.annotation.cloneable] + lazy val CompileTimeOnlyAttr = getClassIfDefined("scala.reflect.macros.compileTimeOnly") lazy val DeprecatedAttr = requiredClass[scala.deprecated] lazy val DeprecatedNameAttr = requiredClass[scala.deprecatedName] lazy val DeprecatedInheritanceAttr = requiredClass[scala.deprecatedInheritance] diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index 68b5794b59..fb1bf9ed9d 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -6,6 +6,7 @@ package scala.reflect package internal +import scala.annotation.elidable import scala.collection.{ mutable, immutable } import util._ @@ -108,6 +109,11 @@ abstract class SymbolTable extends macros.Universe val global: SymbolTable.this.type = SymbolTable.this } with util.TraceSymbolActivity + /** Check that the executing thread is the compiler thread. No-op here, + * overridden in interactive.Global. */ + @elidable(elidable.WARNING) + def assertCorrectThread() {} + /** Are we compiling for Java SE? */ // def forJVM: Boolean diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 30e5ecd643..0ad0275fba 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -740,6 +740,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => def elisionLevel = getAnnotation(ElidableMethodClass) flatMap { _.intArg(0) } def implicitNotFoundMsg = getAnnotation(ImplicitNotFoundClass) flatMap { _.stringArg(0) } + def isCompileTimeOnly = hasAnnotation(CompileTimeOnlyAttr) + def compileTimeOnlyMessage = getAnnotation(CompileTimeOnlyAttr) flatMap (_ stringArg 0) + /** Is this symbol an accessor method for outer? */ final def isOuterAccessor = { hasFlag(STABLE | ARTIFACT) && @@ -1259,6 +1262,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => } val current = phase try { + assertCorrectThread() phase = phaseOf(infos.validFrom) tp.complete(this) } finally { @@ -1329,6 +1333,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => infos = infos.prev if (validTo < curPeriod) { + assertCorrectThread() // adapt any infos that come from previous runs val current = phase try { diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index ddfc1f2af0..7ae7cf1821 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -287,6 +287,68 @@ abstract class TreeInfo { isSelfConstrCall(tree1) || isSuperConstrCall(tree1) } + /** + * Does this tree represent an irrefutable pattern match + * in the position `for { <tree> <- expr }` based only + * on information at the `parser` phase? To qualify, there + * may be no subtree that will be interpreted as a + * Stable Identifier Pattern. + * + * For instance: + * + * {{{ + * foo @ (bar, (baz, quux)) + * }}} + * + * is a variable pattern; if the structure matches, + * then the remainder is inevitable. + * + * The following are not variable patterns. + * + * {{{ + * foo @ (bar, (`baz`, quux)) // back quoted ident, not at top level + * foo @ (bar, Quux) // UpperCase ident, not at top level + * }}} + * + * If the pattern is a simple identifier, it is always + * a variable pattern. For example, the following + * introduce new bindings: + * + * {{{ + * for { X <- xs } yield X + * for { `backquoted` <- xs } yield `backquoted` + * }}} + * + * Note that this differs from a case clause: + * + * {{{ + * object X + * scrut match { + * case X => // case _ if scrut == X + * } + * }}} + * + * Background: [[https://groups.google.com/d/msg/scala-internals/qwa_XOw_7Ks/IktkeTBYqg0J]] + * + */ + def isVarPatternDeep(tree: Tree): Boolean = { + def isVarPatternDeep0(tree: Tree): Boolean = { + tree match { + case Bind(name, pat) => isVarPatternDeep0(pat) + case Ident(name) => isVarPattern(tree) + case Apply(sel, args) => + ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName) + && (args forall isVarPatternDeep0) + ) + case _ => false + } + } + tree match { + case Ident(name) => true + case _ => isVarPatternDeep0(tree) + } + } + /** Is tree a variable pattern? */ def isVarPattern(pat: Tree): Boolean = pat match { case x: Ident => !x.isBackquoted && nme.isVariableName(x.name) @@ -372,24 +434,6 @@ abstract class TreeInfo { case _ => false } - /** Is this tree comprised of nothing but identifiers, - * but possibly in bindings or tuples? For instance - * - * foo @ (bar, (baz, quux)) - * - * is a variable pattern; if the structure matches, - * then the remainder is inevitable. - */ - def isVariablePattern(tree: Tree): Boolean = tree match { - case Bind(name, pat) => isVariablePattern(pat) - case Ident(name) => true - case Apply(sel, args) => - ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName) - && (args forall isVariablePattern) - ) - case _ => false - } - /** Is this argument node of the form <expr> : _* ? */ def isWildcardStarArg(tree: Tree): Boolean = tree match { diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 02cdac4046..42a9d9e456 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -143,6 +143,7 @@ trait Types extends api.Types { self: SymbolTable => /** Undo all changes to constraints to type variables upto `limit`. */ //OPT this method is public so we can do `manual inlining` def undoTo(limit: UndoPairs) { + assertCorrectThread() while ((log ne limit) && log.nonEmpty) { val (tv, constr) = log.head tv.constr = constr diff --git a/src/reflect/scala/reflect/macros/compileTimeOnly.scala b/src/reflect/scala/reflect/macros/compileTimeOnly.scala new file mode 100644 index 0000000000..5a3a352a53 --- /dev/null +++ b/src/reflect/scala/reflect/macros/compileTimeOnly.scala @@ -0,0 +1,16 @@ +package scala.reflect +package macros + +import scala.annotation.meta._ + +/** + * An annotation that designates a member should not be referred to after + * type checking (which includes macro expansion); it must only be used in + * the arguments of some other macro that will eliminate it from the AST. + * + * @param message the error message to print during compilation if a reference remains + * after type checking + * @since 2.10.1 + */ +@getter @setter @beanGetter @beanSetter +final class compileTimeOnly(message: String) extends scala.annotation.StaticAnnotation |