A massive organize imports and formatting of the sources using default Eclipse code...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / lookup / LocalTypeBinding.java
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
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.core.compiler.CharOperation;
14 import net.sourceforge.phpdt.internal.compiler.ast.AnonymousLocalTypeDeclaration;
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
22         ArrayBinding[] localArrayBindings; // used to cache array bindings of
23                                                                                 // various dimensions for this local
24                                                                                 // type
25
26         public LocalTypeBinding(ClassScope scope, SourceTypeBinding enclosingType) {
27                 super(new char[][] { CharOperation.concat(LocalTypePrefix,
28                                 scope.referenceContext.name) }, scope, enclosingType);
29
30                 if (this.sourceName == AnonymousLocalTypeDeclaration.ANONYMOUS_EMPTY_NAME)
31                         this.tagBits |= AnonymousTypeMask;
32                 else
33                         this.tagBits |= LocalTypeMask;
34         }
35
36         /*
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()).
40          */
41
42         public void addInnerEmulationDependent(BlockScope scope,
43                         boolean wasEnclosingInstanceSupplied) {
44                 int index;
45                 if (dependents == null) {
46                         index = 0;
47                         dependents = new InnerEmulationDependency[1];
48                 } else {
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,
55                                         index);
56                 }
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()));
62         }
63
64         /*
65          * Answer the receiver's constant pool name.
66          * 
67          * NOTE: This method should only be used during/after code gen.
68          */
69
70         public char[] constantPoolName() /* java/lang/Object */{
71                 return constantPoolName;
72         }
73
74         ArrayBinding createArrayType(int dimensionCount) {
75                 if (localArrayBindings == null) {
76                         localArrayBindings = new ArrayBinding[] { new ArrayBinding(this,
77                                         dimensionCount) };
78                         return localArrayBindings[0];
79                 }
80
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];
86
87                 // no matching array
88                 System.arraycopy(localArrayBindings, 0,
89                                 localArrayBindings = new ArrayBinding[length + 1], 0, length);
90                 return localArrayBindings[length] = new ArrayBinding(this,
91                                 dimensionCount);
92         }
93
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$
98                         else
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(),
102                                         sourceName, '.');
103                 } else {
104                         return sourceName;
105                 }
106         }
107
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$
112                         else
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(),
116                                         sourceName, '.');
117                 } else {
118                         return sourceName;
119                 }
120         }
121
122         // Record that the type is a local member type
123         public void setAsMemberType() {
124                 tagBits |= MemberTypeMask;
125         }
126
127         public void setConstantPoolName(char[] computedConstantPoolName) /* java/lang/Object */{
128                 this.constantPoolName = computedConstantPoolName;
129         }
130
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$
136                         else
137                                 return ("<" + Util.bind("binding.implementation", new String(superInterfaces[0].sourceName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
138
139                 } else
140                         return sourceName;
141         }
142
143         public String toString() {
144                 if (isAnonymousType())
145                         return "Anonymous type : " + super.toString(); //$NON-NLS-1$
146                 if (isMemberType())
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$
149         }
150
151         /*
152          * Trigger the dependency mechanism forcing the innerclass emulation to be
153          * propagated to all dependent source types.
154          */
155
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);
165                         }
166                 }
167         }
168 }