Namespace.java revision 1095:8fac78c86e3e
1/*
2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.nashorn.internal.codegen;
27
28import static jdk.nashorn.internal.codegen.MethodEmitter.LARGE_STRING_THRESHOLD;
29
30import java.util.HashMap;
31
32/**
33 * A name space hierarchy, where each level holds a name directory with
34 * names that may be unique for each level.
35 */
36
37public class Namespace {
38    /** Parent namespace. */
39    private final Namespace parent;
40
41    /** Name directory - version count for each name */
42    private final HashMap<String, Integer> directory;
43
44    /**
45     * Constructor
46     */
47    public Namespace() {
48        this(null);
49    }
50
51    /**
52     * Constructor
53     *
54     * @param parent parent name space
55     */
56    public Namespace(final Namespace parent) {
57        this.parent    = parent;
58        this.directory = new HashMap<>();
59    }
60
61    /**
62     * Return the parent Namespace of this space.
63     *
64     * @return parent name space
65     */
66    public Namespace getParent() {
67        return parent;
68    }
69
70    /**
71     * Create a uniqueName name in the namespace in the form base$n where n varies.
72     * Also truncates very long names that would otherwise break ASM.
73     *
74     * @param base Base of name.  Base will be returned if uniqueName.
75     * @return Generated uniqueName name.
76     */
77    public String uniqueName(final String base) {
78        final String truncatedBase = base.length() > LARGE_STRING_THRESHOLD ? base.substring(0, LARGE_STRING_THRESHOLD) : base;
79        for (Namespace namespace = this; namespace != null; namespace = namespace.getParent()) {
80            final HashMap<String, Integer> namespaceDirectory = namespace.directory;
81            final Integer                  counter            = namespaceDirectory.get(truncatedBase);
82
83            if (counter != null) {
84                final int count = counter + 1;
85                namespaceDirectory.put(truncatedBase, count);
86                return truncatedBase + '-' + count;
87            }
88        }
89
90        directory.put(truncatedBase, 0);
91
92        return truncatedBase;
93    }
94
95    @Override
96    public String toString() {
97        return directory.toString();
98    }
99}
100