changeset 2948:2a0d51d22cec

Cleanup init and use of ModuleSymbol
author jjg
date Fri, 27 Mar 2015 14:01:18 -0700
parents 2e29011b30ee
children 11b710868183 bbfc8cd47a91
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java test/tools/javac/modules/ProvidesTest.java test/tools/javac/modules/UsesTest.java
diffstat 13 files changed, 256 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java	Thu Mar 26 15:47:59 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java	Fri Mar 27 14:01:18 2015 -0700
@@ -42,7 +42,6 @@
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.Completer;
 import com.sun.tools.javac.code.Symbol.CompletionFailure;
-import com.sun.tools.javac.code.Symbol.ModuleSymbol;
 import com.sun.tools.javac.code.Symbol.PackageSymbol;
 import com.sun.tools.javac.code.Symbol.TypeSymbol;
 import com.sun.tools.javac.comp.Annotate;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java	Thu Mar 26 15:47:59 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java	Fri Mar 27 14:01:18 2015 -0700
@@ -76,16 +76,6 @@
 
     abstract <R, P> R accept(Visitor<R, P> visitor, P data);
 
-    // TODO: should not be required
-    static <T extends Directive> List<T> filter(List<Directive> directives, Kind kind, Class<T> clazz) {
-        ListBuffer<T> list = new ListBuffer<>();
-        for (Directive d: directives) {
-            if (d.getKind() == kind)
-                list.add(clazz.cast(d));
-        }
-        return list.toList();
-    }
-
     /**
      * 'exports' Package ';'
      */
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java	Thu Mar 26 15:47:59 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java	Fri Mar 27 14:01:18 2015 -0700
@@ -201,24 +201,26 @@
                 msym = syms.unnamedModule;
             } else {
                 // Note: the following may trigger a re-entrant call to Modules.enter
-                msym = new ModuleSymbol();
-                ClassSymbol info = new ClassSymbol(Flags.MODULE, names.module_info, msym);
-                info.modle = msym;
-                info.classfile = fo;
-                info.members_field = WriteableScope.create(info);
-                msym.module_info = info;
+//                msym = new ModuleSymbol();
+//                ClassSymbol info = new ClassSymbol(Flags.MODULE, names.module_info, msym);
+//                info.modle = msym;
+//                info.classfile = fo;
+//                info.members_field = WriteableScope.create(info);
+//                msym.module_info = info;
+                msym = ModuleSymbol.create(null, names.module_info);
+                msym.module_info.classfile = fo;
                 // TODO: defer with completer?
-                classFinder.fillIn(info);
-                // TODO: should we do the following here, or as soon as we find the name in
-                // the source or class file?
-                // Consider the case when the class/source path module shadows one on the
-                // module source path
-                if (syms.modules.get(msym.name) != null) {
-                    // error: module already defined
-                    System.err.println("ERROR: module already defined: " + msym);
-                } else {
-                    syms.modules.put(msym.name, msym);
-                }
+                classFinder.fillIn(msym.module_info);
+//                // TODO: should we do the following here, or as soon as we find the name in
+//                // the source or class file?
+//                // Consider the case when the class/source path module shadows one on the
+//                // module source path
+//                if (syms.modules.get(msym.name) != null) {
+//                    // error: module already defined
+//                    System.err.println("ERROR: module already defined: " + msym);
+//                } else {
+//                    syms.modules.put(msym.name, msym);
+//                }
             }
 
             msym.sourceLocation = StandardLocation.SOURCE_PATH;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Mar 26 15:47:59 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Mar 27 14:01:18 2015 -0700
@@ -832,10 +832,9 @@
     }
     /** A class for module symbols.
      */
