diff options
6 files changed, 142 insertions, 32 deletions
diff --git a/bridge/src/org/aspectj/bridge/ISourceLocation.java b/bridge/src/org/aspectj/bridge/ISourceLocation.java index 8dc343f5e..f43a2f54c 100644 --- a/bridge/src/org/aspectj/bridge/ISourceLocation.java +++ b/bridge/src/org/aspectj/bridge/ISourceLocation.java @@ -56,4 +56,7 @@ public interface ISourceLocation { /** @return getLine()..MAX_LINE */ int getEndLine(); + /** @return String application-specific context for source */ + String getContext(); + } diff --git a/bridge/src/org/aspectj/bridge/SourceLocation.java b/bridge/src/org/aspectj/bridge/SourceLocation.java index d388aba36..882d8af1b 100644 --- a/bridge/src/org/aspectj/bridge/SourceLocation.java +++ b/bridge/src/org/aspectj/bridge/SourceLocation.java @@ -55,6 +55,7 @@ public class SourceLocation implements ISourceLocation, java.io.Serializable { private final int startLine; private final int column; private final int endLine; + private final String context; private boolean noColumn; /** @@ -77,6 +78,10 @@ public class SourceLocation implements ISourceLocation, java.io.Serializable { * @param column int character position of starting location - positive number */ public SourceLocation(File file, int line, int endLine, int column) { + this(file, line, endLine, column, (String) null); + } + + public SourceLocation(File file, int line, int endLine, int column, String context) { if (column == NO_COLUMN) { column = 0; noColumn = true; @@ -92,6 +97,7 @@ public class SourceLocation implements ISourceLocation, java.io.Serializable { this.startLine = line; this.column = column; this.endLine = endLine; + this.context = context; } public File getSourceFile() { @@ -113,10 +119,18 @@ public class SourceLocation implements ISourceLocation, java.io.Serializable { return endLine; } - /** @return String {file:}line{:column} */ + /** @return null String or application-specific context */ + public String getContext() { + return context; + } + + /** @return String {context\n}{file:}line{:column} */ public String toString() { StringBuffer sb = new StringBuffer(); - + if (null != context) { + sb.append(context); + sb.append(LangUtil.EOL); + } if (sourceFile != ISourceLocation.NO_FILE) { sb.append(sourceFile.getPath()); sb.append(":"); diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java index 18fbcdb08..d245cb90f 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceLocation.java @@ -15,13 +15,23 @@ package org.aspectj.ajdt.internal.compiler.lookup; import java.io.File; +import org.aspectj.ajdt.internal.core.builder.EclipseAdapterUtils; import org.aspectj.bridge.ISourceLocation; +import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; +import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.problem.ProblemHandler; public class EclipseSourceLocation implements ISourceLocation { - CompilationResult result; + private static String NO_CONTEXT = "USE_NULL--NO_CONTEXT_AVAILABLE"; + CompilationResult result; int startPos, endPos; + // lazy but final + File file; + int startLine = -1; + int endLine = -1; + int column = -1; + String context; public EclipseSourceLocation(CompilationResult result, int startPos, int endPos) { super(); @@ -31,20 +41,55 @@ public class EclipseSourceLocation implements ISourceLocation { } public File getSourceFile() { - return new File(new String(result.fileName)); + if (null == file) { + file = new File(new String(result.fileName)); + } + return file; } public int getLine() { - return ProblemHandler.searchLineNumber(result.lineSeparatorPositions, startPos); + if (-1 == startLine) { + startLine = ProblemHandler.searchLineNumber(result.lineSeparatorPositions, startPos); + } + return startLine; } public int getColumn() { - return 0; //XXX need better search above to get both + if (-1 == column) { + int lineNumber = getLine(); + if (0 < lineNumber) { + int lineStart = result.lineSeparatorPositions[getLine()]; + int col = startPos - lineStart; // 1-based + if (0 <= col) { + column = col; + } else { + column = 0; + } + } + } + return column; } public int getEndLine() { - return getLine(); //XXX no real need to do better + if (-1 == endLine) { + endLine = ProblemHandler.searchLineNumber(result.lineSeparatorPositions, endPos); + } + return endLine; } + + public String getContext() { + if (null == context) { + ICompilationUnit compilationUnit = result.compilationUnit; + IProblem[] problems = result.problems; + if ((null == compilationUnit) || (null == problems) + || (1 != problems.length)) { // ?? which of n>1 problems? + context = NO_CONTEXT; + } else { + context = EclipseAdapterUtils.makeLocationContext(compilationUnit, problems[0]); + } + } + return (NO_CONTEXT == context ? null : context); + } /** @return String {file:}line{:column} */ @@ -61,5 +106,4 @@ public class EclipseSourceLocation implements ISourceLocation { } return sb.toString(); } - } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseAdapterUtils.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseAdapterUtils.java index 39b6fbf2a..d93d6e8cf 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseAdapterUtils.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/EclipseAdapterUtils.java @@ -19,7 +19,6 @@ import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.Message; import org.aspectj.bridge.SourceLocation; -import org.aspectj.util.LangUtil; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.compiler.util.Util; @@ -110,30 +109,26 @@ public class EclipseAdapterUtils { 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. + * @return ISourceLocation with correct file and lines but not column. + */ public static ISourceLocation makeSourceLocation(ICompilationUnit unit, IProblem problem) { int line = problem.getSourceLineNumber(); File file = new File(new String(problem.getOriginatingFileName())); - return new SourceLocation(file, line, line, 0); + String context = makeLocationContext(unit, problem); + // XXX 0 column is wrong but recoverable from makeLocationContext + return new SourceLocation(file, line, line, 0, context); } - /** This renders entire message text, but also sets up source location */ + /** + * Extract message text and source location, including context. + */ public static IMessage makeMessage(ICompilationUnit unit, IProblem problem) { - //??? would like to know the column as well as line - //??? and also should generate highlighting info ISourceLocation sourceLocation = makeSourceLocation(unit, problem); - - String locationContext = makeLocationContext(unit, problem); - StringBuffer mssg = new StringBuffer(); - - mssg.append(problem.getOriginatingFileName()); - mssg.append(":" + problem.getSourceLineNumber()); - mssg.append(": "); - mssg.append(problem.getMessage()); - mssg.append(LangUtil.EOL); - mssg.append(locationContext); - - return new Message(mssg.toString(), sourceLocation, problem.isError()); - } + return new Message(problem.getMessage(), sourceLocation, problem.isError()); + } private EclipseAdapterUtils() { } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java b/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java index 66dbf35c4..e458e5a47 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java @@ -25,11 +25,13 @@ import org.aspectj.bridge.ICommand; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.IMessageHandler; import org.aspectj.bridge.IMessageHolder; +import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.Message; import org.aspectj.bridge.MessageHandler; import org.aspectj.bridge.MessageUtil; import org.aspectj.bridge.ReflectionFactory; import org.aspectj.bridge.Version; +import org.aspectj.util.FileUtil; import org.aspectj.util.LangUtil; /** @@ -343,7 +345,10 @@ public class Main { handler.handleMessage(new Message(message, IMessage.FAIL, thrown, null)); } - /** interceptor IMessageHandler to print as we go */ + /** + * interceptor IMessageHandler to print as we go. + * This formats all messages to the user. + */ public static class MessagePrinter implements IMessageHandler { public static final IMessageHandler VERBOSE @@ -372,6 +377,15 @@ public class Main { return false; } + /** + * Render message differently. + * If abort, then prefix stack trace with feedback request. + * If the actual message is empty, then use toString on the whole. + * Prefix message part with file:line; + * If it has context, suffix message with context. + * @param message the IMessage to render + * @return String rendering IMessage (never null) + */ protected String render(IMessage message) { IMessage.Kind kind = message.getKind(); if (kind.equals(IMessage.ABORT)) { @@ -382,11 +396,36 @@ public class Main { return Main.renderExceptionForUser(t); } } - String m = message.getMessage(); - if (LangUtil.isEmpty(m)) { - m = message.toString(); + StringBuffer sb = new StringBuffer(); + String text = message.getMessage(); + boolean toString = (LangUtil.isEmpty(text)); + if (toString) { + text = message.toString(); + } + ISourceLocation loc = message.getISourceLocation(); + String context = null; + if (null != loc) { + File file = loc.getSourceFile(); + if (null != file) { + String name = file.getName(); + if (!toString || (-1 == text.indexOf(name))) { + sb.append(FileUtil.getBestPath(file)); + sb.append(":" + loc.getLine()); + int col = loc.getColumn(); + if (0 < col) { + sb.append(":" + col); + } + sb.append(" "); + } + } + context = loc.getContext(); + } + sb.append(text); + if (null != context) { + sb.append(LangUtil.EOL); + sb.append(context); } - return m; + return sb.toString(); } public boolean isIgnoring(IMessage.Kind kind) { diff --git a/util/src/org/aspectj/util/FileUtil.java b/util/src/org/aspectj/util/FileUtil.java index 35405ce59..490a79921 100644 --- a/util/src/org/aspectj/util/FileUtil.java +++ b/util/src/org/aspectj/util/FileUtil.java @@ -305,7 +305,22 @@ public class FileUtil { } return path; } - + + /** + * Render as best path, canonical or absolute. + * @param file the File to get the path for (not null) + * @return String of the best-available path + * @throws IllegalArgumentException if file is null + */ + public static String getBestPath(File file) { + LangUtil.throwIaxIfNull(file, "file"); + try { + return file.getCanonicalPath(); + } catch (IOException e) { + return file.getAbsolutePath(); + } + } + /** @return array same length as input, with String absolute paths */ public static String[] getAbsolutePaths(File[] files) { if ((null == files) || (0 == files.length)) { |