summaryrefslogtreecommitdiff
path: root/sources/scalac
diff options
context:
space:
mode:
Diffstat (limited to 'sources/scalac')
-rw-r--r--sources/scalac/ast/parser/Parser.java22
-rw-r--r--sources/scalac/symtab/Type.java37
-rw-r--r--sources/scalac/transformer/UnCurry.java28
-rw-r--r--sources/scalac/transformer/matching/AlgebraicMatcher.java4
-rw-r--r--sources/scalac/typechecker/Analyzer.java14
-rw-r--r--sources/scalac/typechecker/Infer.java21
6 files changed, 75 insertions, 51 deletions
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index 9fa2e92dda..0f5a0b6a1f 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -642,22 +642,15 @@ public class Parser implements Tokens {
t = make.Ident(s.pos, Names.null_);
break;
case SYMBOLLIT:
+ int pos = s.pos;
Tree symt = scalaDot(s.pos, Names.Symbol);
if (isPattern) symt = convertToTypeId(symt);
- t = make.Apply(s.pos,
- symt,
- new Tree[]{make.Literal(s.pos, s.name.toString())});
- s.nextToken();
- if (s.token == LPAREN || s.token == LBRACE) {
- Tree labt = scalaXmlNoBindingDot(s.pos, Names.Element);
- if (isPattern) labt = convertToTypeId(labt);
- Tree listt = isPattern ? scalaDot(s.pos, Names.List.toTypeName())
- : make.Select(s.pos, scalaDot(s.pos, Names.Predef), Names.List);
- t = make.Apply(s.pos,
- labt,
- new Tree[]{t, make.Apply(s.pos, listt, argumentExprs())});
- }
- return t;
+ TreeList ts = new TreeList();
+ ts.append(make.Literal(s.pos, s.name.toString()));
+ s.nextToken();
+ if (s.token == LPAREN || s.token == LBRACE)
+ ts.append(argumentExprs());
+ return make.Apply(pos, symt, ts.toArray());
default:
return syntaxError("illegal literal", true);
}
@@ -2087,4 +2080,3 @@ public class Parser implements Tokens {
}
}
}
-
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index e7b7fd98f5..8b858cbb96 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -821,6 +821,14 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
* inherited members of this type; return Symbol.NONE if not found.
*/
public Symbol lookupNonPrivate(Name name) {
+ return lookupNonPrivate(name, 0);
+ }
+
+ /** Same as before, but with additional parameter `start'.
+ * If start == 0, lookup in all basetypes of a compound type.
+ * If start == 1, lookup only in mixin classes.
+ */
+ private Symbol lookupNonPrivate(Name name, int start) {
switch (this) {
case ErrorType:
return Symbol.ERROR;
@@ -829,26 +837,25 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
case ConstantType(_, _):
return singleDeref().lookupNonPrivate(name);
case TypeRef(_, Symbol sym, _):
- return sym.info().lookupNonPrivate(name);
+ return sym.info().lookupNonPrivate(name, start);
case CompoundType(Type[] parts, Scope members):
Symbol sym = members.lookup(name);
if (sym.kind != NONE && (sym.flags & PRIVATE) == 0)
return sym;
- // search base types in closure; non-abstract members
- // take precedence over abstract ones.
- Type[] cls = closure();
- int i = 1;
- while (i < cls.length &&
- (sym.kind == NONE || (sym.flags & DEFERRED) != 0)) {
- Symbol sym1 = cls[i].members().lookup(name);
- if (sym1.kind != NONE &&
- (sym1.flags & PRIVATE) == 0 &&
- (sym.kind == NONE || (sym1.flags & DEFERRED) == 0))
- sym = sym1;
- i++;
- }
- return sym;
+ // search base types in reverse; non-abstract members
+ // take precedence over abstract ones.
+ int i = parts.length;
+ sym = Symbol.NONE;
+ while (i > start && (sym.kind == NONE || (sym.flags & DEFERRED) != 0)) {
+ i--;
+ Symbol sym1 = parts[i].lookupNonPrivate(name, i == 0 ? 0 : 1);
+ if (sym1.kind != NONE &&
+ (sym1.flags & PRIVATE) == 0 &&
+ (sym.kind == NONE || (sym1.flags & DEFERRED) == 0))
+ sym = sym1;
+ }
+ return sym;
default:
return Symbol.NONE;
}
diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java
index 2293e5e8f2..1f17e47a49 100644
--- a/sources/scalac/transformer/UnCurry.java
+++ b/sources/scalac/transformer/UnCurry.java
@@ -213,7 +213,8 @@ public class UnCurry extends OwnerTransformer
switch (methtype) {
case MethodType(Symbol[] params, _):
- if (params.length == 1 && (params[0].flags & REPEATED) != 0) {
+ if (params.length > 0 &&
+ (params[params.length-1].flags & REPEATED) != 0) {
args = toSequence(pos, params, args);
}
Tree[] args1 = args;
@@ -240,16 +241,27 @@ public class UnCurry extends OwnerTransformer
* escaping
*/
private Tree[] toSequence(int pos, Symbol[] params, Tree[] args) {
- assert (args.length != 1
- || !(args[0] instanceof Tree.Sequence)
- || TreeInfo.isSequenceValued( args[0]));
- if (args.length == 1) {
- switch (args[0]) {
+ Tree[] result = new Tree[params.length];
+ for (int i = 0; i < params.length - 1; i++)
+ result[i] = args[i];
+ assert (args.length != params.length
+ || !(args[params.length-1] instanceof Tree.Sequence)
+ || TreeInfo.isSequenceValued(args[params.length-1]));
+ if (args.length == params.length) {
+ switch (args[params.length-1]) {
case Typed(Tree arg, Ident(TypeNames.WILDCARD_STAR)):
- return new Tree[]{arg};
+ result[params.length-1] = arg;
+ return result;
}
}
- return new Tree[]{make.Sequence( pos, args ).setType(params[0].type())};
+ Tree[] args1 = args;
+ if (params.length != 1) {
+ args1 = new Tree[args.length - (params.length - 1)];
+ System.arraycopy(args, params.length - 1, args1, 0, args1.length);
+ }
+ result[params.length-1] =
+ make.Sequence(pos, args1).setType(params[params.length-1].type());
+ return result;
}
/** for every argument to a def parameter `def x: T':
diff --git a/sources/scalac/transformer/matching/AlgebraicMatcher.java b/sources/scalac/transformer/matching/AlgebraicMatcher.java
index 4708dd6258..7c564882b3 100644
--- a/sources/scalac/transformer/matching/AlgebraicMatcher.java
+++ b/sources/scalac/transformer/matching/AlgebraicMatcher.java
@@ -110,8 +110,8 @@ public class AlgebraicMatcher extends PatternMatcher {
//System.err.println( tree.fun.type.resultType().symbol() );
return (tree.args.length == 1)
&& (tree.type.symbol().flags & Modifiers.CASE) != 0
- && params.length == 1
- && (params[ 0 ].flags & Modifiers.REPEATED) != 0;
+ && params.length > 0
+ && (params[params.length-1].flags & Modifiers.REPEATED) != 0;
}
//////////// generator methods
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index b11f3ac85a..3457499228 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -917,9 +917,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
enterSym(params[i]);
switch (params[i]) {
case ValDef(int mods, _, _, _):
- if ((mods & REPEATED) != 0 && params.length > 1)
+ if ((mods & REPEATED) != 0 && i != params.length - 1)
error(params[i].pos,
- "`*' parameter must be the only parameter of a `('...`)' section");
+ "`*' parameter must be the last parameter of a `('...`)' section");
}
}
return Tree.symbolOf(params);
@@ -1782,11 +1782,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
}
// desugarizing ident patterns
- if (params.length == 1 && (params[0].flags & REPEATED) != 0) {
+ if (params.length > 0 &&
+ (params[params.length - 1].flags & REPEATED) != 0) {
if (( mode & PATTERNmode ) != 0 ) {
desug_allIdentPatterns( args, context.owner );
} else {
- assert (args.length != 1 || !(args[0] instanceof Tree.Sequence));
+ assert (args.length != params.length ||
+ !(args[params.length-1] instanceof Tree.Sequence));
}
}
return argtypes;
@@ -2392,7 +2394,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
switch (alttp) {
case MethodType(Symbol[] params, _):
if (params.length == args.length ||
- params.length == 1 && (params[0].flags & REPEATED) != 0) {
+ params.length > 0 &&
+ args.length >= params.length - 1 &&
+ (params[params.length-1].flags & REPEATED) != 0) {
matching2 = matching1;
matching1 = i;
}
diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java
index ea6cb4ddc4..b2b38ef2da 100644
--- a/sources/scalac/typechecker/Infer.java
+++ b/sources/scalac/typechecker/Infer.java
@@ -333,15 +333,24 @@ public class Infer implements Modifiers, Kinds {
* If `params' is a repeated parameter, a list of `length' copies
* of its type is returned.
*/
- public Type[] formalTypes(Symbol[] params, int length) {
+ public Type[] formalTypes(Symbol[] params, int nargs) {
Type[] result;
- if (params.length == 1 && (params[0].flags & REPEATED) != 0) {
- Type[] formals = new Type[length];
- Type[] args = params[0].type().typeArgs();
+ if (params.length > 0 &&
+ (params[params.length-1].flags & REPEATED) != 0) {
+ Type[] args = params[params.length-1].type().typeArgs();
if (args.length == 1) {
Type ft = args[0];
- // params[0] has type Seq[T], we need T here
- for (int i = 0; i < length; i++) formals[i] = ft;
+ // last param has type Seq[T], we need T here
+ Type[] formals = new Type[nargs];
+ int i = 0;
+ while (i < params.length-1) {
+ formals[i] = params[i].type();
+ i++;
+ }
+ while (i < nargs) {
+ formals[i] = ft;
+ i++;
+ }
return formals;
}
}