package org.eclipse.jdt.internal.compiler.lookup;
public abstract class NestedTypeBinding extends SourceTypeBinding {
public SourceTypeBinding enclosingType;
public SyntheticArgumentBinding[] enclosingInstances;
private ReferenceBinding[] enclosingTypes = Binding.UNINITIALIZED_REFERENCE_TYPES;
public SyntheticArgumentBinding[] outerLocalVariables;
private int outerLocalVariablesSlotSize = -1;
public NestedTypeBinding(char[][] typeName, ClassScope scope, SourceTypeBinding enclosingType) {
super(typeName, enclosingType.fPackage, scope);
this.tagBits |= (TagBits.IsNestedType | TagBits.ContainsNestedTypeReferences);
this.enclosingType = enclosingType;
}
public NestedTypeBinding(NestedTypeBinding prototype) {
super(prototype);
this.enclosingType = prototype.enclosingType;
this.enclosingInstances = prototype.enclosingInstances;
this.enclosingTypes = prototype.enclosingTypes;
this.outerLocalVariables = prototype.outerLocalVariables;
this.outerLocalVariablesSlotSize = prototype.outerLocalVariablesSlotSize;
}
public SyntheticArgumentBinding addSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) {
if (!isPrototype()) throw new IllegalStateException();
SyntheticArgumentBinding synthLocal = null;
if (this.outerLocalVariables == null) {
synthLocal = new SyntheticArgumentBinding(actualOuterLocalVariable);
this.outerLocalVariables = new SyntheticArgumentBinding[] {synthLocal};
} else {
int size = this.outerLocalVariables.length;
int newArgIndex = size;
for (int i = size; --i >= 0;) {
if (this.outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
return this.outerLocalVariables[i];
if (this.outerLocalVariables[i].id > actualOuterLocalVariable.id)
newArgIndex = i;
}
SyntheticArgumentBinding[] synthLocals = new SyntheticArgumentBinding[size + 1];
System.arraycopy(this.outerLocalVariables, 0, synthLocals, 0, newArgIndex);
synthLocals[newArgIndex] = synthLocal = new SyntheticArgumentBinding(actualOuterLocalVariable);
System.arraycopy(this.outerLocalVariables, newArgIndex, synthLocals, newArgIndex + 1, size - newArgIndex);
this.outerLocalVariables = synthLocals;
}
if (this.scope.referenceCompilationUnit().isPropagatingInnerClassEmulation)
updateInnerEmulationDependents();
return synthLocal;
}
public SyntheticArgumentBinding addSyntheticArgument(ReferenceBinding targetEnclosingType) {
if (!isPrototype()) throw new IllegalStateException();
SyntheticArgumentBinding synthLocal = null;
if (this.enclosingInstances == null) {
synthLocal = new SyntheticArgumentBinding(targetEnclosingType);
this.enclosingInstances = new SyntheticArgumentBinding[] {synthLocal};
} else {
int size = this.enclosingInstances.length;
int newArgIndex = size;
if (TypeBinding.equalsEquals(enclosingType(), targetEnclosingType))
newArgIndex = 0;
SyntheticArgumentBinding[] newInstances = new SyntheticArgumentBinding[size + 1];
System.arraycopy(this.enclosingInstances, 0, newInstances, newArgIndex == 0 ? 1 : 0, size);
newInstances[newArgIndex] = synthLocal = new SyntheticArgumentBinding(targetEnclosingType);
this.enclosingInstances = newInstances;
}
if (this.scope.referenceCompilationUnit().isPropagatingInnerClassEmulation)
updateInnerEmulationDependents();
return synthLocal;
}
public SyntheticArgumentBinding addSyntheticArgumentAndField(LocalVariableBinding actualOuterLocalVariable) {
if (!isPrototype()) throw new IllegalStateException();
SyntheticArgumentBinding synthLocal = addSyntheticArgument(actualOuterLocalVariable);
if (synthLocal == null) return null;
if (synthLocal.matchingField == null)
synthLocal.matchingField = addSyntheticFieldForInnerclass(actualOuterLocalVariable);
return synthLocal;
}
public SyntheticArgumentBinding addSyntheticArgumentAndField(ReferenceBinding targetEnclosingType) {
if (!isPrototype()) throw new IllegalStateException();
SyntheticArgumentBinding synthLocal = addSyntheticArgument(targetEnclosingType);
if (synthLocal == null) return null;
if (synthLocal.matchingField == null)
synthLocal.matchingField = addSyntheticFieldForInnerclass(targetEnclosingType);
return synthLocal;
}
@Override
public ReferenceBinding enclosingType() {
return this.enclosingType;
}
@Override
public int getEnclosingInstancesSlotSize() {
if (!isPrototype()) throw new IllegalStateException();
return this.enclosingInstances == null ? 0 : this.enclosingInstances.length;
}
@Override
public int getOuterLocalVariablesSlotSize() {
if (!isPrototype()) throw new IllegalStateException();
if (this.outerLocalVariablesSlotSize < 0) {
this.outerLocalVariablesSlotSize = 0;
int outerLocalsCount = this.outerLocalVariables == null ? 0 : this.outerLocalVariables.length;
for (int i = 0; i < outerLocalsCount; i++){
SyntheticArgumentBinding argument = this.outerLocalVariables[i];
switch (argument.type.id) {
case TypeIds.T_long :
case TypeIds.T_double :
this.outerLocalVariablesSlotSize += 2;
break;
default :
this.outerLocalVariablesSlotSize ++;
break;
}
}
}
return this.outerLocalVariablesSlotSize;
}
public SyntheticArgumentBinding getSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) {
if (!isPrototype()) throw new IllegalStateException();
if (this.outerLocalVariables == null) return null;
for (int i = this.outerLocalVariables.length; --i >= 0;)
if (this.outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
return this.outerLocalVariables[i];
return null;
}
public SyntheticArgumentBinding getSyntheticArgument(ReferenceBinding targetEnclosingType, boolean onlyExactMatch, boolean scopeIsConstructorCall) {
if (!isPrototype()) throw new IllegalStateException();
if (this.enclosingInstances == null) return null;
if (scopeIsConstructorCall && this.enclosingInstances.length > 0)
if (TypeBinding.equalsEquals(this.enclosingInstances[0].type, targetEnclosingType))
if (this.enclosingInstances[0].actualOuterLocalVariable == null)
return this.enclosingInstances[0];
for (int i = this.enclosingInstances.length; --i >= 0;)
if (TypeBinding.equalsEquals(this.enclosingInstances[i].type, targetEnclosingType))
if (this.enclosingInstances[i].actualOuterLocalVariable == null)
return this.enclosingInstances[i];
if (!onlyExactMatch){
for (int i = this.enclosingInstances.length; --i >= 0;)
if (this.enclosingInstances[i].actualOuterLocalVariable == null)
if (this.enclosingInstances[i].type.findSuperTypeOriginatingFrom(targetEnclosingType) != null)
return this.enclosingInstances[i];
}
return null;
}
public SyntheticArgumentBinding[] syntheticEnclosingInstances() {
if (!isPrototype()) throw new IllegalStateException();
return this.enclosingInstances;
}
@Override
public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
if (!isPrototype()) throw new IllegalStateException();
if (this.enclosingTypes == UNINITIALIZED_REFERENCE_TYPES) {
if (this.enclosingInstances == null) {
this.enclosingTypes = null;
} else {
int length = this.enclosingInstances.length;
this.enclosingTypes = new ReferenceBinding[length];
for (int i = 0; i < length; i++) {
this.enclosingTypes[i] = (ReferenceBinding) this.enclosingInstances[i].type;
}
}
}
return this.enclosingTypes;
}
@Override
public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
if (!isPrototype()) throw new IllegalStateException();
return this.outerLocalVariables;
}
public void updateInnerEmulationDependents() {
}
}