/projects/aspectj-1.6.9/aspectjtools1.6.9/org/aspectj/org/eclipse/jdt/internal/eval/VariablesEvaluator.java
Java | 306 lines | 216 code | 25 blank | 65 comment | 43 complexity | d5fdd7ed64675c1a7e90819599b236f8 MD5 | raw file
- /*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
- package org.aspectj.org.eclipse.jdt.internal.eval;
-
- import java.util.Map;
-
- import org.aspectj.org.eclipse.jdt.core.compiler.*;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
- import org.aspectj.org.eclipse.jdt.internal.compiler.Compiler;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ICompilerRequestor;
- import org.aspectj.org.eclipse.jdt.internal.compiler.IProblemFactory;
- import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
- import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
- import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryType;
- import org.aspectj.org.eclipse.jdt.internal.compiler.env.INameEnvironment;
-
- /**
- * A variables evaluator compiles the global variables of an evaluation context and returns
- * the corresponding class files. Or it reports problems against these variables.
- */
- public class VariablesEvaluator extends Evaluator implements EvaluationConstants {
- /**
- * Creates a new global variables evaluator.
- */
- VariablesEvaluator(EvaluationContext context, INameEnvironment environment, Map options, IRequestor requestor, IProblemFactory problemFactory) {
- super(context, environment, options, requestor, problemFactory);
- }
- /**
- * @see org.aspectj.org.eclipse.jdt.internal.eval.Evaluator
- */
- protected void addEvaluationResultForCompilationProblem(Map resultsByIDs, CategorizedProblem problem, char[] cuSource) {
- // set evaluation id and type to an internal problem by default
- char[] evaluationID = cuSource;
- int evaluationType = EvaluationResult.T_INTERNAL;
-
- int pbLine = problem.getSourceLineNumber();
- int currentLine = 1;
-
- // check package declaration
- char[] packageName = getPackageName();
- if (packageName.length > 0) {
- if (pbLine == 1) {
- // set evaluation id and type
- evaluationID = packageName;
- evaluationType = EvaluationResult.T_PACKAGE;
-
- // shift line number, source start and source end
- problem.setSourceLineNumber(1);
- problem.setSourceStart(0);
- problem.setSourceEnd(evaluationID.length - 1);
- }
- currentLine++;
- }
-
- // check imports
- char[][] imports = this.context.imports;
- if ((currentLine <= pbLine) && (pbLine < (currentLine + imports.length))) {
- // set evaluation id and type
- evaluationID = imports[pbLine - currentLine];
- evaluationType = EvaluationResult.T_IMPORT;
-
- // shift line number, source start and source end
- problem.setSourceLineNumber(1);
- problem.setSourceStart(0);
- problem.setSourceEnd(evaluationID.length - 1);
- }
- currentLine += imports.length + 1; // + 1 to skip the class declaration line
-
- // check variable declarations
- int varCount = this.context.variableCount;
- if ((currentLine <= pbLine) && (pbLine < currentLine + varCount)) {
- GlobalVariable var = this.context.variables[pbLine - currentLine];
-
- // set evaluation id and type
- evaluationID = var.getName();
- evaluationType = EvaluationResult.T_VARIABLE;
-
- // shift line number, source start and source end
- int pbStart = problem.getSourceStart() - var.declarationStart;
- int pbEnd = problem.getSourceEnd() - var.declarationStart;
- int typeLength = var.getTypeName().length;
- if ((0 <= pbStart) && (pbEnd < typeLength)) {
- // problem on the type of the variable
- problem.setSourceLineNumber(-1);
- } else {
- // problem on the name of the variable
- pbStart -= typeLength + 1; // type length + space
- pbEnd -= typeLength + 1; // type length + space
- problem.setSourceLineNumber(0);
- }
- problem.setSourceStart(pbStart);
- problem.setSourceEnd(pbEnd);
- }
- currentLine = -1; // not needed any longer
-
- // check variable initializers
- for (int i = 0; i < varCount; i++) {
- GlobalVariable var = this.context.variables[i];
- char[] initializer = var.getInitializer();
- int initializerLength = initializer == null ? 0 : initializer.length;
- if ((var.initializerStart <= problem.getSourceStart()) && (problem.getSourceEnd() < var.initializerStart + var.name.length)) {
- /* Problem with the variable name.
- Ignore because it must have already been reported
- when checking the declaration.
- */
- return;
- } else if ((var.initExpressionStart <= problem.getSourceStart()) && (problem.getSourceEnd() < var.initExpressionStart + initializerLength)) {
- // set evaluation id and type
- evaluationID = var.name;
- evaluationType = EvaluationResult.T_VARIABLE;
-
- // shift line number, source start and source end
- problem.setSourceLineNumber(pbLine - var.initializerLineStart + 1);
- problem.setSourceStart(problem.getSourceStart() - var.initExpressionStart);
- problem.setSourceEnd(problem.getSourceEnd() - var.initExpressionStart);
-
- break;
- }
- }
-
- EvaluationResult result = (EvaluationResult)resultsByIDs.get(evaluationID);
- if (result == null) {
- resultsByIDs.put(evaluationID, new EvaluationResult(evaluationID, evaluationType, new CategorizedProblem[] {problem}));
- } else {
- result.addProblem(problem);
- }
- }
- /**
- * @see org.aspectj.org.eclipse.jdt.internal.eval.Evaluator
- */
- protected char[] getClassName() {
- return CharOperation.concat(EvaluationConstants.GLOBAL_VARS_CLASS_NAME_PREFIX, Integer.toString(EvaluationContext.VAR_CLASS_COUNTER + 1).toCharArray());
- }
- /**
- * Creates and returns a compiler for this evaluator.
- */
- Compiler getCompiler(ICompilerRequestor compilerRequestor) {
- Compiler compiler = super.getCompiler(compilerRequestor);
-
- // Initialize the compiler's lookup environment with the already compiled super class
- IBinaryType binaryType = this.context.getRootCodeSnippetBinary();
- if (binaryType != null) {
- compiler.lookupEnvironment.cacheBinaryType(binaryType, null /*no access restriction*/);
- }
-
- // and the installed global variable classes
- VariablesInfo installedVars = this.context.installedVars;
- if (installedVars != null) {
- ClassFile[] classFiles = installedVars.classFiles;
- for (int i = 0; i < classFiles.length; i++) {
- ClassFile classFile = classFiles[i];
- IBinaryType binary = null;
- try {
- binary = new ClassFileReader(classFile.getBytes(), null);
- } catch (ClassFormatException e) {
- e.printStackTrace(); // Should never happen since we compiled this type
- }
- compiler.lookupEnvironment.cacheBinaryType(binary, null /*no access restriction*/);
- }
- }
-
- return compiler;
- }
- /**
- * Returns the name of package of the current compilation unit.
- */
- protected char[] getPackageName() {
- return this.context.packageName;
- }
- /**
- * @see org.aspectj.org.eclipse.jdt.internal.eval.Evaluator
- */
- protected char[] getSource() {
- StringBuffer buffer = new StringBuffer();
- int lineNumberOffset = 1;
-
- // package declaration
- char[] packageName = getPackageName();
- if (packageName.length != 0) {
- buffer.append("package "); //$NON-NLS-1$
- buffer.append(packageName);
- buffer.append(';').append(this.context.lineSeparator);
- lineNumberOffset++;
- }
-
- // import declarations
- char[][] imports = this.context.imports;
- for (int i = 0; i < imports.length; i++) {
- buffer.append("import "); //$NON-NLS-1$
- buffer.append(imports[i]);
- buffer.append(';').append(this.context.lineSeparator);
- lineNumberOffset++;
- }
-
- // class declaration
- buffer.append("public class "); //$NON-NLS-1$
- buffer.append(getClassName());
- buffer.append(" extends "); //$NON-NLS-1$
- buffer.append(PACKAGE_NAME);
- buffer.append("."); //$NON-NLS-1$
- buffer.append(ROOT_CLASS_NAME);
- buffer.append(" {").append(this.context.lineSeparator); //$NON-NLS-1$
- lineNumberOffset++;
-
- // field declarations
- GlobalVariable[] vars = this.context.variables;
- VariablesInfo installedVars = this.context.installedVars;
- for (int i = 0; i < this.context.variableCount; i++){
- GlobalVariable var = vars[i];
- buffer.append("\tpublic static "); //$NON-NLS-1$
- var.declarationStart = buffer.length();
- buffer.append(var.typeName);
- buffer.append(" "); //$NON-NLS-1$
- char[] varName = var.name;
- buffer.append(varName);
- buffer.append(';').append(this.context.lineSeparator);
- lineNumberOffset++;
- }
-
- // field initializations
- buffer.append("\tstatic {").append(this.context.lineSeparator); //$NON-NLS-1$
- lineNumberOffset++;
- for (int i = 0; i < this.context.variableCount; i++){
- GlobalVariable var = vars[i];
- char[] varName = var.name;
- GlobalVariable installedVar = installedVars == null ? null : installedVars.varNamed(varName);
- if (installedVar == null || !CharOperation.equals(installedVar.typeName, var.typeName)) {
- // Initialize with initializer if there was no previous value
- char[] initializer = var.initializer;
- if (initializer != null) {
- buffer.append("\t\ttry {").append(this.context.lineSeparator); //$NON-NLS-1$
- lineNumberOffset++;
- var.initializerLineStart = lineNumberOffset;
- buffer.append("\t\t\t"); //$NON-NLS-1$
- var.initializerStart = buffer.length();
- buffer.append(varName);
- buffer.append("= "); //$NON-NLS-1$
- var.initExpressionStart = buffer.length();
- buffer.append(initializer);
- lineNumberOffset += numberOfCRs(initializer);
- buffer.append(';').append(this.context.lineSeparator);
- buffer.append("\t\t} catch (Throwable e) {").append(this.context.lineSeparator); //$NON-NLS-1$
- buffer.append("\t\t\te.printStackTrace();").append(this.context.lineSeparator); //$NON-NLS-1$
- buffer.append("\t\t}").append(this.context.lineSeparator); //$NON-NLS-1$
- lineNumberOffset += 4; // 4 CRs
- }
- } else {
- // Initialize with previous value if name and type are the same
- buffer.append("\t\t"); //$NON-NLS-1$
- buffer.append(varName);
- buffer.append("= "); //$NON-NLS-1$
- char[] installedPackageName = installedVars.packageName;
- if (installedPackageName != null && installedPackageName.length != 0) {
- buffer.append(installedPackageName);
- buffer.append("."); //$NON-NLS-1$
- }
- buffer.append(installedVars.className);
- buffer.append("."); //$NON-NLS-1$
- buffer.append(varName);
- buffer.append(';').append(this.context.lineSeparator);
- lineNumberOffset++;
- }
- }
- buffer.append("\t}").append(this.context.lineSeparator); //$NON-NLS-1$
-
- // end of class declaration
- buffer.append('}').append(this.context.lineSeparator);
-
- // return result
- int length = buffer.length();
- char[] result = new char[length];
- buffer.getChars(0, length, result, 0);
- return result;
- }
- /**
- * Returns the number of cariage returns included in the given source.
- */
- private int numberOfCRs(char[] source) {
- int numberOfCRs = 0;
- boolean lastWasCR = false;
- for (int i = 0; i < source.length; i++) {
- char currentChar = source[i];
- switch(currentChar){
- case '\r' :
- lastWasCR = true;
- numberOfCRs++;
- break;
- case '\n' :
- if (!lastWasCR) numberOfCRs++; // merge CR-LF
- lastWasCR = false;
- break;
- default :
- lastWasCR = false;
- }
- }
- return numberOfCRs;
- }
- }