diff options
Diffstat (limited to 'src')
4 files changed, 28 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 9c3739aa91..11ec664904 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -287,6 +287,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { lazy val ProductRootClass: Symbol = getClass("scala.Product") def Product_productArity = getMember(ProductRootClass, nme.productArity) def Product_productElement = getMember(ProductRootClass, nme.productElement) + def Product_productElementName = getMember(ProductRootClass, nme.productElementName) def Product_productPrefix = getMember(ProductRootClass, nme.productPrefix) def Product_canEqual = getMember(ProductRootClass, nme.canEqual_) diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index b17728799b..0d9d98b934 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -314,6 +314,7 @@ trait StdNames extends reflect.generic.StdNames { self: SymbolTable => val print = newTermName("print") val productArity = newTermName("productArity") val productElement = newTermName("productElement") + val productElementName = newTermName("productElementName") val productPrefix = newTermName("productPrefix") val readResolve = newTermName("readResolve") val sameElements = newTermName("sameElements") diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index 2fcce5f5db..6a68ddc68c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -88,14 +88,16 @@ trait SyntheticMethods extends ast.TreeDSL { typer typed { DEF(method) === LIT(nargs) } } - def productElementMethod(accs: List[Symbol]): Tree = { - val symToTpe = makeTypeConstructor(List(IntClass.tpe), AnyClass.tpe) - val method = syntheticMethod(nme.productElement, 0, symToTpe) + /** Common code for productElement and productElementName + */ + def perElementMethod(accs: List[Symbol], methodName: Name, resType: Type, caseFn: Symbol => Tree): Tree = { + val symToTpe = makeTypeConstructor(List(IntClass.tpe), resType) + val method = syntheticMethod(methodName, 0, symToTpe) val arg = method ARG 0 - val default = List( DEFAULT ==> THROW(IndexOutOfBoundsExceptionClass, arg) ) + val default = List(DEFAULT ==> THROW(IndexOutOfBoundsExceptionClass, arg)) val cases = for ((sym, i) <- accs.zipWithIndex) yield - CASE(LIT(i)) ==> Ident(sym) + CASE(LIT(i)) ==> caseFn(sym) typer typed { DEF(method) === { @@ -103,6 +105,11 @@ trait SyntheticMethods extends ast.TreeDSL { } } } + def productElementMethod(accs: List[Symbol]): Tree = + perElementMethod(accs, nme.productElement, AnyClass.tpe, x => Ident(x)) + + def productElementNameMethod(accs: List[Symbol]): Tree = + perElementMethod(accs, nme.productElementName, StringClass.tpe, x => Literal(x.name.toString)) def moduleToStringMethod: Tree = { val method = syntheticMethod(nme.toString_, FINAL, makeNoArgConstructor(StringClass.tpe)) @@ -273,6 +280,7 @@ trait SyntheticMethods extends ast.TreeDSL { Product_productPrefix -> (() => productPrefixMethod), Product_productArity -> (() => productArityMethod(accessors.length)), Product_productElement -> (() => productElementMethod(accessors)), + Product_productElementName -> (() => productElementNameMethod(accessors)), Product_canEqual -> (() => canEqualMethod) ) } diff --git a/src/library/scala/Product.scala b/src/library/scala/Product.scala index 8521cf2437..417b87f191 100644 --- a/src/library/scala/Product.scala +++ b/src/library/scala/Product.scala @@ -20,7 +20,7 @@ package scala */ trait Product extends Equals { - /** for a product <code>A(x_1,...,x_k)</code>, returns <code>x_(n+1)</code> + /** For a product <code>A(x_1,...,x_k)</code>, returns <code>x_(n+1)</code> * for <code>0 <= n < k</code> * * @param n the index of the element to return @@ -29,6 +29,18 @@ trait Product extends Equals { */ def productElement(n: Int): Any + /** Returns the name of the field at the given index from the definition + * of the class. + * + * @param n the index of the element name to return + * @throws NoSuchElementException if the name data is unavailable for any reason + * @throws IndexOutOfBoundsException if the index is out of range + * @return a String representing the field name + */ + def productElementName(n: Int): String = + // the method implementation is synthetic - if it is not generated we always throw. + throw new NoSuchElementException() + /** return k for a product <code>A(x_1,...,x_k)</code> */ def productArity: Int |