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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.lookup;
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;
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
26 public PackageBinding(char[][] compoundName, PackageBinding parent, LookupEnvironment environment) {
27 this.compoundName = compoundName;
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
33 public PackageBinding(char[] topLevelPackageName, LookupEnvironment environment) {
34 this(new char[][] {topLevelPackageName}, null, environment);
36 /* Create the default package.
39 public PackageBinding(LookupEnvironment environment) {
40 this(CharOperation.NO_CHAR_CHAR, null, environment);
42 private void addNotFoundPackage(char[] simpleName) {
43 knownPackages.put(simpleName, LookupEnvironment.TheNotFoundPackage);
45 private void addNotFoundType(char[] simpleName) {
46 if (knownTypes == null)
47 knownTypes = new HashtableOfType(25);
48 knownTypes.put(simpleName, LookupEnvironment.TheNotFoundType);
50 void addPackage(PackageBinding element) {
51 knownPackages.put(element.compoundName[element.compoundName.length - 1], element);
53 void addType(ReferenceBinding element) {
54 if (knownTypes == null)
55 knownTypes = new HashtableOfType(25);
56 knownTypes.put(element.compoundName[element.compoundName.length - 1], element);
59 * Answer the receiver's binding type from Binding.BindingID.
62 public final int kind() {
63 return Binding.PACKAGE;
66 * slash separated name
67 * org.eclipse.jdt.core --> org/eclipse/jdt/core
69 public char[] computeUniqueKey() {
70 return CharOperation.concatWith(compoundName, '/');
72 private PackageBinding findPackage(char[] name) {
73 if (!environment.isPackage(this.compoundName, name))
76 char[][] subPkgCompoundName = CharOperation.arrayConcat(this.compoundName, name);
77 PackageBinding subPackageBinding = new PackageBinding(subPkgCompoundName, this, environment);
78 addPackage(subPackageBinding);
79 return subPackageBinding;
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.
84 * NOTE: This should only be used when we know there is NOT a type with the same name.
87 PackageBinding getPackage(char[] name) {
88 PackageBinding binding = getPackage0(name);
89 if (binding != null) {
90 if (binding == LookupEnvironment.TheNotFoundPackage)
95 if ((binding = findPackage(name)) != null)
98 // not found so remember a problem package binding in the cache for future lookups
99 addNotFoundPackage(name);
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.
106 * NOTE: Senders must convert theNotFoundPackage into a real problem
107 * package if its to returned.
110 PackageBinding getPackage0(char[] name) {
111 return knownPackages.get(name);
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.
117 * NOTE: This should only be used by source types/scopes which know there is NOT a
118 * package with the same name.
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);
131 if (typeBinding == LookupEnvironment.TheNotFoundType)
134 typeBinding = BinaryTypeBinding.resolveType(typeBinding, environment, false); // no raw conversion for now
135 if (typeBinding.isNestedType())
136 return new ProblemReferenceBinding(name, InternalNameProvided);
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.
143 * NOTE: Senders must convert theNotFoundType into a real problem
144 * reference type if its to returned.
147 ReferenceBinding getType0(char[] name) {
148 if (knownTypes == null)
150 return knownTypes.get(name);
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.
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.
158 * NOTE: no visibility checks are performed.
159 * THIS SHOULD ONLY BE USED BY SOURCE TYPES/SCOPES.
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);
171 PackageBinding packageBinding = getPackage0(name);
172 if (packageBinding != null && packageBinding != LookupEnvironment.TheNotFoundPackage)
173 return packageBinding;
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);
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);
187 if (packageBinding == null) { // have not looked for it before
188 if ((packageBinding = findPackage(name)) != null)
189 return packageBinding;
190 addNotFoundPackage(name);
195 public char[] readableName() /*java.lang*/ {
196 return CharOperation.concatWith(compoundName, '.');
198 public String toString() {
199 if (compoundName == CharOperation.NO_CHAR_CHAR)
200 return "The Default Package"; //$NON-NLS-1$
202 return "package " + ((compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED"); //$NON-NLS-1$ //$NON-NLS-2$