added -J option to preserve unmodified files in preexisting jarfile
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / lookup / PackageBinding.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.lookup;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.internal.compiler.util.HashtableOfPackage;
15 import org.eclipse.jdt.internal.compiler.util.HashtableOfType;
16
17 public class PackageBinding extends Binding implements TypeConstants {
18         public char[][] compoundName;
19         PackageBinding parent;
20         public LookupEnvironment environment;
21         HashtableOfType knownTypes;
22         HashtableOfPackage knownPackages;
23 protected PackageBinding() {
24         // for creating problem package
25 }
26 public PackageBinding(char[][] compoundName, PackageBinding parent, LookupEnvironment environment) {
27         this.compoundName = compoundName;
28         this.parent = parent;
29         this.environment = environment;
30         this.knownTypes = null; // initialized if used... class counts can be very large 300-600
31         this.knownPackages = new HashtableOfPackage(3); // sub-package counts are typically 0-3
32 }
33 public PackageBinding(char[] topLevelPackageName, LookupEnvironment environment) {
34         this(new char[][] {topLevelPackageName}, null, environment);
35 }
36 /* Create the default package.
37 */
38
39 public PackageBinding(LookupEnvironment environment) {
40         this(CharOperation.NO_CHAR_CHAR, null, environment);
41 }
42 private void addNotFoundPackage(char[] simpleName) {
43         knownPackages.put(simpleName, LookupEnvironment.TheNotFoundPackage);
44 }
45 private void addNotFoundType(char[] simpleName) {
46         if (knownTypes == null)
47                 knownTypes = new HashtableOfType(25);
48         knownTypes.put(simpleName, LookupEnvironment.TheNotFoundType);
49 }
50 void addPackage(PackageBinding element) {
51         knownPackages.put(element.compoundName[element.compoundName.length - 1], element);
52 }
53 void addType(ReferenceBinding element) {
54         if (knownTypes == null)
55                 knownTypes = new HashtableOfType(25);
56         knownTypes.put(element.compoundName[element.compoundName.length - 1], element);
57 }
58 /* API
59 * Answer the receiver's binding type from Binding.BindingID.
60 */
61
62 public final int kind() {
63         return Binding.PACKAGE;
64 }
65 /*
66  * slash separated name
67  * org.eclipse.jdt.core --> org/eclipse/jdt/core
68  */
69 public char[] computeUniqueKey() {
70         return CharOperation.concatWith(compoundName, '/');
71 }
72 private PackageBinding findPackage(char[] name) {
73         if (!environment.isPackage(this.compoundName, name))
74                 return null;
75
76         char[][] subPkgCompoundName = CharOperation.arrayConcat(this.compoundName, name);
77         PackageBinding subPackageBinding = new PackageBinding(subPkgCompoundName, this, environment);
78         addPackage(subPackageBinding);
79         return subPackageBinding;
80 }
81 /* Answer the subpackage named name; ask the oracle for the package if its not in the cache.
82 * Answer null if it could not be resolved.
83 *
84 * NOTE: This should only be used when we know there is NOT a type with the same name.
85 */
86
87 PackageBinding getPackage(char[] name) {
88         PackageBinding binding = getPackage0(name);
89         if (binding != null) {
90                 if (binding == LookupEnvironment.TheNotFoundPackage)
91                         return null;
92                 else
93                         return binding;
94         }
95         if ((binding = findPackage(name)) != null)
96                 return binding;
97
98         // not found so remember a problem package binding in the cache for future lookups
99         addNotFoundPackage(name);
100         return null;
101 }
102 /* Answer the subpackage named name if it exists in the cache.
103 * Answer theNotFoundPackage if it could not be resolved the first time
104 * it was looked up, otherwise answer null.
105 *
106 * NOTE: Senders must convert theNotFoundPackage into a real problem
107 * package if its to returned.
108 */
109
110 PackageBinding getPackage0(char[] name) {
111         return knownPackages.get(name);
112 }
113 /* Answer the type named name; ask the oracle for the type if its not in the cache.
114 * Answer a NotVisible problem type if the type is not visible from the invocationPackage.
115 * Answer null if it could not be resolved.
116 *
117 * NOTE: This should only be used by source types/scopes which know there is NOT a
118 * package with the same name.
119 */
120
121 ReferenceBinding getType(char[] name) {
122         ReferenceBinding typeBinding = getType0(name);
123         if (typeBinding == null) {
124                 if ((typeBinding = environment.askForType(this, name)) == null) {
125                         // not found so remember a problem type binding in the cache for future lookups
126                         addNotFoundType(name);
127                         return null;
128                 }
129         }
130
131         if (typeBinding == LookupEnvironment.TheNotFoundType)
132                 return null;
133
134         typeBinding = BinaryTypeBinding.resolveType(typeBinding, environment, false); // no raw conversion for now
135         if (typeBinding.isNestedType())
136                 return new ProblemReferenceBinding(name, InternalNameProvided);
137         return typeBinding;
138 }
139 /* Answer the type named name if it exists in the cache.
140 * Answer theNotFoundType if it could not be resolved the first time
141 * it was looked up, otherwise answer null.
142 *
143 * NOTE: Senders must convert theNotFoundType into a real problem
144 * reference type if its to returned.
145 */
146
147 ReferenceBinding getType0(char[] name) {
148         if (knownTypes == null)
149                 return null;
150         return knownTypes.get(name);
151 }
152 /* Answer the package or type named name; ask the oracle if it is not in the cache.
153 * Answer null if it could not be resolved.
154 *
155 * When collisions exist between a type name & a package name, answer the type.
156 * Treat the package as if it does not exist... a problem was already reported when the type was defined.
157 *
158 * NOTE: no visibility checks are performed.
159 * THIS SHOULD ONLY BE USED BY SOURCE TYPES/SCOPES.
160 */
161
162 public Binding getTypeOrPackage(char[] name) {
163         ReferenceBinding typeBinding = getType0(name);
164         if (typeBinding != null && typeBinding != LookupEnvironment.TheNotFoundType) {
165                 typeBinding = BinaryTypeBinding.resolveType(typeBinding, environment, false); // no raw conversion for now
166                 if (typeBinding.isNestedType())
167                         return new ProblemReferenceBinding(name, InternalNameProvided);
168                 return typeBinding;
169         }
170
171         PackageBinding packageBinding = getPackage0(name);
172         if (packageBinding != null && packageBinding != LookupEnvironment.TheNotFoundPackage)
173                 return packageBinding;
174
175         if (typeBinding == null) { // have not looked for it before
176                 if ((typeBinding = environment.askForType(this, name)) != null) {
177                         if (typeBinding.isNestedType())
178                                 return new ProblemReferenceBinding(name, InternalNameProvided);
179                         return typeBinding;
180                 }
181
182                 // Since name could not be found, add a problem binding
183                 // to the collections so it will be reported as an error next time.
184                 addNotFoundType(name);
185         }
186
187         if (packageBinding == null) { // have not looked for it before
188                 if ((packageBinding = findPackage(name)) != null)
189                         return packageBinding;
190                 addNotFoundPackage(name);
191         }
192
193         return null;
194 }
195 public char[] readableName() /*java.lang*/ {
196         return CharOperation.concatWith(compoundName, '.');
197 }
198 public String toString() {
199         if (compoundName == CharOperation.NO_CHAR_CHAR)
200                 return "The Default Package"; //$NON-NLS-1$
201         else
202                 return "package " + ((compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED"); //$NON-NLS-1$ //$NON-NLS-2$
203 }
204 }