/* * INTERNAL USE-ONLY * Innerclasses get their name computed as they are generated, since some may not * be actually outputed if sitting inside unreachable code. */ public char[] computeConstantPoolName(LocalTypeBinding localType) { if (localType.constantPoolName != null) { return localType.constantPoolName; } // delegates to the outermost enclosing classfile, since it is the only one with a global vision // of its innertypes. if (this.constantPoolNameUsage == null) this.constantPoolNameUsage = new HashtableOfType(); ReferenceBinding outerMostEnclosingType = localType.scope.outerMostClassScope().enclosingSourceType(); // ensure there is not already such a local type name defined by the user int index = 0; char[] candidateName; boolean isCompliant15 = compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5; while (true) { if (localType.isMemberType()) { if (index == 0) { candidateName = CharOperation.concat( localType.enclosingType().constantPoolName(), localType.sourceName, '$'); } else { // in case of collision, then member name gets extra $1 inserted // e.g. class X { { class L{} new X(){ class L{} } } } candidateName = CharOperation.concat( localType.enclosingType().constantPoolName(), '$', String.valueOf(index).toCharArray(), '$', localType.sourceName); } } else if (localType.isAnonymousType()) { if (isCompliant15) { // AspectJ Extension start char[] extraInsert = null; if (outerMostEnclosingType instanceof SourceTypeBinding) { SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) outerMostEnclosingType; ClassScope classScope = sourceTypeBinding.scope; if (classScope != null) { TypeDeclaration typeDeclaration = classScope.referenceContext; if (typeDeclaration != null) { extraInsert = typeDeclaration.getLocalTypeNameSuffix(); } } } if (extraInsert != null) { // AspectJ Extension end candidateName = CharOperation.concat( localType.enclosingType.constantPoolName(), '$', extraInsert, '$', String.valueOf(index + 1).toCharArray()); } else { // from 1.5 on, use immediately enclosing type name candidateName = CharOperation.concat( localType.enclosingType.constantPoolName(), String.valueOf(index + 1).toCharArray(), '$'); } // AspectJ extension, closing } } else { candidateName = CharOperation.concat( outerMostEnclosingType.constantPoolName(), String.valueOf(index + 1).toCharArray(), '$'); } } else { // local type if (isCompliant15) { candidateName = CharOperation.concat( CharOperation.concat( localType.enclosingType().constantPoolName(), String.valueOf(index + 1).toCharArray(), '$'), localType.sourceName); } else { candidateName = CharOperation.concat( outerMostEnclosingType.constantPoolName(), '$', String.valueOf(index + 1).toCharArray(), '$', localType.sourceName); } } if (this.constantPoolNameUsage.get(candidateName) != null) { index++; } else { this.constantPoolNameUsage.put(candidateName, localType); break; } } return candidateName; }