|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 | Next > |
|
|
[scala] Testing equality with nullThe code fragments
if (x == null) / if (x != null) currently generate calls to x.equals(null) This behaviour is correct with regards to the spec but is unfortunate with regards to performance and code size - it can be 10 times slower. Option 1:- Perhaps the spec should permit implementations to avoid calling equals when they can deduce that the right hand side is null. In practice, the compiler would only avoid calling equals whenever the right hand side is the Literal(Constant(null)) Option 2:- Perhaps every such fragment in the compiler and library source should be changed to if (x eq null) / if (x ne null) or if (null == x) / if (null != x) This way, ifnonnull/ifnull bytecodes are generated. I've attached the source lines that would be affected, identified using grep -E "==( *)null" grep -E "!=( *)null" An optional compiler warning or a compiler plugin would be another way to detect such cases. ./scala-compiler-src/scala/tools/nsc/ast/NodePrinters.scala:140: if (tree.tpe != null) { ./scala-compiler-src/scala/tools/nsc/ast/parser/Parsers.scala:86: if (xmlp0 == null) ./scala-compiler-src/scala/tools/nsc/ast/parser/Scanners.scala:258: val ret = if (docBuffer != null) docBuffer.toString else null ./scala-compiler-src/scala/tools/nsc/ast/parser/Scanners1.scala:107: val ret = if (docBuffer != null) docBuffer.toString else null ./scala-compiler-src/scala/tools/nsc/ast/TreeGen.scala:217: if (tpe == null && tree.hasSymbol) tpe = tree.symbol.tpe ./scala-compiler-src/scala/tools/nsc/ast/TreePrinters.scala:92: if (tree.symbol != null && tree.symbol != NoSymbol) { ./scala-compiler-src/scala/tools/nsc/ast/Trees.scala:816: override def symbol = if (tpe == null) null else tpe.typeSymbol ./scala-compiler-src/scala/tools/nsc/ast/Trees.scala:220: case (this0 : TypeTree,that0 : TypeTree) if this0.original != null && that0.original != null => ./scala-compiler-src/scala/tools/nsc/backend/icode/GenICode.scala:1477: // expr == null -> if(expr eq null) true else expr.equals(null) ./scala-compiler-src/scala/tools/nsc/backend/jvm/GenJVM.scala:278: if (f != null) ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:253: moduleName = assemName + (if (entryPoint == null) ".dll" else ".exe") ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:373: if (str == null) { ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:380: if (arr == null) { ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:701: if (cb == null) { ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:768: val t = if (tryBlock == null) Nil else List(tryBlock) ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:769: val f = if (finallyBlock == null) Nil else List(finallyBlock) ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:1615: if (handler.finalizer == null || handler.finalizer == NoFinalizer) ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:1948: if (entryPoint == null) ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:1986: if (typ == null) ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:2259: if (delegateCallers == null) ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:227: if (entryPoint != null) { ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:257: assert (mmodule != null) ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:437: if (entryPoint != null) { ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:573: if (mcode != null) { ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:853: if (nextBlock != null && b.contains(nextBlock)) { ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:862: (h.finalizer != null && ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:1033: if (singleAffectedHandler.finalizer != null && singleAffectedHandler.finalizer != NoFinalizer) { ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:1072: if (h.finalizer != null && h.finalizer != NoFinalizer) ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:1124: if (handler.finalizer != null && handler.finalizer != NoFinalizer) { ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:1175: // lastBlock != null is secure ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:1176: def saveResult(resType: MsilType) = if (resType != MVOID && lastBlock != null) { ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:1953: if (cls.symbol.sourceFile != null) // is null for nested classes ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:1995: assert(mType != null, showsym(sym)) ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:2393: assert (mInfo != null, mInfo) ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:2402: assert(methodInfo != null, "Can't find mapping for " + sym + " -> " + ./scala-compiler-src/scala/tools/nsc/backend/msil/GenMSIL.scala:2418: assert(methodSym != null, "cannot find method " + name + "(" + ./scala-compiler-src/scala/tools/nsc/backend/ScalaPrimitives.scala:626: assert(elem != null) ./scala-compiler-src/scala/tools/nsc/dependencies/DependencyAnalysis.scala:79: if (f != null){ ./scala-compiler-src/scala/tools/nsc/dependencies/DependencyAnalysis.scala:85: for (d <- unit.depends; if (d.sourceFile != null)){ ./scala-compiler-src/scala/tools/nsc/dependencies/Files.scala:128: if (underlying == null) throw new NullPointerException(); ./scala-compiler-src/scala/tools/nsc/dependencies/Files.scala:161: if (x == null) currentDirectory ./scala-compiler-src/scala/tools/nsc/dependencies/Files.scala:106: while ({line = reader.readLine; (line != null) && (line != Separator)}){ ./scala-compiler-src/scala/tools/nsc/dependencies/Files.scala:113: while ({line = reader.readLine; (line != null) && (line != Separator)}){ ./scala-compiler-src/scala/tools/nsc/doc/DefaultDocDriver.scala:76: assert(global.definitions != null) ./scala-compiler-src/scala/tools/nsc/doc/DefaultDocDriver.scala:95: assert(pkg != null) ./scala-compiler-src/scala/tools/nsc/doc/DefaultDocDriver.scala:98: assert(pkg != null) ./scala-compiler-src/scala/tools/nsc/doc/DefaultDocDriver.scala:251: if (key != null && roots.contains(key)) return true; ./scala-compiler-src/scala/tools/nsc/doc/DefaultDocDriver.scala:299: if (key != null && roots.contains(key)) { ./scala-compiler-src/scala/tools/nsc/doc/DocUtil.scala:21: if ((str == null) || (str.length == 0)) ./scala-compiler-src/scala/tools/nsc/doc/DocUtil.scala:44: if (href0 == null) return Text(text); ./scala-compiler-src/scala/tools/nsc/doc/ModelExtractor.scala:94: case "public" => "" // assert(qual == null); ""; ./scala-compiler-src/scala/tools/nsc/doc/ModelExtractor.scala:95: case core => core + (if (qual == null) "" else "[" + qual + "]") ./scala-compiler-src/scala/tools/nsc/doc/ModelExtractor.scala:288: if (ret == null) ret = new mutable.LinkedHashSet[Symbol]; ./scala-compiler-src/scala/tools/nsc/doc/ModelExtractor.scala:292: if (ret == null) Nil else ret ./scala-compiler-src/scala/tools/nsc/doc/ModelExtractor.scala:107: else if (sym.privateWithin != null && sym.privateWithin != NoSymbol) ./scala-compiler-src/scala/tools/nsc/doc/ModelFrames.scala:127: if (cnt == null) null else cnt + "#" + docName(sym) ./scala-compiler-src/scala/tools/nsc/doc/ModelFrames.scala:225: val nav = if (navLabel == null) NodeSeq.Empty else ./scala-compiler-src/scala/tools/nsc/doc/ModelFrames.scala:105: assert(ret != null); ./scala-compiler-src/scala/tools/nsc/doc/ModelToXML.scala:30: if (url == null) ./scala-compiler-src/scala/tools/nsc/doc/ModelToXML.scala:38: if (url == null) { // external link (handled by script.js) ./scala-compiler-src/scala/tools/nsc/doc/ModelToXML.scala:177: if (option == null) NodeSeq.Empty; ./scala-compiler-src/scala/tools/nsc/Global.scala:757: while (localPhase != null && (localPhase.id < globalPhase.id || localPhase.id <= namerPhase.id) && !reporter.hasErrors) { ./scala-compiler-src/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala:23: if (file == null) { ./scala-compiler-src/scala/tools/nsc/interpreter/AbstractFileClassLoader.scala:28: if (file == null) { ./scala-compiler-src/scala/tools/nsc/interpreter/Completion.scala:51: val buffer = if (s == null) "" else s ./scala-compiler-src/scala/tools/nsc/interpreter/Completion.scala:154: if (e == null || !e.hasMoreElements) xs else enumToList(e, e.nextElement :: xs) ./scala-compiler-src/scala/tools/nsc/interpreter/JLineReader.scala:26: if (interpreter != null) { ./scala-compiler-src/scala/tools/nsc/Interpreter.scala:153: if (parentClassLoader == null) new URLClassLoader(cp) ./scala-compiler-src/scala/tools/nsc/Interpreter.scala:438: if (req == null || !req.compile) ./scala-compiler-src/scala/tools/nsc/Interpreter.scala:628: if (sel != null && sel != USCOREkw) ./scala-compiler-src/scala/tools/nsc/io/AbstractFile.scala:200: if (existing == null) { ./scala-compiler-src/scala/tools/nsc/io/AbstractFile.scala:216: if (existing == null) { ./scala-compiler-src/scala/tools/nsc/io/VirtualDirectory.scala:49: if (existing == null) { ./scala-compiler-src/scala/tools/nsc/io/VirtualDirectory.scala:60: if (existing == null) { ./scala-compiler-src/scala/tools/nsc/javac/JavaScanners.scala:284: val ret = if (docBuffer != null) docBuffer.toString else null ./scala-compiler-src/scala/tools/nsc/Main.scala:52: if (libpath != null) ./scala-compiler-src/scala/tools/nsc/MainGenericRunner.scala:121: if (specs == null || specs.length == 0) Nil ./scala-compiler-src/scala/tools/nsc/ObjectRunner.scala:27: if (cl == null) null ./scala-compiler-src/scala/tools/nsc/ObjectRunner.scala:28: else if (cl.getParent == null) cl ./scala-compiler-src/scala/tools/nsc/plugins/Plugin.scala:84: if (ent == null) return None ./scala-compiler-src/scala/tools/nsc/ScalaDoc.scala:42: if (libpath != null) ./scala-compiler-src/scala/tools/nsc/symtab/classfile/ClassfileParser.scala:62: if (e.getMessage() != null) e.getMessage() ./scala-compiler-src/scala/tools/nsc/symtab/classfile/ClassfileParser.scala:630: val restype = if (sym != null && sym.isConstructor) { ./scala-compiler-src/scala/tools/nsc/symtab/classfile/ClassfileParser.scala:657: assert(sym != null) ./scala-compiler-src/scala/tools/nsc/symtab/classfile/ICodeReader.scala:191: else if (name == nullName) ./scala-compiler-src/scala/tools/nsc/symtab/clr/CLRTypes.scala:117: val atypes = assem.GetTypes().filter((typ: Type) => typ.DeclaringType == null) ./scala-compiler-src/scala/tools/nsc/symtab/clr/CLRTypes.scala:105: //assert(SCALA_SYMTAB_ATTR != null) ./scala-compiler-src/scala/tools/nsc/symtab/clr/CLRTypes.scala:111: //assert(DELEGATE_COMBINE != null) ./scala-compiler-src/scala/tools/nsc/symtab/clr/CLRTypes.scala:112: //assert(DELEGATE_REMOVE != null) ./scala-compiler-src/scala/tools/nsc/symtab/clr/CLRTypes.scala:141: assert(t != null, name) ./scala-compiler-src/scala/tools/nsc/symtab/clr/CLRTypes.scala:166: if (assem != null) { ./scala-compiler-src/scala/tools/nsc/symtab/clr/CLRTypes.scala:177: if (assem != null) { ./scala-compiler-src/scala/tools/nsc/symtab/clr/CLRTypes.scala:187: if (assem != null) { ./scala-compiler-src/scala/tools/nsc/symtab/clr/CLRTypes.scala:203: if (assem != null) { ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:154: if (!(getter == null || getter.IsPrivate || getter.IsAssembly ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:171: if (!(setter == null || setter.IsPrivate || setter.IsAssembly ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:201: if (!(adder == null || adder.IsPrivate || adder.IsAssembly ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:212: if (!(remover == null || remover.IsPrivate || remover.IsAssembly ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:275: if (rettype == null) return; ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:277: if (mtype == null) return; ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:355: if (rtype == null) null else methodType(method, rtype); ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:388: || (typ.IsArray() && getCLSType(typ.GetElementType()) == null)) ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:80: if (mClass != null) { ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:83: assert (moduleInstance != null, mClass); ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:90: val superType = if (typ.BaseType() != null) getCLRType(typ.BaseType()) ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:150: if (propType != null) { ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:175: if(getter != null) ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:178: if(getter != null) ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:290: assert(mtype != null); ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:298: if (method != null) ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:375: assert(typ != null); ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:391: //scalac.symtab.Type t = s != null ? make.classType(s) : getCLRType(type); ./scala-compiler-src/scala/tools/nsc/symtab/clr/TypeParser.scala:429: assert (res != null, typ) ./scala-compiler-src/scala/tools/nsc/symtab/Constants.scala:54: else if (value == null) NullTag ./scala-compiler-src/scala/tools/nsc/symtab/Constants.scala:197: if (value == null) "null" ./scala-compiler-src/scala/tools/nsc/symtab/Constants.scala:229: if (value == null) 0 else value.hashCode() * 41 + 17 ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:298: if (anyClients == null) anyClients = new LinkedHashSet[Function1[PersistentScope,Unit]] ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:322: return if (lookupEntry(symbol.name) == null) ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:76: while (e != null && e.sym != sym) { ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:84: if (e != null && e.sym == sym) { ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:104: while (e != null && !e.sym.isGetter && (!e.sym.hasFlag(ACCESSOR) || e.sym.accessed != sym)) { ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:107: if (e != null && check(e.sym.accessed == sym, "accessed" + e.sym.accessed +" vs. " + sym) && check(!e.sym.isSetter, "setter: " + e.sym)) { ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:114: while (e != null && !e.sym.isSetter) e = scope lookupNextEntry e ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:115: if (e != null) { ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:140: check(sym != null, "") ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:242: while (other != null && !compareTypes(other.sym.info,oldType(oldS), syms)) ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:244: other != null ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:307: if (anyClients != null) { ./scala-compiler-src/scala/tools/nsc/symtab/IdeSupport.scala:330: if (symbol.owner.isPackageClass && !symbol.isPackageClass && symbol.sourceFile != null) { ./scala-compiler-src/scala/tools/nsc/symtab/Scopes.scala:96: if (from != NoSymbol && depends != null) { ./scala-compiler-src/scala/tools/nsc/symtab/Scopes.scala:102: if (from != NoSymbol && depends != null) { ./scala-compiler-src/scala/tools/nsc/symtab/Scopes.scala:232: if (e1 != null) { ./scala-compiler-src/scala/tools/nsc/symtab/Scopes.scala:237: while (e1.tail != null && e1.tail.sym != sym) e1 = e1.tail ./scala-compiler-src/scala/tools/nsc/symtab/Scopes.scala:238: if (e1.tail != null) { ./scala-compiler-src/scala/tools/nsc/symtab/Scopes.scala:244: if (e != null) { ./scala-compiler-src/scala/tools/nsc/symtab/StdNames.scala:495: if (sn0 == null) sn0 = if (forMSIL) new MSILNames ./scala-compiler-src/scala/tools/nsc/symtab/Symbols.scala:529: e == null ./scala-compiler-src/scala/tools/nsc/symtab/Symbols.scala:727: if (infos == null || runId(infos.validFrom) == currentRunId) { ./scala-compiler-src/scala/tools/nsc/symtab/Symbols.scala:1264: if (ret == null && inIDE && !isModule) this match { ./scala-compiler-src/scala/tools/nsc/symtab/Symbols.scala:566: while (ifs != null) { ./scala-compiler-src/scala/tools/nsc/symtab/Symbols.scala:682: assert(infos != null, name) ./scala-compiler-src/scala/tools/nsc/symtab/Symbols.scala:689: while (curPid < phaseId(infos.validFrom) && infos.prev != null) ./scala-compiler-src/scala/tools/nsc/symtab/Symbols.scala:1056: if (f1 != null && f2 != null && f1 != f2) ./scala-compiler-src/scala/tools/nsc/symtab/Symbols.scala:1265: case sym : ModuleSymbol if sym.referenced != null => ./scala-compiler-src/scala/tools/nsc/symtab/SymbolTable.scala:49: assert(symbol != null) ./scala-compiler-src/scala/tools/nsc/symtab/SymbolTable.scala:52: assert(symbol != null) ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:90: if (original.tpe == null) ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:101: if (t.original.tpe == null) { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:145: val qualifier = if (tree.tpe != null && tree.qualifier.tpe == null) { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:164: if (arg.tpe == null) { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:168: if (tree.tpt.tpe == null) { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:176: if (tree.tpt.tpe == null) { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:183: if (tree.ref.tpe == null) { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:193: if (tree.hasSymbol && (tree.symbol == NoSymbol || tree.symbol == null)) { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:204: if (tree.qualifier.tpe == null) tree.tpe match { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:237: if (tree.rhs.tpe == null) tree.rhs.tpe = sym.info ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:37: case (Super(_,_),SuperType(_,supertp)) if supertp.typeSymbol != NoSymbol && supertp.typeSymbol != null => supertp.typeSymbol ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:38: case _ if t.symbol != NoSymbol && t.symbol != null => t.symbol ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:39: case (t : TypeTree, tp) if tp != null && tp.typeSymbol != null && tp.typeSymbol != NoSymbol => tp.typeSymbol ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:40: case (t : TypeTree, tp) if tp != null && tp.resultType != null && tp.resultType.typeSymbol != null => tp.resultType.typeSymbol ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:41: case (t, tpe : Type) if tpe != null && (t.symbol eq NoSymbol) && t.isTerm && tpe.termSymbol != null => ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:43: case (t, tpe : Type) if tpe != null && (t.symbol eq NoSymbol) && tpe.typeSymbol != null => ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:48: if (sym != null && sym != NoSymbol /* && !sym.hasFlag(SYNTHETIC) */) { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:88: case t : TypeTree if t.original != null => ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:96: case (tree,tpe) => assert(tree != null && tpe != null); h(tree, tpe) ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:110: case (t : MemberDef) if t.symbol != null && t.symbol != NoSymbol => ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:135: if (tree.tpt != null) { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:145: val qualifier = if (tree.tpe != null && tree.qualifier.tpe == null) { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:158: if (tree.tpe != null) { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:189: if (tree.tpe != null && tree.tpe.typeSymbol != null && tree.tpe.typeSymbol.isRefinementClass) tree.tpe.typeSymbol.info match { ./scala-compiler-src/scala/tools/nsc/symtab/SymbolWalker.scala:215: if (tree.tpe != null && tree.tpe.typeSymbol == definitions.ClassClass) { ./scala-compiler-src/scala/tools/nsc/symtab/Types.scala:837: if (inIDE && supertype == null) Nil ./scala-compiler-src/scala/tools/nsc/symtab/Types.scala:1491: if (normalized == null) { ./scala-compiler-src/scala/tools/nsc/symtab/Types.scala:1352: override def isNotNull = value.value != null ./scala-compiler-src/scala/tools/nsc/transform/CleanUp.scala:286: if (method != null) ./scala-compiler-src/scala/tools/nsc/typechecker/Contexts.scala:199: //assert(this.implicitsCache == null || that.implicitsCache == null) ./scala-compiler-src/scala/tools/nsc/typechecker/Contexts.scala:325: if (e != null && e.owner == c.scope) { ./scala-compiler-src/scala/tools/nsc/typechecker/Contexts.scala:505: if (outer != null && outer != this) outer.resetCache ./scala-compiler-src/scala/tools/nsc/typechecker/DeVirtualize.scala:523: if (stat.symbol != null && (stat.symbol hasFlag PARAMACCESSOR)) ./scala-compiler-src/scala/tools/nsc/typechecker/DeVirtualize.scala:542: (if (stat.symbol != null && (stat.symbol hasFlag PRESUPER)) presupers else others) += stat ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:64: if (pos.owner == null) underlying.complete(sym0) else pos.owner.activate(try { ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:123: if (tree.tpe == null) ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:196: if (e == null) { ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:241: if (e == null) dirtyTyped ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:324: } else if (lastType == null) { ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:356: if (use.last.tpe == null) ErrorType else use.last.tpe ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:63: val hadTypeErrors = pos.owner != null && pos.owner.hasTypeErrors ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:80: //if (!hadTypeErrors && pos.owner != null && pos.owner.hasTypeErrors) pos.owner.dirtyTyped ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:81: if (pos.owner != null && pos.owner.hasTypeErrors && (!sym0.rawInfo.isComplete || sym0.info == NoType || sym0.info == ErrorType)) { ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:192: case tree : DefTree if (tree.symbol != NoSymbol && tree.symbol != null) => ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:195: while (e != null && e.sym != tree.symbol) e = namer.context.scope.lookupNextEntry(e) ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:237: case tree :DefTree if tree.symbol != null && tree.symbol != NoSymbol && tree.symbol.isClass && tree.symbol.hasFlag(CASE) => ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:239: while (e != null && !e.sym.hasFlag(MODULE)) e = namer.context.scope.lookupNextEntry(e) ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:240: Console.println("CHECKING: " + e + " " + (if (e != null) caseClassOfModuleClass.contains(e.sym.moduleClass))) ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:244: case tree : DefTree if tree.symbol != null && tree.symbol != NoSymbol => ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:264: if (tree.symbol != NoSymbol && tree.symbol != null) (namer.context.scope,tree) match { ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:277: if (tree.symbol != null && ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:280: tree.symbol.owner != null && ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:283: if (e != null) e.sym.pos match { // retype the object if its in the scope. ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:284: case pos : TrackedPosition if pos.owner != null && pos.owner != MemoizedTree.this => ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:292: else if (hasTypeErrors && lastSymbol != null && lastSymbol != NoSymbol && use.last.symbol != lastSymbol) { ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:293: if (use.last.symbol != null && use.last.symbol != NoSymbol) { ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:329: if ((use.last.tpe != null)) return use.last.tpe ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:340: if (!makeNoChanges && hasTypeErrors && lastType != null) { ./scala-compiler-src/scala/tools/nsc/typechecker/IdeSupport.scala:343: if (!makeNoChanges && !hasTypeErrors && use.last.tpe != null && lastType != null && ./scala-compiler-src/scala/tools/nsc/typechecker/Implicits.scala:401: sym.sourceFile == null || ./scala-compiler-src/scala/tools/nsc/typechecker/Infer.scala:339: if (context.unit != null) ./scala-compiler-src/scala/tools/nsc/typechecker/Infer.scala:1321: if (settings.Xwarndeadcode.value && tree.tpe != null && tree.tpe.typeSymbol == NothingClass) ./scala-compiler-src/scala/tools/nsc/typechecker/Namers.scala:161: (prev.sym.sourceFile == null && sym.getClass == prev.sym.getClass))) { ./scala-compiler-src/scala/tools/nsc/typechecker/Namers.scala:159: if (guess != null) prev = guess ./scala-compiler-src/scala/tools/nsc/typechecker/Namers.scala:160: while (prev != null && (!prev.sym.hasRawInfo || !prev.sym.rawInfo.isComplete || ./scala-compiler-src/scala/tools/nsc/typechecker/Namers.scala:172: if (prev != null && (sym0 ne prev.sym) && conflict(sym0,prev.sym)) { ./scala-compiler-src/scala/tools/nsc/typechecker/Namers.scala:637: assert(cdef.symbol != null && cdef.symbol != NoSymbol) ./scala-compiler-src/scala/tools/nsc/typechecker/Namers.scala:674: if (onlyPresentation && methodArgumentNames != null) ./scala-compiler-src/scala/tools/nsc/typechecker/Namers.scala:876: if !ainfo.atp.isError && annot != null ./scala-compiler-src/scala/tools/nsc/typechecker/SuperAccessors.scala:223: assert(fn.tpe != null, tree) ./scala-compiler-src/scala/tools/nsc/typechecker/SuperAccessors.scala:233: if (tree.symbol != null && tree.symbol != NoSymbol) ./scala-compiler-src/scala/tools/nsc/typechecker/Typers.scala:1331: //assert(vdef.rhs.tpe == null) ./scala-compiler-src/scala/tools/nsc/typechecker/Typers.scala:1349: val formals = (if (fn.tpe == null && inIDE) ErrorType else fn.tpe).paramTypes ./scala-compiler-src/scala/tools/nsc/typechecker/Typers.scala:2108: if ((t.tpe==null) || t.tpe.isErroneous) annotationError ./scala-compiler-src/scala/tools/nsc/typechecker/Typers.scala:3476: val result = if (tree1.isEmpty || (inIDE && tree1.tpe == null)) tree1 else adapt(tree1, mode, pt) ./scala-compiler-src/scala/tools/nsc/typechecker/Typers.scala:909: if (forMSIL && coercion != null && isCorrespondingDelegate(tree.tpe, pt)) { ./scala-compiler-src/scala/tools/nsc/typechecker/Typers.scala:1332: val rhs = if (inIDE && vdef.rhs.tpe != null) vdef.rhs.duplicate else vdef.rhs ./scala-compiler-src/scala/tools/nsc/typechecker/Typers.scala:1371: if sym != null && sym.isModule && (sym.info.baseClasses contains clazz) ./scala-compiler-src/scala/tools/nsc/typechecker/Typers.scala:2572: if (sym != null && sym != NoSymbol && sym.owner.isClass && sym.getter(sym.owner) != NoSymbol) ./scala-compiler-src/scala/tools/nsc/util/ClassPath.scala:85: (if (location == null) "<none>" else location.toString) + ./scala-compiler-src/scala/tools/nsc/util/ClassPath.scala:86: (if (source == null) "" else " source=" + source) ./scala-compiler-src/scala/tools/nsc/util/ClassPath.scala:75: // assert(location != null, "cannot find source location") ./scala-compiler-src/scala/tools/nsc/util/ClassPath.scala:76: // assert(location.getFile() != null, "cannot find source location " + " " + location + " " + location.getClass()) ./scala-compiler-src/scala/tools/nsc/util/ClassPath.scala:81: // assert(location != null, "cannot find classpath location") ./scala-compiler-src/scala/tools/nsc/util/ClassPath.scala:82: // assert(location.getFile() != null, "cannot find classpath location " + " " + location + " " + location.getClass()) ./scala-compiler-src/scala/tools/nsc/util/NameTransformer.scala:144: //System.out.println("= " + (if (buf == null) name else buf.toString()));//DEBUG ./scala-compiler-src/scala/tools/nsc/util/NewCharArrayReader.scala:49: else if (error != null) error(idx, "error in unicode escape"); ./scala-compiler-src/scala/tools/nsc/util/Position.scala:53: if (source == null) this else source.positionInUltimateSource(this) ./scala-library-src/scala/actors/Actor.scala:419: // assert continuation != null ./scala-library-src/scala/actors/ActorGC.scala:55: if (wr != null) { ./scala-library-src/scala/actors/MessageQueue.scala:39: // last == null iff list empty ./scala-library-src/scala/actors/MessageQueue.scala:98: if (last == null) None ./scala-library-src/scala/actors/MessageQueue.scala:129: if (last == null) None ./scala-library-src/scala/actors/MessageQueue.scala:73: while (curr != null) { ./scala-library-src/scala/actors/MessageQueue.scala:103: while(curr.next != null && found.isEmpty) { ./scala-library-src/scala/actors/MessageQueue.scala:142: while(curr.next != null && found.isEmpty) { ./scala-library-src/scala/actors/MessageQueue.scala:180: while(curr.next != null) { ./scala-library-src/scala/actors/Reaction.scala:75: if (f == null) ./scala-library-src/scala/actors/remote/JavaSerializer.scala:45: // use custom stream only if cl != null ./scala-library-src/scala/actors/remote/JavaSerializer.scala:46: val in = if (cl != null) ./scala-library-src/scala/collection/immutable/HashMap.scala:51: if (e == null) None ./scala-library-src/scala/collection/immutable/HashMap.scala:58: if (e == null) { ./scala-library-src/scala/collection/immutable/HashMap.scala:88: if (e == null) this ./scala-library-src/scala/collection/immutable/HashMap.scala:144: if (e == null) null ./scala-library-src/scala/collection/immutable/HashMap.scala:44: while (m.later != null) { ./scala-library-src/scala/collection/immutable/HashMap.scala:100: while (m.later != null) { ./scala-library-src/scala/collection/immutable/HashMap.scala:167: while (m.later != null) m = m.later ./scala-library-src/scala/collection/immutable/HashSet.scala:41: while (m.later != null) { ./scala-library-src/scala/collection/immutable/HashSet.scala:74: while (m.later != null) { ./scala-library-src/scala/collection/immutable/HashSet.scala:124: while (m.later != null) m = m.later ./scala-library-src/scala/collection/immutable/PagedSeq.scala:132: while (absindex >= current.end && current.next != null) ./scala-library-src/scala/collection/immutable/PagedSeq.scala:220: if (later.next != null) later = later.next.latest ./scala-library-src/scala/collection/JavaConversions.scala:464: if (v != null) ./scala-library-src/scala/collection/JavaConversions.scala:477: if (r != null) Some(r) else None ./scala-library-src/scala/collection/JavaConversions.scala:484: if (r != null) Some(r) else None ./scala-library-src/scala/collection/mutable/DefaultMapModel.scala:31: if (e == null) None ./scala-library-src/scala/collection/mutable/DefaultMapModel.scala:37: if (e == null) { addEntry(new Entry(key, value)); None } ./scala-library-src/scala/collection/mutable/FlatHashTable.scala:140: if (table(i) != null && !containsEntry(table(i).asInstanceOf[A])) ./scala-library-src/scala/collection/mutable/HashTable.scala:118: while (es == null && idx > 0) { ./scala-library-src/scala/collection/mutable/HashTable.scala:68: while (e != null && !elemEquals(e.key, key)) e = e.next ./scala-library-src/scala/collection/mutable/HashTable.scala:84: if (e != null) { ./scala-library-src/scala/collection/mutable/HashTable.scala:91: while (e1 != null && !elemEquals(e1.key, key)) { ./scala-library-src/scala/collection/mutable/HashTable.scala:95: if (e1 != null) { ./scala-library-src/scala/collection/mutable/HashTable.scala:110: def hasNext = es != null ./scala-library-src/scala/collection/mutable/HashTable.scala:140: while (e != null) { ./scala-library-src/scala/collection/mutable/LinkedHashMap.scala:51: if (e == null) { ./scala-library-src/scala/collection/mutable/OpenHashMap.scala:119: if (entry == null) { ./scala-library-src/scala/collection/mutable/OpenHashMap.scala:174: while((index <= mask) && (table(index) == null || table(index).value == None)) index+=1; ./scala-library-src/scala/collection/mutable/OpenHashMap.scala:81: if (entry != null && entry.value != None) addEntry(entry)); ./scala-library-src/scala/collection/mutable/OpenHashMap.scala:92: while(table(index) != null && ./scala-library-src/scala/collection/mutable/OpenHashMap.scala:103: if (entry != null) table(findIndex(entry.key, entry.hash)) = entry; ./scala-library-src/scala/collection/mutable/OpenHashMap.scala:134: if (table(index) != null && table(index).value != None){ ./scala-library-src/scala/collection/mutable/OpenHashMap.scala:150: while(entry != null){ ./scala-library-src/scala/collection/mutable/OpenHashMap.scala:215: table.foreach(entry => if (entry != null && entry.value != None) f(entry)); ./scala-library-src/scala/collection/mutable/StringBuilder.scala:256: val str = if (s == null) "null" else s ./scala-library-src/scala/collection/mutable/StringBuilder.scala:270: if (sb == null) ./scala-library-src/scala/collection/mutable/StringBuilder.scala:520: val str = if (x == null) "null" else x ./scala-library-src/scala/Console.scala:222: if (s == null) ./scala-library-src/scala/Console.scala:242: if (s == null) ./scala-library-src/scala/Console.scala:256: if (s == null) ./scala-library-src/scala/Console.scala:270: if (s == null) ./scala-library-src/scala/Console.scala:284: if (s == null) ./scala-library-src/scala/Console.scala:298: if (s == null) ./scala-library-src/scala/Console.scala:312: if (s == null) ./scala-library-src/scala/Console.scala:326: if (s == null) ./scala-library-src/scala/Console.scala:344: if (s == null) ./scala-library-src/scala/ref/ReferenceWrapper.scala:18: @deprecated def isValid = underlying.get != null ./scala-library-src/scala/ref/SoftReference.scala:19: if (queue == null) new java.lang.ref.SoftReference[T](value); ./scala-library-src/scala/ref/WeakReference.scala:19: if (queue == null) new java.lang.ref.WeakReference[T](value) ./scala-library-src/scala/reflect/Manifest.scala:41: (if (subSuperClass == null) Nil else List(subSuperClass)) ::: subSuperInterfaces ./scala-library-src/scala/runtime/RichString.scala:122: if (self == null) null ./scala-library-src/scala/runtime/RichString.scala:187: if (s != null) s.toLowerCase match { ./scala-library-src/scala/runtime/ScalaRunTime.scala:29: if (x == null) throw new UninitializedError else x ./scala-library-src/scala/runtime/ScalaRunTime.scala:76: code = code * 41 + (if (elem == null) 0 else elem.hashCode()) ./scala-library-src/scala/runtime/ScalaRunTime.scala:112: // if (x == null) throw new UndefinedException else x ./scala-library-src/scala/runtime/ScalaRunTime.scala:18: def isArray(x: AnyRef): Boolean = (x != null && x.getClass.isArray) || (x != null && x.isInstanceOf[BoxedArray[_]]) ./scala-library-src/scala/Symbol.scala:69: if (reference == null) null ./scala-library-src/scala/Symbol.scala:89: if (res == null) updateCache() ./scala-library-src/scala/Symbol.scala:78: if (res != null) res ./scala-library-src/scala/util/parsing/combinator/Parsers.scala:763: else if (lastNoSuccess == null || lastNoSuccess.next.pos < in1.pos) ./scala-library-src/scala/util/parsing/combinator/Parsers.scala:145: if (!(lastNoSuccess != null && next.pos < lastNoSuccess.next.pos)) ./scala-library-src/scala/xml/Attribute.scala:29: if (pre == null || pre == "") new UnprefixedAttribute(key, value, next) ./scala-library-src/scala/xml/Attribute.scala:33: if (pre == null || pre == "") new UnprefixedAttribute(key, value, next) ./scala-library-src/scala/xml/dtd/ElementValidator.scala:116: * @pre contentModel != null ./scala-library-src/scala/xml/dtd/ExternalID.scala:26: // public == null: SYSTEM " " systemLiteral ./scala-library-src/scala/xml/dtd/ExternalID.scala:31: if (publicId == null) "SYSTEM " + quotedSystemLiteral ./scala-library-src/scala/xml/dtd/ExternalID.scala:33: (if (systemId == null) "" else " " + quotedSystemLiteral) ./scala-library-src/scala/xml/dtd/ExternalID.scala:25: // public != null: PUBLIC " " publicLiteral " " [systemLiteral] ./scala-library-src/scala/xml/dtd/ExternalID.scala:65: if (systemId != null && !checkSysID(systemId)) ./scala-library-src/scala/xml/include/sax/EncodingHeuristics.scala:74: if (ret != null) ./scala-library-src/scala/xml/include/sax/Main.scala:82: if (resolver != null) includer.setEntityResolver(resolver) ./scala-library-src/scala/xml/include/sax/XIncludeFilter.scala:172: if (href==null) { ./scala-library-src/scala/xml/include/sax/XIncludeFilter.scala:177: if (parse == null) parse = "xml" ./scala-library-src/scala/xml/include/sax/XIncludeFilter.scala:296: if (encoding == null || encoding.trim().equals("")) encoding = "UTF-8"; ./scala-library-src/scala/xml/include/sax/XIncludeFilter.scala:156: if (base != null) { ./scala-library-src/scala/xml/include/sax/XIncludeFilter.scala:266: if (locator != null) { ./scala-library-src/scala/xml/include/sax/XIncludeFilter.scala:315: if (encodingFromHeader != null) ./scala-library-src/scala/xml/include/sax/XIncludeFilter.scala:321: if (contentType != null) { ./scala-library-src/scala/xml/include/sax/XIncludeFilter.scala:394: if(parser != null) { ./scala-library-src/scala/xml/include/sax/XIncludeFilter.scala:397: if (resolver != null) parser.setEntityResolver(resolver); ./scala-library-src/scala/xml/include/sax/XIncluder.scala:156: if (publicID != null) id = " PUBLIC \"" + publicID + "\" \"" + systemID + '"'; ./scala-library-src/scala/xml/include/sax/XIncluder.scala:157: else if (systemID != null) id = " SYSTEM \"" + systemID + '"'; ./scala-library-src/scala/xml/MetaData.scala:142: m != null && (m.equals1(this) || containedIn1(m.next)) ./scala-library-src/scala/xml/NamespaceBinding.scala:57: .append(if (uri == null) "" else uri) ./scala-library-src/scala/xml/Node.scala:68: * @return the namespace if <code>scope != null</code> and prefix was ./scala-library-src/scala/xml/parsing/ExternalSources.scala:36: //while (inputLine = in.readLine()) != null) { ./scala-library-src/scala/xml/pull/XMLEventReader.scala:148: if (buffer == null) fillBuffer ./scala-library-src/scala/xml/pull/XMLEventReader.scala:136: private def isElement(x: T) = x != null && x != EndOfStream ./scala-library-src/scala/xml/pull/XMLEventReader.scala:145: def hasNext() = !eos && (buffer != null || fillBuffer) ./scala-library-src/scala/xml/Xhtml.scala:68: (x.child == null || x.child.length == 0) && ./scala-partest-src/scala/tools/partest/nest/ConsoleFileManager.scala:50: if (cwd != null) ./scala-partest-src/scala/tools/partest/nest/ConsoleFileManager.scala:69: if (testRootProp != null) ./scala-partest-src/scala/tools/partest/nest/ConsoleFileManager.scala:96: if (srcDirProp != null) { ./scala-partest-src/scala/tools/partest/nest/ConsoleFileManager.scala:142: else if (testBuild != null) { ./scala-partest-src/scala/tools/partest/nest/ConsoleRunner.scala:130: else if (fileManager.testBuild != null) ./scala-partest-src/scala/tools/partest/nest/DirectRunner.scala:32: if (coreProp == null) { ./scala-partest-src/scala/tools/partest/nest/StreamAppender.scala:80: while (line != null) { ./scala-partest-src/scala/tools/partest/nest/Worker.scala:625: if (t.getCause != null) ./scala-partest-src/scala/tools/partest/nest/Worker.scala:936: if (t.getCause != null) ./scala-partest-src/scala/tools/partest/nest/Worker.scala:958: reportResult(if (logs != null) Some(logs) else None) ./scala-swing-src/scala/swing/ComboBox.scala:120: selected == null && a != null) { ./scala-swing-src/scala/swing/ComboBox.scala:119: if ((selected != null && selected != a) || ./scala-swing-src/scala/swing/ComboBox.scala:120: selected == null && a != null) { ./scala-swing-src/scala/swing/Swing.scala:16: protected[swing] def toNoIcon(i: Icon): Icon = if(i == null) EmptyIcon else i ./scala-swing-src/scala/swing/Swing.scala:73: def unwrapIcon(icon: Icon): Icon = if (icon == null) EmptyIcon else icon ./scala-swing-src/scala/swing/Swing.scala:18: protected[swing] def nullPeer(c: Component) = if (c != null) c.peer else null ./scala-swing-src/scala/swing/TabbedPane.scala:30: def title_=(t: String) { _title = title0; if (parent != null) parent.peer.setTitleAt(index, t) } ./scala-swing-src/scala/swing/TabbedPane.scala:33: def content_=(c: Component) { _content = c; if (parent != null) parent.peer.setComponentAt(index, c.peer) } ./scala-swing-src/scala/swing/TabbedPane.scala:36: def tip_=(t: String) { _tip = t; if (parent != null) parent.peer.setToolTipTextAt(index, t) } ./scala-swing-src/scala/swing/TabbedPane.scala:39: def enabled_=(b: Boolean) { _enabled = b; if (parent != null) parent.peer.setEnabledAt(index, b) } ./scala-swing-src/scala/swing/TabbedPane.scala:42: def mnemonic_=(k: Int) { _mnemonic = k; if (parent != null) parent.peer.setMnemonicAt(index, k)} ./scala-swing-src/scala/swing/TabbedPane.scala:45: def foreground_=(c: Color) { _foreground = c; if (parent != null) parent.peer.setForegroundAt(index, c)} ./scala-swing-src/scala/swing/TabbedPane.scala:48: def background_=(c: Color) { _background = c; if (parent != null) parent.peer.setBackgroundAt(index, c)} ./scala-swing-src/scala/swing/TabbedPane.scala:53: def index = if(parent != null) parent.peer.indexOfTab(title) else 0//_index ./scala-swing-src/scala/swing/Table.scala:241: if (v != null) ./scala-swing-src/scala/swing/Table.scala:252: if (v != null) ./scalap-src/scala/tools/scalap/Arguments.scala:72: if ((args(i) == null) || (args(i).length() == 0)) ./scalap-src/scala/tools/scalap/Arguments.scala:69: if (args != null) { ./scalap-src/scala/tools/scalap/CodeWriter.scala:33: def getIndentWidth = if (step == null) -1 else step.length() ./scalap-src/scala/tools/scalap/CodeWriter.scala:56: if (step == null) ./scalap-src/scala/tools/scalap/JavaWriter.scala:177: if (cf.pool(cf.superclass) != null) ./scalap-src/scala/tools/scalap/Main.scala:109: if (cfile != null) { ./scalap-src/scala/tools/scalap/Names.scala:44: if (nop == null) ./scalap-src/scala/tools/scalap/Names.scala:68: if (c != null) { ./scalap-src/scala/tools/scalap/scalax/util/StringUtil.scala:11: def trimStart(s: String, prefix: String) = if (s != null && s.startsWith(prefix)) s.substring(prefix.length) else s |
|
|
Re: [scala] Testing equality with nullOn Thu, Oct 1, 2009 at 1:21 PM, Eric Willigers <ewilligers@...> wrote: The code fragments I agree, this change makes sense and code that returns 'true' for 'equals(null)' shouldn't be too common. But it's still a change that potentially breaks existing programs, without notice. iulian
-- « Je déteste la montagne, ça cache le paysage » Alphonse Allais |
|
|
Re: [scala] Testing equality with nullHi Julian,
On Oct 1, 2009, at 17:19, Iulian Dragos wrote:
Still, IMHO, it's better to do it in 2.8.0 than 2.8.1. I get it is easy to implement and, after all, 2.8 will be a new fruit with the already advertised (and not so advertised, like [T: A]), features.
-- __~O -\ <, Christos KK Loverdos (*)/ (*) http://ckkloverdos.com |
|
|
Re: [scala] Testing equality with nullOn Oct 1, 2009, at 17:37, Christos KK Loverdos wrote:
]
-- __~O -\ <, Christos KK Loverdos (*)/ (*) http://ckkloverdos.com |
|
|
Re: [scala] Testing equality with nullFirst, I don't think that performance difference is serious.
Second, you can use if(x eq null) instead of if(x == null) in your code if the performance is very important for you. My scala solutions for Project Euler problems: Click here |
|
|
Re: [scala] Testing equality with nullHi,
On Thu, 2009-10-01 at 09:21 -0700, Eastsun wrote: > Second, you can use if(x eq null) instead of if(x == null) in your code if > the performance is very important for you. One annoying issue is that you can't call eq on Any. Ismael |
|
|
Re: [scala] Testing equality with nullI had very much meant to bring this up on my list of equality issues.
The problem is that all the ancillary issues with equality, of which there are many and which in the aggregate certainly add up to at least one big issue, have had to fall in line behind the even bigger question of whether 0 == 0L always, sometimes, or never. There are a number of places in the compiler which have to insert extra logic specifically and only to accomodate the explicitly-disrecommended hypothetical desire of some people to have "x.equals(null)" return true. But if there is one thing we must have learned at this point, it is that $eq$eq is certainly not equals. No matter what changes we end up making to equality, I guarantee you we silently change the semantics of now-working programs. It is way more likely to my eye that "List(1,2,3) contains 1L" going from true to false will break something than that "x == null" going from true to false will. So I say, now is the time to change this. On Thu, Oct 01, 2009 at 05:43:09PM +0100, Ismael Juma wrote: > One annoying issue is that you can't call eq on Any. That is a good point and it's quite annoying anyway, as every equals method in the world has to deal with it to short-circuit on eq. I don't suppose we can put def eq(other: Any) = false on AnyVal... -- Paul Phillips | Before a man speaks it is always safe to assume Apatheist | that he is a fool. After he speaks, it is seldom Empiricist | necessary to assume it. pal, i pill push | -- H. L. Mencken |
|
|
Re: [scala] Testing equality with nullOn Thu, Oct 01, 2009 at 09:21:30PM +1000, Eric Willigers wrote:
> Perhaps every such fragment in the compiler and library source should > be changed to > if (x eq null) / if (x ne null) > or > if (null == x) / if (null != x) Strongly object. The reason people don't do the former already is because the precedence of eq is hosed. I value code clarity very highly and I cannot bear having to parenthesize every single null check -- not to mention that eq has much inferior visual contrast. Operators made out of alphas are inferior. And personally I have to do a double take every time I come across "literal comparisonOp identifier" as opposed to the other way around. It's a flow breaker. Maybe these sounds like trivial complaints but hey, I'm in tune with the little things. Let's just change the spec so the generated code is the same. -- Paul Phillips | Where there's smoke, there's mirrors! Future Perfect | Empiricist | ha! spill, pupil |----------* http://www.improving.org/paulp/ *---------- |
|
|
Re: [scala] Testing equality with nullAlso, please, take a look at Martin's last comment (#8 If I am not wrong) of about raw performance. On Oct 1, 2009, at 17:38, Christos KK Loverdos wrote:
-- __~O -\ <, Christos KK Loverdos (*)/ (*) http://ckkloverdos.com |
|
|
Re: [scala] Testing equality with nullI was going back and forth on this several times this afternoon, but
in the end I have come down firmly against special casing x == null. Here's why: Scala tries to be a simple language, in what concerns the spec. It's true that its type system and Java interoperability both force some complexities on us, but wherever possible Scala strives for the most simple solution -- simple in terms of sentences needed to specify the language feature. One of the most important simplifications that Scala applies is that every operator is a method call, and that every value is an object. This holds also for the `==' method and the null value. `==' is defined in class Any as follows: def ==(that: Any) = this equals that It is overloaded in the numeric classes for more specialized comparisons. Finally it is overridden in the null object as follows: object null { override def ==(other: Any) = other eq null } At least conceptually, that's how things are supposed to be. It is true that the current implementation of Scala does not implement this behavior, mostly because the people implementing it did not understand what the spec really said (and that includes me), but I am trying to correct that now. When it comes to implementation, of course `null' is not an object, so we have to implement `==' like this: x == y rewrites to if (x eq null) y eq null else x equals y Now this is very elegant, but it looks to me that it leaves no space whatsoever for the x == null optimization that's desired. I invite you to try it; but please scrutinize carefully your solution. Note we *cannot* modify the spec to say def ==(that: Any) = (that ne null) && (this equals that) This would elevate the test against null to a run-time test which would slow down every application of ==. The only possibility would be to say that `==' is ``not really" a method but that it somehow translates to method calls that are also called `=='. I'm sorry but this violates my sense of aesthetics too much to be considered. So what's left? One could envision a program analysis that finds out whether an equals method is doing the right thing for null. In the case where it does, one could optiize `x == null` to `x eq null`. Or one could simply do nothing. The current quoted slow-down of 10 is due to the fact that we pack a lot of crufty semantics into the `==' method. We should not do this; it slows down every call of `=='. (For instance, profiling by Cliff Click showed that our current implementation of `==' is the single hottest spot in the Scala compiler!) We should just keep to the spec as it was outlined above. In that case, for simple versions of `equals' the JVM will be able to inline the call and do the required optimizations. So it might very well be a non-problem once we do the right thing. In summary, instead of overloading `==' with more and more crufty, leaky abstractions, we should throw everything out and just go back to basics. And we should take the spec seriously. Just my (it seems now) weakly repeating sermon. Cheers -- Martin |
|
|
Re: [scala] Testing equality with nullOn Thu, Oct 1, 2009 at 12:27 PM, martin odersky <martin.odersky@...> wrote: I was going back and forth on this several times this afternoon, but Martin, This all makes sense. There's one place in the code that's a question-mark for me: x match { case null => ... } Should this be x == null or x eq null? Is this worthy of a special case (e.g., x eq null)? Thanks, David
-- Lift, the simply functional web framework http://liftweb.net Beginning Scala http://www.apress.com/book/view/1430219890 Follow me: http://twitter.com/dpp Surf the harmonics |
|
|
Re: [scala] Testing equality with nullOn Thu, Oct 01, 2009 at 12:32:54PM -0700, David Pollak wrote:
> This all makes sense. There's one place in the code that's a question-mark > for me: > > x match { > case null => ... > } There are very extensive old discussions (some on scala-devel unfortunately) about the nature of matching equality which should be considered here. I don't have time at this moment to look up and summarize everything, but one issue is that implementing equals with pattern matching in a case object can cause an infinite loop, and that this is not exactly obvious. Here is IntMap.Nil, the comment came into existence after I removed what seemed like pointless code and found in practice its point: private[immutable] case object Nil extends IntMap[Nothing] { // Important! Without this equals method in place, an infinite // loop from Map.equals => size => pattern-match-on-Nil => equals // develops. Case objects and custom equality don't mix without // careful handling. override def equals(that : Any) = that match { case (that : AnyRef) if (this eq that) => true; case (that : IntMap[_]) => false; // The only empty IntMaps are eq Nil case that => super.equals(that); } }; And we get to the proposal: Pattern matching short circuits on reference equality. I forget the cons, but it solves the above. With respect to the null case, because of null's special status in the pattern matcher (it cannot match most patterns by definition) I could reorder a constant null check so it's usually avoided. If we're keeping x.equals(null) as a possibility then I think it has to be the same in the pattern matcher. -- Paul Phillips | One way is to make it so simple that there are Protagonist | obviously no deficiencies. And the other way is to make Empiricist | it so complicated that there are no obvious deficiencies. pp: i haul pills | -- Hoare |
|
|
Re: [scala] Testing equality with nullI've re-read these last few e-mails (and the previous threads on numerical equality) several times and I'll admit my head is still spinning.
Would it be possible for someone who understands the whole situation regarding reference equality, numerical equality, and pattern matching equality to write up something that clearly documents all these behaviors? Ideally it would state the simple principles (that are already in the spec?) that drive these behaviors, but also the implications and ramifications of these principles and how they apply to edge cases that programmers might run into. Ideally it would also point out where the behavior for 2.8 differs from the behavior in 2.7.x. I appreciate that all of this is already in the spec, but sometimes even a few simple principles can have far-reaching, complicated, and not-immediately-obvious interactions (c.f., ZFC). If the implementers of the language didn't understand what the spec really said, then there's little hope for us mere mortals. --j On Thu, Oct 1, 2009 at 12:48 PM, Paul Phillips <paulp@...> wrote:
|
|
|
Re: [scala] Testing equality with nullHi Martin,
Thanx for sharing your thoughts. Please find mine below. On Oct 1, 2009, at 22:27, martin odersky wrote: > I was going back and forth on this several times this afternoon, but > in the end I have come down firmly against special casing x == null. > Here's why: > > Scala tries to be a simple language, in what concerns the spec. It's > true that its type system and Java interoperability both force some > complexities on us, but wherever possible Scala strives for the most > simple solution -- simple in terms of sentences needed to specify the > language feature. > > One of the most important simplifications that Scala applies is that > every operator is a method call, and that every value is an object. > This holds also for the `==' method and the null value. `==' is > defined in class Any as follows: > > def ==(that: Any) = this equals that > > It is overloaded in the numeric classes for more specialized > comparisons. Finally it is overridden in the null object as follows: > > object null { > override def ==(other: Any) = other eq null > } > > At least conceptually, that's how things are supposed to be. It is > true that the current implementation of Scala does not implement this > behavior, mostly because the people implementing it did not understand > what the spec really said (and that includes me), but I am trying to > correct that now. > > When it comes to implementation, of course `null' is not an object, so > we have to implement `==' like this: > > x == y rewrites to if (x eq null) y eq null else x equals y > > Now this is very elegant, but it looks to me that it leaves no space > whatsoever for the x == null optimization that's desired. I invite you > to try it; but please scrutinize carefully your solution. Note we > *cannot* modify the spec to say > > def ==(that: Any) = (that ne null) && (this equals that) Let me take the exercise. a) Fact: We want to analyze x == y. a1) Fact: There are two variables to consider, x and y b) Fact: x == y rewrites if(x eq null) y eq null else x equals y c) Let's assume x eq null (its statically known value is null) c1) Then according to b) null == y rewrites to if(null eq null) y eq null else x equals y rewrites to if(true) y eq null rewrites to y eq null c2) So, if x eq null then null == y rewrites to y eq null d) Let's assume y eq null (statically known, as in c) for x) d1) Then according to b) x == null rewrites to if(x eq null) null eq null else x equals null rewrites to if(x eq null) true else x equals null rewrites to (x eq null) || x equals null d2) So, if y eq null then x == null rewrites to (x eq null) || x equals null Observations: 1) Whether null is on the left or right _matters_. There is a clear asymmetry, as we can see from the results c2) and d2). 2) Null on the left is a better (clear I would say) opportunity for optimization. 3) Null on the right, still seems to need an "extra" check. I think d2) shows the real character of "eq" versus "equals". Then some crazy old chap could use this as a kernel [I am not kidding, but then again I just had this crazy idea] in some kind of algebra, where the behavior of nulls with respect to equality characterizes the behavior of non-nulls ("carries away" their behavior). 4) This asymmetry, if retained, means that there are open possibilities to violate an equivalence relation on == (with nulls being the ones that may spoil the whole thing), because x.equals(null) may not return false. > > This would elevate the test against null to a run-time test which > would slow down every application of ==. The only possibility would be > to say that `==' is ``not really" a method but that it somehow > translates to method calls that are also called `=='. I'm sorry but > this violates my sense of aesthetics too much to be considered. > > So what's left? One could envision a program analysis that finds out > whether an equals method is doing the right thing for null. In the > case where it does, one could optiize `x == null` to `x eq null`. Or > one could simply do nothing. The current quoted slow-down of 10 is due > to the fact that we pack a lot of crufty semantics into the `==' > method. We should not do this; it slows down every call of `=='. (For > instance, profiling by Cliff Click showed that our current > implementation of `==' is the single hottest spot in the Scala > compiler!) We should just keep to the spec as it was outlined above. > In that case, for simple versions of `equals' the JVM will be able to > inline the call and do the required optimizations. So it might very > well be a non-problem once we do the right thing. > > In summary, instead of overloading `==' with more and more crufty, > leaky abstractions, we should throw everything out and just go back to > basics. And we should take the spec seriously. > > Just my (it seems now) weakly repeating sermon. > > Cheers > > -- Martin I would say the whole thing boils down to whether we want to spec that x == y is an equivalence relation with respect to nulls. [But it's already too late and I shouldn't be doing exercises of the kind before my usual, lightweight bed-reading.] BR Christos -- __~O -\ <, Christos KK Loverdos (*)/ (*) http://ckkloverdos.com |
|
|
Re: [scala] Testing equality with nullOn Oct 2, 2009, at 24:13, Christos KK Loverdos wrote: > Hi Martin, > > Thanx for sharing your thoughts. Please find mine below. > > On Oct 1, 2009, at 22:27, martin odersky wrote: > >> I was going back and forth on this several times this afternoon, but >> in the end I have come down firmly against special casing x == null. >> Here's why: >> >> Scala tries to be a simple language, in what concerns the spec. It's >> true that its type system and Java interoperability both force some >> complexities on us, but wherever possible Scala strives for the most >> simple solution -- simple in terms of sentences needed to specify the >> language feature. >> >> One of the most important simplifications that Scala applies is that >> every operator is a method call, and that every value is an object. >> This holds also for the `==' method and the null value. `==' is >> defined in class Any as follows: >> >> def ==(that: Any) = this equals that >> >> It is overloaded in the numeric classes for more specialized >> comparisons. Finally it is overridden in the null object as follows: >> >> object null { >> override def ==(other: Any) = other eq null >> } >> >> At least conceptually, that's how things are supposed to be. It is >> true that the current implementation of Scala does not implement this >> behavior, mostly because the people implementing it did not >> understand >> what the spec really said (and that includes me), but I am trying to >> correct that now. >> >> When it comes to implementation, of course `null' is not an object, >> so >> we have to implement `==' like this: >> >> x == y rewrites to if (x eq null) y eq null else x equals y >> >> Now this is very elegant, but it looks to me that it leaves no space >> whatsoever for the x == null optimization that's desired. I invite >> you >> to try it; but please scrutinize carefully your solution. Note we >> *cannot* modify the spec to say >> >> def ==(that: Any) = (that ne null) && (this equals that) > > Let me take the exercise. > > a) Fact: We want to analyze x == y. > a1) Fact: There are two variables to consider, x and y > > b) Fact: x == y rewrites if(x eq null) y eq null else x equals y > > c) Let's assume x eq null (its statically known value is null) > c1) Then according to b) > null == y rewrites to if(null eq null) y eq null else x equals y > rewrites to if(true) y eq null > rewrites to y eq null > > c2) So, if x eq null then > null == y rewrites to y eq null > > d) Let's assume y eq null (statically known, as in c) for x) > d1) Then according to b) > x == null rewrites to if(x eq null) null eq null else x equals > null > rewrites to if(x eq null) true else x equals null > rewrites to (x eq null) || x equals null > > d2) So, if y eq null then > x == null rewrites to (x eq null) || x equals null > > Observations: > 1) Whether null is on the left or right _matters_. There is a clear > asymmetry, as we can see from the results c2) and d2). > > 2) Null on the left is a better (clear I would say) opportunity for > optimization. > > 3) Null on the right, still seems to need an "extra" check. I think > d2) shows the real character of "eq" versus "equals". Then some > crazy old chap could use this as a kernel [I am not kidding, but > then again I just had this crazy idea] in some kind of algebra, > where the behavior of nulls with respect to equality characterizes > the behavior of non-nulls ("carries away" their behavior). > > 4) This asymmetry, if retained, means that there are open > possibilities to violate an equivalence relation on == (with nulls > being the ones that may spoil the whole thing), because > x.equals(null) may not return false. > > >> >> This would elevate the test against null to a run-time test which >> would slow down every application of ==. The only possibility would >> be >> to say that `==' is ``not really" a method but that it somehow >> translates to method calls that are also called `=='. I'm sorry but >> this violates my sense of aesthetics too much to be considered. > >> >> So what's left? One could envision a program analysis that finds out >> whether an equals method is doing the right thing for null. In the >> case where it does, one could optiize `x == null` to `x eq null`. Or >> one could simply do nothing. The current quoted slow-down of 10 is >> due >> to the fact that we pack a lot of crufty semantics into the `==' >> method. We should not do this; it slows down every call of `=='. (For >> instance, profiling by Cliff Click showed that our current >> implementation of `==' is the single hottest spot in the Scala >> compiler!) We should just keep to the spec as it was outlined above. >> In that case, for simple versions of `equals' the JVM will be able to >> inline the call and do the required optimizations. So it might very >> well be a non-problem once we do the right thing. >> >> In summary, instead of overloading `==' with more and more crufty, >> leaky abstractions, we should throw everything out and just go back >> to >> basics. And we should take the spec seriously. >> >> Just my (it seems now) weakly repeating sermon. >> >> Cheers >> >> -- Martin > > > I would say the whole thing boils down to whether we want to spec > that x == y is an equivalence relation with respect to nulls. clarification/addition: as far as some nulls are statically known, following the analysis previously. Of course, nulls cannot be statically known in the general case and special-casing nulls for == appears an ad-hoc thing to do. > > [But it's already too late and I shouldn't be doing exercises of the > kind before my usual, lightweight bed-reading.] > > BR > Christos > -- > __~O > -\ <, Christos KK Loverdos > (*)/ (*) http://ckkloverdos.com > > > > > > -- __~O -\ <, Christos KK Loverdos (*)/ (*) http://ckkloverdos.com |
|
|
Re: [scala] Testing equality with nullOn Fri, Oct 02, 2009 at 12:13:52AM +0300, Christos KK Loverdos wrote:
> 4) This asymmetry, if retained, means that there are open > possibilities to violate an equivalence relation on == (with nulls > being the ones that may spoil the whole thing), because > x.equals(null) may not return false. I was going to make this case (as I have before in fact) but you kind of have to go out of your way to violate symmetry. In some sense it's not any different from any other value which you unwisely claim yourself equal to, when the other type isn't cooperating. class Bob { override def equals(other: Any) = true } val b = new Bob Now ("Bob" == b) is false but (b == "Bob") is true. You could look at null as the only value of type Null, with an equals method which is only equal to itself, and if you want to go around town violating that, it's on your head. Also: since I'm not 100% sure it's clear to everyone, we already have a runtime test on whether x is null on x == y. There's no avoiding this unless you enjoy NPEs, you can't naively translate to x.equals(y) regardless of the static type of x unless it's verifiably not nullable. The question is whether we should (potentially) double the number of such tests to encompass the RHS as well. If this were C and they were pointers, I bet there's some awesome bit combination trick. -- Paul Phillips | A Sunday school is a prison in which children do Analgesic | penance for the evil conscience of their parents. Empiricist | -- H. L. Mencken pp: i haul pills |----------* http://www.improving.org/paulp/ *---------- |
|
|
[scala] Re: Testing equality with nullOn 2/10/2009 5:27 AM, martin odersky wrote:
> I was going back and forth on this several times this afternoon, but > in the end I have come down firmly against special casing x == null. > Here's why: > > Scala tries to be a simple language, in what concerns the spec. It's > true that its type system and Java interoperability both force some > complexities on us, but wherever possible Scala strives for the most > simple solution -- simple in terms of sentences needed to specify the > language feature. Here's yet another alternative:- Implementations are permitted to assume that "equals" returns false when passed null. Then == looks after itself:- > we have to implement `==' like this: > > x == y rewrites to if (x eq null) y eq null else x equals y With my one sentence change, that simplifies in the null case:- x == null rewrites to if (x eq null) true else false which rewrites to x eq null I'm not advocating a dynamic test for y being null. >> ... for simple versions of `equals' the JVM will be able to >> inline the call and do the required optimizations. So it might very >> well be a non-problem once we do the right thing. I highly value startup performance, not just the performance after JIT inlining: I have programs that take seconds, but I run them many times. On 2/10/2009 3:05 AM, Paul Phillips wrote: > And personally I have to do a double take every time I come across a needless equals call when a null check would suffice. :-) BTW, if === instead of eq was reference equality, Paul's concerns about precedence and visual contrast would be avoided. But it is too late. |
|
|
Re: [scala] Testing equality with nullOn Thu, 2009-10-01 at 21:27 +0200, martin odersky wrote:
> def ==(that: Any) = (that ne null) && (this equals that) > > This would elevate the test against null to a run-time test which > would slow down every application of == For what is worth, null checks that are meant to always pass are very cheap: "Null checks are cheap. They usually fold straight into a related memory access instruction, and use the CPU bus logic to catch nulls. (Deoptimization follows, with regenerated code containing an explicit check.) * User-written null checks are in most cases functionally identical to those inserted by the JVM. * Null checks can be hoisted manually, and suppress implicit null checks in dominated blocks."[1] Of course, this is not particularly helpful for the this thread as the check would fail with foo == null. Personally, I'd just tell people to use foo eq null when they must (and avoid null checks when possible) and to make it less awkward to use eq on Any. As Paul suggested, the reference check short-circuit is beneficial to most equals implementations and right now it's verbose to do so. Best, Ismael [1] http://wikis.sun.com/display/HotSpotInternals/PerformanceTechniques |
|
|
Re: [scala] Testing equality with nullChristos,
I agree with all points of your analysis. I think the only lever we have is to specify a requirement that every equals method must fulfill: x.equals(null) may never be true except if x is the null object We can include spec language to that effect and then state that the Scala compiler is free to optimize based on the assumption that all equals methods satisfy the requirement. We already do something like this for pattern matching where we specify that guards must be side-effect free and the compiler is free to optimize accordingly. That's worth a thought. Cheers -- Martin |
|
|
Re: [scala] Testing equality with nullOn Thu, Oct 1, 2009 at 9:48 PM, Paul Phillips <paulp@...> wrote:
> On Thu, Oct 01, 2009 at 12:32:54PM -0700, David Pollak wrote: >> This all makes sense. There's one place in the code that's a question-mark >> for me: >> >> x match { >> case null => ... >> } > > There are very extensive old discussions (some on scala-devel > unfortunately) about the nature of matching equality which should be > considered here. I don't have time at this moment to look up and > summarize everything, but one issue is that implementing equals with > pattern matching in a case object can cause an infinite loop, and that > this is not exactly obvious. > > Here is IntMap.Nil, the comment came into existence after I removed what > seemed like pointless code and found in practice its point: > > private[immutable] case object Nil extends IntMap[Nothing] { > // Important! Without this equals method in place, an infinite > // loop from Map.equals => size => pattern-match-on-Nil => equals > // develops. Case objects and custom equality don't mix without > // careful handling. > override def equals(that : Any) = that match { > case (that : AnyRef) if (this eq that) => true; > case (that : IntMap[_]) => false; // The only empty IntMaps are eq Nil > case that => super.equals(that); > } > }; > > And we get to the proposal: > > Pattern matching short circuits on reference equality. > special case. When things have a tendency to become complicated it's even more important to simplify. > With respect to the null case, because of null's special status in the > pattern matcher (it cannot match most patterns by definition) I could > reorder a constant null check so it's usually avoided. If we're keeping > x.equals(null) as a possibility then I think it has to be the same in > the pattern matcher. > Another possibility would be to turn around the operands of an equality test. Given x match { case Y => ... } Do we compare x == Y or Y == x? We could easily spec it either way. Depending on what we decide to do with `null' this might or might not make a difference. In any case it would be interesting to find out which of the two alternatives is usually faster. I suspect Y == x might be faster, because the static type info about Y is usually more precise than the one about x and also because I would assume fewer Y values than x values to exist. But this might easily be wrong. Cheers -- Martin |
| < Prev | 1 - 2 | Next > |
| Free embeddable forum powered by Nabble | Forum Help |