Package org.aspectj.org.eclipse.jdt.internal.eval

Source Code of org.aspectj.org.eclipse.jdt.internal.eval.VariablesEvaluator

/*******************************************************************************
* 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;
}
}
TOP

Related Classes of org.aspectj.org.eclipse.jdt.internal.eval.VariablesEvaluator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.