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.ast.AnonymousLocalTypeDeclaration;
15 import net.sourceforge.phpdt.internal.compiler.util.Util;
17 public final class LocalTypeBinding extends NestedTypeBinding {
18 final static char[] LocalTypePrefix = { '$', 'L', 'o', 'c', 'a', 'l', '$' };
20 private InnerEmulationDependency[] dependents;
22 ArrayBinding[] localArrayBindings; // used to cache array bindings of
23 // various dimensions for this local
26 public LocalTypeBinding(ClassScope scope, SourceTypeBinding enclosingType) {
27 super(new char[][] { CharOperation.concat(LocalTypePrefix,
28 scope.referenceContext.name) }, scope, enclosingType);
30 if (this.sourceName == AnonymousLocalTypeDeclaration.ANONYMOUS_EMPTY_NAME)
31 this.tagBits |= AnonymousTypeMask;
33 this.tagBits |= LocalTypeMask;
37 * Record a dependency onto a source target type which may be altered by the
38 * end of the innerclass emulation. Later on, we will revisit all its
39 * dependents so as to update them (see updateInnerEmulationDependents()).
42 public void addInnerEmulationDependent(BlockScope scope,
43 boolean wasEnclosingInstanceSupplied) {
45 if (dependents == null) {
47 dependents = new InnerEmulationDependency[1];
49 index = dependents.length;
50 for (int i = 0; i < index; i++)
51 if (dependents[i].scope == scope)
52 return; // already stored
53 System.arraycopy(dependents, 0,
54 (dependents = new InnerEmulationDependency[index + 1]), 0,
57 dependents[index] = new InnerEmulationDependency(scope,
58 wasEnclosingInstanceSupplied);
59 // System.out.println("Adding dependency: "+ new
60 // String(scope.enclosingType().readableName()) + " --> " + new
61 // String(this.readableName()));
65 * Answer the receiver's constant pool name.
67 * NOTE: This method should only be used during/after code gen.
70 public char[] constantPoolName() /* java/lang/Object */{
71 return constantPoolName;
74 ArrayBinding createArrayType(int dimensionCount) {
75 if (localArrayBindings == null) {
76 localArrayBindings = new ArrayBinding[] { new ArrayBinding(this,
78 return localArrayBindings[0];
81 // find the cached array binding for this dimensionCount (if any)
82 int length = localArrayBindings.length;
83 for (int i = 0; i < length; i++)
84 if (localArrayBindings[i].dimensions == dimensionCount)
85 return localArrayBindings[i];
88 System.arraycopy(localArrayBindings, 0,
89 localArrayBindings = new ArrayBinding[length + 1], 0, length);
90 return localArrayBindings[length] = new ArrayBinding(this,
94 public char[] readableName() {
95 if (isAnonymousType()) {
96 if (superInterfaces == NoSuperInterfaces)
97 return ("<" + Util.bind("binding.subclass", new String(superclass.readableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
99 return ("<" + Util.bind("binding.implementation", new String(superInterfaces[0].readableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
100 } else if (isMemberType()) {
101 return CharOperation.concat(enclosingType().readableName(),
108 public char[] shortReadableName() {
109 if (isAnonymousType()) {
110 if (superInterfaces == NoSuperInterfaces)
111 return ("<" + Util.bind("binding.subclass", new String(superclass.shortReadableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
113 return ("<" + Util.bind("binding.implementation", new String(superInterfaces[0].shortReadableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
114 } else if (isMemberType()) {
115 return CharOperation.concat(enclosingType().shortReadableName(),
122 // Record that the type is a local member type
123 public void setAsMemberType() {
124 tagBits |= MemberTypeMask;
127 public void setConstantPoolName(char[] computedConstantPoolName) /* java/lang/Object */{
128 this.constantPoolName = computedConstantPoolName;
131 public char[] sourceName() {
132 if (isAnonymousType()) {
133 // return readableName();
134 if (superInterfaces == NoSuperInterfaces)
135 return ("<" + Util.bind("binding.subclass", new String(superclass.sourceName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
137 return ("<" + Util.bind("binding.implementation", new String(superInterfaces[0].sourceName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
143 public String toString() {
144 if (isAnonymousType())
145 return "Anonymous type : " + super.toString(); //$NON-NLS-1$
147 return "Local member type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
148 return "Local type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
152 * Trigger the dependency mechanism forcing the innerclass emulation to be
153 * propagated to all dependent source types.
156 public void updateInnerEmulationDependents() {
157 if (dependents != null) {
158 for (int i = 0; i < dependents.length; i++) {
159 InnerEmulationDependency dependency = dependents[i];
160 // System.out.println("Updating " + new
161 // String(this.readableName()) + " --> " + new
162 // String(dependency.scope.enclosingType().readableName()));
163 dependency.scope.propagateInnerEmulation(this,
164 dependency.wasEnclosingInstanceSupplied);