package org.eclipse.jdt.core.dom;
import java.util.Arrays;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.jdt.internal.core.NameLookup;
import org.eclipse.jdt.internal.core.NameLookup.Answer;
import org.eclipse.jdt.internal.core.SearchableEnvironment;
class ModuleBinding implements IModuleBinding {
protected static final ITypeBinding[] NO_TYPE_BINDINGS = new ITypeBinding[0];
private String name = null;
private volatile String key;
private boolean isOpen = false;
private org.eclipse.jdt.internal.compiler.lookup.ModuleBinding binding;
protected BindingResolver resolver;
private IAnnotationBinding[] annotations;
private IModuleBinding[] requiredModules;
private IPackageBinding[] exports;
private IPackageBinding[] opens;
private ITypeBinding[] uses;
private ITypeBinding[] services;
ModuleBinding(BindingResolver resolver, org.eclipse.jdt.internal.compiler.lookup.ModuleBinding binding) {
this.resolver = resolver;
this.binding = binding;
this.isOpen = binding.isOpen();
}
@Override
public IAnnotationBinding[] getAnnotations() {
if (this.annotations == null) {
this.annotations = resolveAnnotationBindings(this.binding.getAnnotations());
}
return this.annotations;
}
private IAnnotationBinding[] resolveAnnotationBindings(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] internalAnnotations) {
int length = internalAnnotations == null ? 0 : internalAnnotations.length;
if (length != 0) {
IAnnotationBinding[] tempAnnotations = new IAnnotationBinding[length];
int convertedAnnotationCount = 0;
for (int i = 0; i < length; i++) {
org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalAnnotation = internalAnnotations[i];
if (internalAnnotation == null)
break;
IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(internalAnnotation);
if (annotationInstance == null)
continue;
tempAnnotations[convertedAnnotationCount++] = annotationInstance;
}
if (convertedAnnotationCount != length) {
if (convertedAnnotationCount == 0) {
return this.annotations = AnnotationBinding.NoAnnotations;
}
System.arraycopy(tempAnnotations, 0, (tempAnnotations = new IAnnotationBinding[convertedAnnotationCount]), 0, convertedAnnotationCount);
}
return tempAnnotations;
}
return AnnotationBinding.NoAnnotations;
}
@Override
public String getName() {
if (this.name == null) {
char[] tmp = this.binding.moduleName;
return tmp != null && tmp.length != 0 ? new String(tmp) : Util.EMPTY_STRING;
}
return this.name;
}
@Override
public int getModifiers() {
return 0;
}
@Override
public boolean isDeprecated() {
return false;
}
@Override
public boolean isRecovered() {
return false;
}
@Override
public boolean isSynthetic() {
return false;
}
@Override
public IJavaElement getJavaElement() {
INameEnvironment nameEnvironment = this.binding.environment.nameEnvironment;
if (!(nameEnvironment instanceof SearchableEnvironment)) return null;
NameLookup nameLookup = ((SearchableEnvironment) nameEnvironment).nameLookup;
if (nameLookup == null) return null;
Answer answer = nameLookup.findModule(this.getName().toCharArray());
if (answer == null) return null;
return answer.module;
}
@Override
public String getKey() {
if (this.key == null) {
char[] k = this.binding.computeUniqueKey();
this.key = k == null || k == CharOperation.NO_CHAR ? Util.EMPTY_STRING : new String(k);
}
return this.key;
}
@Override
public boolean isEqualTo(IBinding other) {
if (other == this)
return true;
if (other == null)
return false;
if (!(other instanceof ModuleBinding))
return false;
org.eclipse.jdt.internal.compiler.lookup.ModuleBinding otherBinding = ((ModuleBinding) other).binding;
return BindingComparator.isEqual(this.binding, otherBinding);
}
@Override
public boolean isOpen() {
return this.isOpen;
}
@Override
public IModuleBinding[] getRequiredModules() {
if (this.requiredModules != null)
return this.requiredModules;
org.eclipse.jdt.internal.compiler.lookup.ModuleBinding[] reqs = this.binding.getRequires();
IModuleBinding[] result = new IModuleBinding[reqs != null ? reqs.length : 0];
for (int i = 0, l = result.length; i < l; ++i) {
org.eclipse.jdt.internal.compiler.lookup.ModuleBinding req = reqs[i];
result[i] = req != null ? this.resolver.getModuleBinding(req) : null;
}
return this.requiredModules = result;
}
@Override
public IPackageBinding[] getExportedPackages() {
if (this.exports == null) {
org.eclipse.jdt.internal.compiler.lookup.PackageBinding[] compilerExports = this.binding.getExports();
this.exports = Arrays.stream(compilerExports)
.map(e -> this.resolver.getPackageBinding(e))
.toArray(IPackageBinding[]::new);
}
return this.exports;
}
@Override
public String[] getExportedTo(IPackageBinding packageBinding) {
return this.binding.getExportRestrictions(((PackageBinding) packageBinding).getCompilerBinding());
}
@Override
public IPackageBinding[] getOpenedPackages() {
if (this.opens == null) {
org.eclipse.jdt.internal.compiler.lookup.PackageBinding[] compilerOpens = this.binding.getOpens();
this.opens = Arrays.stream(compilerOpens)
.map(o -> this.resolver.getPackageBinding(o))
.toArray(IPackageBinding[]::new);
}
return this.opens;
}
@Override
public String[] getOpenedTo(IPackageBinding packageBinding) {
return this.binding.getOpenRestrictions(((PackageBinding) packageBinding).getCompilerBinding());
}
private ITypeBinding[] getTypes(org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] types) {
int length = types == null ? 0 : types.length;
TypeBinding[] result = new TypeBinding[length];
for (int i = 0; i < length; ++i) {
result[i] = (TypeBinding) this.resolver.getTypeBinding(types[i]);
}
return result;
}
@Override
public ITypeBinding[] getUses() {
if (this.uses == null)
this.uses = getTypes(this.binding.getUses());
return this.uses;
}
@Override
public ITypeBinding[] getServices() {
if (this.services == null)
this.services = getTypes(this.binding.getServices());
return this.services;
}
@Override
public ITypeBinding[] getImplementations(ITypeBinding service) {
return getTypes(this.binding.getImplementations(((TypeBinding) service).binding));
}
@Override
public String toString() {
return this.binding.toString();
}
}