KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > eval > CodeSnippetClassFile


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.eval;
12
13 import org.eclipse.jdt.core.compiler.CategorizedProblem;
14 import org.eclipse.jdt.internal.compiler.ClassFile;
15 import org.eclipse.jdt.internal.compiler.CompilationResult;
16 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
17 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
18 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
19 import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
20 import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
21 import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream;
22 import org.eclipse.jdt.internal.compiler.lookup.Binding;
23 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
24 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
25 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
26 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
27
28 public class CodeSnippetClassFile extends ClassFile {
29 /**
30  * CodeSnippetClassFile constructor comment.
31  * @param aType org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding
32  * @param enclosingClassFile org.eclipse.jdt.internal.compiler.ClassFile
33  * @param creatingProblemType boolean
34  */

35 public CodeSnippetClassFile(
36     org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding aType,
37     org.eclipse.jdt.internal.compiler.ClassFile enclosingClassFile,
38     boolean creatingProblemType) {
39     /**
40      * INTERNAL USE-ONLY
41      * This methods creates a new instance of the receiver.
42      *
43      * @param aType org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding
44      * @param enclosingClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
45      * @param creatingProblemType <CODE>boolean</CODE>
46      */

47     this.referenceBinding = aType;
48     initByteArrays();
49     // generate the magic numbers inside the header
50
this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 24);
51     this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 16);
52     this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 8);
53     this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 0);
54
55     this.targetJDK = this.referenceBinding.scope.compilerOptions().targetJDK;
56     this.header[this.headerOffset++] = (byte) (targetJDK >> 8); // minor high
57
this.header[this.headerOffset++] = (byte) (targetJDK >> 0); // minor low
58
this.header[this.headerOffset++] = (byte) (targetJDK >> 24); // major high
59
this.header[this.headerOffset++] = (byte) (targetJDK >> 16); // major low
60

61     this.constantPoolOffset = this.headerOffset;
62     this.headerOffset += 2;
63     this.constantPool = new ConstantPool(this);
64     int accessFlags = aType.getAccessFlags();
65     
66     if (!aType.isInterface()) { // class or enum
67
accessFlags |= ClassFileConstants.AccSuper;
68     }
69     if (aType.isNestedType()) {
70         if (aType.isStatic()) {
71             // clear Acc_Static
72
accessFlags &= ~ClassFileConstants.AccStatic;
73         }
74         if (aType.isPrivate()) {
75             // clear Acc_Private and Acc_Public
76
accessFlags &= ~(ClassFileConstants.AccPrivate | ClassFileConstants.AccPublic);
77         }
78         if (aType.isProtected()) {
79             // clear Acc_Protected and set Acc_Public
80
accessFlags &= ~ClassFileConstants.AccProtected;
81             accessFlags |= ClassFileConstants.AccPublic;
82         }
83     }
84     // clear Acc_Strictfp
85
accessFlags &= ~ClassFileConstants.AccStrictfp;
86
87     this.enclosingClassFile = enclosingClassFile;
88     // now we continue to generate the bytes inside the contents array
89
this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
90     this.contents[this.contentsOffset++] = (byte) accessFlags;
91     int classNameIndex = this.constantPool.literalIndexForType(aType);
92     this.contents[this.contentsOffset++] = (byte) (classNameIndex >> 8);
93     this.contents[this.contentsOffset++] = (byte) classNameIndex;
94     int superclassNameIndex;
95     if (aType.isInterface()) {
96         superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName);
97     } else {
98         superclassNameIndex =
99             (aType.superclass == null ? 0 : this.constantPool.literalIndexForType(aType.superclass));
100     }
101     this.contents[this.contentsOffset++] = (byte) (superclassNameIndex >> 8);
102     this.contents[this.contentsOffset++] = (byte) superclassNameIndex;
103     ReferenceBinding[] superInterfacesBinding = aType.superInterfaces();
104     int interfacesCount = superInterfacesBinding.length;
105     this.contents[this.contentsOffset++] = (byte) (interfacesCount >> 8);
106     this.contents[this.contentsOffset++] = (byte) interfacesCount;
107     for (int i = 0; i < interfacesCount; i++) {
108         int interfaceIndex = this.constantPool.literalIndexForType(superInterfacesBinding[i]);
109         this.contents[this.contentsOffset++] = (byte) (interfaceIndex >> 8);
110         this.contents[this.contentsOffset++] = (byte) interfaceIndex;
111     }
112     this.produceAttributes = this.referenceBinding.scope.compilerOptions().produceDebugAttributes;
113     this.creatingProblemType = creatingProblemType;
114     if (this.targetJDK >= ClassFileConstants.JDK1_6) {
115         this.codeStream = new StackMapFrameCodeStream(this);
116         this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP;
117     } else {
118         this.codeStream = new CodeStream(this);
119     }
120     // retrieve the enclosing one guaranteed to be the one matching the propagated flow info
121
// 1FF9ZBU: LFCOM:ALL - Local variable attributes busted (Sanity check)
122
if (this.enclosingClassFile == null) {
123         this.codeStream.maxFieldCount = aType.scope.referenceType().maxFieldCount;
124     } else {
125         ClassFile outermostClassFile = this.outerMostEnclosingClassFile();
126         this.codeStream.maxFieldCount = outermostClassFile.codeStream.maxFieldCount;
127     }
128 }
129 /**
130  * INTERNAL USE-ONLY
131  * Request the creation of a ClassFile compatible representation of a problematic type
132  *
133  * @param typeDeclaration org.eclipse.jdt.internal.compiler.ast.TypeDeclaration
134  * @param unitResult org.eclipse.jdt.internal.compiler.CompilationUnitResult
135  */

