diff options
author | Martin Odersky <odersky@gmail.com> | 2004-09-02 16:19:06 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2004-09-02 16:19:06 +0000 |
commit | 7320ca34aad20a1c47715d265a85da7274b0eaf4 (patch) | |
tree | d463653247060d0d7d5b2139cbdada138215e554 /sources | |
parent | 5c259cbc76648b0e36e27b47e07a6066704c3f52 (diff) | |
download | scala-7320ca34aad20a1c47715d265a85da7274b0eaf4.tar.gz scala-7320ca34aad20a1c47715d265a85da7274b0eaf4.tar.bz2 scala-7320ca34aad20a1c47715d265a85da7274b0eaf4.zip |
*** empty log message ***
Diffstat (limited to 'sources')
26 files changed, 377 insertions, 89 deletions
diff --git a/sources/scala/Iterable.scala b/sources/scala/Iterable.scala index 84e7a9daa8..0be6cfa000 100644 --- a/sources/scala/Iterable.scala +++ b/sources/scala/Iterable.scala @@ -11,22 +11,46 @@ package scala; object Iterable { - def view[A <% Ordered[A]](x: Iterable[A]): Ordered[Iterable[A]] = new Ordered[Iterable[A]] { - def compareTo[B >: Iterable[A] <% Ordered[B]](that: B): Int = that match { - case y: Iterable[A] => - val xs = x.elements; - val ys = y.elements; - var res = 0; - while (xs.hasNext && ys.hasNext && (res == 0)) { - res = xs.next compareTo ys.next; - } - if (xs.hasNext) 1 - else if (ys.hasNext) -1 - else res; - case _ => - -(that compareTo x) + def view[A <% Ordered[A]](x: Iterable[A]): Ordered[Iterable[A]] = new Ordered[Iterable[A]] { + def compareTo[B >: Iterable[A] <% Ordered[B]](that: B): Int = that match { + case y: Iterable[A] => + val xs = x.elements; + val ys = y.elements; + var res = 0; + while (xs.hasNext && ys.hasNext && (res == 0)) { + res = xs.next compareTo ys.next; } + if (xs.hasNext) 1 + else if (ys.hasNext) -1 + else res; + case _ => + -(that compareTo x) } + } + + /** The minimum element of a non-empty sequence of ordered elements */ + def min[A <% Ordered[A]](seq: Iterable[A]): A = { + val xs = seq.elements; + if (!xs.hasNext) throw new Error("min(<empty>)"); + var min = xs.next; + while (xs.hasNext) { + val x = xs.next; + if (x < min) min = x; + } + min + } + + /** The maximum element of a non-empty sequence of ordered elements */ + def max[A <% Ordered[A]](seq: Iterable[A]): A = { + val xs = seq.elements; + if (!xs.hasNext) throw new Error("max(<empty>)"); + var max = xs.next; + while (xs.hasNext) { + val x = xs.next; + if (max < x) max = x; + } + max + } } /** Collection classes supporting this trait provide a method diff --git a/sources/scala/List.scala b/sources/scala/List.scala index d66728f97e..57752bcafd 100644 --- a/sources/scala/List.scala +++ b/sources/scala/List.scala @@ -137,8 +137,6 @@ object List { res } - - /** Parses a string which contains substrings separated by a * * separator character and returns a list of all substrings. diff --git a/sources/scala/Stream.scala b/sources/scala/Stream.scala index b6eea6c64b..444b4aae3a 100644 --- a/sources/scala/Stream.scala +++ b/sources/scala/Stream.scala @@ -25,7 +25,7 @@ object Stream { def printElems(buf: StringBuffer, prefix: String): StringBuffer = buf; } - def cons[a](hd: a, def tl: Stream[a]) = new Stream[a] { + def cons[a](hd: a, def/*!!!*/ tl: Stream[a]) = new Stream[a] { def isEmpty = false; def head = hd; private var tlVal: Stream[a] = _; @@ -126,7 +126,7 @@ trait Stream[+a] extends Seq[a] { def length: int = if (isEmpty) 0 else tail.length + 1; - def append[b >: a](def rest: Stream[b]): Stream[b] = + def append[b >: a](def/*!!!*/ rest: Stream[b]): Stream[b] = if (isEmpty) rest else Stream.cons(head, tail.append(rest)); diff --git a/sources/scala/runtime/ScalaRunTime.scala b/sources/scala/runtime/ScalaRunTime.scala index 8dd8a2ca1e..adb14a1fee 100644 --- a/sources/scala/runtime/ScalaRunTime.scala +++ b/sources/scala/runtime/ScalaRunTime.scala @@ -15,19 +15,19 @@ object ScalaRunTime { if (r.exc == null) r.result.asInstanceOf[a] else throw r.exc; } - def Try[a](def block: a): Try[a] = + def Try[a](def/*!!!*/ block: a): Try[a] = new Try(ResultOrException.tryBlock(block)); - def While(def cond: Boolean)(def body: Unit): Unit = + def While(def/*!!!*/ cond: Boolean)(def/*!!!*/ body: Unit): Unit = NativeLoop.loopWhile(cond, body); trait DoWhile { - def While(def condition: Boolean): Unit; + def While(def/*!!!*/ condition: Boolean): Unit; } - def Do(def command: Unit): DoWhile = + def Do(def/*!!!*/ command: Unit): DoWhile = new DoWhile { - def While(def condition: Boolean): Unit = { + def While(def/*!!!*/ condition: Boolean): Unit = { command; NativeLoop.loopWhile(condition, command); } diff --git a/sources/scala/tools/scala4ant/AntAdaptor.scala b/sources/scala/tools/scala4ant/AntAdaptor.scala index 19fab5d32d..b61816da0a 100644 --- a/sources/scala/tools/scala4ant/AntAdaptor.scala +++ b/sources/scala/tools/scala4ant/AntAdaptor.scala @@ -1,6 +1,6 @@ import scalac._; -import scalac.util.Reporter; +import scala.tools.util.Reporter; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; diff --git a/sources/scala/tools/scalac/Main.scala b/sources/scala/tools/scalac/Main.scala index 8b637c408e..3b1821fbcb 100644 --- a/sources/scala/tools/scalac/Main.scala +++ b/sources/scala/tools/scalac/Main.scala @@ -6,7 +6,7 @@ ** $Id$ \* */ -import scalac.util.Reporter; +import scala.tools.util.Reporter; import scalac.{CompilerCommand, Global => scalac_Global}; import scalac.symtab.classfile.CLRPackageParser; diff --git a/sources/scala/tools/scalac/ast/parser/Parser.scala b/sources/scala/tools/scalac/ast/parser/Parser.scala index b5edbcef5b..d606e7d527 100644 --- a/sources/scala/tools/scalac/ast/parser/Parser.scala +++ b/sources/scala/tools/scalac/ast/parser/Parser.scala @@ -1462,27 +1462,28 @@ class Parser(unit: CompilationUnit) { def paramClauses(): Array[Array[Tree$ValDef]] = { val ts = new ArrayList(); while (s.token == LPAREN) - ts.add(paramClause()); + ts.add(paramClause(false)); ts.toArray(new Array[Array[Tree$ValDef]](ts.size()).asInstanceOf[Array[java.lang.Object]]) .asInstanceOf[Array[Array[Tree$ValDef]]] } /** ParamClauseOpt ::= [ParamClause] */ - def paramClauseOpt(): Array[Array[Tree$ValDef]] = - if (s.token == LPAREN) NewArray.ValDefArray(paramClause()) + def paramClauseOpt(ofPrimaryConstructor: boolean): Array[Array[Tree$ValDef]] = + if (s.token == LPAREN) NewArray.ValDefArray(paramClause(ofPrimaryConstructor)) else Tree.ValDef_EMPTY_ARRAY_ARRAY; /** ParamClause ::= `(' [Param {`,' Param}] `)' - */ - def paramClause(): Array[Tree$ValDef] = { + * ClassParamClause ::= `(' [ClassParam {`,' ClassParam}] `)' + */ + def paramClause(ofPrimaryConstructor: boolean): Array[Tree$ValDef] = { val pos = accept(LPAREN); val params = new myTreeList(); if (s.token != RPAREN) { - params.append(param()); + params.append(param(ofPrimaryConstructor)); while (s.token == COMMA) { s.nextToken(); - params.append(param()); + params.append(param(ofPrimaryConstructor)); } } accept(RPAREN); @@ -1490,17 +1491,31 @@ class Parser(unit: CompilationUnit) { .asInstanceOf[Array[Tree$ValDef]] } - /** Param ::= [def] Id `:' Type [`*'] - */ - def param(): Tree$ValDef = { + /** Param ::= Id `:' [`=>'] Type [`*'] + * ClassParam ::= [[modifiers] val] Param + */ + def param(ofPrimaryConstructor: boolean): Tree$ValDef = { val pos = s.pos; - var mods = Modifiers.PARAM; + var mods = if (ofPrimaryConstructor) modifiers() | Modifiers.PARAM else Modifiers.PARAM; + if (s.token == VAL) { + s.nextToken(); mods = mods | Modifiers.PARAMACCESSOR; + } else if (mods != Modifiers.PARAM) { + accept(VAL); + } if (s.token == DEF) { mods = mods | Modifiers.DEF; + /* notyet + s.unit.warning(s.pos, "def-parameter syntax `def x: T' is deprecated \n" + + "use `x: => T' instead"); + */ s.nextToken(); } val name = ident(); accept(COLON); + if (s.token == ARROW) { + mods = mods | Modifiers.DEF; + s.nextToken(); + } var tp = typ(); if (s.token == IDENTIFIER && s.name == STAR) { s.nextToken(); @@ -1793,7 +1808,7 @@ class Parser(unit: CompilationUnit) { if (s.token == THIS) { val pos = s.pos; s.nextToken(); - val vparams = NewArray.ValDefArray(paramClause()); + val vparams = NewArray.ValDefArray(paramClause(false)); accept(EQUALS); ts.append( make.DefDef( @@ -1878,7 +1893,7 @@ class Parser(unit: CompilationUnit) { } } - /** ClassDef ::= Id [TypeParamClause] [ParamClause] [`:' SimpleType] ClassTemplate + /** ClassDef ::= Id [TypeParamClause] [ClassParamClause] [`:' SimpleType] ClassTemplate */ def classDef(mods: int): Array[Tree] = { val lhs = new ListBuffer[Tuple4[Int, Name, Array[Tree$AbsTypeDef], Array[Array[Tree$ValDef]]]]; @@ -1887,7 +1902,7 @@ class Parser(unit: CompilationUnit) { lhs.append(Tuple4(s.pos, ident().toTypeName(), typeParamClauseOpt(true), - paramClauseOpt())); + paramClauseOpt(true))); } while (s.token == COMMA); val thistpe = simpleTypedOpt(); val template = classTemplate( (mods & Modifiers.CASE)!= 0 ); diff --git a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala index 0c93b00f4e..09acf7870b 100644 --- a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala +++ b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala @@ -710,6 +710,9 @@ class TextTreePrinter(writer: PrintWriter) with TreePrinter { case Tree$ValDef(mods, name, tpe, Tree.Empty) => printModifiers(mods); + if ((mods & Modifiers.PARAMACCESSOR) != 0) { + print(KW_VAL); print(Space); + } printSymbolDefinition(tree.symbol(), name); printOpt(TXT_COLON, tpe, false); diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala index 9a2b60055b..203e7aa7f0 100644 --- a/sources/scala/tools/scalac/typechecker/Analyzer.scala +++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala @@ -1110,8 +1110,8 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( vparamSyms1(1) = Symbol.EMPTY_ARRAY; vparamSyms = vparamSyms1 } - if ((mods & CASE) != 0 && vparams.length > 0) - templ.body = desugarize.addCaseElements( + if (vparams.length > 0) + templ.body = desugarize.addParamAccessors( templ.body, vparams(vparams.length - 1)); val constrtype: Type = makeMethodType( @@ -1162,8 +1162,12 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( restype = context.enclClass.owner.getType();/*.subst( context.enclClass.owner.typeParams(), tparamSyms)*/; } else { - rhs = transform(rhs, EXPRmode); - (tree.asInstanceOf[Tree$DefDef]).rhs = rhs; + if ((sym.flags & PARAMACCESSOR) != 0) { + rhs.setType(rhs.symbol().getType()); + } else { + rhs = transform(rhs, EXPRmode); + (tree.asInstanceOf[Tree$DefDef]).rhs = rhs; + } restype = rhs.getType(); if (!sym.isFinal()) restype = restype.deconst(); } @@ -1198,12 +1202,8 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( owntype = Type.ErrorType; } } else { - if ((sym.flags & CASEACCESSOR) != 0) { - rhs.setType(rhs.symbol().getType()); - } else { - rhs = transform(rhs, EXPRmode); - (tree.asInstanceOf[Tree$ValDef]).rhs = rhs; - } + rhs = transform(rhs, EXPRmode); + (tree.asInstanceOf[Tree$ValDef]).rhs = rhs; owntype = rhs.getType(); if (sym.isVariable() || !sym.isFinal()) owntype = owntype.deconst(); @@ -1651,7 +1651,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( } else { nextcontext = nextcontext.enclClass; if (nextcontext != Context.NONE) { - sym = nextcontext.owner.thisSym().info().lookup(name); + sym = nextcontext.owner.typeOfThis().lookup(name); if (sym.kind != NONE) { stopPos = nextcontext.owner.pos; } else { @@ -2239,8 +2239,8 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( val vparams1 = transform(vparams); checkNoEscapeParams(vparams1); val tpe1: Tree = transform(tpe, TYPEmode); - if ((sym.flags & CASE) != 0 && vparams.length > 0 && templ.getType() == null) - templ.body = desugarize.addCaseElements( + if (vparams.length > 0 && templ.getType() == null) + templ.body = desugarize.addParamAccessors( templ.body, vparams(vparams.length - 1)); val templ1: Tree$Template = transformTemplate(templ, sym); diff --git a/sources/scala/tools/scalac/typechecker/Context.scala b/sources/scala/tools/scalac/typechecker/Context.scala index 81cf9a28c9..ceedc3c2e0 100644 --- a/sources/scala/tools/scalac/typechecker/Context.scala +++ b/sources/scala/tools/scalac/typechecker/Context.scala @@ -9,6 +9,7 @@ import scalac.symtab._; import scalac.ast._; import scalac.util.Names; import scalac.util.Name; +import scalac.{Global => scalac_Global} package scala.tools.scalac.typechecker { @@ -122,7 +123,13 @@ class Context { if (viewCache == null) { viewCache = outer.viewMeths; - if (scope != outer.scope) { + if (enclClass == this) { + val sym = owner.typeOfThis().lookup(Names.view); + if (sym.kind == VAL) { + addView(sym, owner.thisType().memberType(sym), + scalac_Global.instance.treeGen.This(owner.pos, owner)); + } + } else if (scope != outer.scope) { val e = scope.lookupEntry(Names.view); if (e.owner == scope && e.sym.kind == VAL) addView(e.sym, e.sym.getType(), Tree.Empty); diff --git a/sources/scala/tools/scalac/typechecker/DeSugarize.scala b/sources/scala/tools/scalac/typechecker/DeSugarize.scala index 99ec52fb2b..41db26e4b1 100644 --- a/sources/scala/tools/scalac/typechecker/DeSugarize.scala +++ b/sources/scala/tools/scalac/typechecker/DeSugarize.scala @@ -422,7 +422,7 @@ class DeSugarize(make: TreeFactory, copy: TreeCopier, gen: TreeGen, infer: scala case Tree$ValDef(mods, name, tpe, rhs) => val valname: Name = Name.fromString("" + name + "$"); val valdef1: Tree = copy.ValDef( - tree, (mods & (DEFERRED | MUTABLE | CASEACCESSOR | MODUL)) | PRIVATE, + tree, (mods & (DEFERRED | MUTABLE | PARAMACCESSOR | MODUL)) | PRIVATE, valname, tpe, rhs).setType(null); var mods1: int = mods | ACCESSOR; if ((mods1 & MUTABLE) == 0) mods1 = mods1 | STABLE; @@ -600,24 +600,31 @@ class DeSugarize(make: TreeFactory, copy: TreeCopier, gen: TreeGen, infer: scala /** Build value element definition name for case parameter. */ - def addCaseElement(ts: TreeList, vparam: Tree$ValDef): unit = { - //vparam.symbol().initialize(); - ts.append( - make.ValDef( - vparam.pos, CASEACCESSOR, vparam.name, Tree.Empty, - make.Ident(vparam.pos, vparam.name) - .setSymbol(vparam.symbol()))); + def addParamAccessor(ts: TreeList, vparam: Tree$ValDef): unit = { + if ((vparam.symbol().owner().constructorClass().flags & CASE) != 0) + vparam.mods = vparam.mods | PARAMACCESSOR; + if ((vparam.mods & PARAMACCESSOR) != 0) + ts.append( + make.DefDef( + vparam.pos, (vparam.mods & ~PARAM) | STABLE, vparam.name, + Tree.AbsTypeDef_EMPTY_ARRAY, Tree.ValDef_EMPTY_ARRAY_ARRAY, + Tree.Empty, + make.Ident(vparam.pos, vparam.name) + .setSymbol(vparam.symbol()))) } /** add case constructor, definitions value and access functions. */ - def addCaseElements(body: Array[Tree], vparams: Array[Tree$ValDef]): Array[Tree] = { + def addParamAccessors(body: Array[Tree], vparams: Array[Tree$ValDef]): Array[Tree] = { val stats: TreeList = new TreeList(); for (val i <- Iterator.range(0, vparams.length)) { - addCaseElement(stats, vparams(i)); + addParamAccessor(stats, vparams(i)); + } + if (stats.length() == 0) body + else { + stats.append(body); + stats.toArray() } - stats.append(body); - stats.toArray(); } //debug diff --git a/sources/scala/tools/scaladoc/HTMLGeneratorCommand.java b/sources/scala/tools/scaladoc/HTMLGeneratorCommand.java index dfdc81d18c..bdf6b672da 100644 --- a/sources/scala/tools/scaladoc/HTMLGeneratorCommand.java +++ b/sources/scala/tools/scaladoc/HTMLGeneratorCommand.java @@ -15,11 +15,11 @@ import ch.epfl.lamp.util.HTMLPrinter; import ch.epfl.lamp.util.HTMLRepresentation; import scala.tools.util.ClassPath; +import scala.tools.util.Reporter; import scalac.CompilerCommand; import scalac.util.BooleanOptionParser; import scalac.util.OptionParser; -import scalac.util.Reporter; import scalac.util.StringOptionParser; import scalac.util.ScalaProgramArgumentParser; import scalac.util.Strings; diff --git a/sources/scala/tools/scaladoc/Main.scala b/sources/scala/tools/scaladoc/Main.scala index 2b9a0f3d47..763fa8002c 100644 --- a/sources/scala/tools/scaladoc/Main.scala +++ b/sources/scala/tools/scaladoc/Main.scala @@ -7,7 +7,7 @@ // $Id$ import scala.tools.scalac.Global; -import scalac.util.Reporter; +import scala.tools.util.Reporter; package scala.tools.scaladoc { diff --git a/sources/scala/tools/scalai/InterpreterCommand.java b/sources/scala/tools/scalai/InterpreterCommand.java index d89378da82..9e8907a499 100644 --- a/sources/scala/tools/scalai/InterpreterCommand.java +++ b/sources/scala/tools/scalai/InterpreterCommand.java @@ -11,7 +11,7 @@ package scala.tools.scalai; import scalac.CompilerPhases; import scalac.CompilerCommand; -import scalac.util.Reporter; +import scala.tools.util.Reporter; import scalac.util.StringOptionParser; import scalac.util.BooleanOptionParser; import scalac.util.ScalaProgramArgumentParser; diff --git a/sources/scala/tools/scalai/Main.java b/sources/scala/tools/scalai/Main.java index be19e26be6..b2dc69827c 100644 --- a/sources/scala/tools/scalai/Main.java +++ b/sources/scala/tools/scalai/Main.java @@ -10,7 +10,7 @@ package scala.tools.scalai; import scala.tools.scalac.CompilerPhases$class; -import scalac.util.Reporter; +import scala.tools.util.Reporter; public class Main { diff --git a/sources/scala/tools/scalap/Flags.scala b/sources/scala/tools/scalap/Flags.scala index 6956bb3667..7d5a2fd48f 100644 --- a/sources/scala/tools/scalap/Flags.scala +++ b/sources/scala/tools/scalap/Flags.scala @@ -38,7 +38,8 @@ object Flags { final val PARAM = 0x00008000; // a (type) parameter of a method final val PACKAGE = 0x00100000; // a java package - final val CASEACCESSOR = 0x02000000; // a case constructor + final val PARAMACCESSOR= 0x02000000; // for methods: is an access method for a val parameter + // for parameters: is a val parameter final val ACCESSOR = 0x04000000; // an access function for a value/variable final val BRIDGE = 0x08000000; // a bridge method. diff --git a/sources/scala/tools/scalap/ScalaWriter.scala b/sources/scala/tools/scalap/ScalaWriter.scala index 014a6e2d87..5ff8ea6277 100644 --- a/sources/scala/tools/scalap/ScalaWriter.scala +++ b/sources/scala/tools/scalap/ScalaWriter.scala @@ -89,7 +89,7 @@ class ScalaWriter(args: Arguments, writer: Writer) extends CodeWriter(writer) { sym => { sym match { case s: ValSymbol if (s.tpe.isInstanceOf[OverloadedType] || - (Flags.is(Flags.CASEACCESSOR, s.flags) && + (Flags.is(Flags.PARAMACCESSOR, s.flags) && !s.tpe.isInstanceOf[PolyType])) => case _ => if (!ignoreDef(sym)) { @@ -292,7 +292,7 @@ class ScalaWriter(args: Arguments, writer: Writer) extends CodeWriter(writer) { (Flags.is(Flags.PRIVATE, s.flags) && !((args != null) && (args contains "-private"))) || (s.name == "<init>") || - Flags.is(Flags.CASEACCESSOR, s.flags) || + Flags.is(Flags.PARAMACCESSOR, s.flags) || (Flags.is(Flags.CASE, s.flags) && (s match { case sym: ValSymbol => true diff --git a/sources/scala/tools/util/Reporter.java b/sources/scala/tools/util/Reporter.java new file mode 100644 index 0000000000..4fef766fe9 --- /dev/null +++ b/sources/scala/tools/util/Reporter.java @@ -0,0 +1,237 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scala.tools.util; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashSet; + +import scala.tools.util.Position; + +public class Reporter { + + //######################################################################## + // 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; + + //######################################################################## + // 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; + /** Whether a short file name should be displayed before errors */ + public boolean shortname; + + //######################################################################## + // 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; + this.errors = 0; + } + + //######################################################################## + // Public Methods - Count + + /** Returns the number of errors issued totally */ + public int errors() { + return errors; + } + + /** Returns the number of warnings issued totally */ + public int warnings() { + return warnings; + } + + /** Returns the number of errors issued totally as a string */ + public String getErrorCountString() { + return getCountString(errors, "error"); + } + + /** Returns the number of warnings issued totally as a string */ + public String getWarningCountString() { + return getCountString(warnings, "warning"); + } + + /** 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"; + } + } + + /** Resets all counters */ + public void resetCounters() { + errors = 0; + warnings = 0; + } + + //######################################################################## + // Public Methods - Report + + /** Issues a message */ + public void report(String message) { + printMessage(message); + } + + /** Issues a message */ + public void inform(String message) { + if (verbose) printMessage(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(); + } + + /** Issues a warning */ + public void warning(Position position, String message) { + boolean hidden = testAndLog(position); + if (nowarn) return; + 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) { + message = " " + message; + if (position.getLineNumber() != 0) + message = position.getLineNumber() + ":" + message; + if (shortname) + message = position.getName() + ":" + message; + else + message = position.getPath() + ":" + message; + } + printMessage(message); + printSourceLine(position); + } + + /** Prints the error message. */ + public void printError(Position position, String message) { + if (position == null) 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) { + String line = position == null ? null : position.getLineContent(); + if (line == null) return; + printMessage(line); + printColumnMarker(position); + } + + /** Prints the column marker of the given position. */ + public void printColumnMarker(Position position) { + int column = position == null ? 0 : position.getColumnNumber(); + StringBuffer buffer = new StringBuffer(column); + for (int i = 1; i < column; i++) buffer.append(' '); + if (column > 0) buffer.append('^'); + printMessage(buffer.toString()); + } + + //######################################################################## + // Public Methods - Fail on demand + + /** Fails only if requested. */ + public void failOnDemand() { + failOnDemand("user abort"); + } + + /** 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)) + throw new Error(message); + if ("resume".startsWith(line)) return; + } + } catch (IOException e) { + throw new Error("input read error"); + } + } + + //######################################################################## + // 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.getColumnNumber() == 0) return false; + if (positions.contains(position)) return true; + positions.add(position); + return false; + } + + //######################################################################## +} diff --git a/sources/scalac/CompilerCommand.java b/sources/scalac/CompilerCommand.java index dd3505b6be..a5178ee50d 100644 --- a/sources/scalac/CompilerCommand.java +++ b/sources/scalac/CompilerCommand.java @@ -13,8 +13,8 @@ import java.util.ArrayList; import java.util.List; import scala.tools.util.ClassPath; +import scala.tools.util.Reporter; -import scalac.util.Reporter; import scalac.util.CommandParser; import scalac.util.ArgumentParser; import scalac.util.OptionParser; diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java index 66d8d76506..fe4f528015 100644 --- a/sources/scalac/Global.java +++ b/sources/scalac/Global.java @@ -27,6 +27,7 @@ import scala.tools.util.ClassPath; import scala.tools.util.Position; import scala.tools.util.SourceFile; import scala.tools.util.SourceReader; +import scala.tools.util.Reporter; import scalac.ast.*; import scalac.ast.parser.*; diff --git a/sources/scalac/checkers/TreeChecker.java b/sources/scalac/checkers/TreeChecker.java index bc38e3eafb..b52d6c657c 100644 --- a/sources/scalac/checkers/TreeChecker.java +++ b/sources/scalac/checkers/TreeChecker.java @@ -393,7 +393,8 @@ public class TreeChecker { assert symbol != null && symbol.isTerm(): show(tree); Symbol owner = symbol.owner(); assert owner.isClass() && !owner.isStaticOwner(): show(tree); - assert qualifier.type().baseType(owner) != Type.NoType: show(tree); + assert qualifier.type().baseType(owner) != Type.NoType: + show(tree) + "#" + qualifier.type() + "/" + owner; return expression(qualifier, qualifier.type()); default: diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java index 7a79680bd6..952736083f 100644 --- a/sources/scalac/symtab/Modifiers.java +++ b/sources/scalac/symtab/Modifiers.java @@ -46,7 +46,8 @@ public interface Modifiers { int CAPTURED = 0x01000000; // variables is accessed from // nested function. Set by LambdaLift int INCONSTRUCTOR = 0x01000000; // transient flag for Analyzer - int CASEACCESSOR = 0x02000000; // function is a case constructor + int PARAMACCESSOR = 0x02000000; // for methods: is an access method for a val parameter + // for parameters: is a val parameter int ACCESSOR = 0x04000000; // function is an access function for a // value or variable @@ -102,7 +103,7 @@ public interface Modifiers { } public static boolean isCaseAccessor(int flags) { - return (flags & CASEACCESSOR) != 0; + return (flags & PARAMACCESSOR) != 0; } public static boolean isInterface(int flags) { diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index 5325107000..63206f4044 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -2124,7 +2124,7 @@ public class ClassSymbol extends TypeSymbol { for (int i = 0; i <= index; i++) { do { sym = it.next(); - } while (sym != NONE && sym.kind != VAL || (sym.flags & CASEACCESSOR) == 0 || !sym.isMethod()); + } while (sym != NONE && sym.kind != VAL || (sym.flags & PARAMACCESSOR) == 0 || !sym.isMethod()); } //System.out.println(this + ", case field[" + index + "] = " + sym);//DEBUG } else { diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 5901fc75fa..ff3e25e84f 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -2171,10 +2171,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { this.singleDeref().isSameAs(that) || that.singleDeref().isSingletonType() && - this.isSameAs(that.singleDeref()) - || - deAlias(that) != that && - this.isSameAs(deAlias(that)); + this.isSameAs(that.singleDeref()); default: if (deAlias(this) != this) return deAlias(this).isSameAs(that); @@ -2190,10 +2187,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { this.singleDeref().isSameAs(that) || that.singleDeref().isSingletonType() && - this.isSameAs(that.singleDeref()) - || - (deAlias(this) != this || deAlias(that) != that) && - deAlias(this).isSameAs(deAlias(that)); + this.isSameAs(that.singleDeref()); case ThisType(Symbol sym1): return sym.isModule() && sym.moduleClass() == sym1 @@ -2203,10 +2197,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { this.singleDeref().isSameAs(that) || that.singleDeref().isSingletonType() && - this.isSameAs(that.singleDeref()) - || - deAlias(this) != this && - deAlias(this).isSameAs(that); + this.isSameAs(that.singleDeref()); default: if (deAlias(this) != this) return deAlias(this).isSameAs(that); diff --git a/sources/scalac/transformer/ExplicitOuterClassesPhase.java b/sources/scalac/transformer/ExplicitOuterClassesPhase.java index e7e4fe33d8..b0cd2918d8 100644 --- a/sources/scalac/transformer/ExplicitOuterClassesPhase.java +++ b/sources/scalac/transformer/ExplicitOuterClassesPhase.java @@ -309,6 +309,7 @@ public class ExplicitOuterClassesPhase extends Phase { /** Transforms the given tree. */ public Tree transform(Tree tree) { + if (global.debug) global.log("transforming " + tree);//debug switch (tree) { case ClassDef(_, _, _, _, _, Template impl): diff --git a/sources/scalac/util/OptionParser.java b/sources/scalac/util/OptionParser.java index 6294db9a20..9521ca388e 100644 --- a/sources/scalac/util/OptionParser.java +++ b/sources/scalac/util/OptionParser.java @@ -9,6 +9,7 @@ package scalac.util; import scala.tools.util.Position; +import scala.tools.util.Reporter; import java.text.Format; import java.text.MessageFormat; |