diff options
8 files changed, 231 insertions, 112 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala index 38efe6abbe..c9ecf46c52 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala @@ -14,30 +14,42 @@ abstract class Checkers { val global: Global import global._ - /** - * This class performs a set of checks similar to what the bytecode - * verifier does. For each basic block, it checks that: + /** <p> + * This class performs a set of checks similar to what the bytecode + * verifier does. For each basic block, it checks that: + * </p> + * <ul> + * <li> + * for primitive operations: the type and numer of operands match + * the type of the operation + * </li> + * <li> + * for method calls: the method exists in the type of the receiver + * and the number and type of arguments match the declared type of + * the method. + * </li> + * <li> + * for object creation: the constructor can be called. + * </li> + * <li> + * for load/stores: the field/local/param exists and the type + * of the value matches that of the target. + * </li> + * </ul> + * <p> + * For a control flow graph it checks that type stacks at entry to + * each basic block 'agree': + * </p> + * <ul> + * <li>they have the same length</li> + * <li>there exists a lub for all types at the same position in stacks.</li> + * </ul> * - * - for primitive operations: the type and numer of operands match - * the type of the operation + * @author Iulian Dragos + * @version 1.0, 06/09/2005 * - * - for method calls: the method exists in the type of the receiver - * and the number and type of arguments match the declared type of - * the method. - * - * - for object creation: the constructor can be called. - * - * - for load/stores: the field/local/param exists and the type - * of the value matches that of the target. - * - * For a control flow graph it checks that type stacks at entry to - * each basic block 'agree': - * - * - they have the same length - * - there exists a lub for all types at the same position in stacks. - * - * TODO: Better checks for MONITOR_ENTER/EXIT - * Better checks for local var initializations + * @todo Better checks for <code>MONITOR_ENTER/EXIT</code> + * Better checks for local var initializations */ class ICodeChecker { import icodes._ @@ -210,7 +222,10 @@ abstract class Checkers { } /** Checks that the object passed as receiver has a method - * 'method' and that it is callable from the current method. + * <code>method</code> and that it is callable from the current method. + * + * @param receiver ... + * @param method ... */ def checkMethod(receiver: TypeKind, method: Symbol) = receiver match { @@ -436,9 +451,9 @@ abstract class Checkers { } case CREATE_ARRAY(elem) => - checkStack(1); - checkType(stack.pop, INT); - stack.push(ARRAY(elem)); + checkStack(1) + checkType(stack.pop, INT) + stack.push(ARRAY(elem)) case IS_INSTANCE(tpe) => val ref = stack.pop @@ -557,7 +572,9 @@ abstract class Checkers { //////////////////// Checking ///////////////////////////// - /** Return true if k1 is a subtype of any of the following types. */ + /** Return true if <code>k1</code> is a subtype of any of the following + * types. + */ def isOneOf(k1: TypeKind, kinds: TypeKind*) = kinds.exists( k => k1 <:< k) diff --git a/src/compiler/scala/tools/nsc/io/AbstractFile.scala b/src/compiler/scala/tools/nsc/io/AbstractFile.scala index 0d02770e9a..2b75752543 100644 --- a/src/compiler/scala/tools/nsc/io/AbstractFile.scala +++ b/src/compiler/scala/tools/nsc/io/AbstractFile.scala @@ -17,7 +17,7 @@ object AbstractFile { /** * If the specified File exists and is a regular file, returns an - * abstract regular file backed by it. Otherwise, returns null. + * abstract regular file backed by it. Otherwise, returns <code>null</code>. */ def getFile(file: File): AbstractFile = if (file.isFile() && file.exists()) new PlainFile(file) else null @@ -30,6 +30,9 @@ object AbstractFile { * if the specified File exists and is either a directory or a * readable zip or jar archive, returns an abstract directory * backed by it. Otherwise, returns null. + * + * @param file ... + * @return ... */ def getDirectory(file: File): AbstractFile = { if (file.isDirectory() && file.exists()) return new PlainFile(file); @@ -64,7 +67,7 @@ object AbstractFile { * The class <code>symtab.classfile.AbstractFileReader</code> accesses * bytes, knowing that the character set of classfiles is UTF-8. For * all other cases, the class <code>SourceFile</code> is used, which honors - * <code>global.settings.encoding.value</code>/ + * <code>global.settings.encoding.value</code>. * </p> */ abstract class AbstractFile extends Object with Iterable[AbstractFile] { diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/PickleBuffer.scala b/src/compiler/scala/tools/nsc/symtab/classfile/PickleBuffer.scala index b1707a995f..e189e65863 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/PickleBuffer.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/PickleBuffer.scala @@ -8,9 +8,9 @@ package scala.tools.nsc.symtab.classfile /** Variable length byte arrays, with methods for basic pickling and unpickling. * - * @param data: The initial buffer - * @param from: The first index where defined data are found - * @param to : The first index where new data can be written + * @param data The initial buffer + * @param from The first index where defined data are found + * @param to The first index where new data can be written */ class PickleBuffer(data: Array[byte], from: int, to: int) { @@ -51,8 +51,11 @@ class PickleBuffer(data: Array[byte], from: int, to: int) { writeByte(x & 0x7f) } - /** Write a natural number at `pos' + /** Write a natural number <code>x</code> at position <code>pos</code>. * If number is more than one byte, shift rest of array to make space. + * + * @param pos ... + * @param x ... */ def patchNat(pos: int, x: int): unit = { def patchNatPrefix(x: int): unit = { @@ -67,7 +70,10 @@ class PickleBuffer(data: Array[byte], from: int, to: int) { if (y != 0) patchNatPrefix(y) } - /** Write a long number in signed big endian format, base 256. */ + /** Write a long number <code>x</code> in signed big endian format, base 256. + * + * @param x The long number to be written. + */ def writeLong(x: long): unit = { val y = x >> 8 val z = x & 0xff @@ -106,13 +112,21 @@ class PickleBuffer(data: Array[byte], from: int, to: int) { x << leading >> leading } - /** Perform operation `op' until readIndex == end. + /** Perform operation <code>op</code> until the condition + * <code>readIndex == end</code> is satisfied. * Concatenate results into a list. + * + * @param end ... + * @param op ... + * @return ... */ def until[T](end: int, op: () => T): List[T] = if (readIndex == end) List() else op() :: until(end, op); - /** Create an index */ + /** Create an index. + * + * @return ... + */ def createIndex: Array[int] = { val index = new Array[int](readNat()) for (val i <- Iterator.range(0, index.length)) { diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 604b926b0a..b58d47ef05 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -15,16 +15,25 @@ abstract class AddInterfaces extends InfoTransform { import definitions._ // standard classes and methods import posAssigner.atPos // for filling in tree positions - /** The phase sets lateINTERFACE for non-interface traits that now become interfaces - * It sets lateDEFERRED for formerly concrete methods in such traits + /** <p> + * The phase sets <code>lateINTERFACE</code> for non-interface traits + * that now become interfaces. + * </p> + * <p> + * It sets <code>lateDEFERRED</code> for formerly concrete methods in + * such traits. + * </p> */ override def phaseNewFlags: long = lateDEFERRED | lateINTERFACE - /** Type reference after erasure; to be defined in subclass Erasure */ + /** Type reference after erasure; to be defined in subclass + * <code>Erasure</code>. + */ def erasedTypeRef(sym: Symbol): Type /** A lazily constructed map that associates every non-interface trait with - * its implementation class */ + * its implementation class. + */ private val implClassMap = new HashMap[Symbol, Symbol] /** A lazily constructed map that associates every concrete method in a non-interface @@ -87,20 +96,39 @@ abstract class AddInterfaces extends InfoTransform { } } - /** A lazy type to set the info of an implementation class - * The parents of an implementation class for trait `iface' are: - * - superclass: Object - * - mixin classes: mixin classes of `iface' where every non-interface trait - * is mapped to its implementation class, followed by - * `iface' itself. - * The declarations of a mixin class are - * - for every interface member of `iface' its implemention method, if one is needed. - * - every former member of `iface' that is implementation only + /** <p> + * A lazy type to set the info of an implementation class + * The parents of an implementation class for trait <code>iface</code> are: + * </p> + * <ul> + * <li>superclass: <code>Object</code></li> + * <li> + * mixin classes: mixin classes of <code>iface</code> where every + * non-interface trait is mapped to its implementation class, followed + * by <code>iface</code> itself. + * </li> + * </ul> + * <p> + * The declarations of a mixin class are: + * </p> + * <ul> + * <li> + * for every interface member of <code>iface</code> its implemention + * method, if one is needed. + * </li> + * <li> + * every former member of <code>iface</code> that is implementation only + * </li> + * </ul> */ private class LazyImplClassType(iface: Symbol) extends LazyType { - /** Compute the decls of implementation class `implClass', - * given the decls `ifaceDecls' of its interface + /** Compute the decls of implementation class <code>implClass</code>, + * given the decls <code>ifaceDecls</code> of its interface. + * + * @param implClass ... + * @param ifaceDecls ... + * @return ... */ private def implDecls(implClass: Symbol, ifaceDecls: Scope): Scope = { val decls = newScope @@ -142,8 +170,12 @@ abstract class AddInterfaces extends InfoTransform { override def load(clazz: Symbol): unit = complete(clazz) } - /** If `tp' refers to a non-interface trait, return a reference to its implementation class. - * Otherwise return `tp' itself. + /** If type <code>tp</code> refers to a non-interface trait, return a + * reference to its implementation class. Otherwise return <code>tp</code> + * itself. + * + * @param tp ... + * @return ... */ private def mixinToImplClass(tp: Type): Type = tp match { case TypeRef(pre, sym, args) if (sym.needsImplClass) => @@ -244,8 +276,9 @@ abstract class AddInterfaces extends InfoTransform { } /** Add calls to supermixin constructors - * super[mix].$init$() - * to `tree'. `tree' which is assumed to be the body of a constructor of class `clazz'. + * <blockquote><pre>super[mix].$init$()</pre></blockquote> + * to <code>tree</code>. <code>tree</code> which is assumed to be the body + * of a constructor of class <code>clazz</code>. */ private def addMixinConstructorCalls(tree: Tree, clazz: Symbol): Tree = { def mixinConstructorCall(impl: Symbol): Tree = atPos(tree.pos) { diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index a049914035..818f42a548 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -33,7 +33,7 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter protected def newTransformer(unit: CompilationUnit): Transformer = new ExplicitOuterTransformer(unit) - /** Is given `clazz' an inner class? */ + /** Is given <code>clazz</code> an inner class? */ private def isInner(clazz: Symbol) = !clazz.isPackageClass && !clazz.outerClass.isStaticOwner @@ -54,19 +54,42 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter } } - /** The type transformation method: - * 1. Add an outer parameter to the formal parameters of a constructor - * in a inner non-trait class; - * 2. Add a protected $outer field to an inner class which is not a trait. - * 3. Add an outer accessor $outer$$C to every inner class with fully qualified name C - * that is not an interface. The outer accesssor is abstract for traits, concrete - * for other classes. - * 3a. Also add overriding accessor defs to every class that inherits mixin classes - * with outer accessor defs (unless the superclass already inherits the same mixin). - * 4. Add a mixin constructor $init$ to all mixins except interfaces - * Leave all other types unchanged. todo: move to later - * 5. Make all super accessors and modules in traits non-private, mangling their names. - * 6. Remove protected flag from all members of traits. + /** <p> + * The type transformation method: + * </p> + * <ol> + * <li> + * Add an outer parameter to the formal parameters of a constructor + * in a inner non-trait class; + * </li> + * <li> + * Add a protected $outer field to an inner class which is not a trait. + * </li> + * <li> + * <p> + * Add an outer accessor <code>$outer$$C</code> to every inner class + * with fully qualified name <code>C</code> that is not an interface. + * The outer accesssor is abstract for traits, concrete for other + * classes. + * </p> + * <p> + * 3a. Also add overriding accessor defs to every class that inherits + * mixin classes with outer accessor defs (unless the superclass + * already inherits the same mixin). + * </p> + * <li> + * <li> + * Add a mixin constructor <code>$init$</code> to all mixins except interfaces + * Leave all other types unchanged. todo: move to later + * </li> + * <li> + * Make all super accessors and modules in traits non-private, mangling + * their names. + * </li> + * <li> + * Remove protected flag from all members of traits. + * </li> + * </ol> */ def transformInfo(sym: Symbol, tp: Type): Type = tp match { case MethodType(formals, restpe) => @@ -112,8 +135,8 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter tp } - /** A base class for transformers that maintain `outerParam' values for - * outer parameters of constructors. + /** A base class for transformers that maintain <code>outerParam</code> + * values for outer parameters of constructors. * The class provides methods for referencing via outer. */ abstract class OuterPathTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { @@ -135,7 +158,7 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter localTyper.typed(Apply(Select(base, outerAccessor(base.tpe.symbol)), List())) /** The path - * `base'.$outer$$C1 ... .$outer$$Cn + * <blockquote><pre>`base'.$outer$$C1 ... .$outer$$Cn</pre></blockquote> * which refers to the outer instance of class <code>to</code> of * value <code>base</code>. The result is typed but not positioned. * diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 51a1f4ba23..51872a5ab1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -10,24 +10,31 @@ import symtab.Flags._ import collection.mutable.HashMap import transform.InfoTransform -/** Post-attribution checking and transformation. - * //todo: check whether we always check type parameter bounds. +/** <p> + * Post-attribution checking and transformation. + * </p> + * <p> + * This phase performs the following checks. + * </p> + * <ul> + * <li>All overrides conform to rules.</li> + * <li>All type arguments conform to bounds.</li> + * <li>All type variable uses conform to variance annotations.</li> + * <li>No forward reference to a term symbol extends beyond a value definition.</li> + * </ul> + * <p> + * It performs the following transformations. + * </p> + * <ul> + * <li>Local modules are replaced by variables and classes</li> + * <li>Calls to case factory methods are replaced by new's.</li> + * <li>Eliminate branches in a conditional if the condition is a constant</li> + * </ul> * - * This phase performs the following checks. - * - * - All overrides conform to rules. - * - All type arguments conform to bounds. - * - All type variable uses conform to variance annotations. - * - No forward reference to a term symbol extends beyond a value definition. - * - * It performs the following transformations. - * - * - Local modules are replaced by variables and classes - * - Calls to case factory methods are replaced by new's. - * - eliminate branches in a conditional if the condition is a constant - * - * @author Martin Odersky + * @author Martin Odersky * @version 1.0 + * + * @todo Check whether we always check type parameter bounds. */ abstract class RefChecks extends InfoTransform { @@ -102,7 +109,9 @@ abstract class RefChecks extends InfoTransform { tp1 <:< tp2 } - /* Check that all conditions for overriding `other' by `member' are met. */ + /** Check that all conditions for overriding <code>other</code> by + * <code>member</code> are met. + */ def checkOverride(clazz: Symbol, member: Symbol, other: Symbol): unit = { val pos = if (member.owner == clazz) member.pos else clazz.pos @@ -237,10 +246,18 @@ abstract class RefChecks extends InfoTransform { // Basetype Checking -------------------------------------------------------- - /** 1. Check that later type instances in the base-type sequence - * are subtypes of earlier type instances of the same mixin. - * 2. Check that case classes do not inherit from case classes. - * 3. Check that at most one base type is a case-class. + /** <ol> + * <li> <!-- 1 --> + * Check that later type instances in the base-type sequence + * are subtypes of earlier type instances of the same mixin. + * </li> + * <li> <!-- 2 --> + * Check that case classes do not inherit from case classes. + * </li> + * <li> <!-- 3 --> + * Check that at most one base type is a case-class. + * </li> + * </ol> */ private def validateBaseTypes(clazz: Symbol): unit = { val seenTypes = new Array[Type](clazz.info.closure.length) @@ -286,7 +303,11 @@ abstract class RefChecks extends InfoTransform { private val CoVariance = 1 private val AnyVariance = 2 - /** Check variance of type variables in this type + /** Check variance of type variables in this type. + * + * @param base ... + * @param all ... + * @param variance ... */ private def validateVariance(base: Symbol, all: Type, variance: int): unit = { diff --git a/src/compiler/scala/tools/nsc/util/NameTransformer.scala b/src/compiler/scala/tools/nsc/util/NameTransformer.scala index 893d9a0267..0df9508657 100644 --- a/src/compiler/scala/tools/nsc/util/NameTransformer.scala +++ b/src/compiler/scala/tools/nsc/util/NameTransformer.scala @@ -40,7 +40,11 @@ object NameTransformer { enterOp('?', "$qmark") enterOp('@', "$at") - /** Replace operator symbols by corresponding "$op_name" */ + /** Replace operator symbols by corresponding "<code>$op_name</code>". + * + * @param name ... + * @return ... + */ def encode(name: String): String = { var buf: StringBuffer = null val len = name.length() @@ -61,37 +65,41 @@ object NameTransformer { if (buf == null) name else buf.toString() } - /** Replace $op_name by corresponding operator symbol */ + /** Replace <code>$op_name</code> by corresponding operator symbol. + * + * @param name0 ... + * @return ... + */ def decode(name0: String): String = { //System.out.println("decode: " + name);//DEBUG - val name = if (name0.endsWith("<init>")) name0.substring(0, name0.length() - ("<init>").length()) + "this"; + val name = if (name0.endsWith("<init>")) name0.substring(0, name0.length() - ("<init>").length()) + "this" else name0; - var buf: StringBuffer = null; - val len = name.length(); - var i = 0; + var buf: StringBuffer = null + val len = name.length() + var i = 0 while (i < len) { - var ops: OpCodes = null; - val c = name charAt i; + var ops: OpCodes = null + val c = name charAt i if (c == '$' && i + 2 < len) { - val ch1 = name.charAt(i+1); + val ch1 = name.charAt(i+1) if ('a' <= ch1 && ch1 <= 'z') { - val ch2 = name.charAt(i+2); + val ch2 = name.charAt(i+2) if ('a' <= ch2 && ch2 <= 'z') { - ops = code2op((ch1 - 'a') * 26 + ch2 - 'a'); + ops = code2op((ch1 - 'a') * 26 + ch2 - 'a') while (ops != null && !name.startsWith(ops.code, i)) ops = ops.next; if (ops != null) { if (buf == null) { - buf = new StringBuffer(); - buf.append(name.substring(0, i)); + buf = new StringBuffer() + buf.append(name.substring(0, i)) } - buf.append(ops.op); + buf.append(ops.op) i = i + ops.code.length() } } } } if (ops == null) { - if (buf != null) buf.append(c); + if (buf != null) buf.append(c) i = i + 1 } } diff --git a/src/library/scala/testing/SUnit.scala b/src/library/scala/testing/SUnit.scala index 517d77bd66..367b599349 100644 --- a/src/library/scala/testing/SUnit.scala +++ b/src/library/scala/testing/SUnit.scala @@ -23,8 +23,8 @@ import scala.runtime.compat.StringBuilder * Use these classes like this: * </p> * <pre> - * import scala.testing.SUnit - * import SUnit._ + * <b>import</b> scala.testing.SUnit + * <b>import</b> SUnit._ * * <b>class</b> MyTest(n: String) <b>extends</b> TestCase(n) { * @@ -36,7 +36,7 @@ import scala.runtime.compat.StringBuilder * * <b>val</b> r = <b>new</b> TestResult() * suite.run(r) - * for (<b>val</b> tf <- r.failures()) { + * <b>for</b> (<b>val</b> tf <- r.failures()) { * Console.println(tf.toString()) * } * </pre> |