Makefile fixup
[org.ibex.tool.git] / repo / org.ibex.tool / src / org / eclipse / jdt / internal / compiler / lookup / LocalTypeBinding.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 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 org.eclipse.jdt.internal.compiler.lookup;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
15 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
16 import org.eclipse.jdt.internal.compiler.util.Util;
17
18 public final class LocalTypeBinding extends NestedTypeBinding {
19         final static char[] LocalTypePrefix = { '$', 'L', 'o', 'c', 'a', 'l', '$' };
20
21         private InnerEmulationDependency[] dependents;
22         public ArrayBinding[] localArrayBindings; // used to cache array bindings of various dimensions for this local type
23         public CaseStatement switchCase; // from 1.4 on, local types should not be accessed across switch case blocks (52221)
24         
25 public LocalTypeBinding(ClassScope scope, SourceTypeBinding enclosingType, CaseStatement switchCase) {
26         super(
27                 new char[][] {CharOperation.concat(LocalTypePrefix, scope.referenceContext.name)},
28                 scope,
29                 enclosingType);
30         
31         if (this.sourceName == TypeDeclaration.ANONYMOUS_EMPTY_NAME)
32                 this.tagBits |= AnonymousTypeMask;
33         else
34                 this.tagBits |= LocalTypeMask;
35         this.switchCase = switchCase;
36 }
37 /* Record a dependency onto a source target type which may be altered
38 * by the end of the innerclass emulation. Later on, we will revisit
39 * all its dependents so as to update them (see updateInnerEmulationDependents()).
40 */
41
42 public void addInnerEmulationDependent(BlockScope dependentScope, boolean wasEnclosingInstanceSupplied) {
43         int index;
44         if (dependents == null) {
45                 index = 0;
46                 dependents = new InnerEmulationDependency[1];
47         } else {
48                 index = dependents.length;
49                 for (int i = 0; i < index; i++)
50                         if (dependents[i].scope == dependentScope)
51                                 return; // already stored
52                 System.arraycopy(dependents, 0, (dependents = new InnerEmulationDependency[index + 1]), 0, index);
53         }
54         dependents[index] = new InnerEmulationDependency(dependentScope, wasEnclosingInstanceSupplied);
55         //  System.out.println("Adding dependency: "+ new String(scope.enclosingType().readableName()) + " --> " + new String(this.readableName()));
56 }
57 /* Answer the receiver's constant pool name.
58 *
59 * NOTE: This method should only be used during/after code gen.
60 */
61
62 public char[] constantPoolName() /* java/lang/Object */ {
63         return constantPoolName;
64 }
65
66 ArrayBinding createArrayType(int dimensionCount) {
67         if (localArrayBindings == null) {
68                 localArrayBindings = new ArrayBinding[] {new ArrayBinding(this, dimensionCount)};
69                 return localArrayBindings[0];
70         }
71
72         // find the cached array binding for this dimensionCount (if any)
73         int length = localArrayBindings.length;
74         for (int i = 0; i < length; i++)
75                 if (localArrayBindings[i].dimensions == dimensionCount)
76                         return localArrayBindings[i];
77
78         // no matching array
79         System.arraycopy(localArrayBindings, 0, localArrayBindings = new ArrayBinding[length + 1], 0, length); 
80         return localArrayBindings[length] = new ArrayBinding(this, dimensionCount);
81 }
82
83 public char[] readableName() {
84         if (isAnonymousType()) {
85                 if (superInterfaces == NoSuperInterfaces)
86                         return ("<"+Util.bind("binding.subclass",new String(superclass.readableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
87                 else
88                         return ("<"+Util.bind("binding.implementation",new String(superInterfaces[0].readableName())) + ">").toCharArray();                      //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
89         } else if (isMemberType()) {
90                 return CharOperation.concat(enclosingType().readableName(), sourceName, '.');
91         } else {
92                 return sourceName;
93         }
94 }
95
96 public char[] shortReadableName() {
97         if (isAnonymousType()) {
98                 if (superInterfaces == NoSuperInterfaces)
99                         return ("<"+Util.bind("binding.subclass",new String(superclass.shortReadableName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
100                 else
101                         return ("<"+Util.bind("binding.implementation",new String(superInterfaces[0].shortReadableName())) + ">").toCharArray();                         //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
102         } else if (isMemberType()) {
103                 return CharOperation.concat(enclosingType().shortReadableName(), sourceName, '.');
104         } else {
105                 return sourceName;
106         }
107 }
108
109 // Record that the type is a local member type
110 public void setAsMemberType() {
111         tagBits |= MemberTypeMask;
112 }
113
114 public void setConstantPoolName(char[] computedConstantPoolName) /* java/lang/Object */ {
115         this.constantPoolName = computedConstantPoolName;
116 }
117
118 public char[] sourceName() {
119         if (isAnonymousType()) {
120                 //return readableName();
121                 if (superInterfaces == NoSuperInterfaces)
122                         return ("<"+Util.bind("binding.subclass",new String(superclass.sourceName())) + ">").toCharArray(); //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
123                 else
124                         return ("<"+Util.bind("binding.implementation",new String(superInterfaces[0].sourceName())) + ">").toCharArray();                        //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
125                         
126         } else
127                 return sourceName;
128 }
129 public String toString() {
130         if (isAnonymousType())
131                 return "Anonymous type : " + super.toString(); //$NON-NLS-1$
132         if (isMemberType())
133                 return "Local member type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
134         return "Local type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
135 }
136 /* Trigger the dependency mechanism forcing the innerclass emulation
137 * to be propagated to all dependent source types.
138 */
139
140 public void updateInnerEmulationDependents() {
141         if (dependents != null) {
142                 for (int i = 0; i < dependents.length; i++) {
143                         InnerEmulationDependency dependency = dependents[i];
144                         // System.out.println("Updating " + new String(this.readableName()) + " --> " + new String(dependency.scope.enclosingType().readableName()));
145                         dependency.scope.propagateInnerEmulation(this, dependency.wasEnclosingInstanceSupplied);
146                 }
147         }
148 }
149 }