diff options
author | paltherr <paltherr@epfl.ch> | 2003-06-16 12:37:20 +0000 |
---|---|---|
committer | paltherr <paltherr@epfl.ch> | 2003-06-16 12:37:20 +0000 |
commit | 9c9dfb24a48f11e175d8f82417e7b9c7ab78f7c7 (patch) | |
tree | eada2530c9586b6c61afaedffa30c023a4d12c49 /sources | |
parent | 97e75ddc91094834f60b868e16e14d3417359791 (diff) | |
download | scala-9c9dfb24a48f11e175d8f82417e7b9c7ab78f7c7.tar.gz scala-9c9dfb24a48f11e175d8f82417e7b9c7ab78f7c7.tar.bz2 scala-9c9dfb24a48f11e175d8f82417e7b9c7ab78f7c7.zip |
- Made SourceFile and Position scala-independan...
- Made SourceFile and Position scala-independant (moved them to
ch.epfl.lamp.util) - Added position arguments to methods of class
Reporter - Changed printing of positions to display the whole path not
only the file name.
Diffstat (limited to 'sources')
22 files changed, 211 insertions, 130 deletions
diff --git a/sources/scala/tools/scalai/Compiler.java b/sources/scala/tools/scalai/Compiler.java index 3269322f69..7e79fa692c 100644 --- a/sources/scala/tools/scalai/Compiler.java +++ b/sources/scala/tools/scalai/Compiler.java @@ -31,7 +31,6 @@ import scalac.symtab.TermSymbol; import scalac.util.Debug; import scalac.util.Name; import scalac.util.Names; -import scalac.util.Position; import scala.runtime.RunTime; @@ -97,12 +96,12 @@ public class Compiler { Function.JavaMethod(getInvocationHandler_method), new Code[] { Code.Self}, - Position.NOPOS), + 0), Function.JavaMethod(equals_method), new Code[] { Code.Load( Code.Null, Variable.Argument(0))}, - Position.NOPOS), + 0), 0)); // !!! any_methods.put(_, equals_code); any_methods.put(equals_method, equals_code); @@ -122,7 +121,7 @@ public class Compiler { definitions.HASHCODE, Code.Invoke( Code.Self, Function.HashCode, new Code[0], - Position.NOPOS), + 0), 0)); any_methods.put(definitions.HASHCODE, hashCode_code); any_methods.put(hashCode_method, hashCode_code); @@ -146,7 +145,7 @@ public class Compiler { definitions.TOSTRING, Code.Invoke( Code.Self, Function.ToString, new Code[0], - Position.NOPOS), + 0), 0)); any_methods.put(definitions.TOSTRING, toString_code); any_methods.put(toString_method, toString_code); @@ -183,7 +182,7 @@ public class Compiler { Code.Load( Code.Null, Variable.Argument(0)) }, - Position.NOPOS), + 0), 0)); any_methods.put(definitions.EQEQ, eqeq_code); environment.insertFunction(definitions.EQEQ, Function.EqEq); @@ -203,11 +202,11 @@ public class Compiler { Code.Load( Code.Null, Variable.Argument(0)) }, - Position.NOPOS)}, - Position.NOPOS), + 0)}, + 0), Function.JavaMethod(bang_method), new Code[0], - Position.NOPOS), + 0), 0)); any_methods.put(definitions.BANGEQ, bangeq_code); environment.insertFunction(definitions.BANGEQ, Function.BangEq); @@ -330,8 +329,8 @@ public class Compiler { // Private Methods - private Symbol newGlobalVariable(Type type, Object value) { - Symbol symbol = new TermSymbol(Position.NOPOS, - Name.fromString(value.toString()), definitions.ROOT, 0); + Symbol symbol = new TermSymbol( + 0, Name.fromString(value.toString()), definitions.ROOT, 0); symbol.setInfo(type); environment.insertVariable(symbol, Variable.Global(value)); return symbol; diff --git a/sources/scala/tools/scalai/EvaluatorException.java b/sources/scala/tools/scalai/EvaluatorException.java index e6049deff5..22807adec5 100644 --- a/sources/scala/tools/scalai/EvaluatorException.java +++ b/sources/scala/tools/scalai/EvaluatorException.java @@ -11,10 +11,10 @@ package scalai; import java.util.List; import java.util.ArrayList; +import ch.epfl.lamp.util.Position; + import scalac.Global; -import scalac.ast.parser.Sourcefile; import scalac.symtab.Symbol; -import scalac.util.Position; public class EvaluatorException extends RuntimeException { @@ -54,7 +54,7 @@ public class EvaluatorException extends RuntimeException { buffer.append('.'); buffer.append(method.nameString()); buffer.append('('); - buffer.append(Sourcefile.files[Position.file(pos)]); + buffer.append(Position.file(pos)); buffer.append(':'); buffer.append(Position.line(pos)); buffer.append(")"); diff --git a/sources/scala/tools/scalai/Interpreter.java b/sources/scala/tools/scalai/Interpreter.java index 7e5ec5446d..40aa1efa81 100644 --- a/sources/scala/tools/scalai/Interpreter.java +++ b/sources/scala/tools/scalai/Interpreter.java @@ -63,7 +63,7 @@ public class Interpreter { public EvaluatorResult interpret(String input, boolean interactive) { if (input.trim().length() == 0) return EvaluatorResult.Void; - global.compile(input + ";", interactive); + global.compile("<console>", input + ";", interactive); return interpret(interactive); } @@ -183,7 +183,7 @@ public class Interpreter { // Private Methods - Signaling errors private void error(String message) { - global.reporter.error("error: " + message); + global.reporter.error(null, message); } //######################################################################## diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java index 0f0a144632..51ecb2a7a6 100644 --- a/sources/scalac/Global.java +++ b/sources/scalac/Global.java @@ -8,6 +8,8 @@ package scalac; +import ch.epfl.lamp.util.SourceFile; + import java.io.*; import java.util.*; import scalac.util.*; @@ -231,7 +233,7 @@ public class Global { for (int i = 0; i < files.length; i++) { String file = files[i]; try { - units.add(new Unit(this, new Sourcefile(file), console)); + units.add(new Unit(this, new SourceFile(file), console)); } catch (FileNotFoundException e) { error("file " + file + " not found"); } catch (IOException e) { @@ -244,9 +246,9 @@ public class Global { /** the top-level compilation process */ - public void compile(String input, boolean console) { + public void compile(String filename, String input, boolean console) { reporter.resetCounters(); - Sourcefile source = new Sourcefile(input.getBytes()); + SourceFile source = new SourceFile(filename, input.getBytes()); units = new Unit[]{new Unit(this, source, console)}; compile(); } @@ -283,8 +285,8 @@ public class Global { imports.clear(); for (Iterator it = compiledNow.keySet().iterator(); it.hasNext();) { Symbol sym = (Symbol) it.next(); - Sourcefile f = (Sourcefile) compiledNow.get(sym); - sym.reset(new SourceCompleter(this, f.filename)); + SourceFile f = (SourceFile) compiledNow.get(sym); + sym.reset(new SourceCompleter(this, f.name())); } } compiledNow.clear(); @@ -472,13 +474,13 @@ public class Global { /** issue a global error */ public void error(String message) { - reporter.error("error: " + message); + reporter.error(null, message); } /** issue a global warning */ public void warning(String message) { - reporter.warning("warning: " + message); + reporter.warning(null, message); } /** issue an operation note diff --git a/sources/scalac/Unit.java b/sources/scalac/Unit.java index 5f215b80ec..bc96a972c7 100644 --- a/sources/scalac/Unit.java +++ b/sources/scalac/Unit.java @@ -8,9 +8,11 @@ package scalac; +import ch.epfl.lamp.util.SourceFile; +import ch.epfl.lamp.util.Position; + import scalac.util.*; import scalac.symtab.NameMangler; -import scalac.ast.parser.Sourcefile; import scalac.ast.Tree; import scala.compiler.typechecker.*; import java.io.*; @@ -30,7 +32,7 @@ public class Unit { /** the associated source code file */ - public final Sourcefile source; + public final SourceFile source; /** does this unit come from the interpreter console */ @@ -60,11 +62,12 @@ public class Unit { */ public int notes; - public Unit(Global global, Sourcefile source, boolean console) { + public Unit(Global global, SourceFile source, boolean console) { this.global = global; this.source = source; this.console = console; } + /* public void print(String message) { print(System.out, message); @@ -77,34 +80,17 @@ public class Unit { out.println("[[end " + message + "]]"); } */ - /** issue an error in this compilation unit - */ - public void error(String message) { - error(Position.NOPOS, message); - } /** issue an error in this compilation unit at a specific location */ public void error(int pos, String message) { - boolean hidden = source.testAndSetLog(pos, message); - if (!hidden) errors++; - global.reporter.error(source.getMessage(pos, message), hidden); - } - - /** issue a warning in this compilation unit - */ - public void warning(String message) { - warning(Position.NOPOS, message); + global.reporter.error(decode(pos), message); } /** issue a warning in this compilation unit at a specific location */ public void warning(int pos, String message) { - if (global.reporter.nowarn) return; - message = "warning: " + message; - boolean hidden = source.testAndSetLog(pos, message); - if (!hidden) warnings++; - global.reporter.warning(source.getMessage(pos, message), hidden); + global.reporter.warning(decode(pos), message); } /** return a string representation @@ -112,4 +98,14 @@ public class Unit { public String toString() { return source.toString(); } + + + private Position decode(int pos) { + Position position = new Position(pos); + if (position.file().id() == 0) + if (/* !!! source.id() > Position.FILE_MASK && */ position.line() != 0) + return source.getPosition(position.line(), position.column()); + return position; + } + } diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java index 8c478044fc..e483f09c04 100644 --- a/sources/scalac/ast/parser/Parser.java +++ b/sources/scalac/ast/parser/Parser.java @@ -8,6 +8,8 @@ package scalac.ast.parser; +import ch.epfl.lamp.util.Position; + import java.util.*; import scalac.*; import scalac.util.*; @@ -98,8 +100,8 @@ public class Parser implements Tokens { int accept(int token) { int pos = s.pos; if (s.token != token) { - int errpos = ((s.pos >>> Position.LINESHIFT) > - (s.lastpos >>> Position.LINESHIFT)) ? + int errpos = ((s.pos >>> Position.COLUMN_BITS) > + (s.lastpos >>> Position.COLUMN_BITS)) ? s.lastpos : s.pos; syntaxError(errpos, s.token2string(token) + " expected but " + s.token2string(s.token) + " found.", true); diff --git a/sources/scalac/ast/parser/Scanner.java b/sources/scalac/ast/parser/Scanner.java index c742cd929a..3555dcad5e 100644 --- a/sources/scalac/ast/parser/Scanner.java +++ b/sources/scalac/ast/parser/Scanner.java @@ -8,9 +8,11 @@ package scalac.ast.parser; +import ch.epfl.lamp.util.Position; +import ch.epfl.lamp.util.SourceFile; + import scalac.*; import scalac.util.Name; -import scalac.util.Position; /** A scanner for the programming language Scala. * @@ -22,10 +24,10 @@ public class Scanner extends TokenData { /** layout & character constants */ public int tabinc = 8; - public final static byte LF = 0xA; - protected final static byte FF = 0xC; - protected final static byte CR = 0xD; - protected final static byte SU = Sourcefile.SU; + protected final static byte LF = SourceFile.LF; + protected final static byte FF = SourceFile.FF; + protected final static byte CR = SourceFile.CR; + protected final static byte SU = SourceFile.SU; /** the names of all tokens */ @@ -66,7 +68,7 @@ public class Scanner extends TokenData { /** the current sourcefile */ - public Sourcefile currentSource; + public SourceFile currentSource; /** a buffer for character and string literals */ @@ -82,7 +84,7 @@ public class Scanner extends TokenData { */ public Scanner(Unit unit) { this.unit = unit; - buf = (currentSource = unit.source).getBuffer(); + buf = (currentSource = unit.source).bytes(); cline = 1; bp = -1; ccol = 0; @@ -124,8 +126,8 @@ public class Scanner extends TokenData { break; default: if (token == EOF || - ((pos >>> Position.LINESHIFT) > - (prevpos >>> Position.LINESHIFT))) { + ((pos >>> Position.COLUMN_BITS) > + (prevpos >>> Position.COLUMN_BITS))) { next.copyFrom(this); this.token = SEMI; this.pos = prevpos; @@ -165,7 +167,7 @@ public class Scanner extends TokenData { */ public void fetchToken() { if (token == EOF) return; - lastpos = Position.encode(cline, ccol, currentSource.id); + lastpos = Position.encode(currentSource, cline, ccol); int index = bp; while(true) { switch (ch) { @@ -192,7 +194,7 @@ public class Scanner extends TokenData { nextch(); break; default: - pos = Position.encode(cline, ccol, currentSource.id); + pos = Position.encode(currentSource, cline, ccol); index = bp; switch (ch) { case 'A': case 'B': case 'C': case 'D': case 'E': @@ -324,7 +326,6 @@ public class Scanner extends TokenData { return; case SU: token = EOF; - currentSource.lines = cline; return; default: nextch(); @@ -573,7 +574,7 @@ public class Scanner extends TokenData { putch(ch); break; default: - syntaxError(Position.encode(cline, ccol, currentSource.id) - 1, "invalid escape character"); + syntaxError(Position.encode(currentSource, cline, ccol) - 1, "invalid escape character"); putch(ch); } nextch(); diff --git a/sources/scalac/backend/jvm/GenJVM.java b/sources/scalac/backend/jvm/GenJVM.java index 072f9564ae..11a4cd1316 100644 --- a/sources/scalac/backend/jvm/GenJVM.java +++ b/sources/scalac/backend/jvm/GenJVM.java @@ -13,6 +13,8 @@ package scalac.backend.jvm; +import ch.epfl.lamp.util.Position; + import scalac.*; import scalac.backend.*; import scalac.util.*; diff --git a/sources/scalac/backend/msil/GenMSIL.java b/sources/scalac/backend/msil/GenMSIL.java index c580b06dd5..a12ad149da 100644 --- a/sources/scalac/backend/msil/GenMSIL.java +++ b/sources/scalac/backend/msil/GenMSIL.java @@ -16,7 +16,6 @@ import scalac.util.Debug; import scalac.util.Name; import scalac.util.Names; -import scalac.util.Position; import scalac.util.Debug; import scalac.ast.Tree; import Tree.*; @@ -32,6 +31,7 @@ import scalac.backend.Primitives; import ch.epfl.lamp.compiler.msil.*; import ch.epfl.lamp.compiler.msil.emit.*; +import ch.epfl.lamp.util.Position; import Item.*; @@ -1660,12 +1660,11 @@ public class GenMSIL /*implements Modifiers */ { /** */ void log(String message) { - System.err.println(message); - //log(1, message); + global.reporter.printMessage(message); } void logErr(int pos, String message) { - log(currUnit.source.getMessage(pos, message)); + global.reporter.printMessage(new Position(pos), message); } void logErr(String message) { diff --git a/sources/scalac/backend/msil/TypeCreator.java b/sources/scalac/backend/msil/TypeCreator.java index e89bff38de..02e519d1e2 100644 --- a/sources/scalac/backend/msil/TypeCreator.java +++ b/sources/scalac/backend/msil/TypeCreator.java @@ -15,7 +15,6 @@ import scalac.ast.Tree; import scalac.util.Debug; import scalac.util.Name; import scalac.util.Names; -import scalac.util.Position; import scalac.symtab.Kinds; import scalac.symtab.TypeTags; import scalac.symtab.Symbol; @@ -27,6 +26,7 @@ import Tree.*; import ch.epfl.lamp.compiler.msil.*; import ch.epfl.lamp.compiler.msil.emit.*; +import ch.epfl.lamp.util.Position; import java.util.Map; import java.util.ArrayList; @@ -727,16 +727,11 @@ public final class TypeCreator } void log(String message) { - System.err.println(message); - //log(1, message); + global.reporter.printMessage(message); } void logErr(String message) { - log(formatMessage(message)); - } - - String formatMessage(String message) { - return unit.source.getMessage(pos, message); + global.reporter.printMessage(new Position(pos), message); } } // class TypeCreator diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index 61b078ba39..b729dc4b2a 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -8,6 +8,7 @@ package scalac.symtab; +import ch.epfl.lamp.util.Position; import scalac.*; import scalac.util.*; import scalac.symtab.classfile.*; diff --git a/sources/scalac/symtab/SourceCompleter.java b/sources/scalac/symtab/SourceCompleter.java index fefe00ab16..b315733922 100644 --- a/sources/scalac/symtab/SourceCompleter.java +++ b/sources/scalac/symtab/SourceCompleter.java @@ -8,6 +8,8 @@ package scalac.symtab; +import ch.epfl.lamp.util.SourceFile; + import scalac.*; import scalac.ast.parser.*; import scalac.typechecker.Analyzer; @@ -36,7 +38,7 @@ public class SourceCompleter extends Type.LazyType { try { String fname = filename; long msec = System.currentTimeMillis(); - Unit unit = new Unit(global, new Sourcefile(filename), false); + Unit unit = new Unit(global, new SourceFile(filename), false); filename = null; global.PHASE.PARSER.apply(unit); global.PHASE.ANALYZER.lateEnter(global, unit, c); diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index 7ab12576da..23b062800f 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -10,6 +10,7 @@ package scalac.symtab; +import ch.epfl.lamp.util.Position; import scalac.ApplicationError; import scalac.Global; import scalac.PhaseDescriptor; @@ -17,7 +18,6 @@ import scalac.util.ArrayApply; import scalac.util.Name; import scalac.util.Names; import scalac.util.NameTransformer; -import scalac.util.Position; import scalac.util.Debug; import scalac.symtab.classfile.*; diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 36e7431fdf..3855e86634 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -9,6 +9,7 @@ package scalac.symtab; +import ch.epfl.lamp.util.Position; import scalac.ApplicationError; import scalac.util.*; import scalac.Global; diff --git a/sources/scalac/transformer/PatternMatcher.java b/sources/scalac/transformer/PatternMatcher.java index 11dfb13d51..0e725ca302 100644 --- a/sources/scalac/transformer/PatternMatcher.java +++ b/sources/scalac/transformer/PatternMatcher.java @@ -8,6 +8,8 @@ package scalac.transformer; +import ch.epfl.lamp.util.Position; + import scalac.*; import scalac.ast.*; import scalac.util.*; diff --git a/sources/scalac/transformer/PatternNode.java b/sources/scalac/transformer/PatternNode.java index 506fad2708..e4abdae047 100644 --- a/sources/scalac/transformer/PatternNode.java +++ b/sources/scalac/transformer/PatternNode.java @@ -8,6 +8,7 @@ package scalac.transformer; +import ch.epfl.lamp.util.Position; import scalac.*; import scalac.ast.*; import scalac.symtab.*; @@ -15,7 +16,7 @@ import scalac.typechecker.*; public class PatternNode { - public int pos = scalac.util.Position.NOPOS; + public int pos = Position.NOPOS; public Type type; public PatternNode or; public PatternNode and; diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java index 11dfb13d51..0e725ca302 100644 --- a/sources/scalac/transformer/matching/PatternMatcher.java +++ b/sources/scalac/transformer/matching/PatternMatcher.java @@ -8,6 +8,8 @@ package scalac.transformer; +import ch.epfl.lamp.util.Position; + import scalac.*; import scalac.ast.*; import scalac.util.*; diff --git a/sources/scalac/transformer/matching/PatternNode.java b/sources/scalac/transformer/matching/PatternNode.java index 506fad2708..e4abdae047 100644 --- a/sources/scalac/transformer/matching/PatternNode.java +++ b/sources/scalac/transformer/matching/PatternNode.java @@ -8,6 +8,7 @@ package scalac.transformer; +import ch.epfl.lamp.util.Position; import scalac.*; import scalac.ast.*; import scalac.symtab.*; @@ -15,7 +16,7 @@ import scalac.typechecker.*; public class PatternNode { - public int pos = scalac.util.Position.NOPOS; + public int pos = Position.NOPOS; public Type type; public PatternNode or; public PatternNode and; diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index b4b9d078d0..f4c79f4f94 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -15,6 +15,7 @@ package scalac.typechecker; +import ch.epfl.lamp.util.Position; import scalac.*; import scalac.util.*; import scalac.ast.*; diff --git a/sources/scalac/typechecker/AnalyzerPhase.java b/sources/scalac/typechecker/AnalyzerPhase.java index 1b36ccede7..6d61ba3d01 100644 --- a/sources/scalac/typechecker/AnalyzerPhase.java +++ b/sources/scalac/typechecker/AnalyzerPhase.java @@ -8,6 +8,7 @@ package scalac.typechecker; +import ch.epfl.lamp.util.Position; import scalac.*; import scalac.util.*; import scalac.ast.*; diff --git a/sources/scalac/util/OptionParser.java b/sources/scalac/util/OptionParser.java index 4796c96f93..c2c3af6e6f 100644 --- a/sources/scalac/util/OptionParser.java +++ b/sources/scalac/util/OptionParser.java @@ -8,6 +8,8 @@ package scalac.util; +import ch.epfl.lamp.util.Position; + import java.text.Format; import java.text.MessageFormat; import java.util.List; @@ -106,11 +108,11 @@ public class CommandParser { } public void error(String message) { - reporter.error(product + ": " + message); + reporter.error(new Position(product), message); } public void warning(String message) { - reporter.warning(product + ": " + message); + reporter.warning(new Position(product), message); } } diff --git a/sources/scalac/util/Reporter.java b/sources/scalac/util/Reporter.java index c4a50faf8e..ccf466ae7d 100644 --- a/sources/scalac/util/Reporter.java +++ b/sources/scalac/util/Reporter.java @@ -8,37 +8,59 @@ package scalac.util; +import ch.epfl.lamp.util.Position; + import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.PrintWriter; import java.io.IOException; +import java.util.HashSet; + import scalac.ApplicationError; public class Reporter { //######################################################################## - // Private state + // Private Fields + /** The reader to ask for failures on demand */ private final BufferedReader reader; + /** The writer to print messages */ private final PrintWriter writer; + /** Log of error positions (used to avoid printing errors twice) */ + private final HashSet positions; + /** Number of errors issued totally */ private int errors; /** Number of warning issued totally */ private int warnings; //######################################################################## - // Reporter constructors + // Public Fields + /** Whether warnings should be issued */ + public boolean nowarn; + /** Whether information messages should be issued */ + public boolean verbose; + /** Whether a prompt should be displayed after errors and warnings */ + public boolean prompt; + + //######################################################################## + // Public Constructors + + /** Initializes a new instance. */ public Reporter() { this( new BufferedReader(new InputStreamReader(System.in)), new PrintWriter(System.err, true)); } + /** Initializes a new instance. */ public Reporter(BufferedReader reader, PrintWriter writer) { this.reader = reader; this.writer = writer; + this.positions = new HashSet(); this.prompt = false; this.nowarn = false; this.verbose = false; @@ -46,111 +68,146 @@ public class Reporter { } //######################################################################## - // Reporter state + // Public Methods - Count - /** Whether warnings should be issued */ - public boolean nowarn; - /** Whether information messages should be issued */ - public boolean verbose; - /** Whether a prompt should be displayed after errors and warnings */ - public boolean prompt; - - //######################################################################## - // Reporter interface - query - - /** Return the number of errors issued totally */ + /** Returns the number of errors issued totally */ public int errors() { return errors; } - /** Return the number of warnings issued totally */ + /** Returns the number of warnings issued totally */ public int warnings() { return warnings; } - /** Return the number of errors issued totally as a string */ + /** Returns the number of errors issued totally as a string */ public String getErrorCountString() { return getCountString(errors, "error"); } - /** Return the number of warnings issued totally as a string */ + /** Returns the number of warnings issued totally as a string */ public String getWarningCountString() { return getCountString(warnings, "warning"); } - public String getCountString(int count, String what) { - switch (count) { - case 0: return "no " + what + "s"; - case 1: return "one " + what; - case 2: return "two " + what + "s"; - case 3: return "three " + what + "s"; - case 4: return "four " + what + "s"; - default: return count + " " + what + "s"; + /** Returns a string meaning "n elements". */ + public String getCountString(int n, String elements) { + switch (n) { + case 0: return "no " + elements + "s"; + case 1: return "one " + elements; + case 2: return "two " + elements + "s"; + case 3: return "three " + elements + "s"; + case 4: return "four " + elements + "s"; + default: return n + " " + elements + "s"; } } - //######################################################################## - // Reporter interface - report - - /** Reset all counters */ + /** Resets all counters */ public void resetCounters() { errors = 0; warnings = 0; } - /** Issue a message */ + //######################################################################## + // Public Methods - Report + + /** Issues a message */ public void report(String message) { - writer.println(message); + printMessage(message); } - /** Issue a message */ + /** Issues a message */ public void inform(String message) { - if (verbose) report(message); - } - - /** Issue an error */ - public void error(String message) { - error(message, false); + if (verbose) printMessage(message); } - /** Issue an error if it is not hidden */ - public void error(String message, boolean hidden) { - if (!hidden || prompt) report(message); + /** Issues an error */ + public void error(Position position, String message) { + boolean hidden = testAndLog(position); + if (!hidden || prompt) printError(position, message); if (!hidden) errors++; if (prompt) failOnDemand(); } - /** Issue a warning */ - public void warning(String message) { - warning(message, false); - } - - /** Issue a warning if it is not hidden */ - public void warning(String message, boolean hidden) { + /** Issues a warning */ + public void warning(Position position, String message) { + boolean hidden = testAndLog(position); if (nowarn) return; - if (!hidden || prompt) report(message); + if (!hidden || prompt) printWarning(position, message); if (!hidden) warnings++; if (prompt) failOnDemand(); } + //######################################################################## + // Public Methods - Print + + /** Prints the message. */ + public void printMessage(String message) { + writer.println(message); + } + + /** Prints the message with the given position indication. */ + public void printMessage(Position position, String message) { + if (position != null && position.file().id() != 0) { + message = " " + message; + if (position.line() != 0) + message = position.line() + ":" + message; + message = position.file().name() + ":" + message; + } + printMessage(message); + printSourceLine(position); + } + + /** Prints the error message. */ + public void printError(Position position, String message) { + if (position != null && position.file().id() == 0) + message = "error: " + message; + printMessage(position, message); + } + + /** Prints the warning message. */ + public void printWarning(Position position, String message) { + message = "warning: " + message; + printMessage(position, message); + } + + /** Prints the number of errors and warnings if their are non-zero. */ public void printSummary() { if (errors() > 0) report(getErrorCountString() + " found"); if (warnings() > 0) report(getWarningCountString() + " found"); } + /** Prints the source line of the given position. */ + public void printSourceLine(Position position) { + if (position == null || position.file().id() == 0) return; + if (position.line() == 0) return; + printMessage(position.file().getLine(position.line())); + printColumnMarker(position); + } + + /** Prints the column marker of the given position. */ + public void printColumnMarker(Position position) { + int column = position == null ? 0 : position.column(); + StringBuffer buffer = new StringBuffer(column); + for (int i = 1; i < column; i++) buffer.append(' '); + if (column > 0) buffer.append('^'); + printMessage(buffer.toString()); + } + //######################################################################## - // Reporter interface - fail + // Public Methods - Fail on demand - /** Fail only if requested */ + /** Fails only if requested. */ public void failOnDemand() { failOnDemand("user abort"); } - /** Fail only if requested */ + /** Fails only if requested. */ public void failOnDemand(String message) { try { while (true) { writer.print("r)esume, a)bort: "); + writer.flush(); String line = reader.readLine(); if (line == null) continue; else line = line.toLowerCase(); if ("abort".startsWith(line)) @@ -163,4 +220,18 @@ public class Reporter { } //######################################################################## + // Private Methods + + /** Logs a position and returns true if it was already logged. */ + private boolean testAndLog(Position position) { + if (position == null) return false; + if (position.column() == 0) return false; + if (position.line() == 0) return false; + if (position.file().id() == 0) return false; + if (positions.contains(position)) return true; + positions.add(position); + return false; + } + + //######################################################################## } |