--- old/make/tools/classanalyzer/src/com/sun/classanalyzer/Module.java Wed Oct 20 09:30:57 2010 +++ new/make/tools/classanalyzer/src/com/sun/classanalyzer/Module.java Wed Oct 20 09:30:57 2010 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2010 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 @@ -23,12 +23,11 @@ */ package com.sun.classanalyzer; -import com.sun.classanalyzer.AnnotatedDependency.OptionalDependency; +import com.sun.classanalyzer.ModuleInfo.Dependence; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; -import java.io.PrintWriter; import java.util.ArrayDeque; import java.util.Collection; import java.util.Collections; @@ -35,45 +34,32 @@ import java.util.Deque; import java.util.HashSet; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; -import java.util.TreeMap; import java.util.TreeSet; -import static com.sun.classanalyzer.Platform.*; -import static com.sun.classanalyzer.Trace.*; /** + * Module contains a list of classes and resources. * * @author Mandy Chung */ public class Module implements Comparable { - private static final Map modules = new LinkedHashMap(); + private static final Map modules = + new LinkedHashMap(); - /** - * Returns the top-level modules that are defined in - * the input module config files. - * - */ - static Collection getTopLevelModules() { - Set result = new LinkedHashSet(); - // always put the boot module first and then the base - if (Platform.bootModule() != null) { - result.add(Platform.bootModule()); - } - result.add(findModule(baseModuleName)); + public static Collection getAllModules() { + return Collections.unmodifiableCollection(modules.values()); + } - for (Module m : modules.values()) { - if (m.isTopLevel()) { - result.add(m); - } + public static void addModule(Module m) { + String name = m.name(); + if (modules.containsKey(name)) { + throw new RuntimeException("module \"" + name + "\" already exists"); } - return Collections.unmodifiableCollection(result); + modules.put(name, m); } public static Module addModule(ModuleConfig config) { @@ -81,13 +67,8 @@ if (modules.containsKey(name)) { throw new RuntimeException("module \"" + name + "\" already exists"); } - Module m; - if (Platform.isBootModule(config.module)) { - m = Platform.createBootModule(config); - } else { - m = new Module(config); - } - modules.put(name, m); + Module m = new Module(config); + addModule(m); return m; } @@ -94,17 +75,19 @@ public static Module findModule(String name) { return modules.get(name); } - private static String baseModuleName = "base"; - private static String version = "7-ea"; + private static String baseModuleName = "base"; static void setBaseModule(String name) { + if (name == null || name.isEmpty()) { + throw new RuntimeException("Null or empty base module"); + } baseModuleName = name; } - static void setVersion(String ver) { - version = ver; - } private static Properties moduleProps = new Properties(); + static String getModuleProperty(String key) { + return moduleProps.getProperty(key); + } static void setModuleProperties(String file) throws IOException { File f = new File(file); @@ -123,15 +106,11 @@ private final Set classes; private final Set resources; private final Set unresolved; - private final Map packages; - private final Set dependents; private final Set members; - private final Set requires; // update during the analysis - private Set permits; private Module group; + private ModuleInfo minfo; private boolean isBaseModule; - private int platformApiCount; protected Module(ModuleConfig config) { this.name = config.module; @@ -140,12 +119,8 @@ this.resources = new TreeSet(); this.config = config; this.unresolved = new HashSet(); - this.dependents = new TreeSet(); - this.packages = new TreeMap(); this.members = new TreeSet(); - this.requires = new TreeSet(config.requires()); this.group = this; // initialize to itself - this.platformApiCount = 0; } String name() { @@ -152,6 +127,10 @@ return name; } + ModuleConfig config() { + return config; + } + Module group() { return group; } @@ -160,42 +139,26 @@ return isBaseModule; } - // requires local for JRE modules that are strongly - // connected with the boot module - boolean isBootConnected() { - for (RequiresModule rm : requires) { - if (Platform.isBootModule(rm.modulename)) { - return true; - } - } - return false; + Set classes() { + return Collections.unmodifiableSet(classes); } - private Module moduleForRequires; - synchronized Module toRequiredModule() { - if (moduleForRequires == null) { - // create a module for external requires if needed - moduleForRequires = Platform.toRequiresModule(this); - } - return moduleForRequires; + Set resources() { + return Collections.unmodifiableSet(resources); } Set members() { - return members; + return Collections.unmodifiableSet(members); } - boolean hasPlatformAPIs() { - return platformApiCount > 0; - } - boolean contains(Klass k) { return k != null && classes.contains(k); } boolean isEmpty() { - return classes.isEmpty() && - resources.isEmpty() && - mainClass() == null; + return classes.isEmpty() + && resources.isEmpty() + && mainClass() == null; } boolean allowEmpty() { @@ -202,84 +165,17 @@ return moduleProps.getProperty(name + ".allow.empty") != null; } - Module alias() { - String mn = moduleProps.getProperty(name + ".alias"); - Module m = this; - if (mn != null) { - m = findModule(mn); - if (m == null) { - throw new RuntimeException(name + ".alias = " + mn + " not found"); - } - } - return m; + // returns itself. + public Module exporter(Module from) { + return this; } protected boolean isTopLevel() { // module with no class is not included except the base module - return this.group == this && - (isBase() || !isEmpty() || isAggregator() || allowEmpty()); + return this.group == this + && (isBase() || !isEmpty() || !config.requires().isEmpty() || allowEmpty()); } - boolean isAggregator() { - // a module is an aggregator if it has no class and resource and no main class - // but has a list of requires. - if (isEmpty() && requires.size() > 0) { - // return false if it requires only jdk.boot - if (requires.size() == 1) { - for (RequiresModule rm : requires) { - if (Platform.isBootModule(rm.modulename)) { - return false; - } - } - } - return true; - } - - return false; - } - - // fixup permits and requires set after modules are merged - void fixupModuleInfo() { - Set newPermits = new TreeSet(); - for (Module m : permits()) { - // in case multiple permits from the same group - newPermits.add(m.group()); - } - permits.clear(); - permits.addAll(newPermits); - - // fixup requires set - Set newRequires = new TreeSet(); - for (RequiresModule rm : requires) { - Module req = rm.module(); - if (req.isEmpty() && !req.isAggregator()) { - // remove from requires set if empty and not a module aggregator - continue; - } - - newRequires.add(rm); - if (req.requirePermits()) { - req.permits().add(this.group()); - } - } - requires.clear(); - requires.addAll(newRequires); - - // add this to the permits set of its dependences if needed - for (Dependency d : dependences()) { - if (d.dynamic && !d.optional) { - // ignore dynamic dependencies for now - continue; - } - - // add permits for all local dependencies - Module dm = d.module(); - if (dm.requirePermits()) { - dm.permits().add(this.group()); - } - } - } - Klass mainClass() { String cls = config.mainClass(); if (cls == null) { @@ -290,73 +186,6 @@ return k; } - synchronized Set permits() { - if (permits == null) { - this.permits = new TreeSet(); - // initialize the permits set - for (String s : config.permits()) { - Module m = findModule(s); - if (m != null) { - permits.add(m.group()); - } else { - throw new RuntimeException("module " + s + - " specified in the permits rule for " + name + " doesn't exist"); - } - } - } - return permits; - } - - Set requires() { - return requires; - } - - Collection dependents() { - Map deps = new LinkedHashMap(); - for (Dependency dep : dependents) { - Dependency d = deps.get(dep.module()); - if (d == null || dep.compareTo(d) > 0) { - deps.put(dep.module(), dep); - } - } - return deps.values(); - } - - boolean requires(Module m) { - for (RequiresModule rm : requires()) { - if (rm.module() == m) - return true; - } - return false; - } - /** - * Returns a Collection of Dependency, only one for each dependent - * module of the strongest dependency (i.e. - * hard static > hard dynamic > optional static > optional dynamic - */ - Collection dependences() { - Set result = new TreeSet(); - for (Dependency d : dependents()) { - Module dm = d.module(); - Module rm = dm; - if (!dm.alias().requires(this)) { - // use alias as the dependence except this module - // is required by the alias that will result in - // a recursive dependence. - rm = dm.alias(); - } - if (!isBootConnected()) { - // If it's a local module requiring jdk.boot, retain - // the original requires; otherwise, use its external - // module - rm = rm.toRequiredModule(); - } - - result.add(new Dependency(rm, d.optional, d.dynamic)); - } - return result; - } - @Override public int compareTo(Module o) { if (o == null) { @@ -373,22 +202,6 @@ void addKlass(Klass k) { classes.add(k); k.setModule(this); - if (k.isPlatformAPI()) { - platformApiCount++; - } - - // update package statistics - String pkg = k.getPackageName(); - PackageInfo pkginfo = packages.get(pkg); - if (pkginfo == null) { - pkginfo = new PackageInfo(pkg); - packages.put(pkg, pkginfo); - } - - if (k.exists()) { - // only count the class that is parsed - pkginfo.add(k.getFileSize()); - } } void addResource(ResourceFile res) { @@ -422,7 +235,6 @@ Module otherModule = other.getModule(); if (otherModule != null && otherModule != this) { // this module is dependent on otherModule - addDependency(k, other); continue; } @@ -448,11 +260,6 @@ Module otherModule = other.getModule(); if (otherModule == null) { unresolved.add(new Reference(c, other)); - } else { - if (otherModule != this) { - // this module is dependent on otherModule - addDependency(c, other); - } } } } @@ -470,50 +277,6 @@ } } - void addDependency(Klass from, Klass to) { - Dependency dep = new Dependency(from, to); - dependents.add(dep); - } - - void addRequiresModule(Module m) { - addRequiresModule(m, false); - } - - void addRequiresModule(Module m, boolean optional) { - requires.add(new RequiresModule(m, optional)); - if (m.requirePermits()) { - m.permits().add(this); - } - } - - boolean requirePermits() { - return (name().startsWith("sun.") || - permits().size() > 0); - } - - void fixupDependencies() { - // update dependencies for classes that were allocated to modules after - // this module was processed. - for (Reference ref : unresolved) { - Module m = ref.referree().getModule(); - if (m == null || m != this) { - addDependency(ref.referrer, ref.referree); - } - } - - // add dependency due to the main class - Klass k = mainClass(); - if (k != null) { - dependents.add(new Dependency(k.getModule(), false, false)); - } - fixupAnnotatedDependencies(); - } - - private void fixupAnnotatedDependencies() { - // add dependencies that this klass may depend on due to the AnnotatedDependency - dependents.addAll(AnnotatedDependency.getDependencies(this)); - } - boolean isModuleDependence(Klass k) { Module m = k.getModule(); return m == null || (!classes.contains(k) && !m.isBase()); @@ -533,12 +296,12 @@ return null; } -

void visitMember(Set visited, Visitor

visitor, P p) { +

void visitMembers(Set visited, ModuleVisitor

visitor, P p) { if (!visited.contains(this)) { visited.add(this); visitor.preVisit(this, p); for (Module m : members) { - m.visitMember(visited, visitor, p); + m.visitMembers(visited, visitor, p); visitor.visited(this, m, p); } visitor.postVisit(this, p); @@ -547,38 +310,6 @@ } } - private Set getDepModules() { - Set deps = new TreeSet(); - for (Dependency d : dependences()) { - if (d.dynamic || d.optional) { - // ignore dynamic or optional dependencies for now - continue; - } - deps.add(d.module()); - } - for (RequiresModule req : requires) { - if (req.optional) { - // ignore optional dependencies for now - continue; - } - deps.add(req.module()); - } - return deps; - } - -

void visitDependence(Set visited, Visitor

visitor, P p) { - if (!visited.contains(this)) { - visited.add(this); - - visitor.preVisit(this, p); - for (Module m : getDepModules()) { - m.visitDependence(visited, visitor, p); - visitor.visited(this, m, p); - } - visitor.postVisit(this, p); - } - } - void addMember(Module m) { // merge class list for (Klass k : m.classes) { @@ -589,24 +320,6 @@ for (ResourceFile res : m.resources) { resources.add(res); } - - platformApiCount += m.platformApiCount; - - // merge the package statistics - for (PackageInfo pinfo : m.getPackageInfos()) { - String packageName = pinfo.pkgName; - PackageInfo pkginfo = packages.get(packageName); - if (pkginfo == null) { - pkginfo = new PackageInfo(packageName); - packages.put(packageName, pkginfo); - } - - pkginfo.add(pinfo); - } - - // merge all permits and requires set - permits().addAll(m.permits()); - requires().addAll(m.requires()); } static void buildModuleMembers() { @@ -623,7 +336,7 @@ } // set up the top-level module - Visitor groupSetter = new Visitor() { + ModuleVisitor groupSetter = new ModuleVisitor() { public void preVisit(Module m, Module p) { m.group = p; @@ -646,12 +359,12 @@ for (Module p : modules.values()) { for (Module m : p.members) { if (m.group == m) { - m.visitMember(new TreeSet(), groupSetter, p); + m.visitMembers(new TreeSet(), groupSetter, p); } } } - Visitor mergeClassList = new Visitor() { + ModuleVisitor mergeClassList = new ModuleVisitor() { public void preVisit(Module m, Module p) { // nop - depth-first search @@ -672,518 +385,42 @@ groups.add(m); if (m.members().size() > 0) { // merge class list from all its members - m.visitMember(visited, mergeClassList, m); + m.visitMembers(visited, mergeClassList, m); } - - // clear the dependencies before fixup - m.dependents.clear(); - - // fixup dependencies - for (Klass k : m.classes) { - for (Klass other : k.getReferencedClasses()) { - if (m.isModuleDependence(other)) { - // this module is dependent on otherModule - m.addDependency(k, other); - } - } - } - - // add dependency due to the main class - Klass k = m.mainClass(); - if (k != null && m.isModuleDependence(k)) { - m.dependents.add(new Dependency(k.getModule().group(), false, false)); - } - - // add dependencies that this klass may depend on due to the AnnotatedDependency - m.fixupAnnotatedDependencies(); } } } - Set orderedDependencies() { - Visitor> walker = new Visitor>() { - public void preVisit(Module m, Set result) { - // nop - depth-first search - } - - public void visited(Module m, Module child, Set result) { - } - - public void postVisit(Module m, Set result) { - result.add(m); - } - }; - - Set visited = new TreeSet(); - Set result = new LinkedHashSet(); - - visitDependence(visited, walker, result); - return result; + ModuleInfo getModuleInfo() { + return minfo; } - class PackageInfo implements Comparable { - - final String pkgName; - int count; - long filesize; - - PackageInfo(String name) { - this.pkgName = name; - this.count = 0; - this.filesize = 0; - } - - void add(PackageInfo pkg) { - this.count += pkg.count; - this.filesize += pkg.filesize; - } - - void add(long size) { - count++; - filesize += size; - - } - - @Override - public int compareTo(Object o) { - return pkgName.compareTo(((PackageInfo) o).pkgName); - } + void setModuleInfo(ModuleInfo mi) { + if (minfo != null) + throw new AssertionError("ModuleInfo already created for " + name); + minfo = mi; } - Set getPackageInfos() { - return new TreeSet(packages.values()); - } + public interface Visitor { - void printSummaryTo(String output) throws IOException { - PrintWriter writer = new PrintWriter(output); - try { - long total = 0L; - int count = 0; - int nonCoreAPIs = 0; - writer.format("%10s\t%10s\t%s%n", "Bytes", "Classes", "Package name"); - for (String pkg : packages.keySet()) { - PackageInfo info = packages.get(pkg); - if (info.count > 0) { - if (Platform.isNonCoreAPI(pkg)) { - nonCoreAPIs += info.count; - writer.format("%10d\t%10d\t%s (*)%n", - info.filesize, info.count, pkg); - } else { - writer.format("%10d\t%10d\t%s%n", - info.filesize, info.count, pkg); - } - total += info.filesize; - count += info.count; - } - } + R visitClass(Klass k, P p); - - writer.format("%nTotal: %d bytes (uncompressed) %d classes%n", - total, count); - writer.format("APIs: %d core %d non-core (*)%n", - platformApiCount, nonCoreAPIs); - } finally { - writer.close(); - } - + R visitResource(ResourceFile r, P p); } - void printClassListTo(String output) throws IOException { - if (classes.isEmpty()) { - return; + public void visit(Visitor visitor, P p) { + for (Klass c : classes) { + visitor.visitClass(c, p); } - - PrintWriter writer = new PrintWriter(output); - try { - for (Klass c : classes) { - if (c.exists()) { - writer.format("%s\n", c.getClassFilePathname()); - } else { - trace("%s in module %s missing\n", c, this); - } - } - - } finally { - writer.close(); + for (ResourceFile res : resources) { + visitor.visitResource(res, p); } - } - void printResourceListTo(String output) throws IOException { - // no file created if the module doesn't have any resource file - if (resources.isEmpty()) { - return; - } - - PrintWriter writer = new PrintWriter(output); - try { - for (ResourceFile res : resources) { - writer.format("%s\n", res.getPathname()); - } - - } finally { - writer.close(); - } - - } - - void printDependenciesTo(String output, boolean showDynamic) throws IOException { - PrintWriter writer = new PrintWriter(output); - try { - // classes that this klass may depend on due to the AnnotatedDependency - Map> annotatedDeps = AnnotatedDependency.getReferences(this); - - for (Klass klass : classes) { - Set references = klass.getReferencedClasses(); - for (Klass other : references) { - String classname = klass.getClassName(); - boolean optional = OptionalDependency.isOptional(klass, other); - if (optional) { - classname = "[optional] " + classname; - } - - Module m = getModuleDependence(other); - if (m != null || other.getModule() == null) { - writer.format("%-40s -> %s (%s)", classname, other, m); - Reference ref = new Reference(klass, other); - if (annotatedDeps.containsKey(ref)) { - for (AnnotatedDependency ad : annotatedDeps.get(ref)) { - writer.format(" %s", ad.getTag()); - } - // printed; so remove the dependency from the annotated deps list - annotatedDeps.remove(ref); - } - writer.format("\n"); - } - } - } - - // print remaining dependencies specified in AnnotatedDependency list - if (annotatedDeps.size() > 0) { - for (Map.Entry> entry : annotatedDeps.entrySet()) { - Reference ref = entry.getKey(); - Module m = getModuleDependence(ref.referree); - if (m != null || ref.referree.getModule() == null) { - String classname = ref.referrer.getClassName(); - boolean optional = true; - boolean dynamic = true; - String tag = ""; - for (AnnotatedDependency ad : entry.getValue()) { - if (optional && !ad.isOptional()) { - optional = false; - tag = ad.getTag(); - } - - if (!ad.isDynamic()) { - dynamic = false; - } - } - if (!showDynamic && optional && dynamic) { - continue; - } - - if (optional) { - classname = "[optional] " + classname; - } else if (dynamic) { - classname = "[dynamic] " + classname; - } - writer.format("%-40s -> %s (%s) %s%n", classname, ref.referree, m, tag); - } - } - } - } finally { - writer.close(); - } - - } - - // print module dependency list - void printDepModuleListTo(String output) throws IOException { - PrintWriter writer = new PrintWriter(output); - try { - for (Module m : orderedDependencies()) { - writer.format("%s\n", m.name()); - } - if (Platform.legacyModule() != null && - (this == Platform.jdkBaseModule() || - this == Platform.jdkModule() || - this == Platform.jreModule())) { - // add legacy module in the modules.list - // so that it will install legacy module as well. - writer.format("%s\n", Platform.legacyModule()); - } - } finally { - writer.close(); - } - } - - void printModuleInfoTo(String output) throws IOException { - PrintWriter writer = new PrintWriter(output); - try { - writer.format("module %s @ %s {%n", name, version); - String formatSep = " requires"; - Map reqs = new TreeMap(); - for (RequiresModule rm : requires()) { - reqs.put(rm.module().name(), rm); - } - - for (Dependency dep : dependences()) { - Module dm = dep.module(); - if (!isBootConnected()) { - // If it's a local module requiring jdk.boot, retain - // the original requires - dm = dm.toRequiredModule(); - } - - if (dm == null) { - System.err.format("WARNING: module %s has a dependency on null module%n", name); - } - - StringBuilder attributes = new StringBuilder(); - RequiresModule rm = reqs.get(dm.name()); - - if (rm != null && rm.reexport) { - attributes.append(" public"); - } - - if (isBootConnected() || (rm != null && rm.local)) { - attributes.append(" local"); - } - - if (dep.optional || (rm != null && rm.optional)) { - attributes.append(" optional"); - } - - // FIXME: ignore dynamic dependencies - // Filter out optional dependencies for the boot module - // which are addded in the jdk.base module instead - if (!dep.dynamic || dep.optional) { - reqs.remove(dm.name()); - writer.format("%s%s %s @ %s;%n", - formatSep, - attributes.toString(), - dep != null ? dm : "null", version); - } - - } - // additional requires - if (reqs.size() > 0) { - for (RequiresModule rm : reqs.values()) { - StringBuilder attributes = new StringBuilder(); - if (rm.reexport) { - attributes.append(" public"); - } - if (rm.optional) { - attributes.append(" optional"); - } - if (isBootConnected() || rm.local) { - attributes.append(" local"); - } - - writer.format("%s%s %s @ %s;%n", formatSep, attributes.toString(), rm.module(), version); - } - } - - // permits - if (permits().size() > 0) { - formatSep = " permits"; - for (Module p : permits()) { - writer.format("%s %s", formatSep, p); - formatSep = ","; - } - writer.format(";%n"); - } - if (mainClass() != null) { - writer.format(" class %s;%n", mainClass().getClassName()); - } - writer.format("}%n"); - } finally { - writer.close(); - } - } - - static class Dependency implements Comparable { - - protected Module module; - final boolean optional; - final boolean dynamic; - - Dependency(Klass from, Klass to) { - // static dependency - this.module = to.getModule() != null ? to.getModule().group() : null; - this.optional = OptionalDependency.isOptional(from, to); - this.dynamic = false; - } - - Dependency(Module m, boolean optional, boolean dynamic) { - this.module = m != null ? m.group() : null; - this.optional = optional; - this.dynamic = dynamic; - } - - Module module() { - return module; - } - - public boolean isLocal(Module from) { - if (module().isBootConnected()) { - // local requires if the requesting module is the boot module - // or it's an aggregate platform module - return true; - } - - for (PackageInfo pkg : from.getPackageInfos()) { - // local dependence if any package this module owns is splitted - // across its dependence - for (PackageInfo p : module().getPackageInfos()) { - if (pkg.pkgName.equals(p.pkgName)) { - return true; - } - } - } - return false; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Dependency)) { - return false; - } - if (this == obj) { - return true; - } - - Dependency d = (Dependency) obj; - if (this.module() != d.module()) { - return false; - } else { - return this.optional == d.optional && this.dynamic == d.dynamic; - } - } - - @Override - public int hashCode() { - int hash = 3; - hash = 19 * hash + (this.module() != null ? this.module().hashCode() : 0); - hash = 19 * hash + (this.optional ? 1 : 0); - hash = 19 * hash + (this.dynamic ? 1 : 0); - return hash; - } - - @Override - public int compareTo(Dependency d) { - if (this.equals(d)) { - return 0; - } - - // Hard static > hard dynamic > optional static > optional dynamic - if (this.module() == d.module()) { - if (this.optional == d.optional) { - return this.dynamic ? -1 : 1; - } else { - return this.optional ? -1 : 1; - } - } else if (this.module() != null && d.module() != null) { - return (this.module().compareTo(d.module())); - } else { - return (this.module() == null) ? -1 : 1; - } - } - - @Override - public String toString() { - String s = module().name(); - if (optional) { - s += " (optional)"; - } else if (dynamic) { - s += " (dynamic)"; - } - return s; - } - } - - static class RequiresModule extends Dependency { - - final String modulename; - final boolean reexport; - final boolean local; - - public RequiresModule(String name, boolean optional, boolean reexport, boolean local) { - super(null, optional, false /* dynamic */); - this.modulename = name; - this.reexport = reexport; - this.local = local; - } - - public RequiresModule(Module m, boolean optional) { - super(m, optional, false); - this.modulename = m.name(); - this.reexport = true; - this.local = false; - } - - // deferred initialization until it's called. - // must call after all modules are merged. - synchronized Module fixupModule() { - if (module == null) { - Module m = findModule(modulename); - if (m == null) { - throw new RuntimeException("Required module \"" + modulename + "\" doesn't exist"); - } - module = m.group(); - } - return module; - } - - @Override - Module module() { - return fixupModule(); - } - - @Override - public int compareTo(Dependency d) { - RequiresModule rm = (RequiresModule) d; - if (this.equals(rm)) { - return 0; - } - return modulename.compareTo(rm.modulename); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof RequiresModule)) { - return false; - } - if (this == obj) { - return true; - } - - RequiresModule d = (RequiresModule) obj; - return this.modulename.equals(d.modulename); - } - - @Override - public int hashCode() { - int hash = 3; - hash = 19 * hash + this.modulename.hashCode(); - return hash; - } - - @Override - public String toString() { - String s = reexport ? "public " : ""; - if (optional) { - s += "optional "; - } - s += modulename; - return s; - } - } - static class Reference implements Comparable { - private final Klass referrer, referree; + final Klass referrer, referree; Reference(Klass referrer, Klass referree) { this.referrer = referrer; @@ -1226,7 +463,7 @@ } } - interface Visitor

{ + interface ModuleVisitor

{ public void preVisit(Module m, P param);