136 public static void createProblemType(TypeDeclaration typeDeclaration, CompilationResult unitResult) {
137     SourceTypeBinding typeBinding = typeDeclaration.binding;
138     ClassFile classFile = new CodeSnippetClassFile(typeBinding, null, true);
139
140     // inner attributes
141
if (typeBinding.isNestedType()) {
142         classFile.recordInnerClasses(typeBinding);
143     }
144
145     // add its fields
146
FieldBinding[] fields = typeBinding.fields();
147     if ((fields != null) && (fields != Binding.NO_FIELDS)) {
148         classFile.addFieldInfos();
149     } else {
150         // we have to set the number of fields to be equals to 0
151
classFile.contents[classFile.contentsOffset++] = 0;
152         classFile.contents[classFile.contentsOffset++] = 0;
153     }
154     // leave some space for the methodCount
155
classFile.setForMethodInfos();
156     // add its user defined methods
157
int problemsLength;
158     CategorizedProblem[] problems = unitResult.getErrors();
159     if (problems == null) {
160         problems = new CategorizedProblem[0];
161     }
162     CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
163     System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
164     AbstractMethodDeclaration[] methodDecls = typeDeclaration.methods;
165     if (methodDecls != null) {
166         if (typeBinding.isInterface()) {
167             // we cannot create problem methods for an interface. So we have to generate a clinit
168
// which should contain all the problem
169
classFile.addProblemClinit(problemsCopy);
170             for (int i = 0, length = methodDecls.length; i < length; i++) {
171                 AbstractMethodDeclaration methodDecl = methodDecls[i];
172                 MethodBinding method = methodDecl.binding;
173                 if (method == null || method.isConstructor()) continue;
174                 classFile.addAbstractMethod(methodDecl, method);
175             }
176         } else {
177             for (int i = 0, length = methodDecls.length; i < length; i++) {
178                 AbstractMethodDeclaration methodDecl = methodDecls[i];
179                 MethodBinding method = methodDecl.binding;
180                 if (method == null) continue;
181                 if (method.isConstructor()) {
182                     classFile.addProblemConstructor(methodDecl, method, problemsCopy);
183                 } else {
184                     classFile.addProblemMethod(methodDecl, method, problemsCopy);
185                 }
186             }
187         }
188         // add abstract methods
189
classFile.addDefaultAbstractMethods();
190     }
191     // propagate generation of (problem) member types
192
if (typeDeclaration.memberTypes != null) {
193         for (int i = 0, max = typeDeclaration.memberTypes.length; i < max; i++) {
194             TypeDeclaration memberType = typeDeclaration.memberTypes[i];
195             if (memberType.binding != null) {
196                 ClassFile.createProblemType(memberType, unitResult);
197             }
198         }
199     }
200     classFile.addAttributes();
201     unitResult.record(typeBinding.constantPoolName(), classFile);
202 }
203 }
204
Popular Tags