-    public static class ModuleSymbol extends TypeSymbol // JIGSAW need TypeSymbol?
+    public static class ModuleSymbol extends TypeSymbol
             /*implements ModuleElement*/ {
 
-        public Name fullname; // TODO: do we need this?
         public Name version;
         public JavaFileManager.Location sourceLocation;
         public JavaFileManager.Location classLocation;
@@ -851,6 +850,21 @@
 
         public Set<PackageSymbol> visiblePackages;
 
+        /**
+         * Create a ModuleSymbol with an associated module-info ClassSymbol.
+         * The name of the module may be null, if it is not known yet.
+         */
+        public static ModuleSymbol create(Name name, Name module_info) {
+            ModuleSymbol msym = new ModuleSymbol(name, null);
+            ClassSymbol info = new ClassSymbol(Flags.MODULE, module_info, msym);
+            info.modle = msym;
+            info.fullname = formFullName(module_info, msym);
+            info.flatname = info.fullname;
+            info.members_field = WriteableScope.create(info);
+            msym.module_info = info;
+            return msym;
+        }
+
         public ModuleSymbol() {
             super(MDL, 0, null, null, null);
             this.type = new ModuleType(this);
@@ -859,40 +873,15 @@
         public ModuleSymbol(Name name, Symbol owner) {
             super(MDL, 0, name, null, owner);
             this.type = new ModuleType(this);
-            this.fullname = formFullName(name, owner);
-        }
-
-        // TODO: use exports field
-        public List<ExportsDirective> getExports() {
-            return Directive.filter(directives, Directive.Kind.EXPORTS,
-                    ExportsDirective.class);
-        }
-
-        // TODO: use provides field
-        public List<ProvidesDirective> getProvides() {
-            return Directive.filter(directives, Directive.Kind.PROVIDES,
-                    ProvidesDirective.class);
-        }
-
-        // TODO: use requires field
-        public List<RequiresDirective> getRequires() {
-            return Directive.filter(directives, Directive.Kind.REQUIRES,
-                    RequiresDirective.class);
-        }
-
-        // TODO: use uses field
-        public List<UsesDirective> getUses() {
-            return Directive.filter(directives, Directive.Kind.USES,
-                    UsesDirective.class);
         }
 
         @Override
         public String toString() {
             // TODO: the following strings should be localized
             // Do this with custom anon subtypes in Symtab
-            String n = (fullname == null) ? "<unknown>"
-                    : (fullname.isEmpty()) ? "<unnamed>"
-                    : String.valueOf(fullname);
+            String n = (name == null) ? "<unknown>"
+                    : (name.isEmpty()) ? "<unnamed>"
+                    : String.valueOf(name);
             return n;
         }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Thu Mar 26 15:47:59 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Fri Mar 27 14:01:18 2015 -0700
@@ -30,7 +30,6 @@
 import java.util.Map;
 
 import javax.lang.model.element.ElementVisitor;
-import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.code.Scope.WriteableScope;
@@ -107,7 +106,7 @@
 
     /** A symbol for the root module.
      */
-    public final ModuleSymbol rootModule;
+//    public final ModuleSymbol rootModule;
 
     /** A symbol for the unnamed module.
      */
@@ -353,15 +352,15 @@
         final JavacMessages messages = JavacMessages.instance(context);
 
         // create the basic builtin symbols
-        rootModule = new ModuleSymbol(names.empty, null);
-        unnamedModule = new ModuleSymbol(names.empty, rootModule) {
+//        rootModule = new ModuleSymbol(names.empty, null);
+        unnamedModule = new ModuleSymbol(names.empty, null) {
                 @Override
                 public String toString() {
                     return messages.getLocalizedString("compiler.misc.unnamed.module");
                 }
             };
-        errModule = new ModuleSymbol(names.empty, rootModule) { };
-        noModule = new ModuleSymbol(names.empty, rootModule) { };
+        errModule = new ModuleSymbol(names.empty, null) { };
+        noModule = new ModuleSymbol(names.empty, null) { };
         rootPackage = new PackageSymbol(names.empty, null);
         packages.put(names.empty, rootPackage);
         unnamedPackage = new PackageSymbol(names.empty, rootPackage) {
@@ -644,16 +643,21 @@
     public ModuleSymbol enterModule(Name name) {
         ModuleSymbol msym = modules.get(name);
         if (msym == null) {
-            msym = new ModuleSymbol(name, rootModule);
-            ClassSymbol info = new ClassSymbol(Flags.MODULE, names.module_info, msym);
-            info.modle = msym;
-            info.fullname = ClassSymbol.formFullName(info.name, msym);
-            info.flatname = ClassSymbol.formFlatName(info.name, msym);
-            info.members_field = WriteableScope.create(info);
-            msym.module_info = info;
+            msym = ModuleSymbol.create(name, names.module_info);
             msym.completer = moduleCompleter;
             modules.put(name, msym);
         }
         return msym;
     }
+
+    public void enterModule(ModuleSymbol msym, Name name) {
+        Assert.checkNull(modules.get(name));
+        Assert.checkNull(msym.name);
+        msym.name = name;
+        ClassSymbol info = msym.module_info;
+        info.fullname = msym.name.append('.', names.module_info);
+        info.flatname = info.fullname;
+        modules.put(name, msym);
+    }
+
 }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java	Thu Mar 26 15:47:59 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java	Fri Mar 27 14:01:18 2015 -0700
@@ -1406,7 +1406,7 @@
 
     public static class PackageType extends Type implements NoType {
 
-        PackageType(TypeSymbol tsym) {
+        PackageType(PackageSymbol tsym) {
             // Package types cannot be annotated
             super(tsym, TypeMetadata.empty);
         }
@@ -1444,7 +1444,7 @@
 
     public static class ModuleType extends Type implements NoType {
 
-        ModuleType(TypeSymbol tsym) {
+        ModuleType(ModuleSymbol tsym) {
             // Module types cannot be annotated
             super(tsym, TypeMetadata.empty);
         }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Mar 26 15:47:59 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Mar 27 14:01:18 2015 -0700
@@ -4200,8 +4200,12 @@
     public void visitModuleDef(JCModuleDecl tree) {
         ModuleSymbol msym = env.toplevel.modle;
         msym.directives = List.nil();
+        msym.provides = List.nil();
+        msym.uses = List.nil();
         attribStats(tree.directives, env);
         msym.directives = msym.directives.reverse();
+        msym.provides = msym.provides.reverse();
+        msym.uses = msym.uses.reverse();
 
         if (msym.requires.nonEmpty() && msym.requires.head.flags.contains(RequiresFlag.MANDATED))
             msym.directives = msym.directives.prepend(msym.requires.head);
@@ -4220,6 +4224,7 @@
             ClassSymbol service = (ClassSymbol) st.tsym;
             ClassSymbol impl = (ClassSymbol) it.tsym;
             Directive.ProvidesDirective d = new Directive.ProvidesDirective(service, impl);
+            msym.provides = msym.provides.prepend(d);
             msym.directives = msym.directives.prepend(d);
         }
     }
@@ -4235,6 +4240,7 @@
         if (st.hasTag(CLASS)) {
             ClassSymbol service = (ClassSymbol) st.tsym;
             Directive.UsesDirective d = new Directive.UsesDirective(service);
+            msym.uses = msym.uses.prepend(d);
             msym.directives = msym.directives.prepend(d);
         }
     }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Thu Mar 26 15:47:59 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Fri Mar 27 14:01:18 2015 -0700
@@ -197,8 +197,7 @@
             if (c != null) {
                sym = (ModuleSymbol) c.owner;
                if (sym.name == null) {
-                   sym.fullname = sym.name = name;
-                   c.fullname = c.flatname = name.append('.', names.module_info);
+                   syms.enterModule(sym, name);
                } else {
                    // TODO: validate name
                }
@@ -451,7 +450,7 @@
         public void visitUses(JCUses tree) { }
 
         private void ensureJavaBase() {
-            if (sym.fullname == names.java_base)
+            if (sym.name == names.java_base)
                 return;
 
             for (RequiresDirective d: sym.requires) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Mar 26 15:47:59 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Mar 27 14:01:18 2015 -0700
@@ -2291,9 +2291,12 @@
                     int start = utf8Index + 3;
                     Name modInfoName = names.fromUtf(internalize(buf, start, len));
                     if (c.owner.name == null) {
-                        Name moduleName = Convert.packagePart(modInfoName);
-                        ((ModuleSymbol) c.owner).fullname = c.owner.name = moduleName;
-                        c.fullname = c.flatname = modInfoName;
+//                        Name moduleName = Convert.packagePart(modInfoName);
+//                        c.owner.name = moduleName;
+//                        c.fullname = c.flatname = modInfoName;
+                        syms.enterModule((ModuleSymbol) c.owner, Convert.packagePart(modInfoName));
+                    } else {
+                        // TODO: validate name
                     }
                 }
             }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Mar 26 15:47:59 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Mar 27 14:01:18 2015 -0700
@@ -975,14 +975,14 @@
         ModuleSymbol m = c.modle;
 
         int alenIdx = writeAttr(names.Module);
-        List<RequiresDirective> requires = m.getRequires();
+        List<RequiresDirective> requires = m.requires;
         databuf.appendChar(requires.size());
         for (RequiresDirective r: requires) {
             databuf.appendChar(pool.put(r.module.name));
             databuf.appendChar(RequiresFlag.value(r.flags));
         }
 
-        List<ExportsDirective> exports = m.getExports();
+        List<ExportsDirective> exports = m.exports;
         databuf.appendChar(exports.size());
         for (ExportsDirective e: exports) {
             databuf.appendChar(pool.put(names.fromUtf(externalize(e.packge.flatName()))));
@@ -995,13 +995,13 @@
             }
         }
 
-        List<UsesDirective> uses = m.getUses();
+        List<UsesDirective> uses = m.uses;
         databuf.appendChar(uses.size());
         for (UsesDirective s: uses) {
             databuf.appendChar(pool.put(s.service));
         }
 
-        List<ProvidesDirective> services = m.getProvides();
+        List<ProvidesDirective> services = m.provides;
         databuf.appendChar(services.size());
         for (ProvidesDirective s: services) {
             databuf.appendChar(pool.put(s.service));
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Mar 26 15:47:59 2015 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Mar 27 14:01:18 2015 -0700
@@ -3184,7 +3184,7 @@
                     accept(SEMI);
                     defs.append(toP(F.at(pos).Provides(serviceName, implName)));
                 } else {
-                    log.error("with.expected");
+                    error(token.pos, "expected", "'" + names.with + "'");
                     skip(false, false, false, false);
                 }
             } else if (token.name() == names.uses) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/ProvidesTest.java	Fri Mar 27 14:01:18 2015 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary simple tests of module provides
+ * @library /tools/lib
+ * @modules
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @build ToolBox ModuleTestBase
+ * @run main ProvidesTest
+ */
+
+import java.nio.file.*;
+
+public class ProvidesTest extends ModuleTestBase {
+    public static void main(String... args) throws Exception {
+        ProvidesTest t = new ProvidesTest();
+        t.runTests();
+    }
+
+    @Test
+    void testSimple(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "module m { provides p1.C1 with p2.C2; }",
+                "package p1; public class C1 { }",
+                "package p2; public class C2 extends p1.C1 { }");
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        tb.new JavacTask()
+                .outdir(classes.toString())
+                .files(findJavaFiles(src))
+                .run(ToolBox.Expect.SUCCESS)
+                .writeAll();
+    }
+
+    @Test
+    void testMulti(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src.resolve("m1"),
+                "module m1 { exports p1; }",
+                "package p1; public class C1 { }");
+        tb.writeJavaFiles(src.resolve("m2"),
+                "module m2 { requires m1; provides p1.C1 with p2.C2; }",
+                "package p2; public class C2 extends p1.C1 { }");
+        Path modules = base.resolve("modules");
+        Files.createDirectories(modules);
+
+        tb.new JavacTask()
+                .options("-modulesourcepath", src.toString())
+                .outdir(modules.toString())
+                .files(findJavaFiles(src))
+                .run(ToolBox.Expect.SUCCESS)
+                .writeAll();
+
+    }
+
+    @Test
+    void testMissingWith(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "module m { provides p.C; }",
+                "package p; public class C { }");
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        String log = tb.new JavacTask()
+                .options("-XDrawDiagnostics")
+                .outdir(classes.toString())
+                .files(findJavaFiles(src))
+                .run(ToolBox.Expect.FAIL)
+                .writeAll()
+                .getOutput(ToolBox.OutputKind.DIRECT);
+
+        if (!log.contains("module-info.java:1:24: compiler.err.expected: 'with'"))
+            throw new Exception("expected output not found");
+
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/modules/UsesTest.java	Fri Mar 27 14:01:18 2015 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary simple tests of module uses
+ * @library /tools/lib
+ * @modules
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @build ToolBox ModuleTestBase
+ * @run main UsesTest
+ */
+
+import java.nio.file.*;
+
+public class UsesTest extends ModuleTestBase {
+    public static void main(String... args) throws Exception {
+        UsesTest t = new UsesTest();
+        t.runTests();
+    }
+
+    @Test
+    void testSimple(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "module m { uses p.C; }",
+                "package p; public class C { }");
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        tb.new JavacTask()
+                .outdir(classes.toString())
+                .files(findJavaFiles(src))
+                .run(ToolBox.Expect.SUCCESS)
+                .writeAll();
+    }
+
+    @Test
+    void testMulti(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src.resolve("m1"),
+                "module m1 { exports p; }",
+                "package p; public class C { }");
+        tb.writeJavaFiles(src.resolve("m2"),
+                "module m2 { requires m1; uses p.C; }");
+        Path modules = base.resolve("modules");
+        Files.createDirectories(modules);
+
+        tb.new JavacTask()
+                .options("-modulesourcepath", src.toString())
+                .outdir(modules.toString())
+                .files(findJavaFiles(src))
+                .run(ToolBox.Expect.SUCCESS)
+                .writeAll();
+
+    }
+}
\ No newline at end of file