changeset 5702:6517d36e6905

Merge.
author Doug Simon <doug.simon@oracle.com>
date Wed, 27 Jun 2012 13:01:50 +0200
parents d0a6e25de770 (diff) 764db9ada24f (current diff)
children 0a249ed5566a
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LookupSwitchNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/TableSwitchNode.java
diffstat 3 files changed, 159 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/overview.html	Wed Jun 27 13:01:50 2012 +0200
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright (c) 2012, 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.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the LICENSE file that accompanied this code.
+
+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.
+-->
+
+</head>
+<body bgcolor="white">
+
+<body>
+
+<a href="modules.svg" title="Click to enlarge"><img src="modules.svg" width="400"/></a>
+<p>
+This document is the unified Javadoc for the Graal code base.
+The module dependency graph is shown above.
+Each node in the diagram is a link to the standalone Javadoc for the denoted module.
+
+</body>
+</html>
--- a/mx/commands.py	Wed Jun 27 11:51:18 2012 +0200
+++ b/mx/commands.py	Wed Jun 27 13:01:50 2012 +0200
@@ -1001,6 +1001,68 @@
         mx.abort('jacocoreport takes only one argument : an output directory')
     mx.run_java(['-jar', jacocoreport.get_path(True), '-in', 'jacoco.exec', '-g', join(_graal_home, 'graal'), out])
     
