diff options
Diffstat (limited to 'sources/scalac')
-rw-r--r-- | sources/scalac/ast/parser/Parser.java | 22 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 37 | ||||
-rw-r--r-- | sources/scalac/transformer/UnCurry.java | 28 | ||||
-rw-r--r-- | sources/scalac/transformer/matching/AlgebraicMatcher.java | 4 | ||||
-rw-r--r-- | sources/scalac/typechecker/Analyzer.java | 14 | ||||
-rw-r--r-- | sources/scalac/typechecker/Infer.java | 21 |
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; } } |