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

Last change on this file was 11492, checked in by ehuelsmann, 17 years ago

Revert r11491. It was based on lack of understanding of the order in which classes are
loaded by ABCL: we cannot access symbol values in the Symbol class.

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