+def site(args):
+    """creates a website containing javadoc and the project dependency graph"""
+    
+    parser = ArgumentParser(prog='site')
+    parser.add_argument('-d', '--base', action='store', help='directory for generated site', required=True, metavar='<dir>')
+    parser.add_argument('-c', '--clean', action='store_true', help='remove existing site in <dir>')
+
+    args = parser.parse_args(args)
+    
+    args.base = os.path.abspath(args.base)
+    
+    if not exists(args.base):
+        os.mkdir(args.base)
+    elif args.clean:
+        shutil.rmtree(args.base)
+        os.mkdir(args.base)
+    
+    mx.javadoc(['--base', args.base])
+
+    unified = join(args.base, 'all')
+    if exists(unified):
+        shutil.rmtree(unified)
+    mx.javadoc(['--base', args.base, '--unified', '--arg', '@-overview', '--arg', '@' + join(_graal_home, 'graal', 'overview.html')])
+    os.rename(join(args.base, 'javadoc'), unified)
+        
+    _, tmp = tempfile.mkstemp()
+    try:
+        svg = join(args.base, 'all', 'modules.svg')
+        with open(tmp, 'w') as fp:
+            print >> fp, 'digraph projects {'
+            print >> fp, 'rankdir=BT;'
+            print >> fp, 'size = "13,13";'
+            print >> fp, 'node [shape=rect, fontcolor="blue"];'
+            print >> fp, 'edge [color="green"];'
+            for p in mx.projects():
+                print >> fp, '"' + p.name + '" [URL = "../' + p.name + '/javadoc/index.html", target = "_top"]'  
+                for dep in p.canonical_deps():
+                    if mx.project(dep, False):
+                        print >> fp, '"' + p.name + '" -> "' + dep + '"'
+            depths = dict()
+            for p in mx.projects():
+                d = p.max_depth()
+                depths.setdefault(d, list()).append(p.name)
+            for d, names in depths.iteritems():
+                print >> fp, '{ rank = same; "' + '"; "'.join(names) + '"; }' 
+            print >> fp, '}'
+
+        mx.run(['dot', '-Tsvg', '-o' + svg, tmp])
+        
+        # Post-process generated SVG to remove unified title elements which most browsers
+        # render as redundant (and annoying) tooltips.
+        with open(svg, 'r') as fp:
+            content = fp.read()
+        content = re.sub('<title>.*</title>', '', content)
+        content = re.sub('xlink:title="[^"]*"', '', content)
+        with open(svg, 'w') as fp:
+            fp.write(content)
+        
+        print 'Created website - root is ' + join(unified, 'index.html')
+    finally:
+        os.remove(tmp)
+    
 def mx_init():
     _vmbuild = 'product'
     commands = {
@@ -1022,6 +1084,7 @@
         'unittest' : [unittest, '[filters...]'],
         'jtt' : [jtt, '[filters...]'],
         'jacocoreport' : [jacocoreport, '[output directory]'],
+        'site' : [site, '[-options]'],
         'vm': [vm, '[-options] class [args...]'],
         'vmg': [vmg, '[-options] class [args...]'],
         'vmfg': [vmfg, '[-options] class [args...]']
--- a/mxtool/mx.py	Wed Jun 27 11:51:18 2012 +0200
+++ b/mxtool/mx.py	Wed Jun 27 13:01:50 2012 +0200
@@ -50,10 +50,10 @@
 
   commands.py
       Suite specific extensions to the commands available to mx.
-      This is only processed for the primary suite.
 
   includes
-      Other suites to be loaded. This is recursive.
+      Other suites to be loaded. This is recursive. Each
+      line in an includes file is a path to a suite directory.
 
   env
       A set of environment variable definitions. These override any
@@ -223,11 +223,17 @@
             if d == 1:
                 result.add(n)
 
-
         if len(result) == len(self.deps) and frozenset(self.deps) == result:
             return self.deps
         return result;
 
+    def max_depth(self):
+        """
+        Get the maximum canonical distance between this project and its most distant dependency.
+        """
+        distances = dict()
+        self._compute_max_dep_distances(self.name, distances, 0)
+        return max(distances.values())        
 
     def source_dirs(self):
         """
@@ -288,8 +294,8 @@
         self.primary = primary
         mxDir = join(dir, 'mx')
         self._load_env(mxDir)
-        if primary:
-            self._load_commands(mxDir)
+        self._load_commands(mxDir)
+        self._load_includes(mxDir)
 
     def _load_projects(self, mxDir):
         libsMap = dict()
@@ -360,8 +366,9 @@
         if exists(commands):
             # temporarily extend the Python path
             sys.path.insert(0, mxDir)
-
             mod = __import__('commands')
+            
+            sys.modules[join(mxDir, 'commands')] = sys.modules.pop('commands')
 
             # revert the Python path
             del sys.path[0]
@@ -379,7 +386,9 @@
         if exists(includes):
             with open(includes) as f:
                 for line in f:
-                    self.includes.append(expandvars_in_property(line.strip()))
+                    include = expandvars_in_property(line.strip())
+                    self.includes.append(include)
+                    _loadSuite(include, False)
 
     def _load_env(self, mxDir):
         e = join(mxDir, 'env')
@@ -393,9 +402,8 @@
 
     def _post_init(self, opts):
         mxDir = join(self.dir, 'mx')
-        self._load_includes(mxDir)
         self._load_projects(mxDir)
-        if self.mx_post_parse_cmd_line is not None:
+        if hasattr(self, 'mx_post_parse_cmd_line'):
             self.mx_post_parse_cmd_line(opts)
         for p in self.projects:
             existing = _projects.get(p.name)
@@ -1499,7 +1507,6 @@
             print '"' + p.name + '"->"' + dep + '"'
     print '}'
 
-
 def _source_locator_memento(deps):
     slm = XMLDoc()
     slm.open('sourceLookupDirector')
@@ -1950,16 +1957,17 @@
     eclipseinit(args, suite)
     netbeansinit(args, suite)
 
-def javadoc(args):
+def javadoc(args, parser=None, docDir='javadoc', includeDeps=True):
     """generate javadoc for some/all Java projects"""
 
-    parser = ArgumentParser(prog='mx javadoc')
+    parser = ArgumentParser(prog='mx javadoc') if parser is None else parser
+    parser.add_argument('-d', '--base', action='store', help='base directory for output')
     parser.add_argument('--unified', action='store_true', help='put javadoc in a single directory instead of one per project')
     parser.add_argument('--force', action='store_true', help='(re)generate javadoc even if package-list file exists')
     parser.add_argument('--projects', action='store', help='comma separated projects to process (omit to process all projects)')
     parser.add_argument('--argfile', action='store', help='name of file containing extra javadoc options')
+    parser.add_argument('--arg', action='append', dest='extra_args', help='extra Javadoc arguments (e.g. --arg @-use)', metavar='@<arg>', default=[])
     parser.add_argument('-m', '--memory', action='store', help='-Xmx value to pass to underlying JVM')
-    parser.add_argument('--wiki', action='store_true', help='generate Confluence Wiki format for package-info.java files')
     parser.add_argument('--packages', action='store', help='comma separated packages to process (omit to process all packages)')
 
     args = parser.parse_args(args)
@@ -1969,32 +1977,18 @@
     if args.projects is not None:
         candidates = [project(name) for name in args.projects.split(',')]
 
-    # optionally restrict packages within a project (most useful for wiki)
+    # optionally restrict packages within a project
     packages = []
     if args.packages is not None:
         packages = [name for name in args.packages.split(',')]
 
-    # the WikiDoclet cannot see the -classpath argument passed to javadoc so we pass the
-    # full list of projects as an explicit argument, thereby enabling it to map classes
-    # to projects, which is needed to generate Wiki links to the source code.
-    # There is no virtue in running the doclet on dependent projects as there are
-    # no generated links between Wiki pages
-    docletArgs = []
-    if args.wiki:
-        docDir = 'wikidoc'
-        toolsDir = project('com.oracle.max.tools').output_dir()
-        baseDir = project('com.oracle.max.base').output_dir()
-        dp = os.pathsep.join([toolsDir, baseDir])
-        project_list = ','.join(p.name for p in sorted_deps())
-        docletArgs = ['-docletpath', dp, '-doclet', 'com.oracle.max.tools.javadoc.wiki.WikiDoclet', '-projects', project_list]
-    else:
-        docDir = 'javadoc'
+    def outDir(p):
+        if args.base is None:
+            return join(p.dir, docDir)
+        return join(args.base, p.name, docDir)
 
     def check_package_list(p):
-        if args.wiki:
-            return True
-        else:
-            return not exists(join(p.dir, docDir, 'package-list'))
+        return not exists(join(outDir(p), 'package-list'))
 
     def assess_candidate(p, projects):
         if p in projects:
@@ -2007,7 +2001,7 @@
     projects = []
     for p in candidates:
         if not p.native:
-            if not args.wiki:
+            if includeDeps:
                 deps = p.all_deps([], includeLibs=False, includeSelf=False)
                 for d in deps:
                     assess_candidate(d, projects)
@@ -2024,7 +2018,7 @@
                         pkgs.add(pkg)
         return pkgs
 
-    extraArgs = []
+    extraArgs = [a.lstrip('@') for a in args.extra_args]
     if args.argfile is not None:
         extraArgs += ['@' + args.argfile]
     memory = '2g'
@@ -2037,15 +2031,15 @@
             pkgs = find_packages(p.source_dirs(), set())
             deps = p.all_deps([], includeLibs=False, includeSelf=False)
             links = ['-link', 'http://docs.oracle.com/javase/' + str(p.javaCompliance.value) + '/docs/api/']
-            out = join(p.dir, docDir)
+            out = outDir(p)
             for d in deps:
-                depOut = join(d.dir, docDir)
+                depOut = outDir(d)
                 links.append('-link')
                 links.append(os.path.relpath(depOut, out))
             cp = classpath(p.name, includeSelf=True)
             sp = os.pathsep.join(p.source_dirs())
             log('Generating {2} for {0} in {1}'.format(p.name, out, docDir))
-            run([java().javadoc, memory, '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + docletArgs + links + extraArgs + list(pkgs))
+            run([java().javadoc, memory, '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + links + extraArgs + list(pkgs))
             log('Generated {2} for {0} in {1}'.format(p.name, out, docDir))
     else:
         pkgs = set()
@@ -2058,10 +2052,12 @@
 
         links = ['-link', 'http://docs.oracle.com/javase/' + str(_java.javaCompliance.value) + '/docs/api/']
         out = join(_mainSuite.dir, docDir)
+        if args.base is not None:
+            out = join(args.base, docDir)
         cp = classpath()
         sp = os.pathsep.join(sp)
         log('Generating {2} for {0} in {1}'.format(', '.join(names), out, docDir))
-        run([java().javadoc, memory, '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + docletArgs + links + extraArgs + list(pkgs))
+        run([java().javadoc, memory, '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + links + extraArgs + list(pkgs))
         log('Generated {2} for {0} in {1}'.format(', '.join(names), out, docDir))
 
 def findclass(args):
@@ -2132,11 +2128,27 @@
 
 _argParser = ArgParser()
 
+def _findPrimarySuite():
+    # try current working directory first
+    mxDir = join(os.getcwd(), 'mx')
+    if exists(mxDir) and isdir(mxDir):
+        return dirname(mxDir)
+
+    # now search path of my executable
+    me = sys.argv[0]
+    parent = dirname(me)
+    while parent:
+        mxDir = join(parent, 'mx')
+        if exists(mxDir) and isdir(mxDir):
+            return parent
+        parent = dirname(parent)
+    return None
+
 def main():
-    cwdMxDir = join(os.getcwd(), 'mx')
-    if exists(cwdMxDir) and isdir(cwdMxDir):
+    primarySuiteDir = _findPrimarySuite()
+    if primarySuiteDir:
         global _mainSuite
-        _mainSuite = _loadSuite(os.getcwd(), True)
+        _mainSuite = _loadSuite(primarySuiteDir, True)
 
     opts, commandAndArgs = _argParser._parse_cmd_line()