KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.util.Map JavaDoc;
14
15 import org.eclipse.jdt.core.compiler.*;
16 import org.eclipse.jdt.internal.compiler.ClassFile;
17 import org.eclipse.jdt.internal.compiler.Compiler;
18 import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
19 import org.eclipse.jdt.internal.compiler.IProblemFactory;
20 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
21 import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
22 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
23 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
24
25 /**
26  * A variables evaluator compiles the global variables of an evaluation context and returns
27  * the corresponding class files. Or it reports problems against these variables.
28  */

29 public class VariablesEvaluator extends Evaluator implements EvaluationConstants {
30 /**
31  * Creates a new global variables evaluator.
32  */

33 VariablesEvaluator(EvaluationContext context, INameEnvironment environment, Map JavaDoc options, IRequestor requestor, IProblemFactory problemFactory) {
34     super(context, environment, options, requestor, problemFactory);
35 }
36 /**
37  * @see org.eclipse.jdt.internal.eval.Evaluator
38  */

39 protected void addEvaluationResultForCompilationProblem(Map JavaDoc resultsByIDs, CategorizedProblem problem, char[] cuSource) {
40     // set evaluation id and type to an internal problem by default
41
char[] evaluationID = cuSource;
42     int evaluationType = EvaluationResult.T_INTERNAL;
43
44     int pbLine = problem.getSourceLineNumber();
45     int currentLine = 1;
46
47     // check package declaration
48
char[] packageName = getPackageName();
49     if (packageName.length > 0) {
50         if (pbLine == 1) {
51             // set evaluation id and type
52
evaluationID = packageName;
53             evaluationType = EvaluationResult.T_PACKAGE;
54
55             // shift line number, source start and source end
56
problem.setSourceLineNumber(1);
57             problem.setSourceStart(0);
58             problem.setSourceEnd(evaluationID.length - 1);
59         }
60         currentLine++;
61     }
62
63     // check imports
64
char[][] imports = this.context.imports;
65     if ((currentLine <= pbLine) && (pbLine < (currentLine + imports.length))) {
66         // set evaluation id and type
67
evaluationID = imports[pbLine - currentLine];
68         evaluationType = EvaluationResult.T_IMPORT;
69
70         // shift line number, source start and source end
71
problem.setSourceLineNumber(1);
72         problem.setSourceStart(0);
73         problem.setSourceEnd(evaluationID.length - 1);
74     }
75     currentLine += imports.length + 1; // + 1 to skip the class declaration line
76

77     // check variable declarations
78
int varCount = this.context.variableCount;
79     if ((currentLine <= pbLine) && (pbLine < currentLine + varCount)) {
80         GlobalVariable var = this.context.variables[pbLine - currentLine];
81         
82         // set evaluation id and type
83
evaluationID = var.getName();
84         evaluationType = EvaluationResult.T_VARIABLE;
85
86         // shift line number, source start and source end
87
int pbStart = problem.getSourceStart() - var.declarationStart;
88         int pbEnd = problem.getSourceEnd() - var.declarationStart;
89         int typeLength = var.getTypeName().length;
90         if ((0 <= pbStart) && (pbEnd < typeLength)) {
91             // problem on the type of the variable
92
problem.setSourceLineNumber(-1);
93         } else {
94             // problem on the name of the variable
95
pbStart -= typeLength + 1; // type length + space
96
pbEnd -= typeLength + 1; // type length + space
97
problem.setSourceLineNumber(0);
98         }
99         problem.setSourceStart(pbStart);
100         problem.setSourceEnd(pbEnd);
101     }
102     currentLine = -1; // not needed any longer
103

104     // check variable initializers
105
for (int i = 0; i < varCount; i++) {
106         GlobalVariable var = this.context.variables[i];
107         char[] initializer = var.getInitializer();
108         int initializerLength = initializer == null ? 0 : initializer.length;
109         if ((var.initializerStart <= problem.getSourceStart()) && (problem.getSourceEnd() < var.initializerStart + var.name.length)) {
110             /* Problem with the variable name.
111                Ignore because it must have already been reported
112                when checking the declaration.
113              */

114             return;
115         } else if ((var.initExpressionStart <= problem.getSourceStart()) && (problem.getSourceEnd() < var.initExpressionStart + initializerLength)) {
116             // set evaluation id and type
117
evaluationID = var.name;
118             evaluationType = EvaluationResult.T_VARIABLE;
119
120             // shift line number, source start and source end
121
problem.setSourceLineNumber(pbLine - var.initializerLineStart + 1);
122             problem.setSourceStart(problem.getSourceStart() - var.initExpressionStart);
123             problem.setSourceEnd(problem.getSourceEnd() - var.initExpressionStart);
124
125             break;
126         }
127     }
128
129     EvaluationResult result = (EvaluationResult)resultsByIDs.get(evaluationID);
130     if (result == null) {
131         resultsByIDs.put(evaluationID, new EvaluationResult(evaluationID, evaluationType, new CategorizedProblem[] {problem}));
132     } else {
133         result.addProblem(problem);
134     }
135 }
136 /**
137  * @see org.eclipse.jdt.internal.eval.Evaluator
138  */

139 protected char[] getClassName() {
140     return CharOperation.concat(EvaluationConstants.GLOBAL_VARS_CLASS_NAME_PREFIX, Integer.toString(EvaluationContext.VAR_CLASS_COUNTER + 1).toCharArray());
141 }
142 /**
143  * Creates and returns a compiler for this evaluator.
144  */

145 Compiler JavaDoc getCompiler(ICompilerRequestor compilerRequestor) {
146     Compiler JavaDoc compiler = super.getCompiler(compilerRequestor);
147     
148     // Initialize the compiler's lookup environment with the already compiled super class
149
IBinaryType binaryType = this.context.getRootCodeSnippetBinary();
150     if (binaryType != null) {
151         compiler.lookupEnvironment.cacheBinaryType(binaryType, null /*no access restriction*/);
152     }
153
154     // and the installed global variable classes
155
VariablesInfo installedVars = this.context.installedVars;
156     if (installedVars != null) {
157         ClassFile[] classFiles = installedVars.classFiles;
158         for (int i = 0; i < classFiles.length; i++) {
159             ClassFile classFile = classFiles[i];
160             IBinaryType binary = null;
161             try {
162                 binary = new ClassFileReader(classFile.getBytes(), null);
163             } catch (ClassFormatException e) {
164                 e.printStackTrace(); // Should never happen since we compiled this type
165
}
166             compiler.lookupEnvironment.cacheBinaryType(binary, null /*no access restriction*/);
167         }
168     }
169     
170     return compiler;
171 }
172 /**
173  * Returns the name of package of the current compilation unit.
174  */

175 protected char[] getPackageName() {
176     return this.context.packageName;
177 }
178 /**
179  * @see org.eclipse.jdt.internal.eval.Evaluator
180  */

181 protected char[] getSource() {
182     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
183     int lineNumberOffset = 1;
184     
185     // package declaration
186
char[] packageName = getPackageName();
187     if (packageName.length != 0) {
188         buffer.append("package "); //$NON-NLS-1$
189
buffer.append(packageName);
190         buffer.append(';').append(this.context.lineSeparator);
191         lineNumberOffset++;
192     }
193
194     // import declarations
195
char[][] imports = this.context.imports;
196     for (int i = 0; i < imports.length; i++) {
197         buffer.append("import "); //$NON-NLS-1$
198
buffer.append(imports[i]);
199         buffer.append(';').append(this.context.lineSeparator);
200         lineNumberOffset++;
201     }
202
203     // class declaration
204
buffer.append("public class "); //$NON-NLS-1$
205
buffer.append(getClassName());
206     buffer.append(" extends "); //$NON-NLS-1$
207
buffer.append(PACKAGE_NAME);
208     buffer.append("."); //$NON-NLS-1$
209
buffer.append(ROOT_CLASS_NAME);
210     buffer.append(" {").append(this.context.lineSeparator); //$NON-NLS-1$
211
lineNumberOffset++;
212
213     // field declarations
214
GlobalVariable[] vars = this.context.variables;
215     VariablesInfo installedVars = this.context.installedVars;
216     for (int i = 0; i < this.context.variableCount; i++){
217         GlobalVariable var = vars[i];
218         buffer.append("\tpublic static "); //$NON-NLS-1$
219
var.declarationStart = buffer.length();
220         buffer.append(var.typeName);
221         buffer.append(" "); //$NON-NLS-1$
222
char[] varName = var.name;
223         buffer.append(varName);
224         buffer.append(';').append(this.context.lineSeparator);
225         lineNumberOffset++;
226     }
227
228     // field initializations
229
buffer.append("\tstatic {").append(this.context.lineSeparator); //$NON-NLS-1$
230
lineNumberOffset++;
231     for (int i = 0; i < this.context.variableCount; i++){
232         GlobalVariable var = vars[i];
233         char[] varName = var.name;
234         GlobalVariable installedVar = installedVars == null ? null : installedVars.varNamed(varName);
235         if (installedVar == null || !CharOperation.equals(installedVar.typeName, var.typeName)) {
236             // Initialize with initializer if there was no previous value
237
char[] initializer = var.initializer;
238             if (initializer != null) {
239                 buffer.append("\t\ttry {").append(this.context.lineSeparator); //$NON-NLS-1$
240
lineNumberOffset++;
241                 var.initializerLineStart = lineNumberOffset;
242                 buffer.append("\t\t\t"); //$NON-NLS-1$
243
var.initializerStart = buffer.length();
244                 buffer.append(varName);
245                 buffer.append("= "); //$NON-NLS-1$
246
var.initExpressionStart = buffer.length();
247                 buffer.append(initializer);
248                 lineNumberOffset += numberOfCRs(initializer);
249                 buffer.append(';').append(this.context.lineSeparator);
250                 buffer.append("\t\t} catch (Throwable e) {").append(this.context.lineSeparator); //$NON-NLS-1$
251
buffer.append("\t\t\te.printStackTrace();").append(this.context.lineSeparator); //$NON-NLS-1$
252
buffer.append("\t\t}").append(this.context.lineSeparator); //$NON-NLS-1$
253
lineNumberOffset += 4; // 4 CRs
254
}
255         } else {
256             // Initialize with previous value if name and type are the same
257
buffer.append("\t\t"); //$NON-NLS-1$
258
buffer.append(varName);
259             buffer.append("= "); //$NON-NLS-1$
260
char[] installedPackageName = installedVars.packageName;
261             if (installedPackageName != null && installedPackageName.length != 0) {
262                 buffer.append(installedPackageName);
263                 buffer.append("."); //$NON-NLS-1$
264
}
265             buffer.append(installedVars.className);
266             buffer.append("."); //$NON-NLS-1$
267
buffer.append(varName);
268             buffer.append(';').append(this.context.lineSeparator);
269             lineNumberOffset++;
270         }
271     }
272     buffer.append("\t}").append(this.context.lineSeparator); //$NON-NLS-1$
273

274     // end of class declaration
275
buffer.append('}').append(this.context.lineSeparator);
276
277     // return result
278
int length = buffer.length();
279     char[] result = new char[length];
280     buffer.getChars(0, length, result, 0);
281     return result;
282 }
283 /**
284  * Returns the number of cariage returns included in the given source.
285  */

286 private int numberOfCRs(char[] source) {
287     int numberOfCRs = 0;
288     boolean lastWasCR = false;
289     for (int i = 0; i < source.length; i++) {
290         char currentChar = source[i];
291         switch(currentChar){
292             case '\r' :
293                 lastWasCR = true;
294                 numberOfCRs++;
295                 break;
296             case '\n' :
297                 if (!lastWasCR) numberOfCRs++; // merge CR-LF
298
lastWasCR = false;
299                 break;
300             default :
301                 lastWasCR = false;
302         }
303     }
304     return numberOfCRs;
305 }
306 }
307
Popular Tags