1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.lookup;
13 import net.sourceforge.phpdt.core.compiler.CharOperation;
14 import net.sourceforge.phpdt.internal.compiler.util.Util;
15 import net.sourceforge.phpeclipse.internal.compiler.ast.AnonymousLocalTypeDeclaration;
17 public final class LocalTypeBinding extends NestedTypeBinding {
18 final static char[] LocalTypePrefix = { '$', 'L', 'o', 'c', 'a', 'l', '$' };
20 private InnerEmulationDependency[] dependents;
21 ArrayBinding[] localArrayBindings; // used to cache array bindings of various dimensions for this local type
23 public LocalTypeBinding(ClassScope scope, SourceTypeBinding enclosingType) {
25 new char[][] {CharOperation.concat(LocalTypePrefix, scope.referenceContext.name)},
29 if (this.sourceName == AnonymousLocalTypeDeclaration.ANONYMOUS_EMPTY_NAME)
30 this.tagBits |= AnonymousTypeMask;
32 this.tagBits |= LocalTypeMask;
34 /* Record a dependency onto a source target type which may be altered
35 * by the end of the innerclass emulation. Later on, we will revisit
36 * all its dependents so as to update them (see updateInnerEmulationDependents()).
39 public void addInnerEmulationDependent(BlockScope scope, boolean wasEnclosingInstanceSupplied) {
41 if (dependents == null) {
43 dependents = new InnerEmulationDependency[1];
45 index = dependents.length;
46 for (int i = 0; i < index; i++)
47 if (dependents[i].scope == scope)
48 return; // already stored
49 System.arraycopy(dependents, 0, (dependents = new InnerEmulationDependency[index + 1]), 0, index);
51 dependents[index] = new InnerEmulationDependency(scope, wasEnclosingInstanceSupplied);
52 // System.out.println("Adding dependency: "+ new String(scope.enclosingType().readableName()) + " --> " + new String(this.readableName()));
54 /* Answer the receiver's constant pool name.
56 * NOTE: This method should only be used during/after code gen.
59 public char[] constantPoolName() /* java/lang/Object */ {
60 return constantPoolName;
63 ArrayBinding createArrayType(int dimensionCount) {
64 if (localArrayBindings == null) {
65 localArrayBindings = new ArrayBinding[] {new ArrayBinding(this, dimensionCount)};
66 return localArrayBindings[0];
69 // find the cached array binding for this dimensionCount (if any)
70 int length = localArrayBindings.length;
71 for (int i = 0; i < length; i++)
72 if (localArrayBindings[i].dimensions == dimensionCount)
73 return localArrayBindings[i];
76 System.arraycopy(localArrayBindings, 0, localArrayBindings = new ArrayBinding[length + 1], 0, length);
77 return localArrayBindings[length] = new ArrayBinding(this, dimensionCount);
80 public char[] readableName() {
81 if (isAnonymousType()) {
82 if (superInterfaces == NoSuperInterfaces)
83 return ("<"+Util.bind("binding.subclass",new String(superclass.readableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
85 return ("<"+Util.bind("binding.implementation",new String(superInterfaces[0].readableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
86 } else if (isMemberType()) {
87 return CharOperation.concat(enclosingType().readableName(), sourceName, '.');
93 public char[] shortReadableName() {
94 if (isAnonymousType()) {
95 if (superInterfaces == NoSuperInterfaces)
96 return ("<"+Util.bind("binding.subclass",new String(superclass.shortReadableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
98 return ("<"+Util.bind("binding.implementation",new String(superInterfaces[0].shortReadableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
99 } else if (isMemberType()) {
100 return CharOperation.concat(enclosingType().shortReadableName(), sourceName, '.');
106 // Record that the type is a local member type
107 public void setAsMemberType() {
108 tagBits |= MemberTypeMask;
111 public void setConstantPoolName(char[] computedConstantPoolName) /* java/lang/Object */ {
112 this.constantPoolName = computedConstantPoolName;
115 public char[] sourceName() {
116 if (isAnonymousType()) {
117 //return readableName();
118 if (superInterfaces == NoSuperInterfaces)
119 return ("<"+Util.bind("binding.subclass",new String(superclass.sourceName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
121 return ("<"+Util.bind("binding.implementation",new String(superInterfaces[0].sourceName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
126 public String toString() {
127 if (isAnonymousType())
128 return "Anonymous type : " + super.toString(); //$NON-NLS-1$
130 return "Local member type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
131 return "Local type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
133 /* Trigger the dependency mechanism forcing the innerclass emulation
134 * to be propagated to all dependent source types.
137 public void updateInnerEmulationDependents() {
138 if (dependents != null) {
139 for (int i = 0; i < dependents.length; i++) {
140 InnerEmulationDependency dependency = dependents[i];
141 // System.out.println("Updating " + new String(this.readableName()) + " --> " + new String(dependency.scope.enclosingType().readableName()));
142 dependency.scope.propagateInnerEmulation(this, dependency.wasEnclosingInstanceSupplied);