1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.lookup;
13 import net.sourceforge.phpdt.core.compiler.CharOperation;
14 import net.sourceforge.phpdt.internal.compiler.util.HashtableOfPackage;
15 import net.sourceforge.phpdt.internal.compiler.util.HashtableOfType;
17 public class PackageBinding extends Binding implements TypeConstants {
18 public char[][] compoundName;
20 PackageBinding parent;
22 LookupEnvironment environment;
24 HashtableOfType knownTypes;
26 HashtableOfPackage knownPackages;
28 protected PackageBinding() {
31 public PackageBinding(char[][] compoundName, PackageBinding parent,
32 LookupEnvironment environment) {
33 this.compoundName = compoundName;
35 this.environment = environment;
36 this.knownTypes = null; // initialized if used... class counts can be
38 this.knownPackages = new HashtableOfPackage(3); // sub-package counts
42 public PackageBinding(char[] topLevelPackageName,
43 LookupEnvironment environment) {
44 this(new char[][] { topLevelPackageName }, null, environment);
48 * Create the default package.
51 public PackageBinding(LookupEnvironment environment) {
52 this(CharOperation.NO_CHAR_CHAR, null, environment);
55 private void addNotFoundPackage(char[] simpleName) {
56 knownPackages.put(simpleName, LookupEnvironment.TheNotFoundPackage);
59 private void addNotFoundType(char[] simpleName) {
60 if (knownTypes == null)
61 knownTypes = new HashtableOfType(25);
62 knownTypes.put(simpleName, LookupEnvironment.TheNotFoundType);
65 void addPackage(PackageBinding element) {
67 element.compoundName[element.compoundName.length - 1], element);
70 void addType(ReferenceBinding element) {
71 if (knownTypes == null)
72 knownTypes = new HashtableOfType(25);
73 knownTypes.put(element.compoundName[element.compoundName.length - 1],
78 * API Answer the receiver's binding type from Binding.BindingID.
81 public final int bindingType() {
85 private PackageBinding findPackage(char[] name) {
86 if (!environment.isPackage(this.compoundName, name))
89 char[][] compoundName = CharOperation.arrayConcat(this.compoundName,
91 PackageBinding newPackageBinding = new PackageBinding(compoundName,
93 addPackage(newPackageBinding);
94 return newPackageBinding;
98 * Answer the subpackage named name; ask the oracle for the package if its
99 * not in the cache. Answer null if it could not be resolved.
101 * NOTE: This should only be used when we know there is NOT a type with the
105 PackageBinding getPackage(char[] name) {
106 PackageBinding binding = getPackage0(name);
107 if (binding != null) {
108 if (binding == LookupEnvironment.TheNotFoundPackage)
113 if ((binding = findPackage(name)) != null)
116 // not found so remember a problem package binding in the cache for
118 addNotFoundPackage(name);
123 * Answer the subpackage named name if it exists in the cache. Answer
124 * theNotFoundPackage if it could not be resolved the first time it was
125 * looked up, otherwise answer null.
127 * NOTE: Senders must convert theNotFoundPackage into a real problem package
128 * if its to returned.
131 PackageBinding getPackage0(char[] name) {
132 return knownPackages.get(name);
136 * Answer the type named name; ask the oracle for the type if its not in the
137 * cache. Answer a NotVisible problem type if the type is not visible from
138 * the invocationPackage. Answer null if it could not be resolved.
140 * NOTE: This should only be used by source types/scopes which know there is
141 * NOT a package with the same name.
144 ReferenceBinding getType(char[] name) {
145 ReferenceBinding binding = getType0(name);
146 if (binding == null) {
147 if ((binding = environment.askForType(this, name)) == null) {
148 // not found so remember a problem type binding in the cache for
150 addNotFoundType(name);
155 if (binding == LookupEnvironment.TheNotFoundType)
157 if (binding instanceof UnresolvedReferenceBinding)
158 binding = ((UnresolvedReferenceBinding) binding)
159 .resolve(environment);
160 if (binding.isNestedType())
161 return new ProblemReferenceBinding(name, InternalNameProvided);
166 * Answer the type named name if it exists in the cache. Answer
167 * theNotFoundType if it could not be resolved the first time it was looked
168 * up, otherwise answer null.
170 * NOTE: Senders must convert theNotFoundType into a real problem reference
171 * type if its to returned.
174 ReferenceBinding getType0(char[] name) {
175 if (knownTypes == null)
177 return knownTypes.get(name);
181 * Answer the package or type named name; ask the oracle if it is not in the
182 * cache. Answer null if it could not be resolved.
184 * When collisions exist between a type name & a package name, answer the
185 * package. Treat the type as if it does not exist... a problem was already
186 * reported when the type was defined.
188 * NOTE: no visibility checks are performed. THIS SHOULD ONLY BE USED BY
189 * SOURCE TYPES/SCOPES.
192 public Binding getTypeOrPackage(char[] name) {
193 PackageBinding packageBinding = getPackage0(name);
194 if (packageBinding != null
195 && packageBinding != LookupEnvironment.TheNotFoundPackage)
196 return packageBinding;
198 ReferenceBinding typeBinding = getType0(name);
199 if (typeBinding != null
200 && typeBinding != LookupEnvironment.TheNotFoundType) {
201 if (typeBinding instanceof UnresolvedReferenceBinding)
202 typeBinding = ((UnresolvedReferenceBinding) typeBinding)
203 .resolve(environment);
204 if (typeBinding.isNestedType())
205 return new ProblemReferenceBinding(name, InternalNameProvided);
209 // always look for the name as a sub-package if its not a known type
210 if (packageBinding == null
211 && (packageBinding = findPackage(name)) != null)
212 return packageBinding;
213 if (typeBinding == null) {
214 // if no package was found, find the type named name relative to the
216 if ((typeBinding = environment.askForType(this, name)) != null) {
217 if (typeBinding.isNestedType())
218 return new ProblemReferenceBinding(name,
219 InternalNameProvided);
223 // Since name could not be found, add problem bindings
224 // to the collections so it will be reported as an error next time.
225 addNotFoundPackage(name);
226 addNotFoundType(name);
228 if (packageBinding == LookupEnvironment.TheNotFoundPackage)
229 packageBinding = null;
230 if (typeBinding == LookupEnvironment.TheNotFoundType)
234 if (packageBinding != null)
235 return packageBinding;
240 public char[] readableName() /* java.lang */{
241 return CharOperation.concatWith(compoundName, '.');
244 public String toString() {
245 if (compoundName == CharOperation.NO_CHAR_CHAR)
246 return "The Default Package"; //$NON-NLS-1$
248 return "package " + ((compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED"); //$NON-NLS-1$ //$NON-NLS-2$