Package org.aspectj.ajdt.internal.core.builder

Source Code of org.aspectj.ajdt.internal.core.builder.EclipseAdapterUtils

/* *******************************************************************
* Copyright (c) 1999-2001 Xerox Corporation,
*               2002 Palo Alto Research Center, Incorporated (PARC).
* 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:
*     PARC     initial implementation
* ******************************************************************/

package org.aspectj.ajdt.internal.core.builder;

import java.io.File;

import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IProgressListener;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.Message;
import org.aspectj.bridge.SourceLocation;
import org.aspectj.org.eclipse.jdt.core.compiler.IProblem;
import org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.aspectj.weaver.LintMessage;
import org.aspectj.weaver.World;

public class EclipseAdapterUtils {

  // XXX some cut-and-paste from eclipse sources
  public static String makeLocationContext(ICompilationUnit compilationUnit, IProblem problem) {
    // extra from the source the innacurate token
    // and "highlight" it using some underneath ^^^^^
    // put some context around too.

    // this code assumes that the font used in the console is fixed size

    // sanity .....
    int startPosition = problem.getSourceStart();
    int endPosition = problem.getSourceEnd();

    if ((startPosition > endPosition) || ((startPosition <= 0) && (endPosition <= 0)) || compilationUnit == null)
      //return Util.bind("problem.noSourceInformation"); //$NON-NLS-1$
      return "(no source information available)";

    final char SPACE = '\u0020';
    final char MARK = '^';
    final char TAB = '\t';
    char[] source = compilationUnit.getContents();
    // the next code tries to underline the token.....
    // it assumes (for a good display) that token source does not
    // contain any \r \n. This is false on statements !
    // (the code still works but the display is not optimal !)

    // compute the how-much-char we are displaying around the inaccurate token
    int begin = startPosition >= source.length ? source.length - 1 : startPosition;
    if (begin == -1)
      return "(no source information available)"; // Dont like this - why does it occur? pr152835
    int relativeStart = 0;
    int end = endPosition >= source.length ? source.length - 1 : endPosition;
    int relativeEnd = 0;
    label: for (relativeStart = 0;; relativeStart++) {
      if (begin == 0)
        break label;
      if ((source[begin - 1] == '\n') || (source[begin - 1] == '\r'))
        break label;
      begin--;
    }
    label: for (relativeEnd = 0;; relativeEnd++) {
      if ((end + 1) >= source.length)
        break label;
      if ((source[end + 1] == '\r') || (source[end + 1] == '\n')) {
        break label;
      }
      end++;
    }
    // extract the message form the source
    char[] extract = new char[end - begin + 1];
    System.arraycopy(source, begin, extract, 0, extract.length);
    char c;
    // remove all SPACE and TAB that begin the error message...
    int trimLeftIndex = 0;
    while ((((c = extract[trimLeftIndex++]) == TAB) || (c == SPACE)) && trimLeftIndex < extract.length) {
    }
    if (trimLeftIndex >= extract.length)
      return new String(extract) + "\n";
    System.arraycopy(extract, trimLeftIndex - 1, extract = new char[extract.length - trimLeftIndex + 1], 0, extract.length);
    relativeStart -= trimLeftIndex;
    // buffer spaces and tabs in order to reach the error position
    int pos = 0;
    char[] underneath = new char[extract.length]; // can't be bigger
    for (int i = 0; i <= relativeStart; i++) {
      if (extract[i] == TAB) {
        underneath[pos++] = TAB;
      } else {
        underneath[pos++] = SPACE;
      }
    }
    // mark the error position
    for (int i = startPosition + trimLeftIndex; // AMC if we took stuff off the start, take it into account!
    i <= (endPosition >= source.length ? source.length - 1 : endPosition); i++)
      underneath[pos++] = MARK;
    // resize underneathto remove 'null' chars
    System.arraycopy(underneath, 0, underneath = new char[pos], 0, pos);

    return new String(extract) + "\n" + new String(underneath); //$NON-NLS-2$ //$NON-NLS-1$
  }

