org.eclipse.jdt.internal.compiler.lookup.PackageBinding Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ecj Show documentation
Show all versions of ecj Show documentation
This is Eclipse JDT Core Batch Compiler used by Scout SDK
The newest version!
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contributions for
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
* bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.util.HashtableOfPackage;
import org.eclipse.jdt.internal.compiler.util.HashtableOfType;
public class PackageBinding extends Binding implements TypeConstants {
public long tagBits = 0; // See values in the interface TagBits below
public char[][] compoundName;
PackageBinding parent;
public LookupEnvironment environment;
HashtableOfType knownTypes;
HashtableOfPackage knownPackages;
// code representing the default that has been defined for this package (using @NonNullByDefault)
// one of Binding.{NO_NULL_DEFAULT,NULL_UNSPECIFIED_BY_DEFAULT,NONNULL_BY_DEFAULT}
protected int defaultNullness = NO_NULL_DEFAULT;
protected PackageBinding() {
// for creating problem package
}
public PackageBinding(char[] topLevelPackageName, LookupEnvironment environment) {
this(new char[][] {topLevelPackageName}, null, environment);
}
/* Create the default package.
*/
public PackageBinding(char[][] compoundName, PackageBinding parent, LookupEnvironment environment) {
this.compoundName = compoundName;
this.parent = parent;
this.environment = environment;
this.knownTypes = null; // initialized if used... class counts can be very large 300-600
this.knownPackages = new HashtableOfPackage(3); // sub-package counts are typically 0-3
if (compoundName != CharOperation.NO_CHAR_CHAR)
checkIfNullAnnotationPackage();
}
public PackageBinding(LookupEnvironment environment) {
this(CharOperation.NO_CHAR_CHAR, null, environment);
}
private void addNotFoundPackage(char[] simpleName) {
this.knownPackages.put(simpleName, LookupEnvironment.TheNotFoundPackage);
}
private void addNotFoundType(char[] simpleName) {
if (this.knownTypes == null)
this.knownTypes = new HashtableOfType(25);
this.knownTypes.put(simpleName, LookupEnvironment.TheNotFoundType);
}
void addPackage(PackageBinding element) {
if ((element.tagBits & TagBits.HasMissingType) == 0) clearMissingTagBit();
this.knownPackages.put(element.compoundName[element.compoundName.length - 1], element);
}
void addType(ReferenceBinding element) {
if ((element.tagBits & TagBits.HasMissingType) == 0) clearMissingTagBit();
if (this.knownTypes == null)
this.knownTypes = new HashtableOfType(25);
char [] name = element.compoundName[element.compoundName.length - 1];
ReferenceBinding priorType = this.knownTypes.getput(name, element);
if (priorType != null && priorType.isUnresolvedType() && !element.isUnresolvedType()) {
((UnresolvedReferenceBinding) priorType).setResolvedType(element, this.environment);
}
if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled)
if (element.isAnnotationType() || element instanceof UnresolvedReferenceBinding) // unresolved types don't yet have the modifiers set
checkIfNullAnnotationType(element);
}
void clearMissingTagBit() {
PackageBinding current = this;
do {
current.tagBits &= ~TagBits.HasMissingType;
} while ((current = current.parent) != null);
}
/*
* slash separated name
* org.eclipse.jdt.core --> org/eclipse/jdt/core
*/
public char[] computeUniqueKey(boolean isLeaf) {
return CharOperation.concatWith(this.compoundName, '/');
}
private PackageBinding findPackage(char[] name) {
if (!this.environment.isPackage(this.compoundName, name))
return null;
char[][] subPkgCompoundName = CharOperation.arrayConcat(this.compoundName, name);
PackageBinding subPackageBinding = new PackageBinding(subPkgCompoundName, this, this.environment);
addPackage(subPackageBinding);
return subPackageBinding;
}
/* Answer the subpackage named name; ask the oracle for the package if its not in the cache.
* Answer null if it could not be resolved.
*
* NOTE: This should only be used when we know there is NOT a type with the same name.
*/
PackageBinding getPackage(char[] name) {
PackageBinding binding = getPackage0(name);
if (binding != null) {
if (binding == LookupEnvironment.TheNotFoundPackage)
return null;
else
return binding;
}
if ((binding = findPackage(name)) != null)
return binding;
// not found so remember a problem package binding in the cache for future lookups
addNotFoundPackage(name);
return null;
}
/* Answer the subpackage named name if it exists in the cache.
* Answer theNotFoundPackage if it could not be resolved the first time
* it was looked up, otherwise answer null.
*
* NOTE: Senders must convert theNotFoundPackage into a real problem
* package if its to returned.
*/
PackageBinding getPackage0(char[] name) {
return this.knownPackages.get(name);
}
/* Answer the type named name; ask the oracle for the type if its not in the cache.
* Answer a NotVisible problem type if the type is not visible from the invocationPackage.
* Answer null if it could not be resolved.
*
* NOTE: This should only be used by source types/scopes which know there is NOT a
* package with the same name.
*/
ReferenceBinding getType(char[] name) {
ReferenceBinding referenceBinding = getType0(name);
if (referenceBinding == null) {
if ((referenceBinding = this.environment.askForType(this, name)) == null) {
// not found so remember a problem type binding in the cache for future lookups
addNotFoundType(name);
return null;
}
}
if (referenceBinding == LookupEnvironment.TheNotFoundType)
return null;
referenceBinding = (ReferenceBinding) BinaryTypeBinding.resolveType(referenceBinding, this.environment, false /* no raw conversion for now */);
if (referenceBinding.isNestedType())
return new ProblemReferenceBinding(new char[][]{ name }, referenceBinding, ProblemReasons.InternalNameProvided);
return referenceBinding;
}
/* Answer the type named name if it exists in the cache.
* Answer theNotFoundType if it could not be resolved the first time
* it was looked up, otherwise answer null.
*
* NOTE: Senders must convert theNotFoundType into a real problem
* reference type if its to returned.
*/
ReferenceBinding getType0(char[] name) {
if (this.knownTypes == null)
return null;
return this.knownTypes.get(name);
}
/* Answer the package or type named name; ask the oracle if it is not in the cache.
* Answer null if it could not be resolved.
*
* When collisions exist between a type name & a package name, answer the type.
* Treat the package as if it does not exist... a problem was already reported when the type was defined.
*
* NOTE: no visibility checks are performed.
* THIS SHOULD ONLY BE USED BY SOURCE TYPES/SCOPES.
*/
public Binding getTypeOrPackage(char[] name) {
ReferenceBinding referenceBinding = getType0(name);
if (referenceBinding != null && referenceBinding != LookupEnvironment.TheNotFoundType) {
referenceBinding = (ReferenceBinding) BinaryTypeBinding.resolveType(referenceBinding, this.environment, false /* no raw conversion for now */);
if (referenceBinding.isNestedType()) {
return new ProblemReferenceBinding(new char[][]{name}, referenceBinding, ProblemReasons.InternalNameProvided);
}
if ((referenceBinding.tagBits & TagBits.HasMissingType) == 0) {
return referenceBinding;
}
// referenceBinding is a MissingType, will return it if no package is found
}
PackageBinding packageBinding = getPackage0(name);
if (packageBinding != null && packageBinding != LookupEnvironment.TheNotFoundPackage) {
return packageBinding;
}
if (referenceBinding == null) { // have not looked for it before
if ((referenceBinding = this.environment.askForType(this, name)) != null) {
if (referenceBinding.isNestedType()) {
return new ProblemReferenceBinding(new char[][]{name}, referenceBinding, ProblemReasons.InternalNameProvided);
}
return referenceBinding;
}
// Since name could not be found, add a problem binding
// to the collections so it will be reported as an error next time.
addNotFoundType(name);
}
if (packageBinding == null) { // have not looked for it before
if ((packageBinding = findPackage(name)) != null) {
return packageBinding;
}
if (referenceBinding != null && referenceBinding != LookupEnvironment.TheNotFoundType) {
return referenceBinding; // found cached missing type - check if package conflict
}
addNotFoundPackage(name);
}
return null;
}
public final boolean isViewedAsDeprecated() {
if ((this.tagBits & TagBits.DeprecatedAnnotationResolved) == 0) {
this.tagBits |= TagBits.DeprecatedAnnotationResolved;
if (this.compoundName != CharOperation.NO_CHAR_CHAR) {
ReferenceBinding packageInfo = this.getType(TypeConstants.PACKAGE_INFO_NAME);
if (packageInfo != null) {
packageInfo.initializeDeprecatedAnnotationTagBits();
this.tagBits |= packageInfo.tagBits & TagBits.AllStandardAnnotationsMask;
}
}
}
return (this.tagBits & TagBits.AnnotationDeprecated) != 0;
}
/* API
* Answer the receiver's binding type from Binding.BindingID.
*/
public final int kind() {
return Binding.PACKAGE;
}
public int problemId() {
if ((this.tagBits & TagBits.HasMissingType) != 0)
return ProblemReasons.NotFound;
return ProblemReasons.NoError;
}
void checkIfNullAnnotationPackage() {
LookupEnvironment env = this.environment;
if (env.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
if (isPackageOfQualifiedTypeName(this.compoundName, env.getNullableAnnotationName()))
env.nullableAnnotationPackage = this;
if (isPackageOfQualifiedTypeName(this.compoundName, env.getNonNullAnnotationName()))
env.nonnullAnnotationPackage = this;
if (isPackageOfQualifiedTypeName(this.compoundName, env.getNonNullByDefaultAnnotationName()))
env.nonnullByDefaultAnnotationPackage = this;
}
}
private boolean isPackageOfQualifiedTypeName(char[][] packageName, char[][] typeName) {
int length;
if (typeName == null || (length = packageName.length) != typeName.length -1)
return false;
for (int i=0; i