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

Last change on this file was 13135, checked in by astalla, 15 years ago

Revert to a reflection-based loading scheme for top-level compiled functions. Fix NPE in Package.java.

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