  /**
   * Extract source location file, start and end lines, and context. Column is not extracted correctly.
   * @param progressListener
   *
   * @return ISourceLocation with correct file and lines but not column.
   */
  public static ISourceLocation makeSourceLocation(ICompilationUnit unit, IProblem problem, IProgressListener progressListener) {
    int line = problem.getSourceLineNumber();
    File file = new File(new String(problem.getOriginatingFileName()));
    // cheat here...269912 - don't build the context if under IDE control
    if (progressListener!=null) {
      return new SourceLocation(file, line, line, 0, null);
    } else {
      String context = makeLocationContext(unit, problem);
      // XXX 0 column is wrong but recoverable from makeLocationContext
      return new SourceLocation(file, line, line, 0, context);
    }
  }

  /**
   * Extract message text and source location, including context.
   *
   * @param world
   * @param progressListener
   */
  public static IMessage makeMessage(ICompilationUnit unit, IProblem problem, World world, IProgressListener progressListener) {
    ISourceLocation sourceLocation = makeSourceLocation(unit, problem, progressListener);
    IProblem[] seeAlso = problem.seeAlso();
    // If the user has turned off classfile line number gen, then we may not be able to tell them
    // about all secondary locations (pr209372)
    int validPlaces = 0;
    for (int ii = 0; ii < seeAlso.length; ii++) {
      if (seeAlso[ii].getSourceLineNumber() >= 0)
        validPlaces++;
    }
    ISourceLocation[] seeAlsoLocations = new ISourceLocation[validPlaces];
    int pos = 0;
    for (int i = 0; i < seeAlso.length; i++) {
      if (seeAlso[i].getSourceLineNumber() >= 0) {
        seeAlsoLocations[pos++] = new SourceLocation(new File(new String(seeAlso[i].getOriginatingFileName())), seeAlso[i]
            .getSourceLineNumber());
      }
    }
    // We transform messages from AJ types to eclipse IProblems
    // and back to AJ types. During their time as eclipse problems,
    // we remember whether the message originated from a declare
    // in the extraDetails.
    String extraDetails = problem.getSupplementaryMessageInfo();
    boolean declared = false;
    boolean isLintMessage = false;
    String lintkey = null;
    if (extraDetails != null && extraDetails.endsWith("[deow=true]")) {
      declared = true;
      extraDetails = extraDetails.substring(0, extraDetails.length() - "[deow=true]".length());
    }
    if (extraDetails != null && extraDetails.indexOf("[Xlint:") != -1) {
      isLintMessage = true;
      lintkey = extraDetails.substring(extraDetails.indexOf("[Xlint:"));
      lintkey = lintkey.substring("[Xlint:".length());
      lintkey = lintkey.substring(0, lintkey.indexOf("]"));
    }

    // If the 'problem' represents a TO DO kind of thing then use the message kind that
    // represents this so AJDT sees it correctly.
    IMessage.Kind kind;
    if (problem.getID() == IProblem.Task) {
      kind = IMessage.TASKTAG;
    } else {
      if (problem.isError()) {
        kind = IMessage.ERROR;
      } else {
        kind = IMessage.WARNING;
      }
    }
    IMessage msg = null;
    if (isLintMessage) {
      msg = new LintMessage(problem.getMessage(), extraDetails, world.getLint().fromKey(lintkey), kind, sourceLocation, null,
          seeAlsoLocations, declared, problem.getID(), problem.getSourceStart(), problem.getSourceEnd());
    } else {
      msg = new Message(problem.getMessage(), extraDetails, kind, sourceLocation, null, seeAlsoLocations, declared, problem
          .getID(), problem.getSourceStart(), problem.getSourceEnd());
    }
    return msg;
  }

  public static IMessage makeErrorMessage(ICompilationUnit unit, String text, Exception ex) {
    ISourceLocation loc = new SourceLocation(new File(new String(unit.getFileName())), 0, 0, 0, "");
    IMessage msg = new Message(text, IMessage.ERROR, ex, loc);
    return msg;
  }

  public static IMessage makeErrorMessage(String srcFile, String text, Exception ex) {
    ISourceLocation loc = new SourceLocation(new File(srcFile), 0, 0, 0, "");
    IMessage msg = new Message(text, IMessage.ERROR, ex, loc);
    return msg;
  }

  private EclipseAdapterUtils() {
  }

}
TOP

Related Classes of org.aspectj.ajdt.internal.core.builder.EclipseAdapterUtils

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.