From 1cfdffddd1d0d8d71426ef6c1b43aba3e9187561 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 25 Aug 2003 15:26:29 +0000 Subject: *** empty log message *** --- sources/scalac/ast/TreeGen.java | 25 +++++++++++- sources/scalac/ast/TreeInfo.java | 22 ++++++++--- sources/scalac/symtab/Definitions.java | 15 ++++++-- sources/scalac/symtab/classfile/PackageParser.java | 44 ++++++---------------- sources/scalac/transformer/UnCurry.java | 33 +++++++++++----- sources/scalac/typechecker/Analyzer.java | 9 +++-- sources/scalac/typechecker/DeSugarize.java | 2 +- sources/scalac/util/Debug.java | 2 +- 8 files changed, 95 insertions(+), 57 deletions(-) (limited to 'sources') diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java index 36729e3270..e3c2315005 100644 --- a/sources/scalac/ast/TreeGen.java +++ b/sources/scalac/ast/TreeGen.java @@ -659,6 +659,7 @@ public class TreeGen implements Kinds, Modifiers { return Block(new Tree[]{classDef, alloc}); } + public Tree mkPartialFunction(int pos, Tree applyVisitor, Tree isDefinedAtVisitor, Type pattype, Type restype, Symbol owner) { Type pft = definitions.partialFunctionType(pattype, restype); @@ -688,8 +689,12 @@ public class TreeGen implements Kinds, Modifiers { meth.setInfo(Type.MethodType(new Symbol[]{param}, restype)); clazz.info().members().enter(meth); changeOwner(visitor, prevOwner, meth); - Tree body = Apply( - Select(Ident(param), definitions.MATCH), new Tree[]{visitor}) + Tree body = + Apply( + TypeApply( + Select(Ident(param), definitions.MATCH), + new Tree[]{mkType(pos, pattype), mkType(pos, restype)}), + new Tree[]{visitor}) .setType(restype); return DefDef(meth, body); } @@ -710,4 +715,20 @@ public class TreeGen implements Kinds, Modifiers { }; lifter.traverse(tree); } + + /** Build a postfix function application + */ + public Tree postfixApply(Tree obj, Tree fn, Symbol owner) { + if (TreeInfo.isPureExpr(obj) || TreeInfo.isPureExpr(fn)) { + return Apply(Select(fn, Names.apply), new Tree[]{obj}); + } else { + Name tmpname = global.freshNameCreator.newName("tmp", '$'); + Symbol tmp = new TermSymbol( + obj.pos, tmpname, owner, SYNTHETIC | FINAL) + .setInfo(obj.type); + Tree tmpdef = ValDef(tmp, obj); + Tree expr = postfixApply(Ident(tmp), fn, owner); + return Block(new Tree[]{tmpdef, expr}); + } + } } diff --git a/sources/scalac/ast/TreeInfo.java b/sources/scalac/ast/TreeInfo.java index 19b2341f44..d0a8b41311 100644 --- a/sources/scalac/ast/TreeInfo.java +++ b/sources/scalac/ast/TreeInfo.java @@ -102,6 +102,10 @@ public class TreeInfo { return tree.symbol().isStable(); case Select(Tree qual, _): return tree.symbol().isStable() && isPureExpr(qual); + case Apply(Tree fn, Tree[] args): + return isPureExpr(fn) && args.length == 0; + case TypeApply(Tree fn, Tree[] targs): + return isPureExpr(fn); case Typed(Tree expr, _): return isPureExpr(expr); case Literal(_): @@ -167,19 +171,27 @@ public class TreeInfo { /** The method symbol of an application node, or Symbol.NONE, if none exists. */ public static Symbol methSymbol(Tree tree) { + Tree meth = methPart(tree); + if (meth.hasSymbol()) return meth.symbol(); + else return Symbol.NONE; + } + + /** The method part of an application node + */ + public static Tree methPart(Tree tree) { switch (tree) { case Apply(Tree fn, _): - return methSymbol(fn); + return methPart(fn); case TypeApply(Tree fn, _): - return methSymbol(fn); + return methPart(fn); case AppliedType(Tree fn, _): - return methSymbol(fn); + return methPart(fn); default: - if (tree.hasSymbol()) return tree.symbol(); - else return Symbol.NONE; + return tree; } } + /** returns true if the tree is a sequence-valued pattern. * precondition: tree is a pattern. * calls isSequenceValued( Tree, List ) because needs to remember bound diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index fcafabc1aa..1cf278c6c0 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -315,10 +315,19 @@ public class Definitions { // add members to class scala.Any MATCH = new TermSymbol( Position.NOPOS, Names.match, ANY_CLASS, Modifiers.FINAL); + Symbol matchTyParam1 = newTypeParameter(MATCH, ANY_TYPE); + Symbol matchTyParam2 = newTypeParameter(MATCH, ANY_TYPE); MATCH.setInfo( - Type.MethodType( - new Symbol[]{newParameter(MATCH, OBJECT_TYPE)}, - OBJECT_TYPE)); + Type.PolyType( + new Symbol[]{matchTyParam1, matchTyParam2}, + Type.MethodType( + new Symbol[]{ + newParameter( + MATCH, + functionType( + new Type[]{matchTyParam1.typeConstructor()}, + matchTyParam2.typeConstructor()))}, + matchTyParam2.typeConstructor()))); ANY_CLASS.members().enter(MATCH); AS = new TermSymbol( diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java index 9d62fb1009..842cbd3870 100644 --- a/sources/scalac/symtab/classfile/PackageParser.java +++ b/sources/scalac/symtab/classfile/PackageParser.java @@ -42,9 +42,7 @@ public class PackageParser extends Type.LazyType { String dirname = null; Name name = p.fullName(); HashMap/**/ symFile = new HashMap(); - if (name.length() == 0) { - // includeMembers(AbstractFile.open(null, "."), p, members, false); - } else { + if (name.length() != 0) { dirname = SourceRepresentation.externalizeFileName(name); if (!dirname.endsWith("/")) dirname += "/"; @@ -53,7 +51,7 @@ public class PackageParser extends Type.LazyType { for (int i = 0; i < base.length; i++) { includeMembers( AbstractFile.open(base[i], dirname), - p, members, dirname != null, symFile); + p, members, symFile); } p.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, p)); if (dirname == null) @@ -81,9 +79,10 @@ public class PackageParser extends Type.LazyType { * in package/module scope */ protected void includeMembers(AbstractFile dir, Symbol p, Scope locals, - boolean inclClasses, HashMap symFile) { + HashMap symFile) { if (dir == null) return; + boolean inclClasses = p != global.definitions.ROOT_CLASS; String[] filenames = null; try { if ((filenames = dir.list()) == null) @@ -116,33 +115,6 @@ public class PackageParser extends Type.LazyType { } symFile.put(clazz, f); } - } else if (fname.endsWith("/") && !fname.equals("META-INF/")) { - Name n = Name.fromString(fname.substring(0, fname.length() - 1)); - if (locals.lookup(n) == Symbol.NONE) { - TermSymbol module = TermSymbol.newJavaPackageModule(n, p, this); - locals.enter(module); - //todo: moduleClass needs to be entered? - locals.enter(module.moduleClass()); - } - -/* - } else if (inclClasses && fname.endsWith(".symbl")) { - //todo: compare dates between symbl and scala. - Name n = Name.fromString(fname.substring(0, fname.length() - 6)) - .toTypeName(); - Symbol sym = locals.lookup(n); - if (sym == Symbol.NONE || - sym.isPackage() || - sym.rawInfoAt(Symbol.FIRST_ID) instanceof ClassParser && - !(sym.rawInfoAt(Symbol.FIRST_ID) instanceof SymblParser)) { - ClassSymbol clazz = new ClassSymbol(n, p, symblCompletion); - //todo: needed - clazz.allConstructors().setInfo(symblCompletion); - clazz.module().setInfo(symblCompletion); - locals.enter(clazz); - locals.enter(clazz.module()); - } -*/ } else if (inclClasses && fname.endsWith(".scala")) { Name n = Name.fromString(fname.substring(0, fname.length() - 6)) .toTypeName(); @@ -157,6 +129,14 @@ public class PackageParser extends Type.LazyType { locals.enter(clazz.module()); symFile.put(clazz, f); } + } else if (fname.endsWith("/") && !fname.equals("META-INF/")) { + Name n = Name.fromString(fname.substring(0, fname.length() - 1)); + if (locals.lookup(n) == Symbol.NONE) { + TermSymbol module = TermSymbol.newJavaPackageModule(n, p, this); + locals.enter(module); + //todo: moduleClass needs to be entered? + locals.enter(module.moduleClass()); + } } } } catch (IOException e) { diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java index 3d9d46c9cf..3cae85252a 100644 --- a/sources/scalac/transformer/UnCurry.java +++ b/sources/scalac/transformer/UnCurry.java @@ -16,7 +16,10 @@ import scalac.ast.*; import scalac.symtab.*; import Tree.*; import scalac.typechecker.DeSugarize ; -/** Make all functions into one-argument functions + +/** (1) Make all functions into one-argument functions + * (2) Convert `def' parameters to closures + * (3) Convert matches with non-visitor arguments to postfix applications */ public class UnCurry extends OwnerTransformer implements Modifiers { @@ -105,14 +108,26 @@ public class UnCurry extends OwnerTransformer Type ftype = fn.type; Tree fn1 = transform(fn); Tree[] args1 = transformArgs(tree.pos, args, ftype); - switch (fn1) { - case Apply(Tree fn2, Tree[] args2): - Tree[] newargs = new Tree[args1.length + args2.length]; - System.arraycopy(args2, 0, newargs, 0, args2.length); - System.arraycopy(args1, 0, newargs, args2.length, args1.length); - return copy.Apply(tree, fn2, newargs); - default: - return copy.Apply(tree, fn1, args1); + if (TreeInfo.methSymbol(fn1) == global.definitions.MATCH && + !(args1[0] instanceof Tree.Visitor)) { + switch (TreeInfo.methPart(fn1)) { + case Select(Tree qual, Name name): + assert name == Names.match; + return gen.postfixApply(qual, args1[0], currentOwner); + default: + throw new ApplicationError("illegal prefix for match: " + tree); + } + + } else { + switch (fn1) { + case Apply(Tree fn2, Tree[] args2): + Tree[] newargs = new Tree[args1.length + args2.length]; + System.arraycopy(args2, 0, newargs, 0, args2.length); + System.arraycopy(args1, 0, newargs, args2.length, args1.length); + return copy.Apply(tree, fn2, newargs); + default: + return copy.Apply(tree, fn1, args1); + } } case Select(_, _): diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 3718e377bb..11b715fe56 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -552,13 +552,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { private Type matchQualType(Tree fn) { switch (fn) { case Select(Tree qual, _): - if (fn.symbol() == definitions.OBJECT_TYPE.lookup(Names.match)) + if (fn.symbol() == definitions.MATCH) return qual.type.widen(); break; case TypeApply(Tree fn1, _): return matchQualType(fn1); case Ident(_): - if (fn.symbol() == definitions.OBJECT_TYPE.lookup(Names.match)) + if (fn.symbol() == definitions.MATCH) return context.enclClass.owner.typeOfThis(); break; } @@ -642,10 +642,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { // Entering Symbols ---------------------------------------------------------- Tree transformPackageId(Tree tree) { + if (tree.type != null) return tree; switch (tree) { case Ident(Name name): return tree - .setSymbol(packageSymbol(tree.pos, definitions.ROOT, name)) + .setSymbol(packageSymbol(tree.pos, context.owner, name)) .setType(tree.symbol().type()); case Select(Tree qual, Name name): Tree qual1 = transformPackageId(qual); @@ -2225,7 +2226,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } } - // resolve overloading + // resolve overloading1g switch (fn1.type) { case OverloadedType(Symbol[] alts, Type[] alttypes): try { diff --git a/sources/scalac/typechecker/DeSugarize.java b/sources/scalac/typechecker/DeSugarize.java index 1de733b798..472b6f0a27 100644 --- a/sources/scalac/typechecker/DeSugarize.java +++ b/sources/scalac/typechecker/DeSugarize.java @@ -61,7 +61,7 @@ public class DeSugarize implements Kinds, Modifiers { // Auxiliary definitions and functions ------------------------------------------- - /** introduce fresh variable of the form "deS$56" + /** introduce fresh variable of the form "ds$56" */ Name getvar() { return freshNameCreator.newName("ds", '$'); diff --git a/sources/scalac/util/Debug.java b/sources/scalac/util/Debug.java index 0ae63c4006..c787c34ac8 100644 --- a/sources/scalac/util/Debug.java +++ b/sources/scalac/util/Debug.java @@ -506,7 +506,7 @@ public class DebugSymbol extends DebugAbstractHandler { public void append1(StringBuffer buffer, Symbol that) { if (that != Symbol.NONE && that != Symbol.ERROR) { - if (that.owner() != Global.instance.definitions.ROOT_CLASS) { + if (!that.owner().isRoot()) { Debug.append(buffer, that.owner()); buffer.append("."); } -- cgit v1.2.3