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

Last change on this file was 14061, checked in by ehuelsmann, 12 years ago

Qualify FIND-PACKAGE when used to serialize a package in a FASL:
the current package at FASL load time may not import the CL package.

Patch by: Vladimir Sedach.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 30.0 KB
Line 
1/*
2 * Package.java
3 *
4 * Copyright (C) 2002-2007 Peter Graves <peter@armedbear.org>
5 * $Id: Package.java 14061 2012-08-06 07:45:59Z ehuelsmann $
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            if (usedByList != null) {
174              while (!usedByList.isEmpty()) {
175                usedByList.get(0).unusePackage(this);
176              }
177            }
178
179            Packages.deletePackage(this);
180
181            makeSymbolsUninterned(internalSymbols);
182            makeSymbolsUninterned(externalSymbols); // also clears externalSymbols
183
184            name = null;
185            lispName = null;
186            nicknames = null;
187           
188            return true;
189        }
190        return false;
191    }
192
193    public final synchronized void rename(String newName, LispObject newNicks)
194
195    {
196        ArrayList<String> arrayList = null;
197        while (newNicks != NIL) {
198            if (arrayList == null)
199                arrayList = new ArrayList<String>();
200            arrayList.add(javaString(newNicks.car()));
201            newNicks = newNicks.cdr();
202        }
203        // Remove old name and nicknames from Packages map.
204        Packages.deletePackage(this);
205        // Now change the names...
206        name = newName;
207        lispName = new SimpleString(newName);
208        nicknames = arrayList;
209        // And add the package back.
210        Packages.addPackage(this);
211    }
212
213    public Symbol findInternalSymbol(SimpleString name)
214    {
215        return internalSymbols.get(name.toString());
216    }
217
218    public Symbol findInternalSymbol(String name)
219    {
220        return internalSymbols.get(name);
221    }
222
223    public Symbol findExternalSymbol(SimpleString name)
224    {
225        return externalSymbols.get(name.toString());
226    }
227
228    public Symbol findExternalSymbol(String name)
229    {
230        return externalSymbols.get(name);
231    }
232
233    public Symbol findExternalSymbol(SimpleString name, int hash)
234    {
235        return externalSymbols.get(name.toString());
236    }
237
238    // Returns null if symbol is not accessible in this package.
239    public Symbol findAccessibleSymbol(String name)
240
241    {
242        return findAccessibleSymbol(new SimpleString(name));
243    }
244
245    // Returns null if symbol is not accessible in this package.
246    public Symbol findAccessibleSymbol(SimpleString name)
247
248    {
249        // Look in external and internal symbols of this package.
250        Symbol symbol = externalSymbols.get(name.toString());
251        if (symbol != null)
252            return symbol;
253        symbol = internalSymbols.get(name.toString());
254        if (symbol != null)
255            return symbol;
256        // Look in external symbols of used packages.
257        if (useList instanceof Cons) {
258            LispObject usedPackages = useList;
259            while (usedPackages != NIL) {
260                Package pkg = (Package) usedPackages.car();
261                symbol = pkg.findExternalSymbol(name);
262                if (symbol != null)
263                    return symbol;
264                usedPackages = usedPackages.cdr();
265            }
266        }
267        // Not found.
268        return null;
269    }
270
271    public LispObject findSymbol(String name)
272
273    {
274        final SimpleString s = new SimpleString(name);
275        final LispThread thread = LispThread.currentThread();
276        // Look in external and internal symbols of this package.
277        Symbol symbol = externalSymbols.get(name);
278        if (symbol != null)
279            return thread.setValues(symbol, Keyword.EXTERNAL);
280        symbol = internalSymbols.get(name);
281        if (symbol != null)
282            return thread.setValues(symbol, Keyword.INTERNAL);
283        // Look in external symbols of used packages.
284        if (useList instanceof Cons) {
285            LispObject usedPackages = useList;
286            while (usedPackages != NIL) {
287                Package pkg = (Package) usedPackages.car();
288                symbol = pkg.findExternalSymbol(s);
289                if (symbol != null)
290                    return thread.setValues(symbol, Keyword.INHERITED);
291                usedPackages = usedPackages.cdr();
292            }
293        }
294        // Not found.
295        return thread.setValues(NIL, NIL);
296    }
297
298    // Helper function to add NIL to PACKAGE_CL.
299    public void addSymbol(Symbol symbol)
300    {
301        Debug.assertTrue(symbol.getPackage() == this);
302        Debug.assertTrue(symbol.getName().equals("NIL"));
303        externalSymbols.put(symbol.name.toString(), symbol);
304    }
305
306    private Symbol addSymbol(String name)
307    {
308        Symbol symbol = new Symbol(name, this);
309        if (this == PACKAGE_KEYWORD) {
310            symbol.initializeConstant(symbol);
311            externalSymbols.put(name.toString(), symbol);
312        } else
313            internalSymbols.put(name.toString(), symbol);
314       
315        return symbol;
316    }
317
318    private Symbol addSymbol(SimpleString name)
319    {
320        return addSymbol(name.toString());
321    }
322
323    public Symbol addInternalSymbol(String symbolName)
324    {
325        final Symbol symbol = new Symbol(symbolName, this);
326        internalSymbols.put(symbolName, symbol);
327        return symbol;
328    }
329
330    public Symbol addExternalSymbol(String symbolName)
331    {
332        final Symbol symbol = new Symbol(symbolName, this);
333        externalSymbols.put(symbolName, symbol);
334        return symbol;
335    }
336
337    public synchronized Symbol intern(SimpleString symbolName)
338    {
339        return intern(symbolName.toString());
340    }
341
342    public synchronized Symbol intern(String symbolName)
343    {
344        // Look in external and internal symbols of this package.
345        Symbol symbol = externalSymbols.get(symbolName);
346        if (symbol != null)
347            return symbol;
348        symbol = internalSymbols.get(symbolName);
349        if (symbol != null)
350            return symbol;
351        // Look in external symbols of used packages.
352        if (useList instanceof Cons) {
353            LispObject usedPackages = useList;
354            while (usedPackages != NIL) {
355                Package pkg = (Package) usedPackages.car();
356                symbol = pkg.externalSymbols.get(symbolName);
357                if (symbol != null)
358                    return symbol;
359                usedPackages = usedPackages.cdr();
360            }
361        }
362        // Not found.
363        return addSymbol(symbolName);
364    }
365
366    public synchronized Symbol intern(final SimpleString s,
367                                      final LispThread thread)
368    {
369        // Look in external and internal symbols of this package.
370        Symbol symbol = externalSymbols.get(s.toString());
371        if (symbol != null)
372            return (Symbol) thread.setValues(symbol, Keyword.EXTERNAL);
373        symbol = internalSymbols.get(s.toString());
374        if (symbol != null)
375            return (Symbol) thread.setValues(symbol, Keyword.INTERNAL);
376        // Look in external symbols of used packages.
377        if (useList instanceof Cons) {
378            LispObject usedPackages = useList;
379            while (usedPackages != NIL) {
380                Package pkg = (Package) usedPackages.car();
381                symbol = pkg.findExternalSymbol(s);
382                if (symbol != null)
383                    return (Symbol) thread.setValues(symbol, Keyword.INHERITED);
384                usedPackages = usedPackages.cdr();
385            }
386        }
387        // Not found.
388        return (Symbol) thread.setValues(addSymbol(s), NIL);
389    }
390
391    public synchronized Symbol internAndExport(String symbolName)
392
393    {
394        final SimpleString s = new SimpleString(symbolName);
395        // Look in external and internal symbols of this package.
396        Symbol symbol = externalSymbols.get(s.toString());
397        if (symbol != null)
398            return symbol;
399        symbol = internalSymbols.get(s.toString());
400        if (symbol != null) {
401            export(symbol);
402            return symbol;
403        }
404        if (useList instanceof Cons) {
405            // Look in external symbols of used packages.
406            LispObject usedPackages = useList;
407            while (usedPackages != NIL) {
408                Package pkg = (Package) usedPackages.car();
409                symbol = pkg.findExternalSymbol(s);
410                if (symbol != null) {
411                    export(symbol);
412                    return symbol;
413                }
414                usedPackages = usedPackages.cdr();
415            }
416        }
417        // Not found.
418        symbol = new Symbol(s, this);
419        if (this == PACKAGE_KEYWORD)
420            symbol.initializeConstant(symbol);
421        externalSymbols.put(s.toString(), symbol);
422        return symbol;
423    }
424
425    public synchronized LispObject unintern(final Symbol symbol)
426
427    {
428        final String symbolName = symbol.getName();
429        final boolean shadow;
430        if (shadowingSymbols != null && shadowingSymbols.get(symbolName) == symbol)
431            shadow = true;
432        else
433            shadow = false;
434        if (shadow) {
435            // Check for conflicts that might be exposed in used package list
436            // if we remove the shadowing symbol.
437            Symbol sym = null;
438            if (useList instanceof Cons) {
439                LispObject usedPackages = useList;
440                while (usedPackages != NIL) {
441                    Package pkg = (Package) usedPackages.car();
442                    Symbol s = pkg.findExternalSymbol(symbol.name);
443                    if (s != null) {
444                        if (sym == null)
445                            sym = s;
446                        else if (sym != s) {
447                            StringBuilder sb =
448                                new StringBuilder("Uninterning the symbol ");
449                            sb.append(symbol.getQualifiedName());
450                            sb.append(" causes a name conflict between ");
451                            sb.append(sym.getQualifiedName());
452                            sb.append(" and ");
453                            sb.append(s.getQualifiedName());
454                            return error(new PackageError(sb.toString()));
455                        }
456                    }
457                    usedPackages = usedPackages.cdr();
458                }
459            }
460        }
461        // Reaching here, it's OK to remove the symbol.
462        if (internalSymbols.get(symbol.name.toString()) == symbol)
463            internalSymbols.remove(symbol.name.toString());
464        else if (externalSymbols.get(symbol.name.toString()) == symbol)
465            externalSymbols.remove(symbol.name.toString());
466        else
467            // Not found.
468            return NIL;
469        if (shadow) {
470            Debug.assertTrue(shadowingSymbols != null);
471            shadowingSymbols.remove(symbolName);
472        }
473        if (symbol.getPackage() == this)
474            symbol.setPackage(NIL);
475        return T;
476    }
477
478    public synchronized void importSymbol(Symbol symbol)
479    {
480        if (symbol.getPackage() == this)
481            return; // Nothing to do.
482        Symbol sym = findAccessibleSymbol(symbol.name);
483        if (sym != null && sym != symbol) {
484            StringBuilder sb = new StringBuilder("The symbol ");
485            sb.append(sym.getQualifiedName());
486            sb.append(" is already accessible in package ");
487            sb.append(name);
488            sb.append('.');
489            error(new PackageError(sb.toString()));
490        }
491        internalSymbols.put(symbol.name.toString(), symbol);
492        if (symbol.getPackage() == NIL)
493            symbol.setPackage(this);
494    }
495
496    public synchronized void export(final Symbol symbol)
497    {
498        final String symbolName = symbol.getName();
499        boolean added = false;
500        if (symbol.getPackage() != this) {
501            Symbol sym = findAccessibleSymbol(symbol.name);
502            if (sym != symbol) {
503                StringBuilder sb = new StringBuilder("The symbol ");
504                sb.append(symbol.getQualifiedName());
505                sb.append(" is not accessible in package ");
506                sb.append(name);
507                sb.append('.');
508                error(new PackageError(sb.toString()));
509                return;
510            }
511            internalSymbols.put(symbol.name.toString(), symbol);
512            added = true;
513        }
514        if (added || internalSymbols.get(symbol.name.toString()) == symbol) {
515            if (usedByList != null) {
516                for (Iterator it = usedByList.iterator(); it.hasNext();) {
517                    Package pkg = (Package) it.next();
518                    Symbol sym = pkg.findAccessibleSymbol(symbol.name);
519                    if (sym != null && sym != symbol) {
520                        if (pkg.shadowingSymbols != null &&
521                            pkg.shadowingSymbols.get(symbolName) == sym) {
522                            // OK.
523                        } else {
524                            StringBuilder sb = new StringBuilder("The symbol ");
525                            sb.append(sym.getQualifiedName());
526                            sb.append(" is already accessible in package ");
527                            sb.append(pkg.getName());
528                            sb.append('.');
529                            error(new PackageError(sb.toString()));
530                            return;
531                        }
532                    }
533                }
534            }
535            // No conflicts.
536            internalSymbols.remove(symbol.name.toString());
537            externalSymbols.put(symbol.name.toString(), symbol);
538            return;
539        }
540        if (externalSymbols.get(symbol.name.toString()) == symbol)
541            // Symbol is already exported; there's nothing to do.
542            return;
543        StringBuilder sb = new StringBuilder("The symbol ");
544        sb.append(symbol.getQualifiedName());
545        sb.append(" is not accessible in package ");
546        sb.append(name);
547        sb.append('.');
548        error(new PackageError(sb.toString()));
549    }
550
551    public synchronized void unexport(final Symbol symbol)
552
553    {
554        if (symbol.getPackage() == this) {
555            if (externalSymbols.get(symbol.name.toString()) == symbol) {
556                externalSymbols.remove(symbol.name.toString());
557                internalSymbols.put(symbol.name.toString(), symbol);
558            }
559        } else {
560            // Signal an error if symbol is not accessible.
561            if (useList instanceof Cons) {
562                LispObject usedPackages = useList;
563                while (usedPackages != NIL) {
564                    Package pkg = (Package) usedPackages.car();
565                    if (pkg.findExternalSymbol(symbol.name) == symbol)
566                        return; // OK.
567                    usedPackages = usedPackages.cdr();
568                }
569            }
570            StringBuilder sb = new StringBuilder("The symbol ");
571            sb.append(symbol.getQualifiedName());
572            sb.append(" is not accessible in package ");
573            sb.append(name);
574            error(new PackageError(sb.toString()));
575        }
576    }
577
578    public synchronized void shadow(final String symbolName)
579
580    {
581        if (shadowingSymbols == null)
582            shadowingSymbols = new HashMap<String,Symbol>();
583        final SimpleString s = new SimpleString(symbolName);
584        Symbol symbol = externalSymbols.get(s.toString());
585        if (symbol != null) {
586            shadowingSymbols.put(symbolName, symbol);
587            return;
588        }
589        symbol = internalSymbols.get(s.toString());
590        if (symbol != null) {
591            shadowingSymbols.put(symbolName, symbol);
592            return;
593        }
594        if (shadowingSymbols.get(symbolName) != null)
595            return;
596        symbol = new Symbol(s, this);
597        internalSymbols.put(s.toString(), symbol);
598        shadowingSymbols.put(symbolName, symbol);
599    }
600
601    public synchronized void shadowingImport(Symbol symbol)
602    {
603        LispObject where = NIL;
604        final String symbolName = symbol.getName();
605        Symbol sym = externalSymbols.get(symbol.name.toString());
606        if (sym != null) {
607            where = Keyword.EXTERNAL;
608        } else {
609            sym = internalSymbols.get(symbol.name.toString());
610            if (sym != null) {
611                where = Keyword.INTERNAL;
612            } else {
613                // Look in external symbols of used packages.
614                if (useList instanceof Cons) {
615                    LispObject usedPackages = useList;
616                    while (usedPackages != NIL) {
617                        Package pkg = (Package) usedPackages.car();
618                        sym = pkg.findExternalSymbol(symbol.name);
619                        if (sym != null) {
620                            where = Keyword.INHERITED;
621                            break;
622                        }
623                        usedPackages = usedPackages.cdr();
624                    }
625                }
626            }
627        }
628        if (sym != null) {
629            if (where == Keyword.INTERNAL || where == Keyword.EXTERNAL) {
630                if (sym != symbol) {
631                    if (shadowingSymbols != null)
632                        shadowingSymbols.remove(symbolName);
633                    unintern(sym);
634                } else if (where == Keyword.INTERNAL) {
635                    // Assert rgument is already correctly a shadowing import
636                    Debug.assertTrue(shadowingSymbols != null);
637                    Debug.assertTrue(shadowingSymbols.get(symbolName) != null);
638                    return;
639                }
640            }
641        }
642        internalSymbols.put(symbol.name.toString(), symbol);
643        if (shadowingSymbols == null)
644            shadowingSymbols = new HashMap<String,Symbol>();
645        Debug.assertTrue(shadowingSymbols.get(symbolName) == null);
646        shadowingSymbols.put(symbolName, symbol);
647    }
648
649    // "USE-PACKAGE causes PACKAGE to inherit all the external symbols of
650    // PACKAGES-TO-USE. The inherited symbols become accessible as internal
651    // symbols of PACKAGE."
652    public void usePackage(Package pkg)
653    {
654        if (useList == null)
655            useList = NIL;
656        if (!memq(pkg, useList)) {
657            // "USE-PACKAGE checks for name conflicts between the newly
658            // imported symbols and those already accessible in package."
659            Collection symbols = pkg.getExternalSymbols();
660            for (Iterator<Symbol> i = symbols.iterator(); i.hasNext();) {
661                Symbol symbol = i.next();
662                Symbol existing = findAccessibleSymbol(symbol.name);
663                if (existing != null && existing != symbol) {
664                    if (shadowingSymbols == null ||
665                        shadowingSymbols.get(symbol.getName()) == null)
666                    {
667                        error(new PackageError("A symbol named " + symbol.getName() +
668                                                " is already accessible in package " +
669                                                name + "."));
670                        return;
671                    }
672                }
673            }
674            useList = useList.push(pkg);
675            // Add this package to the used-by list of pkg.
676            if (pkg.usedByList != null)
677                Debug.assertTrue(!pkg.usedByList.contains(this));
678            if (pkg.usedByList == null)
679                pkg.usedByList = new ArrayList<Package>();
680            pkg.usedByList.add(this);
681        }
682    }
683
684    public void unusePackage(Package pkg)
685    {
686        if (useList instanceof Cons) {
687            if (memq(pkg, useList)) {
688                // FIXME Modify the original list instead of copying it!
689                LispObject newList = NIL;
690                while (useList != NIL) {
691                    if (useList.car() != pkg)
692                        newList = newList.push(useList.car());
693                    useList = useList.cdr();
694                }
695                useList = newList.nreverse();
696                Debug.assertTrue(!memq(pkg, useList));
697                Debug.assertTrue(pkg.usedByList != null);
698                Debug.assertTrue(pkg.usedByList.contains(this));
699                pkg.usedByList.remove(this);
700            }
701        }
702    }
703
704    public final void addNickname(String s)
705    {
706        // This call will signal an error if there's a naming conflict.
707        Packages.addNickname(this, s);
708
709        if (nicknames != null) {
710            if (nicknames.contains(s))
711                return; // Nothing to do.
712        } else
713            nicknames = new ArrayList<String>();
714
715        nicknames.add(s);
716    }
717
718    public String getNickname()
719    {
720        if (nicknames != null && nicknames.size() > 0)
721            return (String) nicknames.get(0);
722        return null;
723    }
724
725    public LispObject packageNicknames()
726    {
727        LispObject list = NIL;
728        if (nicknames != null) {
729            for (int i = nicknames.size(); i-- > 0;) {
730                String nickname = (String) nicknames.get(i);
731                list = new Cons(new SimpleString(nickname), list);
732            }
733        }
734        return list;
735    }
736
737    public LispObject getUseList()
738    {
739        if (useList == null)
740            useList = NIL;
741        return useList;
742    }
743
744    public boolean uses(LispObject pkg)
745    {
746        return (useList instanceof Cons) && memq(pkg, useList);
747    }
748
749    public LispObject getUsedByList()
750    {
751        LispObject list = NIL;
752        if (usedByList != null) {
753            for (Iterator it = usedByList.iterator(); it.hasNext();) {
754                Package pkg = (Package) it.next();
755                list = new Cons(pkg, list);
756            }
757        }
758        return list;
759    }
760
761    public LispObject getShadowingSymbols()
762    {
763        LispObject list = NIL;
764        if (shadowingSymbols != null) {
765            for (Iterator it = shadowingSymbols.values().iterator(); it.hasNext();) {
766                Symbol symbol = (Symbol) it.next();
767                list = new Cons(symbol, list);
768            }
769        }
770        return list;
771    }
772
773    public synchronized Collection getExternalSymbols()
774    {
775        return externalSymbols.values();
776    }
777
778    public synchronized List<Symbol> getAccessibleSymbols()
779    {
780        ArrayList<Symbol> list = new ArrayList<Symbol>();
781        list.addAll(internalSymbols.values());
782        list.addAll(externalSymbols.values());
783        if (useList instanceof Cons) {
784            LispObject usedPackages = useList;
785            while (usedPackages != NIL) {
786                Package pkg = (Package) usedPackages.car();
787                list.addAll(pkg.externalSymbols.values());
788
789                usedPackages = usedPackages.cdr();
790            }
791        }
792        return list;
793    }
794
795    public synchronized LispObject PACKAGE_INTERNAL_SYMBOLS()
796    {
797        LispObject list = NIL;
798        Collection symbols = internalSymbols.values();
799        for (Iterator<Symbol> i = symbols.iterator(); i.hasNext();)
800            list = new Cons(i.next(), list);
801        return list;
802    }
803
804    public synchronized LispObject PACKAGE_EXTERNAL_SYMBOLS()
805    {
806        LispObject list = NIL;
807        Collection symbols = externalSymbols.values();
808        for (Iterator<Symbol> i = symbols.iterator(); i.hasNext();)
809            list = new Cons(i.next(), list);
810        return list;
811    }
812
813    public synchronized LispObject PACKAGE_INHERITED_SYMBOLS()
814    {
815        LispObject list = NIL;
816        if (useList instanceof Cons) {
817            LispObject usedPackages = useList;
818            while (usedPackages != NIL) {
819                Package pkg = (Package) usedPackages.car();
820                Collection externals = pkg.getExternalSymbols();
821                for (Iterator<Symbol> i = externals.iterator(); i.hasNext();) {
822                    Symbol symbol = i.next();
823                    if (shadowingSymbols != null && shadowingSymbols.get(symbol.getName()) != null)
824                        continue;
825                    if (externalSymbols.get(symbol.name.toString()) == symbol)
826                        continue;
827                    list = new Cons(symbol, list);
828                }
829                usedPackages = usedPackages.cdr();
830            }
831        }
832        return list;
833    }
834
835    public synchronized LispObject getSymbols()
836    {
837        LispObject list = NIL;
838        Collection internals = internalSymbols.values();
839        for (Iterator<Symbol> i = internals.iterator(); i.hasNext();)
840            list = new Cons(i.next(), list);
841        Collection externals = externalSymbols.values();
842        for (Iterator<Symbol> i = externals.iterator(); i.hasNext();)
843            list = new Cons(i.next(), list);
844        return list;
845    }
846
847    public synchronized Symbol[] symbols()
848    {
849        Collection internals = internalSymbols.values();
850        Collection externals = externalSymbols.values();
851        Symbol[] array = new Symbol[internals.size() + externals.size()];
852        int i = 0;
853        for (Iterator it = internals.iterator(); it.hasNext();) {
854            Symbol symbol = (Symbol) it.next();
855            array[i++] = symbol;
856        }
857        for (Iterator it = externals.iterator(); it.hasNext();) {
858            Symbol symbol = (Symbol) it.next();
859            array[i++] = symbol;
860        }
861        return array;
862    }
863
864    @Override
865    public String printObject()
866    {
867        if (_PRINT_FASL_.symbolValue() != NIL && name != null) {
868            StringBuilder sb = new StringBuilder("#.(CL:FIND-PACKAGE \"");
869            sb.append(name);
870            sb.append("\")");
871            return sb.toString();
872        } else {
873             if (name != null) {
874                return unreadableString("PACKAGE " + name, false);
875            } else
876                return unreadableString("PACKAGE");
877        }
878    }
879
880    public Object readResolve() throws java.io.ObjectStreamException {
881  Package pkg = Packages.findPackage(name);
882  if(pkg != null) {
883      return pkg;
884  } else {
885      return error(new PackageError(name + " is not the name of a package."));
886  }
887    }
888}
Note: See TracBrowser for help on using the repository browser.