681d714905a40ddcaa6a9a48f1a4ee85043efc7b
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / lookup / LocalTypeBinding.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v0.5 
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v05.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.lookup;
12
13 import net.sourceforge.phpdt.internal.compiler.ast.AnonymousLocalTypeDeclaration;
14 import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
15 import net.sourceforge.phpdt.internal.compiler.util.Util;
16
17 public final class LocalTypeBinding extends NestedTypeBinding {
18         final static char[] LocalTypePrefix = { '$', 'L', 'o', 'c', 'a', 'l', '$' };
19
20         private InnerEmulationDependency[] dependents;
21 public LocalTypeBinding(ClassScope scope, SourceTypeBinding enclosingType) {
22         super(
23                 new char[][] {CharOperation.concat(LocalTypePrefix, scope.referenceContext.name)},
24                 scope,
25                 enclosingType);
26
27         if (this.sourceName == AnonymousLocalTypeDeclaration.ANONYMOUS_EMPTY_NAME)
28                 this.tagBits |= AnonymousTypeMask;
29         else
30                 this.tagBits |= LocalTypeMask;
31 }
32 /* Record a dependency onto a source target type which may be altered
33 * by the end of the innerclass emulation. Later on, we will revisit
34 * all its dependents so as to update them (see updateInnerEmulationDependents()).
35 */
36
37 public void addInnerEmulationDependent(BlockScope scope, boolean wasEnclosingInstanceSupplied, boolean useDirectAccess) {
38         int index;
39         if (dependents == null) {
40                 index = 0;
41                 dependents = new InnerEmulationDependency[1];
42         } else {
43                 index = dependents.length;
44                 for (int i = 0; i < index; i++)
45                         if (dependents[i].scope == scope)
46                                 return; // already stored
47                 System.arraycopy(dependents, 0, (dependents = new InnerEmulationDependency[index + 1]), 0, index);
48         }
49         dependents[index] = new InnerEmulationDependency(scope, wasEnclosingInstanceSupplied, useDirectAccess);
50         //  System.out.println("Adding dependency: "+ new String(scope.enclosingType().readableName()) + " --> " + new String(this.readableName()));
51 }
52 /* Answer the receiver's constant pool name.
53 *
54 * NOTE: This method should only be used during/after code gen.
55 */
56
57 public char[] constantPoolName() /* java/lang/Object */ {
58         return constantPoolName;
59 }
60 public void constantPoolName(char[] computedConstantPoolName) /* java/lang/Object */ {
61         this.constantPoolName = computedConstantPoolName;
62 }
63 public char[] readableName() {
64         if (isAnonymousType()) {
65                 if (superInterfaces == NoSuperInterfaces)
66                         return ("<"+Util.bind("binding.subclass",new String(superclass.readableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
67                 else
68                         return ("<"+Util.bind("binding.implementation",new String(superInterfaces[0].readableName())) + ">").toCharArray();                      //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
69         } else if (isMemberType()) {
70                 return CharOperation.concat(enclosingType().readableName(), sourceName, '.');
71         } else {
72                 return sourceName;
73         }
74 }
75 // Record that the type is a local member type
76
77 public void setAsMemberType() {
78         tagBits |= MemberTypeMask;
79 }
80 public char[] sourceName() {
81         if (isAnonymousType())
82                 return readableName();
83         else
84                 return sourceName;
85 }
86 public String toString() {
87         if (isAnonymousType())
88                 return "Anonymous type : " + super.toString(); //$NON-NLS-1$
89         if (isMemberType())
90                 return "Local member type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
91         return "Local type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
92 }
93 /* Trigger the dependency mechanism forcing the innerclass emulation
94 * to be propagated to all dependent source types.
95 */
96
97 public void updateInnerEmulationDependents() {
98         if (dependents != null) {
99                 for (int i = 0; i < dependents.length; i++) {
100                         InnerEmulationDependency dependency = dependents[i];
101                         // System.out.println("Updating " + new String(this.readableName()) + " --> " + new String(dependency.scope.enclosingType().readableName()));
102                         dependency.scope.propagateInnerEmulation(this, dependency.wasEnclosingInstanceSupplied, dependency.useDirectAccess);
103                 }
104         }
105 }
106 }