summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Namers.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-01-03 15:56:13 +0000
committerMartin Odersky <odersky@gmail.com>2007-01-03 15:56:13 +0000
commita961d3dcd6f93ee006cff1d386052bf62326739a (patch)
tree5af3312932236340708522dfd078f32beed20519 /src/compiler/scala/tools/nsc/typechecker/Namers.scala
parent02a45e20bb6f68808708dca377bc72ccaf5bba3d (diff)
downloadscala-a961d3dcd6f93ee006cff1d386052bf62326739a.tar.gz
scala-a961d3dcd6f93ee006cff1d386052bf62326739a.tar.bz2
scala-a961d3dcd6f93ee006cff1d386052bf62326739a.zip
1.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Namers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index cb6e29650f..8e4e0d317e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -533,6 +533,7 @@ trait Namers requires Analyzer {
var result = tp;
if (sym hasFlag IMPLICIT) {
val p = provided(tp);
+ //Console.println("check contractive: "+sym+" "+p+"/"+required(tp))
for (val r <- required(tp)) {
if (!isContainedIn(r, p) || (r =:= p)) {
context.error(sym.pos, "implicit " + sym + " is not contractive," +
@@ -549,6 +550,10 @@ trait Namers requires Analyzer {
makePolyType(typer.reenterTypeParams(tparams), typer.typedType(rhs).tpe);
def typeSig(tree: Tree): Type = {
+ tree match {
+ case md: MemberDef => attributes(md)
+ case _ =>
+ }
val result =
try {
val sym: Symbol = tree.symbol
@@ -644,6 +649,66 @@ trait Namers requires Analyzer {
deSkolemize(result)
}
+ /**
+ * @param defn ...
+ */
+ protected def attributes(defn: MemberDef): Unit = {
+ var attrError: Boolean = false;
+ def error(pos: PositionType, msg: String): Null = {
+ context.error(pos, msg)
+ attrError = true
+ null
+ }
+ def getConstant(tree: Tree): Constant = tree match {
+ case Literal(value) => value
+ case arg => error(arg.pos, "attribute argument needs to be a constant; found: "+arg)
+ }
+ val attrInfos =
+ for (val t @ Attribute(constr, elements) <- defn.mods.attributes) yield {
+ typer.typed(constr, EXPRmode | CONSTmode, AttributeClass.tpe) match {
+ case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>
+ val constrArgs = args map getConstant
+ val attrScope = tpt.tpe.decls.
+ filter(sym => sym.isMethod && !sym.isConstructor && sym.hasFlag(JAVA));
+ val names = new collection.mutable.HashSet[Symbol]
+ names ++= attrScope.elements.filter(.isMethod)
+ if (args.length == 1) {
+ names.retain(sym => sym.name != nme.value)
+ }
+ val nvPairs = elements map {
+ case Assign(ntree @ Ident(name), rhs) => {
+ val sym = attrScope.lookup(name);
+ if (sym == NoSymbol) {
+ error(ntree.pos, "unknown attribute element name: " + name)
+ } else if (!names.contains(sym)) {
+ error(ntree.pos, "duplicate value for element " + name)
+ } else {
+ names -= sym
+ Pair(sym.name, getConstant(typer.typed(rhs, EXPRmode | CONSTmode, sym.tpe.resultType)))
+ }
+ }
+ }
+ for (val name <- names) {
+ if (!name.attributes.contains(Triple(AnnotationDefaultAttr.tpe, List(), List()))) {
+ error(t.pos, "attribute " + tpt.tpe.symbol.fullNameString + " is missing element " + name.name)
+ }
+ }
+ if (tpt.tpe.symbol.hasFlag(JAVA) && settings.target.value == "jvm-1.4") {
+ context.unit.warning (t.pos, "Java annotation will not be emitted in classfile unless you use the '-target:jvm-1.5' option")
+ }
+ Triple(tpt.tpe, constrArgs, nvPairs)
+ }
+ }
+ if (!attrError) {
+ val attributed =
+ if (defn.symbol.isModule) defn.symbol.moduleClass else defn.symbol
+ if (!attrInfos.isEmpty) {
+ attributed.attributes = attrInfos
+ }
+ }
+// defn.mods setAttr List();
+ }
+
/** Check that symbol's definition is well-formed. This means:
* - no conflicting modifiers
* - `abstract' modifier only for classes