summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Zenger <mzenger@gmail.com>2003-08-28 12:39:14 +0000
committerMatthias Zenger <mzenger@gmail.com>2003-08-28 12:39:14 +0000
commit1f02ae13680bcf874db01096105c22b4d5d3f042 (patch)
tree56b6d42ad48f39e669b439373e7e10cc1fafab16
parent7a9bbd21f018981ce132dd7d2d4ab1ca33bd4df2 (diff)
downloadscala-1f02ae13680bcf874db01096105c22b4d5d3f042.tar.gz
scala-1f02ae13680bcf874db01096105c22b4d5d3f042.tar.bz2
scala-1f02ae13680bcf874db01096105c22b4d5d3f042.zip
Added support for case tags.
-rw-r--r--sources/scala/Object.java7
-rw-r--r--sources/scalac/symtab/Symbol.java7
-rw-r--r--sources/scalac/typechecker/RefCheck.java11
3 files changed, 24 insertions, 1 deletions
diff --git a/sources/scala/Object.java b/sources/scala/Object.java
index e0144b1cae..4a44ad0caa 100644
--- a/sources/scala/Object.java
+++ b/sources/scala/Object.java
@@ -14,4 +14,11 @@ package scala;
/** @meta class extends scala.AnyRef;
*/
public class Object {
+
+ /** This method is needed for optimizing pattern matching expressions
+ * which match on constructors of case classes.
+ */
+ public int $tag() {
+ return 0;
+ }
}
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index c3da3e15d9..28772e6bc5 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -1051,6 +1051,13 @@ public abstract class Symbol implements Modifiers, Kinds {
this.infos = TypeIntervalList.EMPTY;
this.setInfo(completer);
}
+
+ /** return a tag which (in the ideal case) uniquely identifies
+ * class symbols
+ */
+ public int tag() {
+ return name.toString().hashCode();
+ }
}
/** A class for term symbols
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index 460e98abeb..d25c547e20 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -588,7 +588,6 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
testtp = testtp.subst(tparams, targs);
}
}
-
// if (that is C) {...
Tree cond = gen.TypeApply(
gen.Select(
@@ -639,6 +638,15 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
return gen.Select(qual, clazz.caseFieldAccessor(i));
}
+ private Tree tagMethod(ClassSymbol clazz) {
+ Symbol tagSym = new TermSymbol(
+ clazz.pos, Names.tag, clazz,
+ clazz.isSubClass(defs.OBJECT_CLASS) ? OVERRIDE : 0)
+ .setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, defs.INT_TYPE));
+ clazz.info().members().enter(tagSym);
+ return gen.DefDef(clazz.pos, tagSym, gen.mkIntLit(clazz.pos, clazz.tag()));
+ }
+
private Tree hashCodeMethod(ClassSymbol clazz) {
Symbol hashCodeSym = new TermSymbol(
clazz.pos, Names.hashCode, clazz, OVERRIDE)
@@ -693,6 +701,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
ts.append(equalsMethod(clazz));
if (!hasImplementation(clazz, Names.hashCode))
ts.append(hashCodeMethod(clazz));
+ ts.append(tagMethod(clazz));
if (ts.length() > 0) {
Tree[] stats1 = new Tree[stats.length + ts.length()];
System.arraycopy(stats, 0, stats1, 0, stats.length);