source: branches/1.0.x/abcl/src/org/armedbear/lisp/Package.java

Last change on this file was 13723, checked in by Mark Evenson, 14 years ago

backport r13705: internal Java API for looking up internal vs. external symbols.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 29.8 KB
Line 
1/*
2 * Package.java
3 *
4 * Copyright (C) 2002-2007 Peter Graves <peter@armedbear.org>
5 * $Id: Package.java 13723 2012-01-06 14:34:39Z mevenson $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36import static org.armedbear.lisp.Lisp.*;
37
38import java.util.ArrayList;
39import java.util.Collection;
40import java.util.HashMap;
41import java.util.Iterator;
42import java.util.List;
43import java.util.concurrent.ConcurrentHashMap;
44
45public final class Package extends LispObject implements java.io.Serializable
46{
47    private String name;
48    private transient SimpleString lispName;
49
50    private transient LispObject propertyList;
51
52    /** Symbols internal to the package. */
53    private transient final ConcurrentHashMap<String, Symbol> internalSymbols
54            = new ConcurrentHashMap<String, Symbol>(16);
55    /** Symbols exported from the package.
56     *
57     * Those symbols in this collection are not contained in the internalSymbols
58     */
59    private transient final ConcurrentHashMap<String, Symbol> externalSymbols
60            = new ConcurrentHashMap<String, Symbol>(16);
61
62    private transient HashMap<String,Symbol> shadowingSymbols;
63    private transient ArrayList<String> nicknames;
64    private transient LispObject useList = null;
65    private transient ArrayList<Package> usedByList = null;
66
67    // Anonymous package.
68    public Package()
69    {
70    }
71
72    public Package(String name)
73    {
74        this.name = name;
75        lispName = new SimpleString(name);
76    }
77
78    public Package(String name, int size)
79    {
80        this.name = name;
81        lispName = new SimpleString(name);
82    }
83
84    @Override
85    public LispObject typeOf()
86    {
87        return Symbol.PACKAGE;
88    }
89
90    @Override
91    public LispObject classOf()
92    {
93        return BuiltInClass.PACKAGE;
94    }
95
96    @Override
97    public LispObject getDescription()
98    {
99        if (name != null) {
100            StringBuilder sb = new StringBuilder("The ");
101            sb.append(name);
102            sb.append(" package");
103            return new SimpleString(sb);
104        }
105        return new SimpleString("PACKAGE");
106    }
107
108    @Override
109    public LispObject typep(LispObject type)
110    {
111        if (type == Symbol.PACKAGE)
112            return T;
113        if (type == BuiltInClass.PACKAGE)
114            return T;
115        return super.typep(type);
116    }
117
118    public final String getName()
119    {
120        return name;
121    }
122
123    public final LispObject NAME()
124    {
125        return lispName != null ? lispName : NIL;
126    }
127
128    @Override
129    public final LispObject getPropertyList()
130    {
131        if (propertyList == null)
132            propertyList = NIL;
133        return propertyList;
134    }
135
136    @Override
137    public final void setPropertyList(LispObject obj)
138    {
139        if (obj == null)
140            throw new NullPointerException();
141        propertyList = obj;
142    }
143
144    public final List getNicknames()
145    {
146        return nicknames;
147    }
148
149    private void makeSymbolsUninterned(ConcurrentHashMap symbolMap) {
150        Symbol sym;
151        for (Iterator<Symbol> it = symbolMap.values().iterator();
152                it.hasNext();) {
153            sym = it.next();
154            if (sym.getPackage() == this) {
155                sym.setPackage(NIL);
156            }
157        }
158        symbolMap.clear();
159    }
160
161    public final synchronized boolean delete()
162    {
163        if (name != null) {
164            if(useList instanceof Cons) {
165                LispObject usedPackages = useList;
166                while (usedPackages != NIL) {
167                    Package pkg = (Package) usedPackages.car();
168                    unusePackage(pkg);
169                    usedPackages = usedPackages.cdr();
170                }
171            }
172
173            Packages.deletePackage(this);
174
175            makeSymbolsUninterned(internalSymbols);
176            makeSymbolsUninterned(externalSymbols); // also clears externalSymbols
177
178            name = null;
179            lispName = null;
180            nicknames = null;
181           
182            return true;
183        }
184        return false;
185    }
186
187    public final synchronized void rename(String newName, LispObject newNicks)
188
189    {
190        ArrayList<String> arrayList = null;
191        while (newNicks != NIL) {
192            if (arrayList == null)
193                arrayList = new ArrayList<String>();
194            arrayList.add(javaString(newNicks.car()));
195            newNicks = newNicks.cdr();
196        }
197        // Remove old name and nicknames from Packages map.
198        Packages.deletePackage(this);
199        // Now change the names...
200        name = newName;
201        lispName = new SimpleString(newName);
202        nicknames = arrayList;
203        // And add the package back.
204        Packages.addPackage(this);
205    }
206
207    public Symbol findInternalSymbol(SimpleString name)
208    {
209        return internalSymbols.get(name.toString());
210    }
211
212    public Symbol findInternalSymbol(String name)
213    {
214        return internalSymbols.get(name);
215    }
216
217    public Symbol findExternalSymbol(SimpleString name)
218    {
219        return externalSymbols.get(name.toString());
220    }
221
222    public Symbol findExternalSymbol(String name)
223    {
224        return externalSymbols.get(name);
225    }
226
227    public Symbol findExternalSymbol(SimpleString name, int hash)
228    {
229        return externalSymbols.get(name.toString());
230    }
231
232    // Returns null if symbol is not accessible in this package.
233    public Symbol findAccessibleSymbol(String name)
234
235    {
236        return findAccessibleSymbol(new SimpleString(name));
237    }
238
239    // Returns null if symbol is not accessible in this package.
240    public Symbol findAccessibleSymbol(SimpleString name)
241
242    {
243        // Look in external and internal symbols of this package.
244        Symbol symbol = externalSymbols.get(name.toString());
245        if (symbol != null)
246            return symbol;
247        symbol = internalSymbols.get(name.toString());
248        if (symbol != null)
249            return symbol;
250        // Look in external symbols of used packages.
251        if (useList instanceof Cons) {
252            LispObject usedPackages = useList;
253            while (usedPackages != NIL) {
254                Package pkg = (Package) usedPackages.car();
255                symbol = pkg.findExternalSymbol(name);
256                if (symbol != null)
257                    return symbol;
258                usedPackages = usedPackages.cdr();
259            }
260        }
261        // Not found.
262        return null;
263    }
264
265    public LispObject findSymbol(String name)
266
267    {
268        final SimpleString s = new SimpleString(name);
269        final LispThread thread = LispThread.currentThread();
270        // Look in external and internal symbols of this package.
271        Symbol symbol = externalSymbols.get(name);
272        if (symbol != null)
273            return thread.setValues(symbol, Keyword.EXTERNAL);
274        symbol = internalSymbols.get(name);
275        if (symbol != null)
276            return thread.setValues(symbol, Keyword.INTERNAL);
277        // Look in external symbols of used packages.
278        if (useList instanceof Cons) {
279            LispObject usedPackages = useList;
280            while (usedPackages != NIL) {
281                Package pkg = (Package) usedPackages.car();
282                symbol = pkg.findExternalSymbol(s);
283                if (symbol != null)
284                    return thread.setValues(symbol, Keyword.INHERITED);
285                usedPackages = usedPackages.cdr();
286            }
287        }
288        // Not found.
289        return thread.setValues(NIL, NIL);
290    }
291
292    // Helper function to add NIL to PACKAGE_CL.
293    public void addSymbol(Symbol symbol)
294    {
295        Debug.assertTrue(symbol.getPackage() == this);
296        Debug.assertTrue(symbol.getName().equals("NIL"));
297        externalSymbols.put(symbol.name.toString(), symbol);
298    }
299
300    private Symbol addSymbol(String name)
301    {
302        Symbol symbol = new Symbol(name, this);
303        if (this == PACKAGE_KEYWORD) {
304            symbol.initializeConstant(symbol);
305            externalSymbols.put(name.toString(), symbol);
306        } else
307            internalSymbols.put(name.toString(), symbol);
308       
309        return symbol;
310    }
311
312    private Symbol addSymbol(SimpleString name)
313    {
314        return addSymbol(name.toString());
315    }
316
317    public Symbol addInternalSymbol(String symbolName)
318    {
319        final Symbol symbol = new Symbol(symbolName, this);
320        internalSymbols.put(symbolName, symbol);
321        return symbol;
322    }
323
324    public Symbol addExternalSymbol(String symbolName)
325    {
326        final Symbol symbol = new Symbol(symbolName, this);
327        externalSymbols.put(symbolName, symbol);
328        return symbol;
329    }
330
331    public synchronized Symbol intern(SimpleString symbolName)
332    {
333        return intern(symbolName.toString());
334    }
335
336    public synchronized Symbol intern(String symbolName)
337    {
338        // Look in external and internal symbols of this package.
339        Symbol symbol = externalSymbols.get(symbolName);
340        if (symbol != null)
341            return symbol;
342        symbol = internalSymbols.get(symbolName);
343        if (symbol != null)
344            return symbol;
345        // Look in external symbols of used packages.
346        if (useList instanceof Cons) {
347            LispObject usedPackages = useList;
348            while (usedPackages != NIL) {
349                Package pkg = (Package) usedPackages.car();
350                symbol = pkg.externalSymbols.get(symbolName);
351                if (symbol != null)
352                    return symbol;
353                usedPackages = usedPackages.cdr();
354            }
355        }
356        // Not found.
357        return addSymbol(symbolName);
358    }
359
360    public synchronized Symbol intern(final SimpleString s,
361                                      final LispThread thread)
362    {
363        // Look in external and internal symbols of this package.
364        Symbol symbol = externalSymbols.get(s.toString());
365        if (symbol != null)
366            return (Symbol) thread.setValues(symbol, Keyword.EXTERNAL);
367        symbol = internalSymbols.get(s.toString());
368        if (symbol != null)
369            return (Symbol) thread.setValues(symbol, Keyword.INTERNAL);
370        // Look in external symbols of used packages.
371        if (useList instanceof Cons) {
372            LispObject usedPackages = useList;
373            while (usedPackages != NIL) {
374                Package pkg = (Package) usedPackages.car();
375                symbol = pkg.findExternalSymbol(s);
376                if (symbol != null)
377                    return (Symbol) thread.setValues(symbol, Keyword.INHERITED);
378                usedPackages = usedPackages.cdr();
379            }
380        }
381        // Not found.
382        return (Symbol) thread.setValues(addSymbol(s), NIL);
383    }
384
385    public synchronized Symbol internAndExport(String symbolName)
386
387    {
388        final SimpleString s = new SimpleString(symbolName);
389        // Look in external and internal symbols of this package.
390        Symbol symbol = externalSymbols.get(s.toString());
391        if (symbol != null)
392            return symbol;
393        symbol = internalSymbols.get(s.toString());
394        if (symbol != null) {
395            export(symbol);
396            return symbol;
397        }
398        if (useList instanceof Cons) {
399            // Look in external symbols of used packages.
400            LispObject usedPackages = useList;
401            while (usedPackages != NIL) {
402                Package pkg = (Package) usedPackages.car();
403                symbol = pkg.findExternalSymbol(s);
404                if (symbol != null) {
405                    export(symbol);
406                    return symbol;
407                }
408                usedPackages = usedPackages.cdr();
409            }
410        }
411        // Not found.
412        symbol = new Symbol(s, this);
413        if (this == PACKAGE_KEYWORD)
414            symbol.initializeConstant(symbol);
415        externalSymbols.put(s.toString(), symbol);
416        return symbol;
417    }
418
419    public synchronized LispObject unintern(final Symbol symbol)
420
421    {
422        final String symbolName = symbol.getName();
423        final boolean shadow;
424        if (shadowingSymbols != null && shadowingSymbols.get(symbolName) == symbol)
425            shadow = true;
426        else
427            shadow = false;
428        if (shadow) {
429            // Check for conflicts that might be exposed in used package list
430            // if we remove the shadowing symbol.
431            Symbol sym = null;
432            if (useList instanceof Cons) {
433                LispObject usedPackages = useList;
434                while (usedPackages != NIL) {
435                    Package pkg = (Package) usedPackages.car();
436                    Symbol s = pkg.findExternalSymbol(symbol.name);
437                    if (s != null) {
438                        if (sym == null)
439                            sym = s;
440                        else if (sym != s) {
441                            StringBuilder sb =
442                                new StringBuilder("Uninterning the symbol ");
443                            sb.append(symbol.getQualifiedName());
444                            sb.append(" causes a name conflict between ");
445                            sb.append(sym.getQualifiedName());
446                            sb.append(" and ");
447                            sb.append(s.getQualifiedName());
448                            return error(new PackageError(sb.toString()));
449                        }
450                    }
451                    usedPackages = usedPackages.cdr();
452                }
453            }
454        }
455        // Reaching here, it's OK to remove the symbol.
456        if (internalSymbols.get(symbol.name.toString()) == symbol)
457            internalSymbols.remove(symbol.name.toString());
458        else if (externalSymbols.get(symbol.name.toString()) == symbol)
459            externalSymbols.remove(symbol.name.toString());
460        else
461            // Not found.
462            return NIL;
463        if (shadow) {
464            Debug.assertTrue(shadowingSymbols != null);
465            shadowingSymbols.remove(symbolName);
466        }
467        if (symbol.getPackage() == this)
468            symbol.setPackage(NIL);
469        return T;
470    }
471
472    public synchronized void importSymbol(Symbol symbol)
473    {
474        if (symbol.getPackage() == this)
475            return; // Nothing to do.
476        Symbol sym = findAccessibleSymbol(symbol.name);
477        if (sym != null && sym != symbol) {
478            StringBuilder sb = new StringBuilder("The symbol ");
479            sb.append(sym.getQualifiedName());
480            sb.append(" is already accessible in package ");
481            sb.append(name);
482            sb.append('.');
483            error(new PackageError(sb.toString()));
484        }
485        internalSymbols.put(symbol.name.toString(), symbol);
486        if (symbol.getPackage() == NIL)
487            symbol.setPackage(this);
488    }
489
490    public synchronized void export(final Symbol symbol)
491    {
492        final String symbolName = symbol.getName();
493        boolean added = false;
494        if (symbol.getPackage() != this) {
495            Symbol sym = findAccessibleSymbol(symbol.name);
496            if (sym != symbol) {
497                StringBuilder sb = new StringBuilder("The symbol ");
498                sb.append(symbol.getQualifiedName());
499                sb.append(" is not accessible in package ");
500                sb.append(name);
501                sb.append('.');
502                error(new PackageError(sb.toString()));
503                return;
504            }
505            internalSymbols.put(symbol.name.toString(), symbol);
506            added = true;
507        }
508        if (added || internalSymbols.get(symbol.name.toString()) == symbol) {
509            if (usedByList != null) {
510                for (Iterator it = usedByList.iterator(); it.hasNext();) {
511                    Package pkg = (Package) it.next();
512                    Symbol sym = pkg.findAccessibleSymbol(symbol.name);
513                    if (sym != null && sym != symbol) {
514                        if (pkg.shadowingSymbols != null &&
515                            pkg.shadowingSymbols.get(symbolName) == sym) {
516                            // OK.
517                        } else {
518                            StringBuilder sb = new StringBuilder("The symbol ");
519                            sb.append(sym.getQualifiedName());
520                            sb.append(" is already accessible in package ");
521                            sb.append(pkg.getName());
522                            sb.append('.');
523                            error(new PackageError(sb.toString()));
524                            return;
525                        }
526                    }
527                }
528            }
529            // No conflicts.
530            internalSymbols.remove(symbol.name.toString());
531            externalSymbols.put(symbol.name.toString(), symbol);
532            return;
533        }
534        if (externalSymbols.get(symbol.name.toString()) == symbol)
535            // Symbol is already exported; there's nothing to do.
536            return;
537        StringBuilder sb = new StringBuilder("The symbol ");
538        sb.append(symbol.getQualifiedName());
539        sb.append(" is not accessible in package ");
540        sb.append(name);
541        sb.append('.');
542        error(new PackageError(sb.toString()));
543    }
544
545    public synchronized void unexport(final Symbol symbol)
546
547    {
548        if (symbol.getPackage() == this) {
549            if (externalSymbols.get(symbol.name.toString()) == symbol) {
550                externalSymbols.remove(symbol.name.toString());
551                internalSymbols.put(symbol.name.toString(), symbol);
552            }
553        } else {
554            // Signal an error if symbol is not accessible.
555            if (useList instanceof Cons) {
556                LispObject usedPackages = useList;
557                while (usedPackages != NIL) {
558                    Package pkg = (Package) usedPackages.car();
559                    if (pkg.findExternalSymbol(symbol.name) == symbol)
560                        return; // OK.
561                    usedPackages = usedPackages.cdr();
562                }
563            }
564            StringBuilder sb = new StringBuilder("The symbol ");
565            sb.append(symbol.getQualifiedName());
566            sb.append(" is not accessible in package ");
567            sb.append(name);
568            error(new PackageError(sb.toString()));
569        }
570    }
571
572    public synchronized void shadow(final String symbolName)
573
574    {
575        if (shadowingSymbols == null)
576            shadowingSymbols = new HashMap<String,Symbol>();
577        final SimpleString s = new SimpleString(symbolName);
578        Symbol symbol = externalSymbols.get(s.toString());
579        if (symbol != null) {
580            shadowingSymbols.put(symbolName, symbol);
581            return;
582        }
583        symbol = internalSymbols.get(s.toString());
584        if (symbol != null) {
585            shadowingSymbols.put(symbolName, symbol);
586            return;
587        }
588        if (shadowingSymbols.get(symbolName) != null)
589            return;
590        symbol = new Symbol(s, this);
591        internalSymbols.put(s.toString(), symbol);
592        shadowingSymbols.put(symbolName, symbol);
593    }
594
595    public synchronized void shadowingImport(Symbol symbol)
596    {
597        LispObject where = NIL;
598        final String symbolName = symbol.getName();
599        Symbol sym = externalSymbols.get(symbol.name.toString());
600        if (sym != null) {
601            where = Keyword.EXTERNAL;
602        } else {
603            sym = internalSymbols.get(symbol.name.toString());
604            if (sym != null) {
605                where = Keyword.INTERNAL;
606            } else {
607                // Look in external symbols of used packages.
608                if (useList instanceof Cons) {
609                    LispObject usedPackages = useList;
610                    while (usedPackages != NIL) {
611                        Package pkg = (Package) usedPackages.car();
612                        sym = pkg.findExternalSymbol(symbol.name);
613                        if (sym != null) {
614                            where = Keyword.INHERITED;
615                            break;
616                        }
617                        usedPackages = usedPackages.cdr();
618                    }
619                }
620            }
621        }
622        if (sym != null) {
623            if (where == Keyword.INTERNAL || where == Keyword.EXTERNAL) {
624                if (sym != symbol) {
625                    if (shadowingSymbols != null)
626                        shadowingSymbols.remove(symbolName);
627                    unintern(sym);
628                } else if (where == Keyword.INTERNAL) {
629                    // Assert rgument is already correctly a shadowing import
630                    Debug.assertTrue(shadowingSymbols != null);
631                    Debug.assertTrue(shadowingSymbols.get(symbolName) != null);
632                    return;
633                }
634            }
635        }
636        internalSymbols.put(symbol.name.toString(), symbol);
637        if (shadowingSymbols == null)
638            shadowingSymbols = new HashMap<String,Symbol>();
639        Debug.assertTrue(shadowingSymbols.get(symbolName) == null);
640        shadowingSymbols.put(symbolName, symbol);
641    }
642
643    // "USE-PACKAGE causes PACKAGE to inherit all the external symbols of
644    // PACKAGES-TO-USE. The inherited symbols become accessible as internal
645    // symbols of PACKAGE."
646    public void usePackage(Package pkg)
647    {
648        if (useList == null)
649            useList = NIL;
650        if (!memq(pkg, useList)) {
651            // "USE-PACKAGE checks for name conflicts between the newly
652            // imported symbols and those already accessible in package."
653            Collection symbols = pkg.getExternalSymbols();
654            for (Iterator<Symbol> i = symbols.iterator(); i.hasNext();) {
655                Symbol symbol = i.next();
656                Symbol existing = findAccessibleSymbol(symbol.name);
657                if (existing != null && existing != symbol) {
658                    if (shadowingSymbols == null ||
659                        shadowingSymbols.get(symbol.getName()) == null)
660                    {
661                        error(new PackageError("A symbol named " + symbol.getName() +
662                                                " is already accessible in package " +
663                                                name + "."));
664                        return;
665                    }
666                }
667            }
668            useList = useList.push(pkg);
669            // Add this package to the used-by list of pkg.
670            if (pkg.usedByList != null)
671                Debug.assertTrue(!pkg.usedByList.contains(this));
672            if (pkg.usedByList == null)
673                pkg.usedByList = new ArrayList<Package>();
674            pkg.usedByList.add(this);
675        }
676    }
677
678    public void unusePackage(Package pkg)
679    {
680        if (useList instanceof Cons) {
681            if (memq(pkg, useList)) {
682                // FIXME Modify the original list instead of copying it!
683                LispObject newList = NIL;
684                while (useList != NIL) {
685                    if (useList.car() != pkg)
686                        newList = newList.push(useList.car());
687                    useList = useList.cdr();
688                }
689                useList = newList.nreverse();
690                Debug.assertTrue(!memq(pkg, useList));
691                Debug.assertTrue(pkg.usedByList != null);
692                Debug.assertTrue(pkg.usedByList.contains(this));
693                pkg.usedByList.remove(this);
694            }
695        }
696    }
697
698    public final void addNickname(String s)
699    {
700        // This call will signal an error if there's a naming conflict.
701        Packages.addNickname(this, s);
702
703        if (nicknames != null) {
704            if (nicknames.contains(s))
705                return; // Nothing to do.
706        } else
707            nicknames = new ArrayList<String>();
708
709        nicknames.add(s);
710    }
711
712    public String getNickname()
713    {
714        if (nicknames != null && nicknames.size() > 0)
715            return (String) nicknames.get(0);
716        return null;
717    }
718
719    public LispObject packageNicknames()
720    {
721        LispObject list = NIL;
722        if (nicknames != null) {
723            for (int i = nicknames.size(); i-- > 0;) {
724                String nickname = (String) nicknames.get(i);
725                list = new Cons(new SimpleString(nickname), list);
726            }
727        }
728        return list;
729    }
730
731    public LispObject getUseList()
732    {
733        if (useList == null)
734            useList = NIL;
735        return useList;
736    }
737
738    public boolean uses(LispObject pkg)
739    {
740        return (useList instanceof Cons) && memq(pkg, useList);
741    }
742
743    public LispObject getUsedByList()
744    {
745        LispObject list = NIL;
746        if (usedByList != null) {
747            for (Iterator it = usedByList.iterator(); it.hasNext();) {
748                Package pkg = (Package) it.next();
749                list = new Cons(pkg, list);
750            }
751        }
752        return list;
753    }
754
755    public LispObject getShadowingSymbols()
756    {
757        LispObject list = NIL;
758        if (shadowingSymbols != null) {
759            for (Iterator it = shadowingSymbols.values().iterator(); it.hasNext();) {
760                Symbol symbol = (Symbol) it.next();
761                list = new Cons(symbol, list);
762            }
763        }
764        return list;
765    }
766
767    public synchronized Collection getExternalSymbols()
768    {
769        return externalSymbols.values();
770    }
771
772    public synchronized List<Symbol> getAccessibleSymbols()
773    {
774        ArrayList<Symbol> list = new ArrayList<Symbol>();
775        list.addAll(internalSymbols.values());
776        list.addAll(externalSymbols.values());
777        if (useList instanceof Cons) {
778            LispObject usedPackages = useList;
779            while (usedPackages != NIL) {
780                Package pkg = (Package) usedPackages.car();
781                list.addAll(pkg.externalSymbols.values());
782
783                usedPackages = usedPackages.cdr();
784            }
785        }
786        return list;
787    }
788
789    public synchronized LispObject PACKAGE_INTERNAL_SYMBOLS()
790    {
791        LispObject list = NIL;
792        Collection symbols = internalSymbols.values();
793        for (Iterator<Symbol> i = symbols.iterator(); i.hasNext();)
794            list = new Cons(i.next(), list);
795        return list;
796    }
797
798    public synchronized LispObject PACKAGE_EXTERNAL_SYMBOLS()
799    {
800        LispObject list = NIL;
801        Collection symbols = externalSymbols.values();
802        for (Iterator<Symbol> i = symbols.iterator(); i.hasNext();)
803            list = new Cons(i.next(), list);
804        return list;
805    }
806
807    public synchronized LispObject PACKAGE_INHERITED_SYMBOLS()
808    {
809        LispObject list = NIL;
810        if (useList instanceof Cons) {
811            LispObject usedPackages = useList;
812            while (usedPackages != NIL) {
813                Package pkg = (Package) usedPackages.car();
814                Collection externals = pkg.getExternalSymbols();
815                for (Iterator<Symbol> i = externals.iterator(); i.hasNext();) {
816                    Symbol symbol = i.next();
817                    if (shadowingSymbols != null && shadowingSymbols.get(symbol.getName()) != null)
818                        continue;
819                    if (externalSymbols.get(symbol.name.toString()) == symbol)
820                        continue;
821                    list = new Cons(symbol, list);
822                }
823                usedPackages = usedPackages.cdr();
824            }
825        }
826        return list;
827    }
828
829    public synchronized LispObject getSymbols()
830    {
831        LispObject list = NIL;
832        Collection internals = internalSymbols.values();
833        for (Iterator<Symbol> i = internals.iterator(); i.hasNext();)
834            list = new Cons(i.next(), list);
835        Collection externals = externalSymbols.values();
836        for (Iterator<Symbol> i = externals.iterator(); i.hasNext();)
837            list = new Cons(i.next(), list);
838        return list;
839    }
840
841    public synchronized Symbol[] symbols()
842    {
843        Collection internals = internalSymbols.values();
844        Collection externals = externalSymbols.values();
845        Symbol[] array = new Symbol[internals.size() + externals.size()];
846        int i = 0;
847        for (Iterator it = internals.iterator(); it.hasNext();) {
848            Symbol symbol = (Symbol) it.next();
849            array[i++] = symbol;
850        }
851        for (Iterator it = externals.iterator(); it.hasNext();) {
852            Symbol symbol = (Symbol) it.next();
853            array[i++] = symbol;
854        }
855        return array;
856    }
857
858    @Override
859    public String printObject()
860    {
861        if (_PRINT_FASL_.symbolValue() != NIL && name != null) {
862            StringBuilder sb = new StringBuilder("#.(FIND-PACKAGE \"");
863            sb.append(name);
864            sb.append("\")");
865            return sb.toString();
866        } else {
867             if (name != null) {
868                return unreadableString("PACKAGE " + name, false);
869            } else
870                return unreadableString("PACKAGE");
871        }
872    }
873
874    public Object readResolve() throws java.io.ObjectStreamException {
875  Package pkg = Packages.findPackage(name);
876  if(pkg != null) {
877      return pkg;
878  } else {
879      return error(new PackageError(name + " is not the name of a package."));
880  }
881    }
882}
Note: See TracBrowser for help on using the repository browser.