1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package net.sourceforge.phpdt.core.dom;
14 import java.util.Iterator;
15 import java.util.List;
16 import net.sourceforge.phpdt.core.ICompilationUnit;
17 import net.sourceforge.phpdt.core.IJavaElement;
18 import net.sourceforge.phpdt.core.IPackageFragment;
19 import net.sourceforge.phpdt.core.IPackageFragmentRoot;
20 import net.sourceforge.phpdt.core.JavaModelException;
22 import net.sourceforge.phpdt.core.compiler.CharOperation;
23 import net.sourceforge.phpdt.internal.compiler.env.IBinaryAnnotation;
24 import net.sourceforge.phpdt.internal.compiler.env.IBinaryType;
25 import net.sourceforge.phpdt.internal.compiler.env.INameEnvironment;
26 import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer;
27 import net.sourceforge.phpdt.internal.compiler.lookup.BinaryTypeBinding;
28 import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
29 import net.sourceforge.phpdt.internal.compiler.util.Util;
30 import net.sourceforge.phpdt.internal.core.NameLookup;
31 import net.sourceforge.phpdt.internal.core.SearchableEnvironment;
34 * Internal implementation of package bindings.
36 class PackageBinding implements IPackageBinding {
38 private static final String[] NO_NAME_COMPONENTS = CharOperation.NO_STRINGS;
39 private static final String UNNAMED = Util.EMPTY_STRING;
40 private static final char PACKAGE_NAME_SEPARATOR = '.';
42 private net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding binding;
44 private BindingResolver resolver;
45 private String[] components;
47 PackageBinding(net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding binding, BindingResolver resolver) {
48 this.binding = binding;
49 this.resolver = resolver;
52 public IAnnotationBinding[] getAnnotations() {
54 INameEnvironment nameEnvironment = this.binding.environment.nameEnvironment;
55 if (!(nameEnvironment instanceof SearchableEnvironment))
56 return AnnotationBinding.NoAnnotations;
57 NameLookup nameLookup = ((SearchableEnvironment) nameEnvironment).nameLookup;
58 if (nameLookup == null)
59 return AnnotationBinding.NoAnnotations;
60 final String pkgName = getName();
61 IPackageFragment[] pkgs = nameLookup.findPackageFragments(pkgName, false/*exact match*/);
63 return AnnotationBinding.NoAnnotations;
65 for (int i = 0, len = pkgs.length; i < len; i++) {
66 int fragType = pkgs[i].getKind();
68 case IPackageFragmentRoot.K_SOURCE:
69 String unitName = "package-info.java"; //$NON-NLS-1$
70 ICompilationUnit unit = pkgs[i].getCompilationUnit(unitName);
71 if (unit != null && unit.exists()) {
72 ASTParser p = ASTParser.newParser(AST.JLS3);
74 p.setResolveBindings(true);
75 p.setUnitName(unitName);
76 p.setFocalPosition(0);
77 p.setKind(ASTParser.K_COMPILATION_UNIT);
78 CompilationUnit domUnit = (CompilationUnit) p.createAST(null);
79 PackageDeclaration pkgDecl = domUnit.getPackage();
80 if (pkgDecl != null) {
81 List annos = pkgDecl.annotations();
82 if (annos == null || annos.isEmpty())
83 return AnnotationBinding.NoAnnotations;
84 IAnnotationBinding[] result = new IAnnotationBinding[annos.size()];
86 for (Iterator it = annos.iterator(); it.hasNext(); index++) {
87 result[index] = ((Annotation) it.next()).resolveAnnotationBinding();
88 // not resolving bindings
89 if (result[index] == null)
90 return AnnotationBinding.NoAnnotations;
96 case IPackageFragmentRoot.K_BINARY:
97 NameEnvironmentAnswer answer =
98 nameEnvironment.findType(TypeConstants.PACKAGE_INFO_NAME, this.binding.compoundName);
99 if (answer != null && answer.isBinaryType()) {
100 IBinaryType type = answer.getBinaryType();
101 char[][][] missingTypeNames = type.getMissingTypeNames();
102 IBinaryAnnotation[] binaryAnnotations = type.getAnnotations();
103 net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding[] binaryInstances =
104 BinaryTypeBinding.createAnnotations(binaryAnnotations, this.binding.environment, missingTypeNames);
105 net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding[] allInstances =
106 net.sourceforge.phpdt.internal.compiler.lookup.AnnotationBinding.addStandardAnnotations(binaryInstances, type.getTagBits(), this.binding.environment);
107 int total = allInstances.length;
108 IAnnotationBinding[] domInstances = new AnnotationBinding[total];
109 for (int a = 0; a < total; a++) {
110 final IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(allInstances[a]);
111 if (annotationInstance == null) {// not resolving binding
112 return AnnotationBinding.NoAnnotations;
114 domInstances[a] = annotationInstance;
120 } catch(JavaModelException e) {
121 return AnnotationBinding.NoAnnotations;
123 return AnnotationBinding.NoAnnotations;
127 * @see IBinding#getName()
129 public String getName() {
131 computeNameAndComponents();
137 * @see IPackageBinding#isUnnamed()
139 public boolean isUnnamed() {
140 return getName().equals(UNNAMED);
144 * @see IPackageBinding#getNameComponents()
146 public String[] getNameComponents() {
147 if (components == null) {
148 computeNameAndComponents();
154 * @see IBinding#getKind()
156 public int getKind() {
157 return IBinding.PACKAGE;
161 * @see IBinding#getModifiers()
163 public int getModifiers() {
164 return Modifier.NONE;
168 * @see IBinding#isDeprecated()
170 public boolean isDeprecated() {
175 * @see IBinding#isRecovered()
177 public boolean isRecovered() {
182 * @see IBinding#isSynthetic()
184 public boolean isSynthetic() {
189 * @see IBinding#getJavaElement()
191 public IJavaElement getJavaElement() {
192 INameEnvironment nameEnvironment = this.binding.environment.nameEnvironment; // a package binding always has a LooupEnvironment set
193 if (!(nameEnvironment instanceof SearchableEnvironment)) return null;
194 NameLookup nameLookup = ((SearchableEnvironment) nameEnvironment).nameLookup;
195 if (nameLookup == null) return null;
196 IJavaElement[] pkgs = nameLookup.findPackageFragments(getName(), false/*exact match*/);
197 if (pkgs == null) return null;
202 * @see IBinding#getKey()
204 public String getKey() {
205 return new String(this.binding.computeUniqueKey());
209 * @see IBinding#isEqualTo(Binding)
212 public boolean isEqualTo(IBinding other) {
214 // identical binding - equal (key or no key)
218 // other binding missing
221 if (!(other instanceof PackageBinding)) {
224 net.sourceforge.phpdt.internal.compiler.lookup.PackageBinding packageBinding2 = ((PackageBinding) other).binding;
225 return CharOperation.equals(this.binding.compoundName, packageBinding2.compoundName);
228 private void computeNameAndComponents() {
229 char[][] compoundName = this.binding.compoundName;
230 if (compoundName == CharOperation.NO_CHAR_CHAR || compoundName == null) {
232 components = NO_NAME_COMPONENTS;
234 int length = compoundName.length;
235 components = new String[length];
236 StringBuffer buffer = new StringBuffer();
237 for (int i = 0; i < length - 1; i++) {
238 components[i] = new String(compoundName[i]);
239 buffer.append(compoundName[i]).append(PACKAGE_NAME_SEPARATOR);
241 components[length - 1] = new String(compoundName[length - 1]);
242 buffer.append(compoundName[length - 1]);
243 name = buffer.toString();
248 * For debugging purpose only.
249 * @see java.lang.Object#toString()
251 public String toString() {
252 return this.binding.toString();