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

Last change on this file was 14570, checked in by Mark Evenson, 11 years ago

Restore Packages.findPackage() API for obtaining the current package in Java.

Restore examples/java-to-lisp-1/MainAlternative.java to this use of
the API.

Fixes #324.

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