KickJava   Java API By Example, From Geeks To Geeks.

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


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.Locale JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import org.eclipse.jdt.core.CompletionRequestor;
17 import org.eclipse.jdt.core.IJavaProject;
18 import org.eclipse.jdt.core.compiler.*;
19 import org.eclipse.jdt.internal.codeassist.CompletionEngine;
20 import org.eclipse.jdt.internal.codeassist.ISelectionRequestor;
21 import org.eclipse.jdt.internal.codeassist.SelectionEngine;
22 import org.eclipse.jdt.internal.compiler.ClassFile;
23 import org.eclipse.jdt.internal.compiler.IProblemFactory;
24 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
25 import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
26 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
27 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
28 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
29 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
30 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
31 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
32 import org.eclipse.jdt.internal.core.SearchableEnvironment;
33 import org.eclipse.jdt.internal.core.util.Util;
34
35 /**
36  * @see org.eclipse.jdt.core.eval.IEvaluationContext
37  */

38 public class EvaluationContext implements EvaluationConstants, SuffixConstants {
39     /**
40      * Whether timing information should be output to the stdout
41      */

42     static final boolean TIMING = false;
43
44     /**
45      * Global counters so that several evaluation context can deploy on the same runtime.
46      */

47     static int VAR_CLASS_COUNTER = 0;
48     static int CODE_SNIPPET_COUNTER = 0;
49
50     GlobalVariable[] variables;
51     int variableCount;
52     char[][] imports;
53     char[] packageName;
54     boolean varsChanged;
55     VariablesInfo installedVars;
56     IBinaryType codeSnippetBinary;
57     String JavaDoc lineSeparator;
58
59     /* do names implicitly refer to a given type */
60     char[] declaringTypeName;
61     int[] localVariableModifiers;
62     char[][] localVariableTypeNames;
63     char[][] localVariableNames;
64     
65     /* can 'this' be used in this context */
66     boolean isStatic;
67     boolean isConstructorCall;
68 /**
69  * Creates a new evaluation context.
70  */

71 public EvaluationContext() {
72     this.variables = new GlobalVariable[5];
73     this.variableCount = 0;
74     this.imports = CharOperation.NO_CHAR_CHAR;
75     this.packageName = CharOperation.NO_CHAR;
76     this.varsChanged = true;
77     this.isStatic = true;
78     this.isConstructorCall = false;
79     this.lineSeparator = org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR; // default value
80
}
81 /**
82  * Returns the global variables of this evaluation context in the order they were created in.
83  */

84 public GlobalVariable[] allVariables() {
85     GlobalVariable[] result = new GlobalVariable[this.variableCount];
86     System.arraycopy(this.variables, 0, result, 0, this.variableCount);
87     return result;
88 }
89 /**
90  * Computes a completion at the specified position of the given code snippet.
91  * (Note that this evaluation context's VM doesn't need to be running.)
92  *
93  * @param environment
94  * used to resolve type/package references and search for types/packages
95  * based on partial names.
96  *
97  * @param requestor
98  * since the engine might produce answers of various forms, the engine
99  * is associated with a requestor able to accept all possible completions.
100  *
101  * @param options
102  * set of options used to configure the code assist engine.
103  */

104 public void complete(char[] codeSnippet, int completionPosition, SearchableEnvironment environment, CompletionRequestor requestor, Map JavaDoc options, IJavaProject project) {
105     try {
106         IRequestor variableRequestor = new IRequestor() {
107             public boolean acceptClassFiles(ClassFile[] classFiles, char[] codeSnippetClassName) {
108                 // Do nothing
109
return true;
110             }
111             public void acceptProblem(CategorizedProblem problem, char[] fragmentSource, int fragmentKind) {
112                 // Do nothing
113
}
114         };
115         this.evaluateVariables(environment, options, variableRequestor, new DefaultProblemFactory(Locale.getDefault()));
116     } catch (InstallException e) {
117         // Do nothing
118
}
119     final char[] className = "CodeSnippetCompletion".toCharArray(); //$NON-NLS-1$
120
final CodeSnippetToCuMapper mapper = new CodeSnippetToCuMapper(
121         codeSnippet,
122         this.packageName,
123         this.imports,
124         className,
125         this.installedVars == null ? null : this.installedVars.className,
126         this.localVariableNames,
127         this.localVariableTypeNames,
128         this.localVariableModifiers,
129         this.declaringTypeName,
130         this.lineSeparator
131     );
132     ICompilationUnit sourceUnit = new ICompilationUnit() {
133         public char[] getFileName() {
134             return CharOperation.concat(className, Util.defaultJavaExtension().toCharArray());
135         }
136         public char[] getContents() {
137             return mapper.getCUSource(EvaluationContext.this.lineSeparator);
138         }
139         public char[] getMainTypeName() {
140             return className;
141         }
142         public char[][] getPackageName() {
143             return null;
144         }
145     };
146     
147     CompletionEngine engine = new CompletionEngine(environment, mapper.getCompletionRequestor(requestor), options, project);
148     
149     if (this.installedVars != null) {
150         IBinaryType binaryType = this.getRootCodeSnippetBinary();
151         if (binaryType != null) {
152             engine.lookupEnvironment.cacheBinaryType(binaryType, null /*no access restriction*/);
153         }
154         
155         ClassFile[] classFiles = installedVars.classFiles;
156         for (int i = 0; i < classFiles.length; i++) {
157             ClassFile classFile = classFiles[i];
158             IBinaryType binary = null;
159             try {
160                 binary = new ClassFileReader(classFile.getBytes(), null);
161             } catch (ClassFormatException e) {
162                 e.printStackTrace(); // Should never happen since we compiled this type
163
}
164             engine.lookupEnvironment.cacheBinaryType(binary, null /*no access restriction*/);
165         }
166     }
167     
168     engine.complete(sourceUnit, mapper.startPosOffset + completionPosition, mapper.startPosOffset);
169 }
170 /**
171  * Deletes the given variable from this evaluation context. This will take effect in the target VM only
172  * the next time global variables are installed.
173  */

174 public void deleteVariable(GlobalVariable variable) {
175     GlobalVariable[] vars = this.variables;
176     int index = -1;
177     for (int i = 0; i < this.variableCount; i++) {
178         if (vars[i].equals(variable)) {
179             index = i;
180             break;
181         }
182     }
183     if (index == -1) {
184         return;
185     }
186     int elementCount = this.variableCount--;
187     int j = elementCount - index - 1;
188     if (j > 0) {
189         System.arraycopy(vars, index + 1, vars, index, j);
190     }
191     vars[elementCount - 1] = null;
192     this.varsChanged = true;
193 }
194 private void deployCodeSnippetClassIfNeeded(IRequestor requestor) {
195     if (this.codeSnippetBinary == null) {
196         // Deploy CodeSnippet class (only once)
197
requestor.acceptClassFiles(
198             new ClassFile[] {
199                 new ClassFile() {
200                     public byte[] getBytes() {
201                         return getCodeSnippetBytes();
202                     }
203                     public char[][] getCompoundName() {
204                         return EvaluationConstants.ROOT_COMPOUND_NAME;
205                     }
206                 }
207             },
208             null);
209     }
210 }
211 /**
212  * @see org.eclipse.jdt.core.eval.IEvaluationContext
213  * @exception org.eclipse.jdt.internal.eval.InstallException if the code snippet class files could not be deployed.
214  */

215 public void evaluate(
216     char[] codeSnippet,
217     char[][] contextLocalVariableTypeNames,
218     char[][] contextLocalVariableNames,
219     int[] contextLocalVariableModifiers,
220     char[] contextDeclaringTypeName,
221     boolean contextIsStatic,
222     boolean contextIsConstructorCall,
223     INameEnvironment environment,
224     Map JavaDoc options,
225     final IRequestor requestor,
226     IProblemFactory problemFactory) throws InstallException {
227
228     // Initialialize context
229
this.localVariableTypeNames = contextLocalVariableTypeNames;
230     this.localVariableNames = contextLocalVariableNames;
231     this.localVariableModifiers = contextLocalVariableModifiers;
232     this.declaringTypeName = contextDeclaringTypeName;
233     this.isStatic = contextIsStatic;
234     this.isConstructorCall = contextIsConstructorCall;
235
236     this.deployCodeSnippetClassIfNeeded(requestor);
237
238     try {
239         // Install new variables if needed
240
class ForwardingRequestor implements IRequestor {
241             boolean hasErrors = false;
242             public boolean acceptClassFiles(ClassFile[] classFiles, char[] codeSnippetClassName) {
243                 return requestor.acceptClassFiles(classFiles, codeSnippetClassName);
244             }
245             public void acceptProblem(CategorizedProblem problem, char[] fragmentSource, int fragmentKind) {
246                 requestor.acceptProblem(problem, fragmentSource, fragmentKind);
247                 if (problem.isError()) {
248                     this.hasErrors = true;
249                 }
250             }
251         }
252         ForwardingRequestor forwardingRequestor = new ForwardingRequestor();
253         if (this.varsChanged) {
254             evaluateVariables(environment, options, forwardingRequestor, problemFactory);
255         }
256         
257         // Compile code snippet if there was no errors while evaluating the variables
258
if (!forwardingRequestor.hasErrors) {
259             Evaluator evaluator =
260                 new CodeSnippetEvaluator(
261                     codeSnippet,
262                     this,
263                     environment,
264                     options,
265                     requestor,
266                     problemFactory);
267             ClassFile[] classes = null;
268             if (TIMING) {
269                 long start = System.currentTimeMillis();
270                 classes = evaluator.getClasses();
271                 System.out.println("Time to compile [" + new String JavaDoc(codeSnippet) + "] was " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
272
} else {
273                 classes = evaluator.getClasses();
274             }
275             // Send code snippet on target
276
if (classes != null && classes.length > 0) {
277                 char[] simpleClassName = evaluator.getClassName();
278                 char[] pkgName = this.getPackageName();
279                 char[] qualifiedClassName =
280                     pkgName.length == 0 ?
281                         simpleClassName :
282                         CharOperation.concat(pkgName, simpleClassName, '.');
283                 CODE_SNIPPET_COUNTER++;
284                 requestor.acceptClassFiles(classes, qualifiedClassName);
285             }
286         }
287     } finally {
288         // Reinitialize context to default values
289
this.localVariableTypeNames = null;
290         this.localVariableNames = null;
291         this.localVariableModifiers = null;
292         this.declaringTypeName = null;
293         this.isStatic = true;
294         this.isConstructorCall = false;
295     }
296 }
297 /**
298  * @see org.eclipse.jdt.core.eval.IEvaluationContext
299  * @exception org.eclipse.jdt.internal.eval.InstallException if the code snippet class files could not be deployed.
300  */

301 public void evaluate(char[] codeSnippet, INameEnvironment environment, Map JavaDoc options, final IRequestor requestor, IProblemFactory problemFactory) throws InstallException {
302     this.evaluate(
303         codeSnippet,
304         null,
305         null,
306         null,
307         null,
308         true,
309         false,
310         environment,
311         options,
312         requestor,
313         problemFactory);
314 }
315 /**
316  * @see org.eclipse.jdt.core.eval.IEvaluationContext
317  */

318 public void evaluateImports(INameEnvironment environment, IRequestor requestor, IProblemFactory problemFactory) {
319     for (int i = 0; i < this.imports.length; i++) {
320         CategorizedProblem[] problems = new CategorizedProblem[] {null};
321         char[] importDeclaration = this.imports[i];
322         char[][] splitDeclaration = CharOperation.splitOn('.', importDeclaration);
323         int splitLength = splitDeclaration.length;
324         if (splitLength > 0) {
325             char[] pkgName = splitDeclaration[splitLength - 1];
326             if (pkgName.length == 1 && pkgName[0] == '*') {
327                 char[][] parentName;
328                 switch (splitLength) {
329                     case 1:
330                         parentName = null;
331                         break;
332                     case 2:
333                         parentName = null;
334                         pkgName = splitDeclaration[splitLength - 2];
335                         break;
336                     default:
337                         parentName = CharOperation.subarray(splitDeclaration, 0, splitLength - 2);
338                         pkgName = splitDeclaration[splitLength - 2];
339                 }
340                 if (!environment.isPackage(parentName, pkgName)) {
341                     String JavaDoc[] arguments = new String JavaDoc[] {new String JavaDoc(importDeclaration)};
342                     problems[0] = problemFactory.createProblem(importDeclaration, IProblem.ImportNotFound, arguments, arguments, ProblemSeverities.Warning, 0, importDeclaration.length - 1, i, 0);
343                 }
344             } else {
345                 if (environment.findType(splitDeclaration) == null) {
346                     String JavaDoc[] arguments = new String JavaDoc[] {new String JavaDoc(importDeclaration)};
347                     problems[0] = problemFactory.createProblem(importDeclaration, IProblem.ImportNotFound, arguments, arguments, ProblemSeverities.Warning, 0, importDeclaration.length - 1, i, 0);
348                 }
349             }
350         } else {
351             String JavaDoc[] arguments = new String JavaDoc[] {new String JavaDoc(importDeclaration)};
352             problems[0] = problemFactory.createProblem(importDeclaration, IProblem.ImportNotFound, arguments, arguments, ProblemSeverities.Warning, 0, importDeclaration.length - 1, i, 0);
353         }
354         if (problems[0] != null) {
355             requestor.acceptProblem(problems[0], importDeclaration, EvaluationResult.T_IMPORT);
356         }
357     }
358 }
359 /**
360  * @see org.eclipse.jdt.core.eval.IEvaluationContext
361  * @exception org.eclipse.jdt.internal.eval.InstallException if the code snippet class files could not be deployed.
362  * @exception java.lang.IllegalArgumentException if the global has not been installed yet.
363  */

364 public void evaluateVariable(GlobalVariable variable, INameEnvironment environment, Map JavaDoc options, IRequestor requestor, IProblemFactory problemFactory) throws InstallException {
365     this.evaluate(variable.getName(), environment, options, requestor, problemFactory);
366 }
367 /**
368  * @see org.eclipse.jdt.core.eval.IEvaluationContext
369  * @exception org.eclipse.jdt.internal.eval.InstallException if the code snippet class files could not be deployed.
370  */

371 public void evaluateVariables(INameEnvironment environment, Map JavaDoc options, IRequestor requestor, IProblemFactory problemFactory) throws InstallException {
372     this.deployCodeSnippetClassIfNeeded(requestor);
373     VariablesEvaluator evaluator = new VariablesEvaluator(this, environment, options, requestor, problemFactory);
374     ClassFile[] classes = evaluator.getClasses();
375     if (classes != null) {
376         if (classes.length > 0) {
377             // Sort classes so that enclosing types are cached before nested types
378
// otherwise an AbortCompilation is thrown in 1.5 mode since the enclosing type
379
// is needed to resolve a nested type
380
Util.sort(classes, new Util.Comparer() {
381                 public int compare(Object JavaDoc a, Object JavaDoc b) {
382                     if (a == b) return 0;
383                     ClassFile enclosing = ((ClassFile) a).enclosingClassFile;
384                     while (enclosing != null) {
385                         if (enclosing == b)
386                             return 1;
387                         enclosing = enclosing.enclosingClassFile;
388                     }
389                     return -1;
390                 }
391             });
392             
393             // Send classes
394
if (!requestor.acceptClassFiles(classes, null)) {
395                 throw new InstallException();
396             }
397
398             // Remember that the variables have been installed
399
int count = this.variableCount;
400             GlobalVariable[] variablesCopy = new GlobalVariable[count];
401             System.arraycopy(this.variables, 0, variablesCopy, 0, count);
402             this.installedVars = new VariablesInfo(evaluator.getPackageName(), evaluator.getClassName(), classes, variablesCopy, count);
403             VAR_CLASS_COUNTER++;
404         }
405         this.varsChanged = false;
406     }
407 }
408 /**
409  * Returns the bytes of the CodeSnippet class.
410  * Generated using the following code snippet:
411 [java.io.BufferedWriter writer = new java.io.BufferedWriter(new java.io.FileWriter("d:/temp/CodeSnippet.java"));
412 writer.write(org.eclipse.jdt.internal.eval.EvaluationContext.getCodeSnippetSource());
413 writer.close();
414 org.eclipse.jdt.internal.compiler.batch.Main.compile(
415     "d:/temp/CodeSnippet.java -d d:/temp -classpath d:/jdk1.2.2/jre/lib/rt.jar -verbose");
416 java.io.FileInputStream reader = new java.io.FileInputStream("d:/temp/org/eclipse/jdt/internal/eval/target/CodeSnippet.class");
417 byte[] bytes = org.eclipse.jdt.internal.core.Util.readContentsAsBytes(reader);
418 reader.close();
419 StringBuffer buffer = new StringBuffer();
420 buffer.append("private byte[] getCodeSnippetBytes() {\n");
421 buffer.append(" return new byte[] {\n");
422 buffer.append(" ");
423 for (int i = 0; i < bytes.length; i++) {
424     buffer.append(bytes[i]);
425     if (i == bytes.length - 1) {
426         buffer.append("\n");
427     } else {
428         buffer.append(", ");
429     }
430 }
431 buffer.append(" };\n");
432 buffer.append("}");
433 buffer.toString()
434 ]
435  */

436 byte[] getCodeSnippetBytes() {
437     return new byte[] {
438         -54, -2, -70, -66, 0, 3, 0, 45, 0, 35, 1, 0, 48, 111, 114, 103, 47, 101, 99, 108, 105, 112, 115, 101, 47, 106, 100, 116, 47, 105, 110, 116, 101, 114, 110, 97, 108, 47, 101, 118, 97, 108, 47, 116, 97, 114, 103, 101, 116, 47, 67, 111, 100, 101, 83, 110, 105, 112, 112, 101, 116, 7, 0, 1, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 7, 0, 3, 1, 0, 10, 114, 101, 115, 117, 108, 116, 84, 121, 112, 101, 1, 0, 17, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 59, 1, 0, 11, 114, 101, 115, 117, 108, 116, 86, 97, 108, 117, 101, 1, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 1, 0, 7, 99, 108, 97, 115, 115, 36, 48, 1, 0, 9, 83, 121, 110, 116, 104, 101, 116, 105, 99, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 12, 0, 11, 0, 12, 10, 0, 4, 0, 14, 1, 0, 14, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 86, 111, 105, 100, 7, 0, 16, 1, 0, 4, 84, 89, 80, 69, 12, 0, 18, 0, 6, 9, 0, 17, 0, 19, 12, 0, 5, 0, 6, 9, 0, 2, 0, 21, 12, 0, 7, 0, 8, 9, 0, 2, 0, 23, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 13, 103, 101, 116, 82, 101, 115, 117, 108, 116, 84, 121, 112, 101, 1, 0, 19, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 59, 1, 0, 14, 103, 101, 116, 82, 101, 115, 117, 108, 116, 86, 97, 108, 117, 101, 1, 0, 20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 1, 0, 3, 114, 117, 110, 1, 0, 9, 115, 101, 116, 82, 101, 115, 117, 108, 116, 1, 0, 38, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 59, 41, 86, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 16, 67, 111, 100, 101, 83, 110, 105, 112, 112, 101, 116, 46, 106, 97, 118, 97, 0, 33, 0, 2, 0, 4, 0, 0, 0, 3, 0, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 7, 0, 8, 0, 0, 0, 8, 0, 9, 0, 6, 0, 1, 0, 10, 0, 0, 0, 0, 0, 5, 0, 1, 0, 11, 0, 12, 0, 1, 0, 13, 0, 0, 0, 53, 0, 2, 0, 1, 0, 0, 0, 17, 42, -73, 0, 15, 42, -78, 0, 20, -75, 0, 22, 42, 1, -75, 0, 24, -79, 0, 0, 0, 1, 0, 25, 0, 0, 0, 18, 0, 4, 0, 0, 0, 17, 0, 4, 0, 18, 0, 11, 0, 19, 0, 16, 0, 17, 0, 1, 0, 26, 0, 27, 0, 1, 0, 13, 0, 0, 0, 29, 0, 1, 0, 1, 0, 0, 0, 5, 42, -76, 0, 22, -80, 0, 0, 0, 1, 0, 25, 0, 0, 0, 6, 0, 1, 0, 0, 0, 24, 0, 1, 0, 28, 0, 29, 0, 1, 0, 13, 0, 0, 0, 29, 0, 1, 0, 1, 0, 0, 0, 5, 42, -76, 0, 24, -80, 0, 0, 0, 1, 0, 25, 0, 0, 0, 6, 0, 1, 0, 0, 0, 30, 0, 1, 0, 30, 0, 12, 0, 1, 0, 13, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, -79, 0, 0, 0, 1, 0, 25, 0, 0, 0, 6, 0, 1, 0, 0, 0, 36, 0, 1, 0, 31, 0, 32, 0, 1, 0, 13, 0, 0, 0, 43, 0, 2, 0, 3, 0, 0, 0, 11, 42, 43, -75, 0, 24, 42, 44, -75, 0, 22, -79, 0, 0, 0, 1, 0, 25, 0, 0, 0, 14, 0, 3, 0, 0, 0, 42, 0, 5, 0, 43, 0, 10, 0, 41, 0, 1, 0, 33, 0, 0, 0, 2, 0, 34
439     };
440 }
441 /**
442  * Returns the source of the CodeSnippet class.
443  * This is used to generate the binary of the CodeSnippetClass
444  */

445 public static String JavaDoc getCodeSnippetSource() {
446     return
447         "package org.eclipse.jdt.internal.eval.target;\n" + //$NON-NLS-1$
448
"\n" + //$NON-NLS-1$
449
"/*\n" + //$NON-NLS-1$
450
" * (c) Copyright IBM Corp. 2000, 2001.\n" + //$NON-NLS-1$
451
" * All Rights Reserved.\n" + //$NON-NLS-1$
452
" */\n" + //$NON-NLS-1$
453
"/**\n" + //$NON-NLS-1$
454
" * The root of all code snippet classes. Code snippet classes\n" + //$NON-NLS-1$
455
" * are supposed to overide the run() method.\n" + //$NON-NLS-1$
456
" * <p>\n" + //$NON-NLS-1$
457
" * IMPORTANT NOTE:\n" + //$NON-NLS-1$
458
" * All methods in this class must be public since this class is going to be loaded by the\n" + //$NON-NLS-1$
459
" * bootstrap class loader, and the other code snippet support classes might be loaded by \n" + //$NON-NLS-1$
460
" * another class loader (so their runtime packages are going to be different).\n" + //$NON-NLS-1$
461
" */\n" + //$NON-NLS-1$
462
"public class CodeSnippet {\n" + //$NON-NLS-1$
463
" private Class resultType = void.class;\n" + //$NON-NLS-1$
464
" private Object resultValue = null;\n" + //$NON-NLS-1$
465
"/**\n" + //$NON-NLS-1$
466
" * Returns the result type of the code snippet evaluation.\n" + //$NON-NLS-1$
467
" */\n" + //$NON-NLS-1$
468
"public Class getResultType() {\n" + //$NON-NLS-1$
469
" return this.resultType;\n" + //$NON-NLS-1$
470
"}\n" + //$NON-NLS-1$
471
"/**\n" + //$NON-NLS-1$
472
" * Returns the result value of the code snippet evaluation.\n" + //$NON-NLS-1$
473
" */\n" + //$NON-NLS-1$
474
"public Object getResultValue() {\n" + //$NON-NLS-1$
475
" return this.resultValue;\n" + //$NON-NLS-1$
476
"}\n" + //$NON-NLS-1$
477
"/**\n" + //$NON-NLS-1$
478
" * The code snippet. Subclasses must override this method with a transformed code snippet\n" + //$NON-NLS-1$
479
" * that stores the result using setResult(Class, Object).\n" + //$NON-NLS-1$
480
" */\n" + //$NON-NLS-1$
481
"public void run() {\n" + //$NON-NLS-1$
482
"}\n" + //$NON-NLS-1$
483
"/**\n" + //$NON-NLS-1$
484
" * Stores the result type and value of the code snippet evaluation.\n" + //$NON-NLS-1$
485
" */\n" + //$NON-NLS-1$
486
"public void setResult(Object someResultValue, Class someResultType) {\n" + //$NON-NLS-1$
487
" this.resultValue = someResultValue;\n" + //$NON-NLS-1$
488
" this.resultType = someResultType;\n" + //$NON-NLS-1$
489
"}\n" + //$NON-NLS-1$
490
"}\n"; //$NON-NLS-1$
491
}
492 /**
493  * Returns the imports of this evaluation context. An import is the name of a package
494  * or the fully qualified name of a type as defined in the import statement of
495  * a compilation unit.
496  */

497 public char[][] getImports() {
498     return this.imports;
499 }
500 /**
501  * Returns the dot-separated name of the package code snippets are run into.
502  * Returns an empty array for the default package. This is the default if
503  * the package name has never been set.
504  */

505 public char[] getPackageName() {
506     return this.packageName;
507 }
508 /**
509  * Return the binary for the root code snippet class (ie. org.eclipse.jdt.internal.eval.target.CodeSnippet).
510  */

511 IBinaryType getRootCodeSnippetBinary() {
512     if (this.codeSnippetBinary == null) {
513         this.codeSnippetBinary = new CodeSnippetSkeleton();
514     }
515     return this.codeSnippetBinary;
516 }
517 public char[] getVarClassName() {
518     if (installedVars == null) return CharOperation.NO_CHAR;
519     return CharOperation.concat(installedVars.packageName, installedVars.className, '.');
520 }
521 /**
522  * Creates a new global variable with the given name, type and initializer.
523  * If the variable is not initialized, the initializer can be null.
524  * Note that this doesn't install it to this evaluation context's VM.
525  *
526  * @see GlobalVariable
527  */

528 public GlobalVariable newVariable(char[] typeName, char[] name, char[] initializer) {
529     GlobalVariable var = new GlobalVariable(typeName, name, initializer);
530     if (this.variableCount >= this.variables.length) // assume variables is never empty
531
System.arraycopy(this.variables, 0, this.variables = new GlobalVariable[this.variableCount * 2], 0, this.variableCount);
532     this.variables[this.variableCount++] = var;
533     this.varsChanged = true;
534     return var;
535 }
536 /**
537  * Computes the selection at the specified positions of the given code snippet.
538  * (Note that this evaluation context's VM doesn't need to be running.)
539  * @param codeSnippet char[]
540  * The code snipper source
541  *
542  * @param selectionSourceStart int
543  *
544  * @param selectionSourceEnd int
545  *
546  * @param environment org.eclipse.jdt.internal.core.SearchableEnvironment
547  * used to resolve type/package references and search for types/packages
548  * based on partial names.
549  *
550  * @param requestor org.eclipse.jdt.internal.codeassist.ISelectionRequestor
551  * since the engine might produce answers of various forms, the engine
552  * is associated with a requestor able to accept all possible selections.
553  *
554  * @param options java.util.Map
555  * set of options used to configure the code assist engine.
556  */

557 public void select(
558     char[] codeSnippet,
559     int selectionSourceStart,
560     int selectionSourceEnd,
561     SearchableEnvironment environment,
562     ISelectionRequestor requestor,
563     Map JavaDoc options) {
564         
565     final char[] className = "CodeSnippetSelection".toCharArray(); //$NON-NLS-1$
566
final CodeSnippetToCuMapper mapper = new CodeSnippetToCuMapper(
567         codeSnippet,
568         this.packageName,
569         this.imports,
570         className,
571         this.installedVars == null ? null : this.installedVars.className,
572         this.localVariableNames,
573         this.localVariableTypeNames,
574         this.localVariableModifiers,
575         this.declaringTypeName,
576         this.lineSeparator
577     );
578     ICompilationUnit sourceUnit = new ICompilationUnit() {
579         public char[] getFileName() {
580             return CharOperation.concat(className, Util.defaultJavaExtension().toCharArray());
581         }
582         public char[] getContents() {
583             return mapper.getCUSource(EvaluationContext.this.lineSeparator);
584         }
585         public char[] getMainTypeName() {
586             return className;
587         }
588         public char[][] getPackageName() {
589             return null;
590         }
591     };
592     SelectionEngine engine = new SelectionEngine(environment, mapper.getSelectionRequestor(requestor), options);
593     engine.select(sourceUnit, mapper.startPosOffset + selectionSourceStart, mapper.startPosOffset + selectionSourceEnd);
594 }
595 /**
596  * Sets the imports of this evaluation context. An import is the name of a package
597  * or the fully qualified name of a type as defined in the import statement of
598  * a compilation unit (see the Java Language Specifications for more details).
599  */

600 public void setImports(char[][] imports) {
601     this.imports = imports;
602     this.varsChanged = true; // this may change the visibility of the variable's types
603
}
604 /**
605  * Sets the line separator used by this evaluation context.
606  */

607 public void setLineSeparator(String JavaDoc lineSeparator) {
608     this.lineSeparator = lineSeparator;
609 }
610 /**
611  * Sets the dot-separated name of the package code snippets are ran into.
612  * The default package name is an empty array.
613  */

614 public void setPackageName(char[] packageName) {
615     this.packageName = packageName;
616     this.varsChanged = true; // this may change the visibility of the variable's types
617
}
618 }
619
Popular Tags