diff options
author | Paul Phillips <paulp@improving.org> | 2010-12-21 19:31:28 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-12-21 19:31:28 +0000 |
commit | 5bc2fc576949f03980ddd092b303b4484ab3172c (patch) | |
tree | c72cad9532854ccf436c72cfabfa0bdc0fc974fa | |
parent | c9ae821b7702169147fe324eb160710623c16280 (diff) | |
download | scala-5bc2fc576949f03980ddd092b303b4484ab3172c.tar.gz scala-5bc2fc576949f03980ddd092b303b4484ab3172c.tar.bz2 scala-5bc2fc576949f03980ddd092b303b4484ab3172c.zip |
More elimination of avoidable calls to List#len...
More elimination of avoidable calls to List#length. No review.
13 files changed, 111 insertions, 113 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index e2ff0f6600..686adc1800 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -35,7 +35,7 @@ abstract class TreeGen { mkAttributedRef(AbstractFunctionClass(argtpes.length)) else mkAttributedRef(FunctionClass(argtpes.length)) - AppliedTypeTree(cls, argtpes ::: List(restpe)) + AppliedTypeTree(cls, argtpes :+ restpe) } /** Builds a reference to value whose type is given stable prefix. diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index 8e663c32dd..829cca9e08 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -196,7 +196,7 @@ abstract class TreeInfo { /** Is name a variable name? */ def isVariableName(name: Name): Boolean = { val first = name(0) - ((first.isLower && first.isLetter) || first == '_') && !(reserved contains name) + ((first.isLower && first.isLetter) || first == '_') && !reserved(name) } /** Is tree a this node which belongs to `enclClass'? */ diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index a5b5902545..f6434b1662 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -1122,8 +1122,7 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable => private class ResetLocalAttrsTraverser extends ResetAttrsTraverser { private val erasedSyms = new HashSet[Symbol](8) - override protected def isLocal(sym: Symbol) = - erasedSyms contains sym + override protected def isLocal(sym: Symbol) = erasedSyms(sym) override protected def resetDef(tree: Tree) { erasedSyms addEntry tree.symbol super.resetDef(tree) diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 56f130a183..f54854a227 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -1822,7 +1822,6 @@ abstract class GenICode extends SubComponent { * in code generation */ class Context { - /** The current package. */ var packg: Name = _ diff --git a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala index 2151fdaaf2..ad85ded12b 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala @@ -12,11 +12,12 @@ import scala.tools.nsc.ast._ import scala.collection.{ mutable, immutable } import mutable.ListBuffer -trait Linearizers { self: ICodes => - import opcodes._; +trait Linearizers { + self: ICodes => + import opcodes._ abstract class Linearizer { - def linearize(c: IMethod): List[BasicBlock]; + def linearize(c: IMethod): List[BasicBlock] def linearizeAt(c: IMethod, start: BasicBlock): List[BasicBlock] } @@ -28,11 +29,9 @@ trait Linearizers { self: ICodes => * 'true', the loop continues). */ class NormalLinearizer extends Linearizer with WorklistAlgorithm { - type Elem = BasicBlock; - - val worklist: WList = new mutable.Stack(); - - var blocks: List[BasicBlock] = Nil; + type Elem = BasicBlock + val worklist: WList = new mutable.Stack() + var blocks: List[BasicBlock] = Nil def linearize(m: IMethod): List[BasicBlock] = { val b = m.code.startBlock; diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala index 3d7219923d..43ab35b83e 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala @@ -355,13 +355,11 @@ abstract class CopyPropagation { } case BOX(tpe) => - val top = out.stack.head - top match { - case Deref(loc) => - out.stack = Boxed(loc) :: out.stack.tail - case _ => - out.stack = Unknown :: out.stack.drop(1) + val top = out.stack.head match { + case Deref(loc) => Boxed(loc) + case _ => Unknown } + out.stack = top :: out.stack.tail case UNBOX(tpe) => val top = out.stack.head @@ -371,14 +369,10 @@ abstract class CopyPropagation { } case NEW(kind) => - val v1 = - kind match { - case REFERENCE(cls) => - Record(cls, new HashMap[Symbol, Value]) - // bq: changed from _ to null, otherwise would be unreachable - case null => - Unknown - } + val v1 = kind match { + case REFERENCE(cls) => Record(cls, new HashMap[Symbol, Value]) + case _ => Unknown + } out.stack = v1 :: out.stack case CREATE_ARRAY(elem, dims) => diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala index be50640d9c..dd9341ac91 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala @@ -67,7 +67,7 @@ trait DataFlowAnalysis[L <: SemiLattice] { out(point) = output val succs = point.successors succs foreach { p => - if (!worklist.contains(p)) + if (!worklist(p)) worklist += p; if (!in.isDefinedAt(p)) assert(false, "Invalid successor for: " + point + " successor " + p + " does not exist") @@ -91,19 +91,17 @@ trait DataFlowAnalysis[L <: SemiLattice] { * @param f ... */ def backwardAnalysis(f: (P, lattice.Elem) => lattice.Elem): Unit = - while (!worklist.isEmpty) { + while (worklist.nonEmpty) { if (stat) iterations += 1 - val point = worklist.iterator.next; worklist -= point + val point = worklist.head + worklist -= point out(point) = lattice.lub(point.successors map in.apply, false) // TODO check for exception handlers val input = f(point, out(point)) if ((lattice.bottom == in(point)) || input != in(point)) { in(point) = input - point.predecessors foreach { p => - if (!worklist.contains(p)) - worklist += p; - } + worklist ++= point.predecessors } } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 41782ffdcb..2bc501cea0 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -238,11 +238,8 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid { parents = parents.distinct - if (parents.length > 1) { - ifaces = new Array[String](parents.length - 1) - parents.drop(1).map((s) => javaName(s.typeSymbol)).copyToArray(ifaces, 0) - () - } + if (parents.tail.nonEmpty) + ifaces = parents drop 1 map (x => javaName(x.typeSymbol)) toArray; jclass = fjbgContext.JClass(javaFlags(c.symbol), name, diff --git a/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala b/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala index c230533765..72dc5b9e91 100644 --- a/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala +++ b/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala @@ -188,8 +188,8 @@ trait BaseTypeSeqs { val buf = new ListBuffer[Type] buf += tsym.tpe var btsSize = 1 - val nparents = parents.length - if (nparents != 0) { + if (parents.nonEmpty) { + val nparents = parents.length val pbtss = new Array[BaseTypeSeq](nparents) val index = new Array[Int](nparents) var i = 0 diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 8dc1d3fb3b..fa410a2afd 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -312,19 +312,22 @@ trait Definitions extends reflect.generic.StandardDefinitions { def isTupleType(tp: Type): Boolean = isTupleType(tp, false) def isTupleTypeOrSubtype(tp: Type): Boolean = isTupleType(tp, true) private def isTupleType(tp: Type, subtypeOK: Boolean) = tp.normalize match { - case TypeRef(_, sym, args) => - args.nonEmpty && args.length <= MaxTupleArity && { - val tsym = TupleClass(args.length) + case TypeRef(_, sym, args) if args.nonEmpty => + val len = args.length + len <= MaxTupleArity && { + val tsym = TupleClass(len) (sym == tsym) || (subtypeOK && !tp.isHigherKinded && sym.isSubClass(tsym)) } case _ => false } - def tupleType(elems: List[Type]) = - if (elems.length <= MaxTupleArity) { - val sym = TupleClass(elems.length) + def tupleType(elems: List[Type]) = { + val len = elems.length + if (len <= MaxTupleArity) { + val sym = TupleClass(len) typeRef(sym.typeConstructor.prefix, sym, elems) - } else NoType; + } else NoType + } lazy val ProductRootClass: Symbol = getClass("scala.Product") def Product_productArity = getMember(ProductRootClass, nme.productArity) @@ -338,16 +341,22 @@ trait Definitions extends reflect.generic.StandardDefinitions { /** returns true if this type is exactly ProductN[T1,...,Tn], not some subclass */ def isExactProductType(tp: Type): Boolean = cond(tp.normalize) { - case TypeRef(_, sym, elems) => elems.length <= MaxProductArity && sym == ProductClass(elems.length) + case TypeRef(_, sym, elems) => + val len = elems.length + len <= MaxProductArity && sym == ProductClass(len) } - def productType(elems: List[Type]) = - if (elems.isEmpty) - UnitClass.tpe - else if (elems.length <= MaxProductArity) { - val sym = ProductClass(elems.length) - typeRef(sym.typeConstructor.prefix, sym, elems) - } else NoType + def productType(elems: List[Type]) = { + if (elems.isEmpty) UnitClass.tpe + else { + val len = elems.length + if (len <= MaxProductArity) { + val sym = ProductClass(len) + typeRef(sym.typeConstructor.prefix, sym, elems) + } + else NoType + } + } /** if tpe <: ProductN[T1,...,TN], returns Some(T1,...,TN) else None */ def getProductArgs(tpe: Type): Option[List[Type]] = @@ -360,11 +369,13 @@ trait Definitions extends reflect.generic.StandardDefinitions { }).normalize def functionApply(n: Int) = getMember(FunctionClass(n), nme.apply) - def functionType(formals: List[Type], restpe: Type) = - if (formals.length <= MaxFunctionArity) { - val sym = FunctionClass(formals.length) + def functionType(formals: List[Type], restpe: Type) = { + val len = formals.length + if (len <= MaxFunctionArity) { + val sym = FunctionClass(len) typeRef(sym.typeConstructor.prefix, sym, formals :+ restpe) } else NoType + } def abstractFunctionForFunctionType(tp: Type) = tp.normalize match { case tr @ TypeRef(_, _, args) if isFunctionType(tr) => @@ -375,9 +386,9 @@ trait Definitions extends reflect.generic.StandardDefinitions { } def isFunctionType(tp: Type): Boolean = tp.normalize match { - case TypeRef(_, sym, args) => - (args.length > 0) && (args.length - 1 <= MaxFunctionArity) && - (sym == FunctionClass(args.length - 1)) + case TypeRef(_, sym, args) if args.nonEmpty => + val len = args.length + len < MaxFunctionArity && sym == FunctionClass(len - 1) case _ => false } diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index ba83f173aa..62540527e8 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -1584,7 +1584,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable => /** String representation of symbol's definition following its name */ final def infoString(tp: Type): String = { def typeParamsString: String = tp match { - case PolyType(tparams, _) if (tparams.length != 0) => + case PolyType(tparams, _) if tparams.nonEmpty => (tparams map (_.defString)).mkString("[", ",", "]") case _ => "" diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 6681076e94..ad1cf598b6 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -3574,20 +3574,21 @@ A type's typeSymbol should never be inspected directly. } class InstantiateDependentMap(params: List[Symbol], actuals: List[Type]) extends TypeMap { + private val actualsIndexed = actuals.toIndexedSeq override val dropNonConstraintAnnotations = true object ParamWithActual { def unapply(sym: Symbol): Option[Type] = { val pid = params indexOf sym - if(pid != -1) Some(actuals(pid)) else None + if(pid != -1) Some(actualsIndexed(pid)) else None } } def apply(tp: Type): Type = mapOver(tp) match { - case SingleType(NoPrefix, ParamWithActual(arg)) if arg isStable => arg // unsound to replace args by unstable actual #3873 + case SingleType(NoPrefix, ParamWithActual(arg)) if arg.isStable => arg // unsound to replace args by unstable actual #3873 // (soundly) expand type alias selections on implicit arguments, see depmet_implicit_oopsla* test cases -- typically, `param.isImplicit` - case tp1@TypeRef(SingleType(NoPrefix, param@ParamWithActual(arg)), sym, targs) => + case tp1@TypeRef(SingleType(NoPrefix, ParamWithActual(arg)), sym, targs) => val res = typeRef(arg, sym, targs) if(res.typeSymbolDirect isAliasType) res.dealias else tp1 @@ -3596,8 +3597,8 @@ A type's typeSymbol should never be inspected directly. def existentialsNeeded: List[Symbol] = existSyms.filter(_ ne null).toList - private val existSyms: Array[Symbol] = new Array(actuals.length) - private def haveExistential(i: Int) = {assert((i >= 0) && (i <= actuals.length)); existSyms(i) ne null} + private val existSyms: Array[Symbol] = new Array(actualsIndexed.size) + private def haveExistential(i: Int) = {assert((i >= 0) && (i <= actualsIndexed.size)); existSyms(i) ne null} /* Return the type symbol for referencing a parameter inside the existential quantifier. * (Only needed if the actual is unstable.) @@ -3607,7 +3608,7 @@ A type's typeSymbol should never be inspected directly. else { val oldSym = params(actualIdx) val symowner = oldSym.owner - val bound = singletonBounds(actuals(actualIdx)) + val bound = singletonBounds(actualsIndexed(actualIdx)) val sym = symowner.newExistential(oldSym.pos, oldSym.name+".type") sym.setInfo(bound) @@ -3625,9 +3626,9 @@ A type's typeSymbol should never be inspected directly. case RefParamAt(pid) => // TODO: this should be simplified; in the stable case, one can probably // just use an Ident to the tree.symbol. Why an existential in the non-stable case? - val actual = actuals(pid) - if(actual.isStable && actual.typeSymbol != NothingClass) { - mkAttributedQualifier(actuals(pid), tree.symbol) + val actual = actualsIndexed(pid) + if (actual.isStable && actual.typeSymbol != NothingClass) { + mkAttributedQualifier(actualsIndexed(pid), tree.symbol) } else { val sym = existSymFor(pid) (Ident(sym.name) @@ -3638,11 +3639,9 @@ A type's typeSymbol should never be inspected directly. } } object RefParamAt { - def unapply(tree: Tree): Option[(Int)] = tree match { - case Ident(_) => - val pid = params indexOf tree.symbol - if(pid != -1) Some((pid)) else None - case _ => None + def unapply(tree: Tree): Option[Int] = tree match { + case Ident(_) => Some(params indexOf tree.symbol) filterNot (_ == -1) + case _ => None } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 3311b5852a..5592126c92 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -483,7 +483,7 @@ trait Typers { self: Analyzer => case TypeRef(_, sym, args) => checkNoEscape(sym) if (!hiddenSymbols.isEmpty && hiddenSymbols.head == sym && - sym.isAliasType && sym.typeParams.length == args.length) { + sym.isAliasType && sameLength(sym.typeParams, args)) { hiddenSymbols = hiddenSymbols.tail t.normalize } else t @@ -906,7 +906,7 @@ trait Typers { self: Analyzer => ((mode & HKmode) != 0) && // @M: don't check tree.tpe.symbol.typeParams. check tree.tpe.typeParams!!! // (e.g., m[Int] --> tree.tpe.symbol.typeParams.length == 1, tree.tpe.typeParams.length == 0!) - tree.tpe.typeParams.length != pt.typeParams.length && + !sameLength(tree.tpe.typeParams, pt.typeParams) && !(tree.tpe.typeSymbol==AnyClass || tree.tpe.typeSymbol==NothingClass || pt == WildcardType )) { @@ -1620,8 +1620,8 @@ trait Typers { self: Analyzer => val (superConstr, args1) = decompose(fn) val params = fn.tpe.params val args2 = if (params.isEmpty || !isRepeatedParamType(params.last.tpe)) args - else args.take(params.length - 1) ::: List(EmptyTree) - assert(args2.length == params.length, "mismatch " + clazz + " " + (params map (_.tpe)) + " " + args2)//debug + else args.take(params.length - 1) :+ EmptyTree + assert(sameLength(args2, params), "mismatch " + clazz + " " + (params map (_.tpe)) + " " + args2)//debug (superConstr, args1 ::: args2) case Block(stats, expr) if !stats.isEmpty => decompose(stats.last) @@ -1643,7 +1643,7 @@ trait Typers { self: Analyzer => val superClazz = superConstr.symbol.owner if (!superClazz.isJavaDefined) { val superParamAccessors = superClazz.constrParamAccessors - if (superParamAccessors.length == superArgs.length) { + if (sameLength(superParamAccessors, superArgs)) { (superParamAccessors, superArgs).zipped map { (superAcc, superArg) => superArg match { case Ident(name) => @@ -2005,27 +2005,28 @@ trait Typers { self: Analyzer => * @return ... */ def typedFunction(fun: Function, mode: Int, pt: Type): Tree = { + val numVparams = fun.vparams.length val codeExpected = !forMSIL && (pt.typeSymbol isNonBottomSubClass CodeClass) - if (fun.vparams.length > definitions.MaxFunctionArity) + if (numVparams > definitions.MaxFunctionArity) return errorTree(fun, "implementation restricts functions to " + definitions.MaxFunctionArity + " parameters") def decompose(pt: Type): (Symbol, List[Type], Type) = if ((isFunctionType(pt) || pt.typeSymbol == PartialFunctionClass && - fun.vparams.length == 1 && fun.body.isInstanceOf[Match]) + numVparams == 1 && fun.body.isInstanceOf[Match]) && // see bug901 for a reason why next conditions are needed - (pt.normalize.typeArgs.length - 1 == fun.vparams.length + (pt.normalize.typeArgs.length - 1 == numVparams || fun.vparams.exists(_.tpt.isEmpty))) (pt.typeSymbol, pt.normalize.typeArgs.init, pt.normalize.typeArgs.last) else - (FunctionClass(fun.vparams.length), fun.vparams map (x => NoType), WildcardType) + (FunctionClass(numVparams), fun.vparams map (x => NoType), WildcardType) val (clazz, argpts, respt) = decompose(if (codeExpected) pt.normalize.typeArgs.head else pt) - if (fun.vparams.length != argpts.length) + if (argpts.lengthCompare(numVparams) != 0) errorTree(fun, "wrong number of parameters; expected = " + argpts.length) else { val vparamSyms = (fun.vparams, argpts).zipped map { (vparam, argpt) => @@ -2040,7 +2041,7 @@ trait Typers { self: Analyzer => // if context,undetparams is not empty, the function was polymorphic, // so we need the missing arguments to infer its type. See #871 //println("typing eta "+fun+":"+fn1.tpe+"/"+context.undetparams) - val ftpe = normalize(fn1.tpe) baseType FunctionClass(fun.vparams.length) + val ftpe = normalize(fn1.tpe) baseType FunctionClass(numVparams) if (isFunctionType(ftpe) && isFullyDefined(ftpe)) return typedFunction(fun, mode, ftpe) case _ => @@ -2064,7 +2065,7 @@ trait Typers { self: Analyzer => var body = typed(fun.body, respt) val formals = vparamSyms map (_.tpe) val restpe = packedType(body, fun.symbol).deconst - val funtpe = typeRef(clazz.tpe.prefix, clazz, formals ::: List(restpe)) + val funtpe = typeRef(clazz.tpe.prefix, clazz, formals :+ restpe) // body = checkNoEscaping.locals(context.scope, restpe, body) val fun1 = treeCopy.Function(fun, vparams, body).setType(funtpe) if (codeExpected) { @@ -2219,7 +2220,7 @@ trait Typers { self: Analyzer => def typedArgs(args: List[Tree], mode: Int, originalFormals: List[Type], adaptedFormals: List[Type]) = { var newmodes = originalFormals map (tp => if (isByNameParamType(tp)) 0 else BYVALmode) if (isVarArgTypes(originalFormals)) // TR check really necessary? - newmodes = newmodes.init ::: List.fill(args.length - originalFormals.length + 1)(STARmode | BYVALmode) + newmodes = newmodes.init ++ List.fill(args.length - originalFormals.length + 1)(STARmode | BYVALmode) (args, adaptedFormals, newmodes).zipped map { (arg, formal, m) => typedArg(arg, mode, m, formal) @@ -2339,7 +2340,7 @@ trait Typers { self: Analyzer => // if 1 formal, 1 arg (a tuple), otherwise unmodified args val tupleArgs = actualArgs(tree.pos.makeTransparent, args, formals.length) - if (tupleArgs.length != args.length && !isUnitForVarArgs(args, params)) { + if (!sameLength(tupleArgs, args) && !isUnitForVarArgs(args, params)) { // expected one argument, but got 0 or >1 ==> try applying to tuple // the inner "doTypedApply" does "extractUndetparams" => restore when it fails val savedUndetparams = context.undetparams @@ -2360,21 +2361,21 @@ trait Typers { self: Analyzer => * and defaults is ruled out by typedDefDef. */ def tryNamesDefaults: Tree = { + val lencmp = compareLengths(args, formals) + if (mt.isErroneous) setError(tree) else if ((mode & PATTERNmode) != 0) // #2064 errorTree(tree, "wrong number of arguments for "+ treeSymTypeMsg(fun)) - else if (args.length > formals.length) { - tryTupleApply.getOrElse { - errorTree(tree, "too many arguments for "+treeSymTypeMsg(fun)) - } - } else if (args.length == formals.length) { + else if (lencmp > 0) { + tryTupleApply getOrElse errorTree(tree, "too many arguments for "+treeSymTypeMsg(fun)) + } else if (lencmp == 0) { // we don't need defaults. names were used, so this application is transformed // into a block (@see transformNamedApplication in NamesDefaults) val (namelessArgs, argPos) = removeNames(Typer.this)(args, params) if (namelessArgs exists (_.isErroneous)) { setError(tree) - } else if (!isIdentity(argPos) && (formals.length != params.length)) + } else if (!isIdentity(argPos) && !sameLength(formals, params)) // !isIdentity indicates that named arguments are used to re-order arguments errorTree(tree, "when using named arguments, the vararg parameter "+ "has to be specified exactly once") @@ -2405,12 +2406,14 @@ trait Typers { self: Analyzer => } val (allArgs, missing) = addDefaults(args, qual, targs, previousArgss, params, fun.pos.focus, context) val funSym = fun1 match { case Block(_, expr) => expr.symbol } - if (allArgs.length != args.length && callToCompanionConstr(context, funSym)) { + val lencmp2 = compareLengths(allArgs, formals) + + if (!sameLength(allArgs, args) && callToCompanionConstr(context, funSym)) { errorTree(tree, "module extending its companion class cannot use default constructor arguments") - } else if (allArgs.length > formals.length) { + } else if (lencmp2 > 0) { removeNames(Typer.this)(allArgs, params) // #3818 setError(tree) - } else if (allArgs.length == formals.length) { + } else if (lencmp2 == 0) { // useful when a default doesn't match parameter type, e.g. def f[T](x:T="a"); f[Int]() val note = "Error occurred in an application involving default arguments." if (!(context.diagnostic contains note)) context.diagnostic = note :: context.diagnostic @@ -2422,10 +2425,10 @@ trait Typers { self: Analyzer => } } - if (formals.length != args.length || // wrong nb of arguments - args.exists(isNamed(_)) || // uses a named argument - isNamedApplyBlock(fun)) { // fun was transformed to a named apply block => - // integrate this application into the block + if (!sameLength(formals, args) || // wrong nb of arguments + (args exists isNamed) || // uses a named argument + isNamedApplyBlock(fun)) { // fun was transformed to a named apply block => + // integrate this application into the block tryNamesDefaults } else { val tparams = context.extractUndetparams() @@ -2570,7 +2573,7 @@ trait Typers { self: Analyzer => else { val formals0 = unapplyTypeList(fun1.symbol, fun1.tpe) val formals1 = formalTypes(formals0, args.length) - if (formals1.length == args.length) { + if (sameLength(formals1, args)) { val args1 = typedArgs(args, mode, formals0, formals1) if (!isFullyDefined(pt)) assert(false, tree+" ==> "+UnApply(fun1, args1)+", pt = "+pt) val itype = glb(List(pt, arg.tpe)) @@ -2784,8 +2787,7 @@ trait Typers { self: Analyzer => error(t.pos, "unexpected tree after typing annotation: "+ typedAnn) } - if (annType.typeSymbol == DeprecatedAttr && - (argss.length == 0 || argss.head.length == 0)) + if (annType.typeSymbol == DeprecatedAttr && (argss.isEmpty || argss.head.isEmpty)) unit.deprecationWarning(ann.pos, "the `deprecated' annotation now takes a (message: String) as parameter\n"+ "indicating the reason for deprecation. That message is printed to the console and included in scaladoc.") @@ -2944,7 +2946,7 @@ trait Typers { self: Analyzer => case OverloadedType(pre, alts) => inferPolyAlternatives(fun, args map (_.tpe)) val tparams = fun.symbol.typeParams //@M TODO: fun.symbol.info.typeParams ? (as in typedAppliedTypeTree) - val args1 = if(args.length == tparams.length) { + val args1 = if (sameLength(args, tparams)) { //@M: in case TypeApply we can't check the kind-arities of the type arguments, // as we don't know which alternative to choose... here we do map2Conserve(args, tparams) { @@ -2960,8 +2962,8 @@ trait Typers { self: Analyzer => typedTypeApply(tree, mode, fun, args1) case SingleType(_, _) => typedTypeApply(tree, mode, fun setType fun.tpe.widen, args) - case PolyType(tparams, restpe) if (tparams.length != 0) => - if (tparams.length == args.length) { + case PolyType(tparams, restpe) if tparams.nonEmpty => + if (sameLength(tparams, args)) { val targs = args map (_.tpe) checkBounds(tree.pos, NoPrefix, NoSymbol, tparams, targs, "") if (fun.symbol == Predef_classOf) { @@ -3779,7 +3781,7 @@ trait Typers { self: Analyzer => errorTree(tree, tpt1.tpe+" does not take type parameters") } else { val tparams = tpt1.symbol.typeParams - if (tparams.length == args.length) { + if (sameLength(tparams, args)) { // @M: kind-arity checking is done here and in adapt, full kind-checking is in checkKindBounds (in Infer) val args1 = if(!tpt1.symbol.rawInfo.isComplete) @@ -3813,7 +3815,7 @@ trait Typers { self: Analyzer => result // you only get to see the wrapped tree after running this check :-p }).setType(result.tpe) else result - } else if (tparams.length == 0) { + } else if (tparams.isEmpty) { errorTree(tree, tpt1.tpe+" does not take type parameters") } else { //Console.println("\{tpt1}:\{tpt1.symbol}:\{tpt1.symbol.info}") @@ -4015,7 +4017,7 @@ trait Typers { self: Analyzer => //context.undetparams = undets // @M maybe the well-kindedness check should be done when checking the type arguments conform to the type parameters' bounds? - val args1 = if(args.length == tparams.length) map2Conserve(args, tparams) { + val args1 = if (sameLength(args, tparams)) map2Conserve(args, tparams) { //@M! the polytype denotes the expected kind (arg, tparam) => typedHigherKindedType(arg, mode, polyType(tparam.typeParams, AnyClass.tpe)) } else { |