org.aspectj.ajdt.internal.core.builder.EclipseAdapterUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjtools Show documentation
Show all versions of aspectjtools Show documentation
Tools from the AspectJ project
/* *******************************************************************
* 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() {
}
}