diff options
Diffstat (limited to 'src')
29 files changed, 1714 insertions, 1374 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 2ba45c5972..f4039cf6d3 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -1872,7 +1872,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => def unpackLocation: AnyRef = null /** Remove private modifier from symbol `sym`s definition. If `sym` is a - * term symbol rename it by expanding its name to avoid name clashes + * is not a constructor nor a static module rename it by expanding its name to avoid name clashes + * @param base the fully qualified name of this class will be appended if name expansion is needed */ final def makeNotPrivate(base: Symbol) { if (this.isPrivate) { diff --git a/src/compiler/scala/reflect/runtime/Universe.scala b/src/compiler/scala/reflect/runtime/Universe.scala index 324fee87ab..7a5dda3d8e 100644 --- a/src/compiler/scala/reflect/runtime/Universe.scala +++ b/src/compiler/scala/reflect/runtime/Universe.scala @@ -39,6 +39,11 @@ class Universe extends SymbolTable { definitions.AnyValClass // force it. + type TreeAnnotation = Position + val NoTreeAnnotation: TreeAnnotation = NoPosition + def positionToAnnotation(pos: Position): TreeAnnotation = pos // TODO + def annotationToPosition(annot: TreeAnnotation): Position = annot //TODO + // establish root association to avoid cyclic dependency errors later classToScala(classOf[java.lang.Object]).initialize diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index 678f7b3028..d3f4688d4b 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -229,31 +229,36 @@ trait DocComments { self: Global => * 1. It takes longer to run compared to merge * 2. The inheritdoc annotation should not be used very often, as building the comment from pieces severely * impacts performance + * + * @param parent The source (or parent) comment + * @param child The child (overriding member or usecase) comment + * @param sym The child symbol + * @return The child comment with the inheritdoc sections expanded */ - def expandInheritdoc(src: String, dst: String, sym: Symbol): String = - if (dst.indexOf("@inheritdoc") == -1) - dst + def expandInheritdoc(parent: String, child: String, sym: Symbol): String = + if (child.indexOf("@inheritdoc") == -1) + child else { - val srcSections = tagIndex(src) - val dstSections = tagIndex(dst) - val srcTagMap = sectionTagMap(src, srcSections) - val srcNamedParams = Map() + - ("@param" -> paramDocs(src, "@param", srcSections)) + - ("@tparam" -> paramDocs(src, "@tparam", srcSections)) + - ("@throws" -> paramDocs(src, "@throws", srcSections)) + val parentSections = tagIndex(parent) + val childSections = tagIndex(child) + val parentTagMap = sectionTagMap(parent, parentSections) + val parentNamedParams = Map() + + ("@param" -> paramDocs(parent, "@param", parentSections)) + + ("@tparam" -> paramDocs(parent, "@tparam", parentSections)) + + ("@throws" -> paramDocs(parent, "@throws", parentSections)) val out = new StringBuilder - def replaceInheritdoc(src: String, dst: String) = - if (dst.indexOf("@inheritdoc") == -1) - dst - else - dst.replaceAllLiterally("@inheritdoc", src) + def replaceInheritdoc(childSection: String, parentSection: => String) = + if (childSection.indexOf("@inheritdoc") == -1) + childSection + else + childSection.replaceAllLiterally("@inheritdoc", parentSection) - def getSourceSection(section: (Int, Int)): String = { + def getParentSection(section: (Int, Int)): String = { - def getSectionHeader = extractSectionTag(dst, section) match { - case param@("@param"|"@tparam"|"@throws") => param + " " + extractSectionParam(dst, section) + def getSectionHeader = extractSectionTag(child, section) match { + case param@("@param"|"@tparam"|"@throws") => param + " " + extractSectionParam(child, section) case other => other } @@ -261,17 +266,19 @@ trait DocComments { self: Global => paramMap.get(param) match { case Some(section) => // Cleanup the section tag and parameter - val sectionTextBounds = extractSectionText(src, section) - cleanupSectionText(src.substring(sectionTextBounds._1, sectionTextBounds._2)) + val sectionTextBounds = extractSectionText(parent, section) + cleanupSectionText(parent.substring(sectionTextBounds._1, sectionTextBounds._2)) case None => reporter.info(sym.pos, "The \"" + getSectionHeader + "\" annotation of the " + sym + " comment contains @inheritdoc, but the corresponding section in the parent is not defined.", true) "<invalid inheritdoc annotation>" } - dst.substring(section._1, section._1 + 7) match { - case param@("@param "|"@tparam"|"@throws") => sectionString(extractSectionParam(dst, section), srcNamedParams(param.trim)) - case _ => sectionString(extractSectionTag(dst, section), srcTagMap) + child.substring(section._1, section._1 + 7) match { + case param@("@param "|"@tparam"|"@throws") => + sectionString(extractSectionParam(child, section), parentNamedParams(param.trim)) + case _ => + sectionString(extractSectionTag(child, section), parentTagMap) } } @@ -283,11 +290,11 @@ trait DocComments { self: Global => // Append main comment out.append("/**") - out.append(replaceInheritdoc(mainComment(src, srcSections), mainComment(dst, dstSections))) + out.append(replaceInheritdoc(mainComment(child, childSections), mainComment(parent, parentSections))) // Append sections - for (section <- dstSections) - out.append(replaceInheritdoc(getSourceSection(section), dst.substring(section._1, section._2))) + for (section <- childSections) + out.append(replaceInheritdoc(child.substring(section._1, section._2), getParentSection(section))) out.append("*/") out.toString diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala index bd5f98bab7..0c9c88c0f5 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala @@ -345,6 +345,17 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage } } + val fullSignature: Seq[scala.xml.Node] = { + mbr match { + case nte: NonTemplateMemberEntity if nte.isUseCase => + <div class="full-signature-block toggleContainer"> + <span class="toggle">Full Signature</span> + <div class="hiddenContent full-signature-usecase">{ signature(nte.useCaseOf.get,true) }</div> + </div> + case _ => NodeSeq.Empty + } + } + val selfType: Seq[scala.xml.Node] = mbr match { case dtpl: DocTemplateEntity if (isSelf && !dtpl.selfType.isEmpty && !isReduced) => <dt>Self Type</dt> @@ -466,7 +477,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage } // end attributes block vals --- - val attributesInfo = attributes ++ definitionClasses ++ selfType ++ annotations ++ deprecation ++ migration ++ sourceLink ++ mainComment + val attributesInfo = attributes ++ definitionClasses ++ fullSignature ++ selfType ++ annotations ++ deprecation ++ migration ++ sourceLink ++ mainComment val attributesBlock = if (attributesInfo.isEmpty) NodeSeq.Empty diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css index 4f552b7169..6fb83c133e 100644 --- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css +++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css @@ -340,6 +340,30 @@ div.members > ol > li:last-child { color: darkgreen; } +.full-signature-usecase h4 span { + font-size: 10pt; +} + +.full-signature-usecase > #signature { + padding-top: 0px; +} + +#template .full-signature-usecase > .signature.closed { + background: none; +} + +#template .full-signature-usecase > .signature.opened { + background: none; +} + +.full-signature-block { + padding: 5px 0 0; + border-top: 1px solid #EBEBEB; + margin-top: 5px; + margin-bottom: 5px; +} + + /* Comments text formating */ .cmt {} diff --git a/src/compiler/scala/tools/nsc/symtab/Positions.scala b/src/compiler/scala/tools/nsc/symtab/Positions.scala index c96c709fb0..680b06f8ce 100644 --- a/src/compiler/scala/tools/nsc/symtab/Positions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Positions.scala @@ -14,6 +14,15 @@ self: scala.tools.nsc.symtab.SymbolTable => type Position = scala.tools.nsc.util.Position val NoPosition = scala.tools.nsc.util.NoPosition + type TreeAnnotation = scala.tools.nsc.util.TreeAnnotation + val NoTreeAnnotation: TreeAnnotation = NoPosition + def positionToAnnotation(pos: Position): TreeAnnotation = pos + def annotationToPosition(annot: TreeAnnotation): Position = annot.pos + override def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = { + if (tree.pos != NoPosition && tree.pos != annot.pos) debugwarn("Overwriting annotation "+ tree.annotation +" of tree "+ tree +" with annotation "+ annot) + // if ((tree.annotation.isInstanceOf[scala.tools.nsc.util.Position] || !annot.isInstanceOf[scala.tools.nsc.util.Position]) && tree.isInstanceOf[Block]) + // println("Updating block from "+ tree.annotation +" to "+ annot) + } def focusPos(pos: Position): Position = pos.focus def isRangePos(pos: Position): Boolean = pos.isRange def showPos(pos: Position): String = pos.show diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 4c3972519a..5104518dd9 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -28,6 +28,9 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { /** the following two members override abstract members in Transform */ val phaseName: String = "extmethods" + /** The following flags may be set by this phase: */ + override def phaseNewFlags: Long = notPRIVATE + def newTransformer(unit: CompilationUnit): Transformer = new Extender(unit) @@ -101,6 +104,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { case Template(_, _, _) => if (currentOwner.isDerivedValueClass) { extensionDefs(currentOwner.companionModule) = new mutable.ListBuffer[Tree] + currentOwner.primaryConstructor.makeNotPrivate(NoSymbol) super.transform(tree) } else if (currentOwner.isStaticOwner) { super.transform(tree) diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index f32ad9293c..5287fad3bb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -169,6 +169,16 @@ trait MethodSynthesis { self: Namer => import NamerErrorGen._ + + /** TODO - synthesize method. + */ + def enterImplicitClass(tree: ClassDef) { + /** e.g. + val ClassDef(mods, name, tparams, impl) = tree + val converter = ImplicitClassConverter(tree).createAndEnterSymbol() + ... + */ + } def enterGetterSetter(tree: ValDef) { val ValDef(mods, name, _, _) = tree @@ -230,14 +240,33 @@ trait MethodSynthesis { } trait Derived { + /** The tree from which we are deriving a synthetic member. */ + def tree: Tree def name: TermName def flagsMask: Long def flagsExtra: Long + + /** The tree, symbol, and type completer for the synthetic member. */ def completer(sym: Symbol): Type + def derivedSym: Symbol + def derivedTree: Tree } - trait DerivedFromValDef extends Derived { - /** The declaration from which we are deriving. - */ + + trait DerivedFromMemberDef extends Derived { + def tree: MemberDef + + // Final methods to make the rest easier to reason about. + final def mods = tree.mods + final def basisSym = tree.symbol + final def enclClass = basisSym.enclClass + final def derivedFlags: Long = basisSym.flags & flagsMask | flagsExtra + } + + trait DerivedFromClassDef extends DerivedFromMemberDef { + def tree: ClassDef + } + + trait DerivedFromValDef extends DerivedFromMemberDef { def tree: ValDef /** Which meta-annotation is associated with this kind of entity. @@ -245,14 +274,8 @@ trait MethodSynthesis { */ def category: Symbol - // Final methods to make the rest easier to reason about. - final def mods = tree.mods - final def basisSym = tree.symbol - final def enclClass = basisSym.enclClass - final def completer(sym: Symbol) = namerOf(sym).accessorTypeCompleter(tree, isSetter) final def fieldSelection = Select(This(enclClass), basisSym) - final def derivedFlags: Long = basisSym.flags & flagsMask | flagsExtra final def derivedMods: Modifiers = mods & flagsMask | flagsExtra mapAnnotations (_ => Nil) def derivedSym: Symbol = tree.symbol @@ -312,6 +335,19 @@ trait MethodSynthesis { private def setterDef = DefDef(derivedSym, setterRhs) override def derivedTree: Tree = if (setterParam == NoSymbol) EmptyTree else setterDef } + + /** A synthetic method which performs the implicit conversion implied by + * the declaration of an implicit class. Yet to be written. + */ + case class ImplicitClassConverter(tree: ClassDef) extends DerivedFromClassDef { + def completer(sym: Symbol): Type = ??? + def derivedSym: Symbol = ??? + def derivedTree: DefDef = ??? + def flagsExtra: Long = ??? + def flagsMask: Long = ??? + def name: TermName = ??? + } + case class Getter(tree: ValDef) extends DerivedGetter { def name = tree.name def category = GetterTargetClass diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index c5fb13a5a9..6b27c27652 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -665,6 +665,10 @@ trait Namers extends MethodSynthesis { "If possible, define " + tree.symbol + " in " + owner.skipPackageObject + " instead." ) } + + // Suggested location only. + if (mods.isImplicit) + enterImplicitClass(tree) } // this logic is needed in case typer was interrupted half diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index ed263cbbef..105c2c0b98 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -263,8 +263,8 @@ abstract class TreeCheckers extends Analyzer { tree match { case x: PackageDef => - if (sym.ownerChain contains currentOwner) () - else fail(sym + " owner chain does not contain currentOwner " + currentOwner) + if ((sym.ownerChain contains currentOwner) || currentOwner == definitions.EmptyPackageClass) () + else fail(sym + " owner chain does not contain currentOwner " + currentOwner + sym.ownerChain) case _ => def cond(s: Symbol) = !s.isTerm || s.isMethod || s == sym.owner diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index e17a271dd0..6efa595d99 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -252,12 +252,17 @@ trait TypeDiagnostics { } "" // no elaborable variance situation found } - def foundReqMsg(found: Type, req: Type): String = ( - withDisambiguation(Nil, found, req)( + // TODO - figure out how to avoid doing any work at all + // when the message will never be seen. I though context.reportErrors + // being false would do that, but if I return "<suppressed>" under + // that condition, I see it. + def foundReqMsg(found: Type, req: Type): String = { + def baseMessage = ( ";\n found : " + found.toLongString + existentialContext(found) + explainAlias(found) + "\n required: " + req + existentialContext(req) + explainAlias(req) - ) + explainVariance(found, req) - ) + ) + withDisambiguation(Nil, found, req)(baseMessage) + explainVariance(found, req) + } case class TypeDiag(tp: Type, sym: Symbol) extends Ordered[TypeDiag] { // save the name because it will be mutated until it has been @@ -307,16 +312,37 @@ trait TypeDiagnostics { ) } } - private def typeDiags(locals: List[Symbol], types: Type*): List[TypeDiag] = { - object SymExtractor { - def unapply(x: Any) = x match { - case t @ ConstantType(_) => Some(t -> t.underlying.typeSymbol) - case t @ TypeRef(_, sym, _) => if (locals contains sym) None else Some(t -> sym) - case _ => None + /** This is tricky stuff - we need to traverse types deeply to + * explain name ambiguities, which may occur anywhere. However + * when lub explosions come through it knocks us into an n^2 + * disaster, see SI-5580. This is trying to perform the initial + * filtering of possibly ambiguous types in a sufficiently + * aggressive way that the state space won't explode. + */ + private def typeDiags(locals: List[Symbol], types0: Type*): List[TypeDiag] = { + val types = types0.toList + // If two different type diag instances are seen for a given + // key (either the string representation of a type, or the simple + // name of a symbol) then keep them for disambiguation. + val strings = mutable.Map[String, Set[TypeDiag]]() withDefaultValue Set() + val names = mutable.Map[Name, Set[TypeDiag]]() withDefaultValue Set() + + def record(t: Type, sym: Symbol) = { + val diag = TypeDiag(t, sym) + + strings("" + t) += diag + names(sym.name) += diag + } + for (tpe <- types ; t <- tpe) { + t match { + case ConstantType(_) => record(t, t.underlying.typeSymbol) + case TypeRef(_, sym, _) => record(t, sym) + case _ => () } } - for (tp <- types.toList; SymExtractor(t, sym) <- tp) yield TypeDiag(t, sym) + val collisions = strings.values ++ names.values filter (_.size > 1) + collisions.flatten.toList } /** The distinct pairs from an ordered list. */ diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index ad48712a32..49ce9712df 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1158,6 +1158,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val qtpe = qual.tpe.widen ( !isPastTyper && qual.isTerm + && !qual.isInstanceOf[Super] && ((qual.symbol eq null) || !qual.symbol.isTerm || qual.symbol.isValue) && !qtpe.isError && !qtpe.typeSymbol.isBottomClass @@ -1173,12 +1174,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { ) } - def adaptToMember(qual: Tree, searchTemplate: Type): Tree = - adaptToMember(qual, searchTemplate, true, true) - def adaptToMember(qual: Tree, searchTemplate: Type, reportAmbiguous: Boolean): Tree = - adaptToMember(qual, searchTemplate, reportAmbiguous, true) - - def adaptToMember(qual: Tree, searchTemplate: Type, reportAmbiguous: Boolean, saveErrors: Boolean): Tree = { + def adaptToMember(qual: Tree, searchTemplate: Type, reportAmbiguous: Boolean = true, saveErrors: Boolean = true): Tree = { if (isAdaptableWithView(qual)) { qual.tpe.widen.normalize match { case et: ExistentialType => @@ -1284,8 +1280,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { unit.error(clazz.pos, "value class may not be a "+ (if (clazz.owner.isTerm) "local class" else "member of another class")) val constr = clazz.primaryConstructor - if ((constr hasFlag (PRIVATE | PROTECTED)) || constr.privateWithin != NoSymbol) - unit.error(constr.pos, "value class must have public primary constructor") clazz.info.decls.toList.filter(acc => acc.isMethod && (acc hasFlag PARAMACCESSOR)) match { case List(acc) => def isUnderlyingAcc(sym: Symbol) = diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala index 53c767be20..bc74717366 100644 --- a/src/compiler/scala/tools/nsc/util/Position.scala +++ b/src/compiler/scala/tools/nsc/util/Position.scala @@ -33,6 +33,16 @@ object Position { } } +/** + * A tree does not directly store a Position. It stores a TreeAnnotation, which /typically/ is a Position. + * + * A TreeAnnotion may encompass more than just a Position, though, depending on the exact subclass of TreeAnnotation. + */ +trait TreeAnnotation { + def pos: Position +} + + /** The Position class and its subclasses represent positions of ASTs and symbols. * Except for NoPosition and FakePos, every position refers to a SourceFile * and to an offset in the sourcefile (its `point`). For batch compilation, @@ -77,7 +87,8 @@ object Position { * pos.makeTransparent converts an opaque range position into a transparent one. * returns all other positions unchanged. */ -trait Position { +trait Position extends TreeAnnotation { + def pos: Position = this /** An optional value containing the source file referred to by this position, or * None if not defined. diff --git a/src/library/scala/collection/JavaConversions.scala b/src/library/scala/collection/JavaConversions.scala index 50919e506a..75ab3f28f5 100644 --- a/src/library/scala/collection/JavaConversions.scala +++ b/src/library/scala/collection/JavaConversions.scala @@ -8,6 +8,9 @@ package scala.collection +import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } +import convert._ + /** A collection of implicit conversions supporting interoperability between * Scala and Java collections. * @@ -46,877 +49,81 @@ package scala.collection * @author Martin Odersky * @since 2.8 */ -object JavaConversions { +object JavaConversions extends WrapAsScala with WrapAsJava { + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type ConcurrentMapWrapper[A, B] = Wrappers.ConcurrentMapWrapper[A, B] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type DictionaryWrapper[A, B] = Wrappers.DictionaryWrapper[A, B] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type IterableWrapper[A] = Wrappers.IterableWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type IteratorWrapper[A] = Wrappers.IteratorWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JCollectionWrapper[A] = Wrappers.JCollectionWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JConcurrentMapWrapper[A, B] = Wrappers.JConcurrentMapWrapper[A, B] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JDictionaryWrapper[A, B] = Wrappers.JDictionaryWrapper[A, B] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JEnumerationWrapper[A] = Wrappers.JEnumerationWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JIterableWrapper[A] = Wrappers.JIterableWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JIteratorWrapper[A] = Wrappers.JIteratorWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JListWrapper[A] = Wrappers.JListWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JMapWrapper[A, B] = Wrappers.JMapWrapper[A, B] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JPropertiesWrapper = Wrappers.JPropertiesWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type JSetWrapper[A] = Wrappers.JSetWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MapWrapper[A, B] = Wrappers.MapWrapper[A, B] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableBufferWrapper[A] = Wrappers.MutableBufferWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableMapWrapper[A, B] = Wrappers.MutableMapWrapper[A, B] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableSeqWrapper[A] = Wrappers.MutableSeqWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type MutableSetWrapper[A] = Wrappers.MutableSetWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type SeqWrapper[A] = Wrappers.SeqWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type SetWrapper[A] = Wrappers.SetWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") type ToIteratorWrapper[A] = Wrappers.ToIteratorWrapper[A] + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val DictionaryWrapper = Wrappers.DictionaryWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val IterableWrapper = Wrappers.IterableWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val IteratorWrapper = Wrappers.IteratorWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JCollectionWrapper = Wrappers.JCollectionWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JConcurrentMapWrapper = Wrappers.JConcurrentMapWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JDictionaryWrapper = Wrappers.JDictionaryWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JEnumerationWrapper = Wrappers.JEnumerationWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JIterableWrapper = Wrappers.JIterableWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JIteratorWrapper = Wrappers.JIteratorWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JListWrapper = Wrappers.JListWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JMapWrapper = Wrappers.JMapWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JPropertiesWrapper = Wrappers.JPropertiesWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val JSetWrapper = Wrappers.JSetWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val MutableBufferWrapper = Wrappers.MutableBufferWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val MutableMapWrapper = Wrappers.MutableMapWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val MutableSeqWrapper = Wrappers.MutableSeqWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val MutableSetWrapper = Wrappers.MutableSetWrapper + @deprecated("Use a member of scala.collection.convert.Wrappers", "2.10.0") val SeqWrapper = Wrappers.SeqWrapper + // Note to implementors: the cavalcade of deprecated methods herein should // serve as a warning to any who follow: don't overload implicit methods. - import java.{ lang => jl, util => ju } - import java.util.{ concurrent => juc } - - // Scala => Java - - /** - * Implicitly converts a Scala Iterator to a Java Iterator. - * The returned Java Iterator is backed by the provided Scala - * Iterator and any side-effects of using it via the Java interface will - * be visible via the Scala interface and vice versa. - * - * If the Scala Iterator was previously obtained from an implicit or - * explicit call of `asIterator(java.util.Iterator)` then the original - * Java Iterator will be returned. - * - * @param i The Iterator to be converted. - * @return A Java Iterator view of the argument. - */ - implicit def asJavaIterator[A](it: Iterator[A]): ju.Iterator[A] = it match { - case JIteratorWrapper(wrapped) => wrapped.asInstanceOf[ju.Iterator[A]] - case _ => IteratorWrapper(it) - } - - /** - * Implicitly converts a Scala Iterator to a Java Enumeration. - * The returned Java Enumeration is backed by the provided Scala - * Iterator and any side-effects of using it via the Java interface will - * be visible via the Scala interface and vice versa. - * - * If the Scala Iterator was previously obtained from an implicit or - * explicit call of `asIterator(java.util.Enumeration)` then the - * original Java Enumeration will be returned. - * - * @param i The Iterator to be converted. - * @return A Java Enumeration view of the argument. - */ - implicit def asJavaEnumeration[A](it: Iterator[A]): ju.Enumeration[A] = it match { - case JEnumerationWrapper(wrapped) => wrapped.asInstanceOf[ju.Enumeration[A]] - case _ => IteratorWrapper(it) - } - - /** - * Implicitly converts a Scala Iterable to a Java Iterable. - * The returned Java Iterable is backed by the provided Scala - * Iterable and any side-effects of using it via the Java interface will - * be visible via the Scala interface and vice versa. - * - * If the Scala Iterable was previously obtained from an implicit or - * explicit call of `asIterable(java.lang.Iterable)` then the original - * Java Iterable will be returned. - * - * @param i The Iterable to be converted. - * @return A Java Iterable view of the argument. - */ - implicit def asJavaIterable[A](i: Iterable[A]): jl.Iterable[A] = i match { - case JIterableWrapper(wrapped) => wrapped.asInstanceOf[jl.Iterable[A]] - case _ => IterableWrapper(i) - } - - /** - * Implicitly converts a Scala Iterable to an immutable Java - * Collection. - * - * If the Scala Iterable was previously obtained from an implicit or - * explicit call of `asSizedIterable(java.util.Collection)` then the original - * Java Collection will be returned. - * - * @param i The SizedIterable to be converted. - * @return A Java Collection view of the argument. - */ - implicit def asJavaCollection[A](it: Iterable[A]): ju.Collection[A] = it match { - case JCollectionWrapper(wrapped) => wrapped.asInstanceOf[ju.Collection[A]] - case _ => new IterableWrapper(it) - } - - /** - * Implicitly converts a Scala mutable Buffer to a Java List. - * The returned Java List is backed by the provided Scala - * Buffer and any side-effects of using it via the Java interface will - * be visible via the Scala interface and vice versa. - * - * If the Scala Buffer was previously obtained from an implicit or - * explicit call of `asBuffer(java.util.List)` then the original - * Java List will be returned. - * - * @param b The Buffer to be converted. - * @return A Java List view of the argument. - */ - implicit def bufferAsJavaList[A](b: mutable.Buffer[A]): ju.List[A] = b match { - case JListWrapper(wrapped) => wrapped - case _ => new MutableBufferWrapper(b) - } @deprecated("use bufferAsJavaList instead", "2.9.0") def asJavaList[A](b : mutable.Buffer[A]): ju.List[A] = bufferAsJavaList[A](b) - /** - * Implicitly converts a Scala mutable Seq to a Java List. - * The returned Java List is backed by the provided Scala - * Seq and any side-effects of using it via the Java interface will - * be visible via the Scala interface and vice versa. - * - * If the Scala Seq was previously obtained from an implicit or - * explicit call of `asSeq(java.util.List)` then the original - * Java List will be returned. - * - * @param b The Seq to be converted. - * @return A Java List view of the argument. - */ - implicit def mutableSeqAsJavaList[A](seq: mutable.Seq[A]): ju.List[A] = seq match { - case JListWrapper(wrapped) => wrapped - case _ => new MutableSeqWrapper(seq) - } @deprecated("use mutableSeqAsJavaList instead", "2.9.0") def asJavaList[A](b : mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList[A](b) - /** - * Implicitly converts a Scala Seq to a Java List. - * The returned Java List is backed by the provided Scala - * Seq and any side-effects of using it via the Java interface will - * be visible via the Scala interface and vice versa. - * - * If the Scala Seq was previously obtained from an implicit or - * explicit call of `asSeq(java.util.List)` then the original - * Java List will be returned. - * - * @param b The Seq to be converted. - * @return A Java List view of the argument. - */ - implicit def seqAsJavaList[A](seq: Seq[A]): ju.List[A] = seq match { - case JListWrapper(wrapped) => wrapped.asInstanceOf[ju.List[A]] - case _ => new SeqWrapper(seq) - } - @deprecated("use seqAsJavaList instead", "2.9.0") def asJavaList[A](b : Seq[A]): ju.List[A] = seqAsJavaList[A](b) - /** - * Implicitly converts a Scala mutable Set to a Java Set. - * The returned Java Set is backed by the provided Scala - * Set and any side-effects of using it via the Java interface will - * be visible via the Scala interface and vice versa. - * - * If the Scala Set was previously obtained from an implicit or - * explicit call of `asSet(java.util.Set)` then the original - * Java Set will be returned. - * - * @param s The Set to be converted. - * @return A Java Set view of the argument. - */ - implicit def mutableSetAsJavaSet[A](s: mutable.Set[A]): ju.Set[A] = s match { - case JSetWrapper(wrapped) => wrapped - case _ => new MutableSetWrapper(s) - } - @deprecated("use mutableSetAsJavaSet instead", "2.9.0") def asJavaSet[A](s : mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet[A](s) - /** - * Implicitly converts a Scala Set to a Java Set. - * The returned Java Set is backed by the provided Scala - * Set and any side-effects of using it via the Java interface will - * be visible via the Scala interface and vice versa. - * - * If the Scala Set was previously obtained from an implicit or - * explicit call of asSet(java.util.Set) then the original - * Java Set will be returned. - * - * @param s The Set to be converted. - * @return A Java Set view of the argument. - */ - implicit def setAsJavaSet[A](s: Set[A]): ju.Set[A] = s match { - case JSetWrapper(wrapped) => wrapped - case _ => new SetWrapper(s) - } - @deprecated("use setAsJavaSet instead", "2.9.0") def asJavaSet[A](s: Set[A]): ju.Set[A] = setAsJavaSet[A](s) - /** - * Implicitly converts a Scala mutable Map to a Java Map. - * The returned Java Map is backed by the provided Scala - * Map and any side-effects of using it via the Java interface will - * be visible via the Scala interface and vice versa. - * - * If the Scala Map was previously obtained from an implicit or - * explicit call of `asMap(java.util.Map)` then the original - * Java Map will be returned. - * - * @param m The Map to be converted. - * @return A Java Map view of the argument. - */ - implicit def mutableMapAsJavaMap[A, B](m: mutable.Map[A, B]): ju.Map[A, B] = m match { - //case JConcurrentMapWrapper(wrapped) => wrapped - case JMapWrapper(wrapped) => wrapped - case _ => new MutableMapWrapper(m) - } - @deprecated("use mutableMapAsJavaMap instead", "2.9.0") def asJavaMap[A, B](m : mutable.Map[A, B]): ju.Map[A, B] = mutableMapAsJavaMap[A, B](m) - /** - * Implicitly converts a Scala mutable `Map` to a Java `Dictionary`. - * - * The returned Java `Dictionary` is backed by the provided Scala - * `Dictionary` and any side-effects of using it via the Java interface - * will be visible via the Scala interface and vice versa. - * - * If the Scala `Dictionary` was previously obtained from an implicit or - * explicit call of `asMap(java.util.Dictionary)` then the original - * Java Dictionary will be returned. - * - * @param m The `Map` to be converted. - * @return A Java `Dictionary` view of the argument. - */ - implicit def asJavaDictionary[A, B](m: mutable.Map[A, B]): ju.Dictionary[A, B] = m match { - //case JConcurrentMapWrapper(wrapped) => wrapped - case JDictionaryWrapper(wrapped) => wrapped - case _ => new DictionaryWrapper(m) - } - - /** - * Implicitly converts a Scala `Map` to a Java `Map`. - * - * The returned Java `Map` is backed by the provided Scala `Map` and - * any side-effects of using it via the Java interface will be visible - * via the Scala interface and vice versa. - * - * If the Scala `Map` was previously obtained from an implicit or - * explicit call of `asMap(java.util.Map)` then the original - * Java `Map` will be returned. - * - * @param m The `Map` to be converted. - * @return A Java `Map` view of the argument. - */ - implicit def mapAsJavaMap[A, B](m: Map[A, B]): ju.Map[A, B] = m match { - //case JConcurrentMapWrapper(wrapped) => wrapped - case JMapWrapper(wrapped) => wrapped.asInstanceOf[ju.Map[A, B]] - case _ => new MapWrapper(m) - } - @deprecated("use mapAsJavaMap instead", "2.9.0") def asJavaMap[A, B](m : Map[A, B]): ju.Map[A, B] = mapAsJavaMap[A, B](m) - /** - * Implicitly converts a Scala mutable `ConcurrentMap` to a Java - * `ConcurrentMap`. - * - * The returned Java `ConcurrentMap` is backed by the provided Scala - * `ConcurrentMap` and any side-effects of using it via the Java interface - * will be visible via the Scala interface and vice versa. - * - * If the Scala `ConcurrentMap` was previously obtained from an implicit or - * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)` - * then the original Java ConcurrentMap will be returned. - * - * @param m The `ConcurrentMap` to be converted. - * @return A Java `ConcurrentMap` view of the argument. - */ - implicit def asJavaConcurrentMap[A, B](m: mutable.ConcurrentMap[A, B]): juc.ConcurrentMap[A, B] = m match { - case JConcurrentMapWrapper(wrapped) => wrapped - case _ => new ConcurrentMapWrapper(m) - } - - // Java => Scala - - /** - * Implicitly converts a Java `Iterator` to a Scala `Iterator`. - * - * The returned Scala `Iterator` is backed by the provided Java `Iterator` - * and any side-effects of using it via the Scala interface will be visible - * via the Java interface and vice versa. - * - * If the Java `Iterator` was previously obtained from an implicit or - * explicit call of `asIterator(scala.collection.Iterator)` then the - * original Scala `Iterator` will be returned. - * - * @param i The `Iterator` to be converted. - * @return A Scala `Iterator` view of the argument. - */ - implicit def asScalaIterator[A](it: ju.Iterator[A]): Iterator[A] = it match { - case IteratorWrapper(wrapped) => wrapped - case _ => JIteratorWrapper(it) - } - - /** - * Implicitly converts a Java Enumeration to a Scala Iterator. - * The returned Scala Iterator is backed by the provided Java - * Enumeration and any side-effects of using it via the Scala interface will - * be visible via the Java interface and vice versa. - * - * If the Java Enumeration was previously obtained from an implicit or - * explicit call of `enumerationAsScalaIterator(scala.collection.Iterator)` - * then the original Scala Iterator will be returned. - * - * @param i The Enumeration to be converted. - * @return A Scala Iterator view of the argument. - */ - implicit def enumerationAsScalaIterator[A](i: ju.Enumeration[A]): Iterator[A] = i match { - case IteratorWrapper(wrapped) => wrapped - case _ => JEnumerationWrapper(i) - } - - /** - * Implicitly converts a Java `Iterable` to a Scala `Iterable`. - * - * The returned Scala `Iterable` is backed by the provided Java `Iterable` - * and any side-effects of using it via the Scala interface will be visible - * via the Java interface and vice versa. - * - * If the Java `Iterable` was previously obtained from an implicit or - * explicit call of `iterableAsScalaIterable(scala.collection.Iterable)` - * then the original Scala Iterable will be returned. - * - * @param i The Iterable to be converted. - * @return A Scala Iterable view of the argument. - */ - implicit def iterableAsScalaIterable[A](i: jl.Iterable[A]): Iterable[A] = i match { - case IterableWrapper(wrapped) => wrapped - case _ => JIterableWrapper(i) - } - @deprecated("use iterableAsScalaIterable instead", "2.9.0") def asScalaIterable[A](i : jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable[A](i) - /** - * Implicitly converts a Java `Collection` to an Scala `Iterable`. - * - * If the Java `Collection` was previously obtained from an implicit or - * explicit call of `collectionAsScalaIterable(scala.collection.SizedIterable)` - * then the original Scala `Iterable` will be returned. - * - * @param i The Collection to be converted. - * @return A Scala Iterable view of the argument. - */ - implicit def collectionAsScalaIterable[A](i: ju.Collection[A]): Iterable[A] = i match { - case IterableWrapper(wrapped) => wrapped - case _ => JCollectionWrapper(i) - } @deprecated("use collectionAsScalaIterable instead", "2.9.0") def asScalaIterable[A](i : ju.Collection[A]): Iterable[A] = collectionAsScalaIterable[A](i) - /** - * Implicitly converts a Java `List` to a Scala mutable `Buffer`. - * - * The returned Scala `Buffer` is backed by the provided Java `List` - * and any side-effects of using it via the Scala interface will - * be visible via the Java interface and vice versa. - * - * If the Java `List` was previously obtained from an implicit or - * explicit call of `asScalaBuffer(scala.collection.mutable.Buffer)` - * then the original Scala `Buffer` will be returned. - * - * @param l The `List` to be converted. - * @return A Scala mutable `Buffer` view of the argument. - */ - implicit def asScalaBuffer[A](l: ju.List[A]): mutable.Buffer[A] = l match { - case MutableBufferWrapper(wrapped) => wrapped - case _ =>new JListWrapper(l) - } - - /** - * Implicitly converts a Java Set to a Scala mutable Set. - * The returned Scala Set is backed by the provided Java - * Set and any side-effects of using it via the Scala interface will - * be visible via the Java interface and vice versa. - * - * If the Java Set was previously obtained from an implicit or - * explicit call of `asScalaSet(scala.collection.mutable.Set)` then - * the original Scala Set will be returned. - * - * @param s The Set to be converted. - * @return A Scala mutable Set view of the argument. - */ - implicit def asScalaSet[A](s: ju.Set[A]): mutable.Set[A] = s match { - case MutableSetWrapper(wrapped) => wrapped - case _ =>new JSetWrapper(s) - } - - /** - * Implicitly converts a Java `Map` to a Scala mutable `Map`. - * - * The returned Scala `Map` is backed by the provided Java `Map` and any - * side-effects of using it via the Scala interface will be visible via - * the Java interface and vice versa. - * - * If the Java `Map` was previously obtained from an implicit or - * explicit call of `mapAsScalaMap(scala.collection.mutable.Map)` then - * the original Scala Map will be returned. - * - * @param m The Map to be converted. - * @return A Scala mutable Map view of the argument. - */ - implicit def mapAsScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = m match { - //case ConcurrentMapWrapper(wrapped) => wrapped - case MutableMapWrapper(wrapped) => wrapped - case _ => new JMapWrapper(m) - } - @deprecated("use mapAsScalaMap instead", "2.9.0") def asScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap[A, B](m) - /** - * Implicitly converts a Java ConcurrentMap to a Scala mutable ConcurrentMap. - * The returned Scala ConcurrentMap is backed by the provided Java - * ConcurrentMap and any side-effects of using it via the Scala interface will - * be visible via the Java interface and vice versa. - * - * If the Java ConcurrentMap was previously obtained from an implicit or - * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)` - * then the original Scala ConcurrentMap will be returned. - * - * @param m The ConcurrentMap to be converted. - * @return A Scala mutable ConcurrentMap view of the argument. - */ - implicit def asScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): mutable.ConcurrentMap[A, B] = m match { - case cmw: ConcurrentMapWrapper[a, b] => cmw.underlying - case _ => new JConcurrentMapWrapper(m) - } - - /** - * Implicitly converts a Java `Dictionary` to a Scala mutable - * `Map[String, String]`. - * - * The returned Scala `Map[String, String]` is backed by the provided Java - * `Dictionary` and any side-effects of using it via the Scala interface - * will be visible via the Java interface and vice versa. - * - * @param m The Dictionary to be converted. - * @return A Scala mutable Map[String, String] view of the argument. - */ - implicit def dictionaryAsScalaMap[A, B](p: ju.Dictionary[A, B]): mutable.Map[A, B] = p match { - case DictionaryWrapper(wrapped) => wrapped - case _ => new JDictionaryWrapper(p) - } - - /** - * Implicitly converts a Java `Properties` to a Scala `mutable Map[String, String]`. - * - * The returned Scala `Map[String, String]` is backed by the provided Java - * `Properties` and any side-effects of using it via the Scala interface - * will be visible via the Java interface and vice versa. - * - * @param m The Properties to be converted. - * @return A Scala mutable Map[String, String] view of the argument. - */ - implicit def propertiesAsScalaMap(p: ju.Properties): mutable.Map[String, String] = p match { - case _ => new JPropertiesWrapper(p) - } - @deprecated("use propertiesAsScalaMap instead", "2.9.0") def asScalaMap(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p) - - // Private implementations (shared by JavaConverters) ... - - trait IterableWrapperTrait[A] extends ju.AbstractCollection[A] { - val underlying: Iterable[A] - def size = underlying.size - override def iterator = IteratorWrapper(underlying.iterator) - override def isEmpty = underlying.isEmpty - } - - case class IteratorWrapper[A](underlying: Iterator[A]) - extends ju.Iterator[A] with ju.Enumeration[A] { - def hasNext = underlying.hasNext - def next() = underlying.next - def hasMoreElements = underlying.hasNext - def nextElement() = underlying.next - def remove() = throw new UnsupportedOperationException - } - - class ToIteratorWrapper[A](underlying : Iterator[A]) { - def asJava = new IteratorWrapper(underlying) - } - - case class JIteratorWrapper[A](underlying: ju.Iterator[A]) extends AbstractIterator[A] with Iterator[A] { - def hasNext = underlying.hasNext - def next() = underlying.next - } - - case class JEnumerationWrapper[A](underlying: ju.Enumeration[A]) extends AbstractIterator[A] with Iterator[A] { - def hasNext = underlying.hasMoreElements - def next() = underlying.nextElement - } - - case class IterableWrapper[A](underlying: Iterable[A]) - extends ju.AbstractCollection[A] - with IterableWrapperTrait[A] { } - - case class JIterableWrapper[A](underlying: jl.Iterable[A]) extends AbstractIterable[A] with Iterable[A] { - def iterator = underlying.iterator - def newBuilder[B] = new mutable.ArrayBuffer[B] - } - - case class JCollectionWrapper[A](underlying: ju.Collection[A]) extends AbstractIterable[A] with Iterable[A] { - def iterator = underlying.iterator - override def size = underlying.size - override def isEmpty = underlying.isEmpty - def newBuilder[B] = new mutable.ArrayBuffer[B] - } - - case class SeqWrapper[A](underlying: Seq[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] { - def get(i: Int) = underlying(i) - } - - case class MutableSeqWrapper[A](underlying: mutable.Seq[A]) - extends ju.AbstractList[A] with IterableWrapperTrait[A] { - def get(i: Int) = underlying(i) - override def set(i: Int, elem: A) = { - val p = underlying(i) - underlying(i) = elem - p - } - } - - case class MutableBufferWrapper[A](underlying: mutable.Buffer[A]) - extends ju.AbstractList[A] with IterableWrapperTrait[A] { - def get(i: Int) = underlying(i) - override def set(i: Int, elem: A) = { val p = underlying(i); underlying(i) = elem; p } - override def add(elem: A) = { underlying append elem; true } - override def remove(i: Int) = underlying remove i - } - - case class JListWrapper[A](val underlying: ju.List[A]) extends mutable.AbstractBuffer[A] with mutable.Buffer[A] { - def length = underlying.size - override def isEmpty = underlying.isEmpty - override def iterator: Iterator[A] = underlying.iterator - def apply(i: Int) = underlying.get(i) - def update(i: Int, elem: A) = underlying.set(i, elem) - def +=:(elem: A) = { underlying.subList(0, 0) add elem; this } - def +=(elem: A): this.type = { underlying add elem; this } - def insertAll(i: Int, elems: Traversable[A]) = { - val ins = underlying.subList(0, i) - elems.seq.foreach(ins.add(_)) - } - def remove(i: Int) = underlying.remove(i) - def clear() = underlying.clear() - def result = this - } - - class SetWrapper[A](underlying: Set[A]) extends ju.AbstractSet[A] { - self => - def size = underlying.size - def iterator = new ju.Iterator[A] { - val ui = underlying.iterator - var prev: Option[A] = None - def hasNext = ui.hasNext - def next = { val e = ui.next; prev = Some(e); e } - def remove = prev match { - case Some(e) => - underlying match { - case ms: mutable.Set[a] => - ms remove e - prev = None - case _ => - throw new UnsupportedOperationException("remove") - } - case _ => - throw new IllegalStateException("next must be called at least once before remove") - } - } - } - - case class MutableSetWrapper[A](underlying: mutable.Set[A]) extends SetWrapper[A](underlying) { - override def add(elem: A) = { - val sz = underlying.size - underlying += elem - sz < underlying.size - } - override def remove(elem: AnyRef) = - try underlying remove elem.asInstanceOf[A] - catch { case ex: ClassCastException => false } - override def clear() = underlying.clear() - } - - case class JSetWrapper[A](underlying: ju.Set[A]) - extends mutable.AbstractSet[A] - with mutable.Set[A] - with mutable.SetLike[A, JSetWrapper[A]] { - - override def size = underlying.size - - def iterator = underlying.iterator - - def contains(elem: A): Boolean = underlying.contains(elem) - - def +=(elem: A): this.type = { underlying add elem; this } - def -=(elem: A): this.type = { underlying remove elem; this } - - override def add(elem: A): Boolean = underlying add elem - override def remove(elem: A): Boolean = underlying remove elem - override def clear() = underlying.clear() - - override def empty = JSetWrapper(new ju.HashSet[A]) - } - - class MapWrapper[A, B](underlying: Map[A, B]) extends ju.AbstractMap[A, B] { self => - override def size = underlying.size - - override def get(key: AnyRef): B = try { - underlying get key.asInstanceOf[A] match { - case None => null.asInstanceOf[B] - case Some(v) => v - } - } catch { - case ex: ClassCastException => null.asInstanceOf[B] - } - - override def entrySet: ju.Set[ju.Map.Entry[A, B]] = new ju.AbstractSet[ju.Map.Entry[A, B]] { - def size = self.size - - def iterator = new ju.Iterator[ju.Map.Entry[A, B]] { - val ui = underlying.iterator - var prev : Option[A] = None - - def hasNext = ui.hasNext - - def next() = { - val (k, v) = ui.next - prev = Some(k) - new ju.Map.Entry[A, B] { - def getKey = k - def getValue = v - def setValue(v1 : B) = self.put(k, v1) - override def hashCode = k.hashCode + v.hashCode - override def equals(other: Any) = other match { - case e: ju.Map.Entry[_, _] => k == e.getKey && v == e.getValue - case _ => false - } - } - } - - def remove() { - prev match { - case Some(k) => - underlying match { - case mm: mutable.Map[a, _] => - mm remove k - prev = None - case _ => - throw new UnsupportedOperationException("remove") - } - case _ => - throw new IllegalStateException("next must be called at least once before remove") - } - } - } - } - } - - case class MutableMapWrapper[A, B](underlying: mutable.Map[A, B]) - extends MapWrapper[A, B](underlying) { - override def put(k: A, v: B) = underlying.put(k, v) match { - case Some(v1) => v1 - case None => null.asInstanceOf[B] - } - - override def remove(k: AnyRef): B = try { - underlying remove k.asInstanceOf[A] match { - case None => null.asInstanceOf[B] - case Some(v) => v - } - } catch { - case ex: ClassCastException => null.asInstanceOf[B] - } - - override def clear() = underlying.clear() - } - - trait JMapWrapperLike[A, B, +Repr <: mutable.MapLike[A, B, Repr] with mutable.Map[A, B]] - extends mutable.Map[A, B] with mutable.MapLike[A, B, Repr] { - def underlying: ju.Map[A, B] - - override def size = underlying.size - - def get(k: A) = { - val v = underlying get k - if (v != null) - Some(v) - else if (underlying containsKey k) - Some(null.asInstanceOf[B]) - else - None - } - - def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this } - def -=(key: A): this.type = { underlying remove key; this } - - override def put(k: A, v: B): Option[B] = { - val r = underlying.put(k, v) - if (r != null) Some(r) else None - } - - override def update(k: A, v: B) { underlying.put(k, v) } - - override def remove(k: A): Option[B] = { - val r = underlying remove k - if (r != null) Some(r) else None - } - - def iterator: Iterator[(A, B)] = new AbstractIterator[(A, B)] { - val ui = underlying.entrySet.iterator - def hasNext = ui.hasNext - def next() = { val e = ui.next(); (e.getKey, e.getValue) } - } - - override def clear() = underlying.clear() - - override def empty: Repr = null.asInstanceOf[Repr] - } - - case class JMapWrapper[A, B](val underlying : ju.Map[A, B]) - extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JMapWrapper[A, B]] { - override def empty = JMapWrapper(new ju.HashMap[A, B]) - } - - class ConcurrentMapWrapper[A, B](override val underlying: mutable.ConcurrentMap[A, B]) - extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] { - - def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match { - case Some(v) => v - case None => null.asInstanceOf[B] - } - - def remove(k: AnyRef, v: AnyRef) = try { - underlying.remove(k.asInstanceOf[A], v.asInstanceOf[B]) - } catch { - case ex: ClassCastException => - false - } - - def replace(k: A, v: B): B = underlying.replace(k, v) match { - case Some(v) => v - case None => null.asInstanceOf[B] - } - - def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval) - } - - case class JConcurrentMapWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) - extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] with mutable.ConcurrentMap[A, B] { - override def get(k: A) = { - val v = underlying get k - if (v != null) Some(v) - else None - } - - override def empty = new JConcurrentMapWrapper(new juc.ConcurrentHashMap[A, B]) - - def putIfAbsent(k: A, v: B): Option[B] = { - val r = underlying.putIfAbsent(k, v) - if (r != null) Some(r) else None - } - - def remove(k: A, v: B): Boolean = underlying.remove(k, v) - - def replace(k: A, v: B): Option[B] = { - val prev = underlying.replace(k, v) - if (prev != null) Some(prev) else None - } - - def replace(k: A, oldvalue: B, newvalue: B): Boolean = - underlying.replace(k, oldvalue, newvalue) - } - - case class DictionaryWrapper[A, B](underlying: mutable.Map[A, B]) - extends ju.Dictionary[A, B] { - def size: Int = underlying.size - def isEmpty: Boolean = underlying.isEmpty - def keys: ju.Enumeration[A] = asJavaEnumeration(underlying.keysIterator) - def elements: ju.Enumeration[B] = asJavaEnumeration(underlying.valuesIterator) - def get(key: AnyRef) = try { - underlying get key.asInstanceOf[A] match { - case None => null.asInstanceOf[B] - case Some(v) => v - } - } catch { - case ex: ClassCastException => null.asInstanceOf[B] - } - def put(key: A, value: B): B = underlying.put(key, value) match { - case Some(v) => v - case None => null.asInstanceOf[B] - } - override def remove(key: AnyRef) = try { - underlying remove key.asInstanceOf[A] match { - case None => null.asInstanceOf[B] - case Some(v) => v - } - } catch { - case ex: ClassCastException => null.asInstanceOf[B] - } - } - - case class JDictionaryWrapper[A, B](underlying: ju.Dictionary[A, B]) - extends mutable.AbstractMap[A, B] with mutable.Map[A, B] { - override def size: Int = underlying.size - - def get(k: A) = { - val v = underlying get k - if (v != null) Some(v) else None - } - - def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this } - def -=(key: A): this.type = { underlying remove key; this } - - override def put(k: A, v: B): Option[B] = { - val r = underlying.put(k, v) - if (r != null) Some(r) else None - } - - override def update(k: A, v: B) { underlying.put(k, v) } - - override def remove(k: A): Option[B] = { - val r = underlying remove k - if (r != null) Some(r) else None - } - - def iterator = enumerationAsScalaIterator(underlying.keys) map (k => (k, underlying get k)) - - override def clear() = underlying.clear() - } - - case class JPropertiesWrapper(underlying: ju.Properties) - extends mutable.AbstractMap[String, String] - with mutable.Map[String, String] - with mutable.MapLike[String, String, JPropertiesWrapper] { - - override def size = underlying.size - - def get(k: String) = { - val v = underlying get k - if (v != null) Some(v.asInstanceOf[String]) else None - } - - def +=(kv: (String, String)): this.type = { underlying.put(kv._1, kv._2); this } - def -=(key: String): this.type = { underlying remove key; this } - - override def put(k: String, v: String): Option[String] = { - val r = underlying.put(k, v) - if (r != null) Some(r.asInstanceOf[String]) else None - } - - override def update(k: String, v: String) { underlying.put(k, v) } - - override def remove(k: String): Option[String] = { - val r = underlying remove k - if (r != null) Some(r.asInstanceOf[String]) else None - } - - def iterator: Iterator[(String, String)] = new AbstractIterator[(String, String)] { - val ui = underlying.entrySet.iterator - def hasNext = ui.hasNext - def next() = { - val e = ui.next() - (e.getKey.asInstanceOf[String], e.getValue.asInstanceOf[String]) - } - } - - override def clear() = underlying.clear() - - override def empty = JPropertiesWrapper(new ju.Properties) - - def getProperty(key: String) = underlying.getProperty(key) - - def getProperty(key: String, defaultValue: String) = - underlying.getProperty(key, defaultValue) - - def setProperty(key: String, value: String) = - underlying.setProperty(key, value) - } } diff --git a/src/library/scala/collection/JavaConverters.scala b/src/library/scala/collection/JavaConverters.scala index d213e60112..07e8518cb0 100755 --- a/src/library/scala/collection/JavaConverters.scala +++ b/src/library/scala/collection/JavaConverters.scala @@ -8,6 +8,14 @@ package scala.collection +import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } +import convert._ + +// TODO: I cleaned all this documentation up in JavaConversions, but the +// documentation in here is basically the pre-cleaned-up version with minor +// additions. Would be nice to have in one place. + + /** A collection of decorators that allow to convert between * Scala and Java collections using `asScala` and `asJava` methods. * @@ -48,494 +56,48 @@ package scala.collection * @author Martin Odersky * @since 2.8.1 */ - -trait JavaConverters { - import java.{ lang => jl, util => ju } - import java.util.{ concurrent => juc } - import JavaConversions._ - - // TODO: I cleaned all this documentation up in JavaConversions, but the - // documentation in here is basically the pre-cleaned-up version with minor - // additions. Would be nice to have in one place. - - // Conversion decorator classes - - /** Generic class containing the `asJava` converter method */ - class AsJava[C](op: => C) { - /** Converts a Scala collection to the corresponding Java collection */ - def asJava: C = op - } - - /** Generic class containing the `asScala` converter method */ - class AsScala[C](op: => C) { - /** Converts a Java collection to the corresponding Scala collection */ - def asScala: C = op - } - - /** Generic class containing the `asJavaCollection` converter method */ - class AsJavaCollection[A](i: Iterable[A]) { - /** Converts a Scala `Iterable` to a Java `Collection` */ - def asJavaCollection: ju.Collection[A] = JavaConversions.asJavaCollection(i) - } - - /** Generic class containing the `asJavaEnumeration` converter method */ - class AsJavaEnumeration[A](i: Iterator[A]) { - /** Converts a Scala `Iterator` to a Java `Enumeration` */ - def asJavaEnumeration: ju.Enumeration[A] = JavaConversions.asJavaEnumeration(i) - } - - /** Generic class containing the `asJavaDictionary` converter method */ - class AsJavaDictionary[A, B](m : mutable.Map[A, B]) { - /** Converts a Scala `Map` to a Java `Dictionary` */ - def asJavaDictionary: ju.Dictionary[A, B] = JavaConversions.asJavaDictionary(m) - } - - // Scala => Java - - /** - * Adds an `asJava` method that implicitly converts a Scala `Iterator` to a - * Java `Iterator`. The returned Java `Iterator` is backed by the provided Scala - * `Iterator` and any side-effects of using it via the Java interface will - * be visible via the Scala interface and vice versa. - * - * If the Scala `Iterator` was previously obtained from an implicit or explicit - * call of `asIterator(java.util.Iterator)` then the original Java `Iterator` - * will be returned by the `asJava` method. - * - * @param i The `Iterator` to be converted. - * @return An object with an `asJava` method that returns a Java `Iterator` view of the argument. - */ - implicit def asJavaIteratorConverter[A](i : Iterator[A]): AsJava[ju.Iterator[A]] = - new AsJava(asJavaIterator(i)) - - /** - * Adds an `asJavaEnumeration` method that implicitly converts a Scala - * `Iterator` to a Java `Enumeration`. The returned Java `Enumeration` is - * backed by the provided Scala `Iterator` and any side-effects of using - * it via the Java interface will be visible via the Scala interface and - * vice versa. - * - * If the Scala `Iterator` was previously obtained from an implicit or - * explicit call of `asIterator(java.util.Enumeration)` then the - * original Java `Enumeration` will be returned. - * - * @param i The `Iterator` to be converted. - * @return An object with an `asJavaEnumeration` method that returns a Java - * `Enumeration` view of the argument. - */ - implicit def asJavaEnumerationConverter[A](i : Iterator[A]): AsJavaEnumeration[A] = - new AsJavaEnumeration(i) - - /** - * Adds an `asJava` method that implicitly converts a Scala `Iterable` to - * a Java `Iterable`. - * - * The returned Java `Iterable` is backed by the provided Scala `Iterable` - * and any side-effects of using it via the Java interface will be visible - * via the Scala interface and vice versa. - * - * If the Scala `Iterable` was previously obtained from an implicit or - * explicit call of `asIterable(java.lang.Iterable)` then the original - * Java `Iterable` will be returned. - * - * @param i The `Iterable` to be converted. - * @return An object with an `asJavaCollection` method that returns a Java - * `Iterable` view of the argument. - */ - implicit def asJavaIterableConverter[A](i : Iterable[A]): AsJava[jl.Iterable[A]] = - new AsJava(asJavaIterable(i)) - - /** - * Adds an `asJavaCollection` method that implicitly converts a Scala - * `Iterable` to an immutable Java `Collection`. - * - * If the Scala `Iterable` was previously obtained from an implicit or - * explicit call of `asSizedIterable(java.util.Collection)` then the - * original Java `Collection` will be returned. - * - * @param i The `SizedIterable` to be converted. - * @return An object with an `asJava` method that returns a Java - * `Collection` view of the argument. - */ - implicit def asJavaCollectionConverter[A](i : Iterable[A]): AsJavaCollection[A] = - new AsJavaCollection(i) - - /** - * Adds an `asJava` method that implicitly converts a Scala mutable `Buffer` - * to a Java `List`. - * - * The returned Java `List` is backed by the provided Scala `Buffer` and any - * side-effects of using it via the Java interface will be visible via the - * Scala interface and vice versa. - * - * If the Scala `Buffer` was previously obtained from an implicit or explicit - * call of `asBuffer(java.util.List)` then the original Java `List` will be - * returned. - * - * @param b The `Buffer` to be converted. - * @return An object with an `asJava` method that returns a Java `List` view - * of the argument. - */ - implicit def bufferAsJavaListConverter[A](b : mutable.Buffer[A]): AsJava[ju.List[A]] = - new AsJava(bufferAsJavaList(b)) - - /** - * Adds an `asJava` method that implicitly converts a Scala mutable `Seq` - * to a Java `List`. - * - * The returned Java `List` is backed by the provided Scala `Seq` and any - * side-effects of using it via the Java interface will be visible via the - * Scala interface and vice versa. - * - * If the Scala `Seq` was previously obtained from an implicit or explicit - * call of `asSeq(java.util.List)` then the original Java `List` will be - * returned. - * - * @param b The `Seq` to be converted. - * @return An object with an `asJava` method that returns a Java `List` - * view of the argument. - */ - implicit def mutableSeqAsJavaListConverter[A](b : mutable.Seq[A]): AsJava[ju.List[A]] = - new AsJava(mutableSeqAsJavaList(b)) - - /** - * Adds an `asJava` method that implicitly converts a Scala `Seq` to a - * Java `List`. - * - * The returned Java `List` is backed by the provided Scala `Seq` and any - * side-effects of using it via the Java interface will be visible via the - * Scala interface and vice versa. - * - * If the Scala `Seq` was previously obtained from an implicit or explicit - * call of `asSeq(java.util.List)` then the original Java `List` will be - * returned. - * - * @param b The `Seq` to be converted. - * @return An object with an `asJava` method that returns a Java `List` - * view of the argument. - */ - implicit def seqAsJavaListConverter[A](b : Seq[A]): AsJava[ju.List[A]] = - new AsJava(seqAsJavaList(b)) +object JavaConverters extends DecorateAsJava with DecorateAsScala { + @deprecated("Don't access these decorators directly.", "2.10.0") + type AsJava[A] = Decorators.AsJava[A] + @deprecated("Don't access these decorators directly.", "2.10.0") + type AsScala[A] = Decorators.AsScala[A] + @deprecated("Don't access these decorators directly.", "2.10.0") + type AsJavaCollection[A] = Decorators.AsJavaCollection[A] + @deprecated("Don't access these decorators directly.", "2.10.0") + type AsJavaEnumeration[A] = Decorators.AsJavaEnumeration[A] + @deprecated("Don't access these decorators directly.", "2.10.0") + type AsJavaDictionary[A, B] = Decorators.AsJavaDictionary[A, B] @deprecated("Use bufferAsJavaListConverter instead", "2.9.0") def asJavaListConverter[A](b : mutable.Buffer[A]): AsJava[ju.List[A]] = bufferAsJavaListConverter(b) + @deprecated("Use mutableSeqAsJavaListConverter instead", "2.9.0") def asJavaListConverter[A](b : mutable.Seq[A]): AsJava[ju.List[A]] = mutableSeqAsJavaListConverter(b) + @deprecated("Use seqAsJavaListConverter instead", "2.9.0") def asJavaListConverter[A](b : Seq[A]): AsJava[ju.List[A]] = seqAsJavaListConverter(b) - /** - * Adds an `asJava` method that implicitly converts a Scala mutable `Set`> - * to a Java `Set`. - * - * The returned Java `Set` is backed by the provided Scala `Set` and any - * side-effects of using it via the Java interface will be visible via - * the Scala interface and vice versa. - * - * If the Scala `Set` was previously obtained from an implicit or explicit - * call of `asSet(java.util.Set)` then the original Java `Set` will be - * returned. - * - * @param s The `Set` to be converted. - * @return An object with an `asJava` method that returns a Java `Set` view - * of the argument. - */ - implicit def mutableSetAsJavaSetConverter[A](s : mutable.Set[A]): AsJava[ju.Set[A]] = - new AsJava(mutableSetAsJavaSet(s)) - @deprecated("Use mutableSetAsJavaSetConverter instead", "2.9.0") def asJavaSetConverter[A](s : mutable.Set[A]): AsJava[ju.Set[A]] = mutableSetAsJavaSetConverter(s) - /** - * Adds an `asJava` method that implicitly converts a Scala `Set` to a - * Java `Set`. - * - * The returned Java `Set` is backed by the provided Scala `Set` and any - * side-effects of using it via the Java interface will be visible via - * the Scala interface and vice versa. - * - * If the Scala `Set` was previously obtained from an implicit or explicit - * call of `asSet(java.util.Set)` then the original Java `Set` will be - * returned. - * - * @param s The `Set` to be converted. - * @return An object with an `asJava` method that returns a Java `Set` view - * of the argument. - */ - implicit def setAsJavaSetConverter[A](s : Set[A]): AsJava[ju.Set[A]] = - new AsJava(setAsJavaSet(s)) - @deprecated("Use setAsJavaSetConverter instead", "2.9.0") def asJavaSetConverter[A](s : Set[A]): AsJava[ju.Set[A]] = setAsJavaSetConverter(s) - /** - * Adds an `asJava` method that implicitly converts a Scala mutable `Map` - * to a Java `Map`. - * - * The returned Java `Map` is backed by the provided Scala `Map` and any - * side-effects of using it via the Java interface will be visible via the - * Scala interface and vice versa. - * - * If the Scala `Map` was previously obtained from an implicit or explicit - * call of `asMap(java.util.Map)` then the original Java `Map` will be - * returned. - * - * @param m The `Map` to be converted. - * @return An object with an `asJava` method that returns a Java `Map` view - * of the argument. - */ - implicit def mutableMapAsJavaMapConverter[A, B](m : mutable.Map[A, B]): AsJava[ju.Map[A, B]] = - new AsJava(mutableMapAsJavaMap(m)) - @deprecated("use mutableMapAsJavaMapConverter instead", "2.9.0") def asJavaMapConverter[A, B](m : mutable.Map[A, B]): AsJava[ju.Map[A, B]] = mutableMapAsJavaMapConverter(m) - /** - * Adds an `asJavaDictionary` method that implicitly converts a Scala - * mutable `Map` to a Java `Dictionary`. - * - * The returned Java `Dictionary` is backed by the provided Scala - * `Dictionary` and any side-effects of using it via the Java interface - * will be visible via the Scala interface and vice versa. - * - * If the Scala `Dictionary` was previously obtained from an implicit or - * explicit call of `asMap(java.util.Dictionary)` then the original - * Java `Dictionary` will be returned. - * - * @param m The `Map` to be converted. - * @return An object with an `asJavaDictionary` method that returns a - * Java `Dictionary` view of the argument. - */ - implicit def asJavaDictionaryConverter[A, B](m : mutable.Map[A, B]): AsJavaDictionary[A, B] = - new AsJavaDictionary(m) - - /** - * Adds an `asJava` method that implicitly converts a Scala `Map` to - * a Java `Map`. - * - * The returned Java `Map` is backed by the provided Scala `Map` and any - * side-effects of using it via the Java interface will be visible via - * the Scala interface and vice versa. - * - * If the Scala `Map` was previously obtained from an implicit or explicit - * call of `asMap(java.util.Map)` then the original Java `Map` will be - * returned. - * - * @param m The `Map` to be converted. - * @return An object with an `asJava` method that returns a Java `Map` view - * of the argument. - */ - implicit def mapAsJavaMapConverter[A, B](m : Map[A, B]): AsJava[ju.Map[A, B]] = - new AsJava(mapAsJavaMap(m)) - @deprecated("Use mapAsJavaMapConverter instead", "2.9.0") def asJavaMapConverter[A, B](m : Map[A, B]): AsJava[ju.Map[A, B]] = mapAsJavaMapConverter(m) - /** - * Adds an `asJava` method that implicitly converts a Scala mutable - * `ConcurrentMap` to a Java `ConcurrentMap`. - * - * The returned Java `ConcurrentMap` is backed by the provided Scala - * `ConcurrentMap` and any side-effects of using it via the Java interface - * will be visible via the Scala interface and vice versa. - * - * If the Scala `ConcurrentMap` was previously obtained from an implicit or - * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)` - * then the original Java `ConcurrentMap` will be returned. - * - * @param m The `ConcurrentMap` to be converted. - * @return An object with an `asJava` method that returns a Java - * `ConcurrentMap` view of the argument. - */ - implicit def asJavaConcurrentMapConverter[A, B](m: mutable.ConcurrentMap[A, B]): AsJava[juc.ConcurrentMap[A, B]] = - new AsJava(asJavaConcurrentMap(m)) - - /** - * Adds an `asScala` method that implicitly converts a Java `Iterator` to - * a Scala `Iterator`. - * - * The returned Scala `Iterator` is backed by the provided Java `Iterator` - * and any side-effects of using it via the Scala interface will be visible - * via the Java interface and vice versa. - * - * If the Java `Iterator` was previously obtained from an implicit or - * explicit call of `asIterator(scala.collection.Iterator)` then the - * original Scala `Iterator` will be returned. - * - * @param i The `Iterator` to be converted. - * @return An object with an `asScala` method that returns a Scala - * `Iterator` view of the argument. - */ - implicit def asScalaIteratorConverter[A](i : ju.Iterator[A]): AsScala[Iterator[A]] = - new AsScala(asScalaIterator(i)) - - /** - * Adds an `asScala` method that implicitly converts a Java `Enumeration` - * to a Scala `Iterator`. - * - * The returned Scala `Iterator` is backed by the provided Java - * `Enumeration` and any side-effects of using it via the Scala interface - * will be visible via the Java interface and vice versa. - * - * If the Java `Enumeration` was previously obtained from an implicit or - * explicit call of `asEnumeration(scala.collection.Iterator)` then the - * original Scala `Iterator` will be returned. - * - * @param i The `Enumeration` to be converted. - * @return An object with an `asScala` method that returns a Scala - * `Iterator` view of the argument. - */ - implicit def enumerationAsScalaIteratorConverter[A](i : ju.Enumeration[A]): AsScala[Iterator[A]] = - new AsScala(enumerationAsScalaIterator(i)) - - /** - * Adds an `asScala` method that implicitly converts a Java `Iterable` to - * a Scala `Iterable`. - * - * The returned Scala `Iterable` is backed by the provided Java `Iterable` - * and any side-effects of using it via the Scala interface will be visible - * via the Java interface and vice versa. - * - * If the Java `Iterable` was previously obtained from an implicit or - * explicit call of `asIterable(scala.collection.Iterable)` then the original - * Scala `Iterable` will be returned. - * - * @param i The `Iterable` to be converted. - * @return An object with an `asScala` method that returns a Scala `Iterable` - * view of the argument. - */ - implicit def iterableAsScalaIterableConverter[A](i : jl.Iterable[A]): AsScala[Iterable[A]] = - new AsScala(iterableAsScalaIterable(i)) - @deprecated("Use iterableAsScalaIterableConverter instead", "2.9.0") def asScalaIterableConverter[A](i : jl.Iterable[A]): AsScala[Iterable[A]] = iterableAsScalaIterableConverter(i) - /** - * Adds an `asScala` method that implicitly converts a Java `Collection` to - * an Scala `Iterable`. - * - * If the Java `Collection` was previously obtained from an implicit or - * explicit call of `asCollection(scala.collection.SizedIterable)` then - * the original Scala `SizedIterable` will be returned. - * - * @param i The `Collection` to be converted. - * @return An object with an `asScala` method that returns a Scala - * `SizedIterable` view of the argument. - */ - implicit def collectionAsScalaIterableConverter[A](i : ju.Collection[A]): AsScala[Iterable[A]] = - new AsScala(collectionAsScalaIterable(i)) - @deprecated("Use collectionAsScalaIterableConverter instead", "2.9.0") def asScalaIterableConverter[A](i : ju.Collection[A]): AsScala[Iterable[A]] = collectionAsScalaIterableConverter(i) - /** - * Adds an `asScala` method that implicitly converts a Java `List` to a - * Scala mutable `Buffer`. - * - * The returned Scala `Buffer` is backed by the provided Java `List` and - * any side-effects of using it via the Scala interface will be visible via - * the Java interface and vice versa. - * - * If the Java `List` was previously obtained from an implicit or explicit - * call of `asList(scala.collection.mutable.Buffer)` then the original - * Scala `Buffer` will be returned. - * - * @param l The `List` to be converted. - * @return An object with an `asScala` method that returns a Scala mutable - * `Buffer` view of the argument. - */ - implicit def asScalaBufferConverter[A](l : ju.List[A]): AsScala[mutable.Buffer[A]] = - new AsScala(asScalaBuffer(l)) - - /** - * Adds an `asScala` method that implicitly converts a Java `Set` to a - * Scala mutable `Set`. - * - * The returned Scala `Set` is backed by the provided Java `Set` and any - * side-effects of using it via the Scala interface will be visible via - * the Java interface and vice versa. - * - * If the Java `Set` was previously obtained from an implicit or explicit - * call of `asSet(scala.collection.mutable.Set)` then the original - * Scala `Set` will be returned. - * - * @param s The `Set` to be converted. - * @return An object with an `asScala` method that returns a Scala mutable - * `Set` view of the argument. - */ - implicit def asScalaSetConverter[A](s : ju.Set[A]): AsScala[mutable.Set[A]] = - new AsScala(asScalaSet(s)) - - /** - * Adds an `asScala` method that implicitly converts a Java `Map` to a Scala - * mutable `Map`. The returned Scala `Map` is backed by the provided Java - * `Map` and any side-effects of using it via the Scala interface will - * be visible via the Java interface and vice versa. - * - * If the Java `Map` was previously obtained from an implicit or explicit - * call of `asMap(scala.collection.mutable.Map)` then the original - * Scala `Map` will be returned. - * - * @param m The `Map` to be converted. - * @return An object with an `asScala` method that returns a Scala mutable - * `Map` view of the argument. - */ - implicit def mapAsScalaMapConverter[A, B](m : ju.Map[A, B]): AsScala[mutable.Map[A, B]] = - new AsScala(mapAsScalaMap(m)) - @deprecated("Use mapAsScalaMapConverter instead", "2.9.0") def asScalaMapConverter[A, B](m : ju.Map[A, B]): AsScala[mutable.Map[A, B]] = mapAsScalaMapConverter(m) - /** - * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap` - * to a Scala mutable `ConcurrentMap`. The returned Scala `ConcurrentMap` is - * backed by the provided Java `ConcurrentMap` and any side-effects of using - * it via the Scala interface will be visible via the Java interface and - * vice versa. - * - * If the Java `ConcurrentMap` was previously obtained from an implicit or - * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)` - * then the original Scala `ConcurrentMap` will be returned. - * - * @param m The `ConcurrentMap` to be converted. - * @return An object with an `asScala` method that returns a Scala mutable - * `ConcurrentMap` view of the argument. - */ - implicit def asScalaConcurrentMapConverter[A, B](m: juc.ConcurrentMap[A, B]): AsScala[mutable.ConcurrentMap[A, B]] = - new AsScala(asScalaConcurrentMap(m)) - - /** - * Adds an `asScala` method that implicitly converts a Java `Dictionary` - * to a Scala mutable `Map[String, String]`. The returned Scala - * `Map[String, String]` is backed by the provided Java `Dictionary` and - * any side-effects of using it via the Scala interface will be visible via - * the Java interface and vice versa. - * - * @param m The `Dictionary` to be converted. - * @return An object with an `asScala` method that returns a Scala mutable - * `Map[String, String]` view of the argument. - */ - implicit def dictionaryAsScalaMapConverter[A, B](p: ju.Dictionary[A, B]): AsScala[mutable.Map[A, B]] = - new AsScala(dictionaryAsScalaMap(p)) - - /** - * Adds an `asScala` method that implicitly converts a Java `Properties` - * to a Scala mutable `Map[String, String]`. The returned Scala - * `Map[String, String]` is backed by the provided Java `Properties` and - * any side-effects of using it via the Scala interface will be visible via - * the Java interface and vice versa. - * - * @param m The `Properties` to be converted. - * @return An object with an `asScala` method that returns a Scala mutable - * `Map[String, String]` view of the argument. - */ - implicit def propertiesAsScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] = - new AsScala(propertiesAsScalaMap(p)) - @deprecated("Use propertiesAsScalaMapConverter instead", "2.9.0") - def asScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] = - propertiesAsScalaMapConverter(p) - -} - -object JavaConverters extends JavaConverters
\ No newline at end of file + def asScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] = propertiesAsScalaMapConverter(p) +}
\ No newline at end of file diff --git a/src/library/scala/collection/convert/DecorateAsJava.scala b/src/library/scala/collection/convert/DecorateAsJava.scala new file mode 100644 index 0000000000..76837d937c --- /dev/null +++ b/src/library/scala/collection/convert/DecorateAsJava.scala @@ -0,0 +1,296 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.collection +package convert + +import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } +import Decorators._ +import WrapAsJava._ + +/** A collection of decorators that allow to convert between + * Scala and Java collections using `asScala` and `asJava` methods. + * + * The following conversions are supported via `asJava`, `asScala` + * + * - `scala.collection.Iterable` <=> `java.lang.Iterable` + * - `scala.collection.Iterator` <=> `java.util.Iterator` + * - `scala.collection.mutable.Buffer` <=> `java.util.List` + * - `scala.collection.mutable.Set` <=> `java.util.Set` + * - `scala.collection.mutable.Map` <=> `java.util.Map` + * - `scala.collection.mutable.ConcurrentMap` <=> `java.util.concurrent.ConcurrentMap` + * + * In all cases, converting from a source type to a target type and back + * again will return the original source object, e.g. + * {{{ + * import scala.collection.JavaConverters._ + * + * val sl = new scala.collection.mutable.ListBuffer[Int] + * val jl : java.util.List[Int] = sl.asJava + * val sl2 : scala.collection.mutable.Buffer[Int] = jl.asScala + * assert(sl eq sl2) + * }}} + * The following conversions also are supported, but the + * direction Scala to Java is done my a more specifically named method: + * `asJavaCollection`, `asJavaEnumeration`, `asJavaDictionary`. + * + * - `scala.collection.Iterable` <=> `java.util.Collection` + * - `scala.collection.Iterator` <=> `java.util.Enumeration` + * - `scala.collection.mutable.Map` <=> `java.util.Dictionary` + * + * In addition, the following one way conversions are provided via `asJava`: + * + * - `scala.collection.Seq` => `java.util.List` + * - `scala.collection.mutable.Seq` => `java.util.List` + * - `scala.collection.Set` => `java.util.Set` + * - `scala.collection.Map` => `java.util.Map` + * + * @author Martin Odersky + * @since 2.8.1 + */ + +trait DecorateAsJava { + /** + * Adds an `asJava` method that implicitly converts a Scala `Iterator` to a + * Java `Iterator`. The returned Java `Iterator` is backed by the provided Scala + * `Iterator` and any side-effects of using it via the Java interface will + * be visible via the Scala interface and vice versa. + * + * If the Scala `Iterator` was previously obtained from an implicit or explicit + * call of `asIterator(java.util.Iterator)` then the original Java `Iterator` + * will be returned by the `asJava` method. + * + * @param i The `Iterator` to be converted. + * @return An object with an `asJava` method that returns a Java `Iterator` view of the argument. + */ + implicit def asJavaIteratorConverter[A](i : Iterator[A]): AsJava[ju.Iterator[A]] = + new AsJava(asJavaIterator(i)) + + /** + * Adds an `asJavaEnumeration` method that implicitly converts a Scala + * `Iterator` to a Java `Enumeration`. The returned Java `Enumeration` is + * backed by the provided Scala `Iterator` and any side-effects of using + * it via the Java interface will be visible via the Scala interface and + * vice versa. + * + * If the Scala `Iterator` was previously obtained from an implicit or + * explicit call of `asIterator(java.util.Enumeration)` then the + * original Java `Enumeration` will be returned. + * + * @param i The `Iterator` to be converted. + * @return An object with an `asJavaEnumeration` method that returns a Java + * `Enumeration` view of the argument. + */ + implicit def asJavaEnumerationConverter[A](i : Iterator[A]): AsJavaEnumeration[A] = + new AsJavaEnumeration(i) + + /** + * Adds an `asJava` method that implicitly converts a Scala `Iterable` to + * a Java `Iterable`. + * + * The returned Java `Iterable` is backed by the provided Scala `Iterable` + * and any side-effects of using it via the Java interface will be visible + * via the Scala interface and vice versa. + * + * If the Scala `Iterable` was previously obtained from an implicit or + * explicit call of `asIterable(java.lang.Iterable)` then the original + * Java `Iterable` will be returned. + * + * @param i The `Iterable` to be converted. + * @return An object with an `asJavaCollection` method that returns a Java + * `Iterable` view of the argument. + */ + implicit def asJavaIterableConverter[A](i : Iterable[A]): AsJava[jl.Iterable[A]] = + new AsJava(asJavaIterable(i)) + + /** + * Adds an `asJavaCollection` method that implicitly converts a Scala + * `Iterable` to an immutable Java `Collection`. + * + * If the Scala `Iterable` was previously obtained from an implicit or + * explicit call of `asSizedIterable(java.util.Collection)` then the + * original Java `Collection` will be returned. + * + * @param i The `SizedIterable` to be converted. + * @return An object with an `asJava` method that returns a Java + * `Collection` view of the argument. + */ + implicit def asJavaCollectionConverter[A](i : Iterable[A]): AsJavaCollection[A] = + new AsJavaCollection(i) + + /** + * Adds an `asJava` method that implicitly converts a Scala mutable `Buffer` + * to a Java `List`. + * + * The returned Java `List` is backed by the provided Scala `Buffer` and any + * side-effects of using it via the Java interface will be visible via the + * Scala interface and vice versa. + * + * If the Scala `Buffer` was previously obtained from an implicit or explicit + * call of `asBuffer(java.util.List)` then the original Java `List` will be + * returned. + * + * @param b The `Buffer` to be converted. + * @return An object with an `asJava` method that returns a Java `List` view + * of the argument. + */ + implicit def bufferAsJavaListConverter[A](b : mutable.Buffer[A]): AsJava[ju.List[A]] = + new AsJava(bufferAsJavaList(b)) + + /** + * Adds an `asJava` method that implicitly converts a Scala mutable `Seq` + * to a Java `List`. + * + * The returned Java `List` is backed by the provided Scala `Seq` and any + * side-effects of using it via the Java interface will be visible via the + * Scala interface and vice versa. + * + * If the Scala `Seq` was previously obtained from an implicit or explicit + * call of `asSeq(java.util.List)` then the original Java `List` will be + * returned. + * + * @param b The `Seq` to be converted. + * @return An object with an `asJava` method that returns a Java `List` + * view of the argument. + */ + implicit def mutableSeqAsJavaListConverter[A](b : mutable.Seq[A]): AsJava[ju.List[A]] = + new AsJava(mutableSeqAsJavaList(b)) + + /** + * Adds an `asJava` method that implicitly converts a Scala `Seq` to a + * Java `List`. + * + * The returned Java `List` is backed by the provided Scala `Seq` and any + * side-effects of using it via the Java interface will be visible via the + * Scala interface and vice versa. + * + * If the Scala `Seq` was previously obtained from an implicit or explicit + * call of `asSeq(java.util.List)` then the original Java `List` will be + * returned. + * + * @param b The `Seq` to be converted. + * @return An object with an `asJava` method that returns a Java `List` + * view of the argument. + */ + implicit def seqAsJavaListConverter[A](b : Seq[A]): AsJava[ju.List[A]] = + new AsJava(seqAsJavaList(b)) + + /** + * Adds an `asJava` method that implicitly converts a Scala mutable `Set`> + * to a Java `Set`. + * + * The returned Java `Set` is backed by the provided Scala `Set` and any + * side-effects of using it via the Java interface will be visible via + * the Scala interface and vice versa. + * + * If the Scala `Set` was previously obtained from an implicit or explicit + * call of `asSet(java.util.Set)` then the original Java `Set` will be + * returned. + * + * @param s The `Set` to be converted. + * @return An object with an `asJava` method that returns a Java `Set` view + * of the argument. + */ + implicit def mutableSetAsJavaSetConverter[A](s : mutable.Set[A]): AsJava[ju.Set[A]] = + new AsJava(mutableSetAsJavaSet(s)) + + /** + * Adds an `asJava` method that implicitly converts a Scala `Set` to a + * Java `Set`. + * + * The returned Java `Set` is backed by the provided Scala `Set` and any + * side-effects of using it via the Java interface will be visible via + * the Scala interface and vice versa. + * + * If the Scala `Set` was previously obtained from an implicit or explicit + * call of `asSet(java.util.Set)` then the original Java `Set` will be + * returned. + * + * @param s The `Set` to be converted. + * @return An object with an `asJava` method that returns a Java `Set` view + * of the argument. + */ + implicit def setAsJavaSetConverter[A](s : Set[A]): AsJava[ju.Set[A]] = + new AsJava(setAsJavaSet(s)) + + /** + * Adds an `asJava` method that implicitly converts a Scala mutable `Map` + * to a Java `Map`. + * + * The returned Java `Map` is backed by the provided Scala `Map` and any + * side-effects of using it via the Java interface will be visible via the + * Scala interface and vice versa. + * + * If the Scala `Map` was previously obtained from an implicit or explicit + * call of `asMap(java.util.Map)` then the original Java `Map` will be + * returned. + * + * @param m The `Map` to be converted. + * @return An object with an `asJava` method that returns a Java `Map` view + * of the argument. + */ + implicit def mutableMapAsJavaMapConverter[A, B](m : mutable.Map[A, B]): AsJava[ju.Map[A, B]] = + new AsJava(mutableMapAsJavaMap(m)) + + /** + * Adds an `asJavaDictionary` method that implicitly converts a Scala + * mutable `Map` to a Java `Dictionary`. + * + * The returned Java `Dictionary` is backed by the provided Scala + * `Dictionary` and any side-effects of using it via the Java interface + * will be visible via the Scala interface and vice versa. + * + * If the Scala `Dictionary` was previously obtained from an implicit or + * explicit call of `asMap(java.util.Dictionary)` then the original + * Java `Dictionary` will be returned. + * + * @param m The `Map` to be converted. + * @return An object with an `asJavaDictionary` method that returns a + * Java `Dictionary` view of the argument. + */ + implicit def asJavaDictionaryConverter[A, B](m : mutable.Map[A, B]): AsJavaDictionary[A, B] = + new AsJavaDictionary(m) + + /** + * Adds an `asJava` method that implicitly converts a Scala `Map` to + * a Java `Map`. + * + * The returned Java `Map` is backed by the provided Scala `Map` and any + * side-effects of using it via the Java interface will be visible via + * the Scala interface and vice versa. + * + * If the Scala `Map` was previously obtained from an implicit or explicit + * call of `asMap(java.util.Map)` then the original Java `Map` will be + * returned. + * + * @param m The `Map` to be converted. + * @return An object with an `asJava` method that returns a Java `Map` view + * of the argument. + */ + implicit def mapAsJavaMapConverter[A, B](m : Map[A, B]): AsJava[ju.Map[A, B]] = + new AsJava(mapAsJavaMap(m)) + + /** + * Adds an `asJava` method that implicitly converts a Scala mutable + * `ConcurrentMap` to a Java `ConcurrentMap`. + * + * The returned Java `ConcurrentMap` is backed by the provided Scala + * `ConcurrentMap` and any side-effects of using it via the Java interface + * will be visible via the Scala interface and vice versa. + * + * If the Scala `ConcurrentMap` was previously obtained from an implicit or + * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)` + * then the original Java `ConcurrentMap` will be returned. + * + * @param m The `ConcurrentMap` to be converted. + * @return An object with an `asJava` method that returns a Java + * `ConcurrentMap` view of the argument. + */ + implicit def asJavaConcurrentMapConverter[A, B](m: mutable.ConcurrentMap[A, B]): AsJava[juc.ConcurrentMap[A, B]] = + new AsJava(asJavaConcurrentMap(m)) +} diff --git a/src/library/scala/collection/convert/DecorateAsScala.scala b/src/library/scala/collection/convert/DecorateAsScala.scala new file mode 100644 index 0000000000..bb14228e67 --- /dev/null +++ b/src/library/scala/collection/convert/DecorateAsScala.scala @@ -0,0 +1,189 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.collection +package convert + +import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } +import Decorators._ +import WrapAsScala._ + +trait DecorateAsScala { + /** + * Adds an `asScala` method that implicitly converts a Java `Iterator` to + * a Scala `Iterator`. + * + * The returned Scala `Iterator` is backed by the provided Java `Iterator` + * and any side-effects of using it via the Scala interface will be visible + * via the Java interface and vice versa. + * + * If the Java `Iterator` was previously obtained from an implicit or + * explicit call of `asIterator(scala.collection.Iterator)` then the + * original Scala `Iterator` will be returned. + * + * @param i The `Iterator` to be converted. + * @return An object with an `asScala` method that returns a Scala + * `Iterator` view of the argument. + */ + implicit def asScalaIteratorConverter[A](i : ju.Iterator[A]): AsScala[Iterator[A]] = + new AsScala(asScalaIterator(i)) + + /** + * Adds an `asScala` method that implicitly converts a Java `Enumeration` + * to a Scala `Iterator`. + * + * The returned Scala `Iterator` is backed by the provided Java + * `Enumeration` and any side-effects of using it via the Scala interface + * will be visible via the Java interface and vice versa. + * + * If the Java `Enumeration` was previously obtained from an implicit or + * explicit call of `asEnumeration(scala.collection.Iterator)` then the + * original Scala `Iterator` will be returned. + * + * @param i The `Enumeration` to be converted. + * @return An object with an `asScala` method that returns a Scala + * `Iterator` view of the argument. + */ + implicit def enumerationAsScalaIteratorConverter[A](i : ju.Enumeration[A]): AsScala[Iterator[A]] = + new AsScala(enumerationAsScalaIterator(i)) + + /** + * Adds an `asScala` method that implicitly converts a Java `Iterable` to + * a Scala `Iterable`. + * + * The returned Scala `Iterable` is backed by the provided Java `Iterable` + * and any side-effects of using it via the Scala interface will be visible + * via the Java interface and vice versa. + * + * If the Java `Iterable` was previously obtained from an implicit or + * explicit call of `asIterable(scala.collection.Iterable)` then the original + * Scala `Iterable` will be returned. + * + * @param i The `Iterable` to be converted. + * @return An object with an `asScala` method that returns a Scala `Iterable` + * view of the argument. + */ + implicit def iterableAsScalaIterableConverter[A](i : jl.Iterable[A]): AsScala[Iterable[A]] = + new AsScala(iterableAsScalaIterable(i)) + + /** + * Adds an `asScala` method that implicitly converts a Java `Collection` to + * an Scala `Iterable`. + * + * If the Java `Collection` was previously obtained from an implicit or + * explicit call of `asCollection(scala.collection.SizedIterable)` then + * the original Scala `SizedIterable` will be returned. + * + * @param i The `Collection` to be converted. + * @return An object with an `asScala` method that returns a Scala + * `SizedIterable` view of the argument. + */ + implicit def collectionAsScalaIterableConverter[A](i : ju.Collection[A]): AsScala[Iterable[A]] = + new AsScala(collectionAsScalaIterable(i)) + + /** + * Adds an `asScala` method that implicitly converts a Java `List` to a + * Scala mutable `Buffer`. + * + * The returned Scala `Buffer` is backed by the provided Java `List` and + * any side-effects of using it via the Scala interface will be visible via + * the Java interface and vice versa. + * + * If the Java `List` was previously obtained from an implicit or explicit + * call of `asList(scala.collection.mutable.Buffer)` then the original + * Scala `Buffer` will be returned. + * + * @param l The `List` to be converted. + * @return An object with an `asScala` method that returns a Scala mutable + * `Buffer` view of the argument. + */ + implicit def asScalaBufferConverter[A](l : ju.List[A]): AsScala[mutable.Buffer[A]] = + new AsScala(asScalaBuffer(l)) + + /** + * Adds an `asScala` method that implicitly converts a Java `Set` to a + * Scala mutable `Set`. + * + * The returned Scala `Set` is backed by the provided Java `Set` and any + * side-effects of using it via the Scala interface will be visible via + * the Java interface and vice versa. + * + * If the Java `Set` was previously obtained from an implicit or explicit + * call of `asSet(scala.collection.mutable.Set)` then the original + * Scala `Set` will be returned. + * + * @param s The `Set` to be converted. + * @return An object with an `asScala` method that returns a Scala mutable + * `Set` view of the argument. + */ + implicit def asScalaSetConverter[A](s : ju.Set[A]): AsScala[mutable.Set[A]] = + new AsScala(asScalaSet(s)) + + /** + * Adds an `asScala` method that implicitly converts a Java `Map` to a Scala + * mutable `Map`. The returned Scala `Map` is backed by the provided Java + * `Map` and any side-effects of using it via the Scala interface will + * be visible via the Java interface and vice versa. + * + * If the Java `Map` was previously obtained from an implicit or explicit + * call of `asMap(scala.collection.mutable.Map)` then the original + * Scala `Map` will be returned. + * + * @param m The `Map` to be converted. + * @return An object with an `asScala` method that returns a Scala mutable + * `Map` view of the argument. + */ + implicit def mapAsScalaMapConverter[A, B](m : ju.Map[A, B]): AsScala[mutable.Map[A, B]] = + new AsScala(mapAsScalaMap(m)) + + /** + * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap` + * to a Scala mutable `ConcurrentMap`. The returned Scala `ConcurrentMap` is + * backed by the provided Java `ConcurrentMap` and any side-effects of using + * it via the Scala interface will be visible via the Java interface and + * vice versa. + * + * If the Java `ConcurrentMap` was previously obtained from an implicit or + * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)` + * then the original Scala `ConcurrentMap` will be returned. + * + * @param m The `ConcurrentMap` to be converted. + * @return An object with an `asScala` method that returns a Scala mutable + * `ConcurrentMap` view of the argument. + */ + implicit def asScalaConcurrentMapConverter[A, B](m: juc.ConcurrentMap[A, B]): AsScala[mutable.ConcurrentMap[A, B]] = + new AsScala(asScalaConcurrentMap(m)) + + /** + * Adds an `asScala` method that implicitly converts a Java `Dictionary` + * to a Scala mutable `Map[String, String]`. The returned Scala + * `Map[String, String]` is backed by the provided Java `Dictionary` and + * any side-effects of using it via the Scala interface will be visible via + * the Java interface and vice versa. + * + * @param m The `Dictionary` to be converted. + * @return An object with an `asScala` method that returns a Scala mutable + * `Map[String, String]` view of the argument. + */ + implicit def dictionaryAsScalaMapConverter[A, B](p: ju.Dictionary[A, B]): AsScala[mutable.Map[A, B]] = + new AsScala(dictionaryAsScalaMap(p)) + + /** + * Adds an `asScala` method that implicitly converts a Java `Properties` + * to a Scala mutable `Map[String, String]`. The returned Scala + * `Map[String, String]` is backed by the provided Java `Properties` and + * any side-effects of using it via the Scala interface will be visible via + * the Java interface and vice versa. + * + * @param m The `Properties` to be converted. + * @return An object with an `asScala` method that returns a Scala mutable + * `Map[String, String]` view of the argument. + */ + implicit def propertiesAsScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] = + new AsScala(propertiesAsScalaMap(p)) +} diff --git a/src/library/scala/collection/convert/Decorators.scala b/src/library/scala/collection/convert/Decorators.scala new file mode 100644 index 0000000000..3bdd9a0f1c --- /dev/null +++ b/src/library/scala/collection/convert/Decorators.scala @@ -0,0 +1,46 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.collection +package convert + +import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } + +private[collection] trait Decorators { + /** Generic class containing the `asJava` converter method */ + class AsJava[A](op: => A) { + /** Converts a Scala collection to the corresponding Java collection */ + def asJava: A = op + } + + /** Generic class containing the `asScala` converter method */ + class AsScala[A](op: => A) { + /** Converts a Java collection to the corresponding Scala collection */ + def asScala: A = op + } + + /** Generic class containing the `asJavaCollection` converter method */ + class AsJavaCollection[A](i: Iterable[A]) { + /** Converts a Scala `Iterable` to a Java `Collection` */ + def asJavaCollection: ju.Collection[A] = JavaConversions.asJavaCollection(i) + } + + /** Generic class containing the `asJavaEnumeration` converter method */ + class AsJavaEnumeration[A](i: Iterator[A]) { + /** Converts a Scala `Iterator` to a Java `Enumeration` */ + def asJavaEnumeration: ju.Enumeration[A] = JavaConversions.asJavaEnumeration(i) + } + + /** Generic class containing the `asJavaDictionary` converter method */ + class AsJavaDictionary[A, B](m : mutable.Map[A, B]) { + /** Converts a Scala `Map` to a Java `Dictionary` */ + def asJavaDictionary: ju.Dictionary[A, B] = JavaConversions.asJavaDictionary(m) + } +} + +private[collection] object Decorators extends Decorators diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala new file mode 100644 index 0000000000..6274518d1a --- /dev/null +++ b/src/library/scala/collection/convert/WrapAsJava.scala @@ -0,0 +1,256 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.collection +package convert + +import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } +import Wrappers._ + +trait WrapAsJava { + /** + * Implicitly converts a Scala Iterator to a Java Iterator. + * The returned Java Iterator is backed by the provided Scala + * Iterator and any side-effects of using it via the Java interface will + * be visible via the Scala interface and vice versa. + * + * If the Scala Iterator was previously obtained from an implicit or + * explicit call of `asIterator(java.util.Iterator)` then the original + * Java Iterator will be returned. + * + * @param i The Iterator to be converted. + * @return A Java Iterator view of the argument. + */ + implicit def asJavaIterator[A](it: Iterator[A]): ju.Iterator[A] = it match { + case JIteratorWrapper(wrapped) => wrapped.asInstanceOf[ju.Iterator[A]] + case _ => IteratorWrapper(it) + } + + /** + * Implicitly converts a Scala Iterator to a Java Enumeration. + * The returned Java Enumeration is backed by the provided Scala + * Iterator and any side-effects of using it via the Java interface will + * be visible via the Scala interface and vice versa. + * + * If the Scala Iterator was previously obtained from an implicit or + * explicit call of `asIterator(java.util.Enumeration)` then the + * original Java Enumeration will be returned. + * + * @param i The Iterator to be converted. + * @return A Java Enumeration view of the argument. + */ + implicit def asJavaEnumeration[A](it: Iterator[A]): ju.Enumeration[A] = it match { + case JEnumerationWrapper(wrapped) => wrapped.asInstanceOf[ju.Enumeration[A]] + case _ => IteratorWrapper(it) + } + + /** + * Implicitly converts a Scala Iterable to a Java Iterable. + * The returned Java Iterable is backed by the provided Scala + * Iterable and any side-effects of using it via the Java interface will + * be visible via the Scala interface and vice versa. + * + * If the Scala Iterable was previously obtained from an implicit or + * explicit call of `asIterable(java.lang.Iterable)` then the original + * Java Iterable will be returned. + * + * @param i The Iterable to be converted. + * @return A Java Iterable view of the argument. + */ + implicit def asJavaIterable[A](i: Iterable[A]): jl.Iterable[A] = i match { + case JIterableWrapper(wrapped) => wrapped.asInstanceOf[jl.Iterable[A]] + case _ => IterableWrapper(i) + } + + /** + * Implicitly converts a Scala Iterable to an immutable Java + * Collection. + * + * If the Scala Iterable was previously obtained from an implicit or + * explicit call of `asSizedIterable(java.util.Collection)` then the original + * Java Collection will be returned. + * + * @param i The SizedIterable to be converted. + * @return A Java Collection view of the argument. + */ + implicit def asJavaCollection[A](it: Iterable[A]): ju.Collection[A] = it match { + case JCollectionWrapper(wrapped) => wrapped.asInstanceOf[ju.Collection[A]] + case _ => new IterableWrapper(it) + } + + /** + * Implicitly converts a Scala mutable Buffer to a Java List. + * The returned Java List is backed by the provided Scala + * Buffer and any side-effects of using it via the Java interface will + * be visible via the Scala interface and vice versa. + * + * If the Scala Buffer was previously obtained from an implicit or + * explicit call of `asBuffer(java.util.List)` then the original + * Java List will be returned. + * + * @param b The Buffer to be converted. + * @return A Java List view of the argument. + */ + implicit def bufferAsJavaList[A](b: mutable.Buffer[A]): ju.List[A] = b match { + case JListWrapper(wrapped) => wrapped + case _ => new MutableBufferWrapper(b) + } + + /** + * Implicitly converts a Scala mutable Seq to a Java List. + * The returned Java List is backed by the provided Scala + * Seq and any side-effects of using it via the Java interface will + * be visible via the Scala interface and vice versa. + * + * If the Scala Seq was previously obtained from an implicit or + * explicit call of `asSeq(java.util.List)` then the original + * Java List will be returned. + * + * @param b The Seq to be converted. + * @return A Java List view of the argument. + */ + implicit def mutableSeqAsJavaList[A](seq: mutable.Seq[A]): ju.List[A] = seq match { + case JListWrapper(wrapped) => wrapped + case _ => new MutableSeqWrapper(seq) + } + + /** + * Implicitly converts a Scala Seq to a Java List. + * The returned Java List is backed by the provided Scala + * Seq and any side-effects of using it via the Java interface will + * be visible via the Scala interface and vice versa. + * + * If the Scala Seq was previously obtained from an implicit or + * explicit call of `asSeq(java.util.List)` then the original + * Java List will be returned. + * + * @param b The Seq to be converted. + * @return A Java List view of the argument. + */ + implicit def seqAsJavaList[A](seq: Seq[A]): ju.List[A] = seq match { + case JListWrapper(wrapped) => wrapped.asInstanceOf[ju.List[A]] + case _ => new SeqWrapper(seq) + } + + /** + * Implicitly converts a Scala mutable Set to a Java Set. + * The returned Java Set is backed by the provided Scala + * Set and any side-effects of using it via the Java interface will + * be visible via the Scala interface and vice versa. + * + * If the Scala Set was previously obtained from an implicit or + * explicit call of `asSet(java.util.Set)` then the original + * Java Set will be returned. + * + * @param s The Set to be converted. + * @return A Java Set view of the argument. + */ + implicit def mutableSetAsJavaSet[A](s: mutable.Set[A]): ju.Set[A] = s match { + case JSetWrapper(wrapped) => wrapped + case _ => new MutableSetWrapper(s) + } + + /** + * Implicitly converts a Scala Set to a Java Set. + * The returned Java Set is backed by the provided Scala + * Set and any side-effects of using it via the Java interface will + * be visible via the Scala interface and vice versa. + * + * If the Scala Set was previously obtained from an implicit or + * explicit call of asSet(java.util.Set) then the original + * Java Set will be returned. + * + * @param s The Set to be converted. + * @return A Java Set view of the argument. + */ + implicit def setAsJavaSet[A](s: Set[A]): ju.Set[A] = s match { + case JSetWrapper(wrapped) => wrapped + case _ => new SetWrapper(s) + } + + /** + * Implicitly converts a Scala mutable Map to a Java Map. + * The returned Java Map is backed by the provided Scala + * Map and any side-effects of using it via the Java interface will + * be visible via the Scala interface and vice versa. + * + * If the Scala Map was previously obtained from an implicit or + * explicit call of `asMap(java.util.Map)` then the original + * Java Map will be returned. + * + * @param m The Map to be converted. + * @return A Java Map view of the argument. + */ + implicit def mutableMapAsJavaMap[A, B](m: mutable.Map[A, B]): ju.Map[A, B] = m match { + //case JConcurrentMapWrapper(wrapped) => wrapped + case JMapWrapper(wrapped) => wrapped + case _ => new MutableMapWrapper(m) + } + + /** + * Implicitly converts a Scala mutable `Map` to a Java `Dictionary`. + * + * The returned Java `Dictionary` is backed by the provided Scala + * `Dictionary` and any side-effects of using it via the Java interface + * will be visible via the Scala interface and vice versa. + * + * If the Scala `Dictionary` was previously obtained from an implicit or + * explicit call of `asMap(java.util.Dictionary)` then the original + * Java Dictionary will be returned. + * + * @param m The `Map` to be converted. + * @return A Java `Dictionary` view of the argument. + */ + implicit def asJavaDictionary[A, B](m: mutable.Map[A, B]): ju.Dictionary[A, B] = m match { + //case JConcurrentMapWrapper(wrapped) => wrapped + case JDictionaryWrapper(wrapped) => wrapped + case _ => new DictionaryWrapper(m) + } + + /** + * Implicitly converts a Scala `Map` to a Java `Map`. + * + * The returned Java `Map` is backed by the provided Scala `Map` and + * any side-effects of using it via the Java interface will be visible + * via the Scala interface and vice versa. + * + * If the Scala `Map` was previously obtained from an implicit or + * explicit call of `asMap(java.util.Map)` then the original + * Java `Map` will be returned. + * + * @param m The `Map` to be converted. + * @return A Java `Map` view of the argument. + */ + implicit def mapAsJavaMap[A, B](m: Map[A, B]): ju.Map[A, B] = m match { + //case JConcurrentMapWrapper(wrapped) => wrapped + case JMapWrapper(wrapped) => wrapped.asInstanceOf[ju.Map[A, B]] + case _ => new MapWrapper(m) + } + + /** + * Implicitly converts a Scala mutable `ConcurrentMap` to a Java + * `ConcurrentMap`. + * + * The returned Java `ConcurrentMap` is backed by the provided Scala + * `ConcurrentMap` and any side-effects of using it via the Java interface + * will be visible via the Scala interface and vice versa. + * + * If the Scala `ConcurrentMap` was previously obtained from an implicit or + * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)` + * then the original Java ConcurrentMap will be returned. + * + * @param m The `ConcurrentMap` to be converted. + * @return A Java `ConcurrentMap` view of the argument. + */ + implicit def asJavaConcurrentMap[A, B](m: mutable.ConcurrentMap[A, B]): juc.ConcurrentMap[A, B] = m match { + case JConcurrentMapWrapper(wrapped) => wrapped + case _ => new ConcurrentMapWrapper(m) + } +} + +object WrapAsJava extends WrapAsJava { } diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala new file mode 100644 index 0000000000..02b58f55a4 --- /dev/null +++ b/src/library/scala/collection/convert/WrapAsScala.scala @@ -0,0 +1,193 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.collection +package convert + +import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } +import Wrappers._ + +trait WrapAsScala { + /** + * Implicitly converts a Java `Iterator` to a Scala `Iterator`. + * + * The returned Scala `Iterator` is backed by the provided Java `Iterator` + * and any side-effects of using it via the Scala interface will be visible + * via the Java interface and vice versa. + * + * If the Java `Iterator` was previously obtained from an implicit or + * explicit call of `asIterator(scala.collection.Iterator)` then the + * original Scala `Iterator` will be returned. + * + * @param i The `Iterator` to be converted. + * @return A Scala `Iterator` view of the argument. + */ + implicit def asScalaIterator[A](it: ju.Iterator[A]): Iterator[A] = it match { + case IteratorWrapper(wrapped) => wrapped + case _ => JIteratorWrapper(it) + } + + /** + * Implicitly converts a Java Enumeration to a Scala Iterator. + * The returned Scala Iterator is backed by the provided Java + * Enumeration and any side-effects of using it via the Scala interface will + * be visible via the Java interface and vice versa. + * + * If the Java Enumeration was previously obtained from an implicit or + * explicit call of `enumerationAsScalaIterator(scala.collection.Iterator)` + * then the original Scala Iterator will be returned. + * + * @param i The Enumeration to be converted. + * @return A Scala Iterator view of the argument. + */ + implicit def enumerationAsScalaIterator[A](i: ju.Enumeration[A]): Iterator[A] = i match { + case IteratorWrapper(wrapped) => wrapped + case _ => JEnumerationWrapper(i) + } + + /** + * Implicitly converts a Java `Iterable` to a Scala `Iterable`. + * + * The returned Scala `Iterable` is backed by the provided Java `Iterable` + * and any side-effects of using it via the Scala interface will be visible + * via the Java interface and vice versa. + * + * If the Java `Iterable` was previously obtained from an implicit or + * explicit call of `iterableAsScalaIterable(scala.collection.Iterable)` + * then the original Scala Iterable will be returned. + * + * @param i The Iterable to be converted. + * @return A Scala Iterable view of the argument. + */ + implicit def iterableAsScalaIterable[A](i: jl.Iterable[A]): Iterable[A] = i match { + case IterableWrapper(wrapped) => wrapped + case _ => JIterableWrapper(i) + } + + /** + * Implicitly converts a Java `Collection` to an Scala `Iterable`. + * + * If the Java `Collection` was previously obtained from an implicit or + * explicit call of `collectionAsScalaIterable(scala.collection.SizedIterable)` + * then the original Scala `Iterable` will be returned. + * + * @param i The Collection to be converted. + * @return A Scala Iterable view of the argument. + */ + implicit def collectionAsScalaIterable[A](i: ju.Collection[A]): Iterable[A] = i match { + case IterableWrapper(wrapped) => wrapped + case _ => JCollectionWrapper(i) + } + + /** + * Implicitly converts a Java `List` to a Scala mutable `Buffer`. + * + * The returned Scala `Buffer` is backed by the provided Java `List` + * and any side-effects of using it via the Scala interface will + * be visible via the Java interface and vice versa. + * + * If the Java `List` was previously obtained from an implicit or + * explicit call of `asScalaBuffer(scala.collection.mutable.Buffer)` + * then the original Scala `Buffer` will be returned. + * + * @param l The `List` to be converted. + * @return A Scala mutable `Buffer` view of the argument. + */ + implicit def asScalaBuffer[A](l: ju.List[A]): mutable.Buffer[A] = l match { + case MutableBufferWrapper(wrapped) => wrapped + case _ =>new JListWrapper(l) + } + + /** + * Implicitly converts a Java Set to a Scala mutable Set. + * The returned Scala Set is backed by the provided Java + * Set and any side-effects of using it via the Scala interface will + * be visible via the Java interface and vice versa. + * + * If the Java Set was previously obtained from an implicit or + * explicit call of `asScalaSet(scala.collection.mutable.Set)` then + * the original Scala Set will be returned. + * + * @param s The Set to be converted. + * @return A Scala mutable Set view of the argument. + */ + implicit def asScalaSet[A](s: ju.Set[A]): mutable.Set[A] = s match { + case MutableSetWrapper(wrapped) => wrapped + case _ =>new JSetWrapper(s) + } + + /** + * Implicitly converts a Java `Map` to a Scala mutable `Map`. + * + * The returned Scala `Map` is backed by the provided Java `Map` and any + * side-effects of using it via the Scala interface will be visible via + * the Java interface and vice versa. + * + * If the Java `Map` was previously obtained from an implicit or + * explicit call of `mapAsScalaMap(scala.collection.mutable.Map)` then + * the original Scala Map will be returned. + * + * @param m The Map to be converted. + * @return A Scala mutable Map view of the argument. + */ + implicit def mapAsScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = m match { + //case ConcurrentMapWrapper(wrapped) => wrapped + case MutableMapWrapper(wrapped) => wrapped + case _ => new JMapWrapper(m) + } + + /** + * Implicitly converts a Java ConcurrentMap to a Scala mutable ConcurrentMap. + * The returned Scala ConcurrentMap is backed by the provided Java + * ConcurrentMap and any side-effects of using it via the Scala interface will + * be visible via the Java interface and vice versa. + * + * If the Java ConcurrentMap was previously obtained from an implicit or + * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)` + * then the original Scala ConcurrentMap will be returned. + * + * @param m The ConcurrentMap to be converted. + * @return A Scala mutable ConcurrentMap view of the argument. + */ + implicit def asScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): mutable.ConcurrentMap[A, B] = m match { + case cmw: ConcurrentMapWrapper[a, b] => cmw.underlying + case _ => new JConcurrentMapWrapper(m) + } + + /** + * Implicitly converts a Java `Dictionary` to a Scala mutable + * `Map[String, String]`. + * + * The returned Scala `Map[String, String]` is backed by the provided Java + * `Dictionary` and any side-effects of using it via the Scala interface + * will be visible via the Java interface and vice versa. + * + * @param m The Dictionary to be converted. + * @return A Scala mutable Map[String, String] view of the argument. + */ + implicit def dictionaryAsScalaMap[A, B](p: ju.Dictionary[A, B]): mutable.Map[A, B] = p match { + case DictionaryWrapper(wrapped) => wrapped + case _ => new JDictionaryWrapper(p) + } + + /** + * Implicitly converts a Java `Properties` to a Scala `mutable Map[String, String]`. + * + * The returned Scala `Map[String, String]` is backed by the provided Java + * `Properties` and any side-effects of using it via the Scala interface + * will be visible via the Java interface and vice versa. + * + * @param m The Properties to be converted. + * @return A Scala mutable Map[String, String] view of the argument. + */ + implicit def propertiesAsScalaMap(p: ju.Properties): mutable.Map[String, String] = p match { + case _ => new JPropertiesWrapper(p) + } +} + +object WrapAsScala extends WrapAsScala { } diff --git a/src/library/scala/collection/convert/Wrappers.scala b/src/library/scala/collection/convert/Wrappers.scala new file mode 100644 index 0000000000..8136e462cb --- /dev/null +++ b/src/library/scala/collection/convert/Wrappers.scala @@ -0,0 +1,422 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.collection +package convert + +import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } +import WrapAsScala._ +import WrapAsJava._ + +/** Don't put the implementations in the same scope as the implicits + * which utilize them, or they will stow away into every scope which + * extends one of those implementations. See SI-5580. + */ +private[collection] trait Wrappers { + trait IterableWrapperTrait[A] extends ju.AbstractCollection[A] { + val underlying: Iterable[A] + def size = underlying.size + override def iterator = IteratorWrapper(underlying.iterator) + override def isEmpty = underlying.isEmpty + } + + case class IteratorWrapper[A](underlying: Iterator[A]) extends ju.Iterator[A] with ju.Enumeration[A] { + def hasNext = underlying.hasNext + def next() = underlying.next + def hasMoreElements = underlying.hasNext + def nextElement() = underlying.next + def remove() = throw new UnsupportedOperationException + } + + class ToIteratorWrapper[A](underlying : Iterator[A]) { + def asJava = new IteratorWrapper(underlying) + } + + case class JIteratorWrapper[A](underlying: ju.Iterator[A]) extends AbstractIterator[A] with Iterator[A] { + def hasNext = underlying.hasNext + def next() = underlying.next + } + + case class JEnumerationWrapper[A](underlying: ju.Enumeration[A]) extends AbstractIterator[A] with Iterator[A] { + def hasNext = underlying.hasMoreElements + def next() = underlying.nextElement + } + + case class IterableWrapper[A](underlying: Iterable[A]) extends ju.AbstractCollection[A] with IterableWrapperTrait[A] { } + + case class JIterableWrapper[A](underlying: jl.Iterable[A]) extends AbstractIterable[A] with Iterable[A] { + def iterator = underlying.iterator + def newBuilder[B] = new mutable.ArrayBuffer[B] + } + + case class JCollectionWrapper[A](underlying: ju.Collection[A]) extends AbstractIterable[A] with Iterable[A] { + def iterator = underlying.iterator + override def size = underlying.size + override def isEmpty = underlying.isEmpty + def newBuilder[B] = new mutable.ArrayBuffer[B] + } + + case class SeqWrapper[A](underlying: Seq[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] { + def get(i: Int) = underlying(i) + } + + case class MutableSeqWrapper[A](underlying: mutable.Seq[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] { + def get(i: Int) = underlying(i) + override def set(i: Int, elem: A) = { + val p = underlying(i) + underlying(i) = elem + p + } + } + + case class MutableBufferWrapper[A](underlying: mutable.Buffer[A]) extends ju.AbstractList[A] with IterableWrapperTrait[A] { + def get(i: Int) = underlying(i) + override def set(i: Int, elem: A) = { val p = underlying(i); underlying(i) = elem; p } + override def add(elem: A) = { underlying append elem; true } + override def remove(i: Int) = underlying remove i + } + + case class JListWrapper[A](val underlying: ju.List[A]) extends mutable.AbstractBuffer[A] with mutable.Buffer[A] { + def length = underlying.size + override def isEmpty = underlying.isEmpty + override def iterator: Iterator[A] = underlying.iterator + def apply(i: Int) = underlying.get(i) + def update(i: Int, elem: A) = underlying.set(i, elem) + def +=:(elem: A) = { underlying.subList(0, 0) add elem; this } + def +=(elem: A): this.type = { underlying add elem; this } + def insertAll(i: Int, elems: Traversable[A]) = { + val ins = underlying.subList(0, i) + elems.seq.foreach(ins.add(_)) + } + def remove(i: Int) = underlying.remove(i) + def clear() = underlying.clear() + def result = this + } + + class SetWrapper[A](underlying: Set[A]) extends ju.AbstractSet[A] { + self => + def size = underlying.size + def iterator = new ju.Iterator[A] { + val ui = underlying.iterator + var prev: Option[A] = None + def hasNext = ui.hasNext + def next = { val e = ui.next; prev = Some(e); e } + def remove = prev match { + case Some(e) => + underlying match { + case ms: mutable.Set[a] => + ms remove e + prev = None + case _ => + throw new UnsupportedOperationException("remove") + } + case _ => + throw new IllegalStateException("next must be called at least once before remove") + } + } + } + + case class MutableSetWrapper[A](underlying: mutable.Set[A]) extends SetWrapper[A](underlying) { + override def add(elem: A) = { + val sz = underlying.size + underlying += elem + sz < underlying.size + } + override def remove(elem: AnyRef) = + try underlying remove elem.asInstanceOf[A] + catch { case ex: ClassCastException => false } + override def clear() = underlying.clear() + } + + case class JSetWrapper[A](underlying: ju.Set[A]) extends mutable.AbstractSet[A] with mutable.Set[A] with mutable.SetLike[A, JSetWrapper[A]] { + + override def size = underlying.size + + def iterator = underlying.iterator + + def contains(elem: A): Boolean = underlying.contains(elem) + + def +=(elem: A): this.type = { underlying add elem; this } + def -=(elem: A): this.type = { underlying remove elem; this } + + override def add(elem: A): Boolean = underlying add elem + override def remove(elem: A): Boolean = underlying remove elem + override def clear() = underlying.clear() + + override def empty = JSetWrapper(new ju.HashSet[A]) + } + + class MapWrapper[A, B](underlying: Map[A, B]) extends ju.AbstractMap[A, B] { self => + override def size = underlying.size + + override def get(key: AnyRef): B = try { + underlying get key.asInstanceOf[A] match { + case None => null.asInstanceOf[B] + case Some(v) => v + } + } catch { + case ex: ClassCastException => null.asInstanceOf[B] + } + + override def entrySet: ju.Set[ju.Map.Entry[A, B]] = new ju.AbstractSet[ju.Map.Entry[A, B]] { + def size = self.size + + def iterator = new ju.Iterator[ju.Map.Entry[A, B]] { + val ui = underlying.iterator + var prev : Option[A] = None + + def hasNext = ui.hasNext + + def next() = { + val (k, v) = ui.next + prev = Some(k) + new ju.Map.Entry[A, B] { + def getKey = k + def getValue = v + def setValue(v1 : B) = self.put(k, v1) + override def hashCode = k.hashCode + v.hashCode + override def equals(other: Any) = other match { + case e: ju.Map.Entry[_, _] => k == e.getKey && v == e.getValue + case _ => false + } + } + } + + def remove() { + prev match { + case Some(k) => + underlying match { + case mm: mutable.Map[a, _] => + mm remove k + prev = None + case _ => + throw new UnsupportedOperationException("remove") + } + case _ => + throw new IllegalStateException("next must be called at least once before remove") + } + } + } + } + } + + case class MutableMapWrapper[A, B](underlying: mutable.Map[A, B]) extends MapWrapper[A, B](underlying) { + override def put(k: A, v: B) = underlying.put(k, v) match { + case Some(v1) => v1 + case None => null.asInstanceOf[B] + } + + override def remove(k: AnyRef): B = try { + underlying remove k.asInstanceOf[A] match { + case None => null.asInstanceOf[B] + case Some(v) => v + } + } catch { + case ex: ClassCastException => null.asInstanceOf[B] + } + + override def clear() = underlying.clear() + } + + trait JMapWrapperLike[A, B, +Repr <: mutable.MapLike[A, B, Repr] with mutable.Map[A, B]] extends mutable.Map[A, B] with mutable.MapLike[A, B, Repr] { + def underlying: ju.Map[A, B] + + override def size = underlying.size + + def get(k: A) = { + val v = underlying get k + if (v != null) + Some(v) + else if (underlying containsKey k) + Some(null.asInstanceOf[B]) + else + None + } + + def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this } + def -=(key: A): this.type = { underlying remove key; this } + + override def put(k: A, v: B): Option[B] = { + val r = underlying.put(k, v) + if (r != null) Some(r) else None + } + + override def update(k: A, v: B) { underlying.put(k, v) } + + override def remove(k: A): Option[B] = { + val r = underlying remove k + if (r != null) Some(r) else None + } + + def iterator: Iterator[(A, B)] = new AbstractIterator[(A, B)] { + val ui = underlying.entrySet.iterator + def hasNext = ui.hasNext + def next() = { val e = ui.next(); (e.getKey, e.getValue) } + } + + override def clear() = underlying.clear() + + override def empty: Repr = null.asInstanceOf[Repr] + } + + case class JMapWrapper[A, B](val underlying : ju.Map[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JMapWrapper[A, B]] { + override def empty = JMapWrapper(new ju.HashMap[A, B]) + } + + class ConcurrentMapWrapper[A, B](override val underlying: mutable.ConcurrentMap[A, B]) extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] { + + def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match { + case Some(v) => v + case None => null.asInstanceOf[B] + } + + def remove(k: AnyRef, v: AnyRef) = try { + underlying.remove(k.asInstanceOf[A], v.asInstanceOf[B]) + } catch { + case ex: ClassCastException => + false + } + + def replace(k: A, v: B): B = underlying.replace(k, v) match { + case Some(v) => v + case None => null.asInstanceOf[B] + } + + def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval) + } + + case class JConcurrentMapWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] with mutable.ConcurrentMap[A, B] { + override def get(k: A) = { + val v = underlying get k + if (v != null) Some(v) + else None + } + + override def empty = new JConcurrentMapWrapper(new juc.ConcurrentHashMap[A, B]) + + def putIfAbsent(k: A, v: B): Option[B] = { + val r = underlying.putIfAbsent(k, v) + if (r != null) Some(r) else None + } + + def remove(k: A, v: B): Boolean = underlying.remove(k, v) + + def replace(k: A, v: B): Option[B] = { + val prev = underlying.replace(k, v) + if (prev != null) Some(prev) else None + } + + def replace(k: A, oldvalue: B, newvalue: B): Boolean = + underlying.replace(k, oldvalue, newvalue) + } + + case class DictionaryWrapper[A, B](underlying: mutable.Map[A, B]) extends ju.Dictionary[A, B] { + def size: Int = underlying.size + def isEmpty: Boolean = underlying.isEmpty + def keys: ju.Enumeration[A] = asJavaEnumeration(underlying.keysIterator) + def elements: ju.Enumeration[B] = asJavaEnumeration(underlying.valuesIterator) + def get(key: AnyRef) = try { + underlying get key.asInstanceOf[A] match { + case None => null.asInstanceOf[B] + case Some(v) => v + } + } catch { + case ex: ClassCastException => null.asInstanceOf[B] + } + def put(key: A, value: B): B = underlying.put(key, value) match { + case Some(v) => v + case None => null.asInstanceOf[B] + } + override def remove(key: AnyRef) = try { + underlying remove key.asInstanceOf[A] match { + case None => null.asInstanceOf[B] + case Some(v) => v + } + } catch { + case ex: ClassCastException => null.asInstanceOf[B] + } + } + + case class JDictionaryWrapper[A, B](underlying: ju.Dictionary[A, B]) extends mutable.AbstractMap[A, B] with mutable.Map[A, B] { + override def size: Int = underlying.size + + def get(k: A) = { + val v = underlying get k + if (v != null) Some(v) else None + } + + def +=(kv: (A, B)): this.type = { underlying.put(kv._1, kv._2); this } + def -=(key: A): this.type = { underlying remove key; this } + + override def put(k: A, v: B): Option[B] = { + val r = underlying.put(k, v) + if (r != null) Some(r) else None + } + + override def update(k: A, v: B) { underlying.put(k, v) } + + override def remove(k: A): Option[B] = { + val r = underlying remove k + if (r != null) Some(r) else None + } + + def iterator = enumerationAsScalaIterator(underlying.keys) map (k => (k, underlying get k)) + + override def clear() = underlying.clear() + } + + case class JPropertiesWrapper(underlying: ju.Properties) extends mutable.AbstractMap[String, String] + with mutable.Map[String, String] + with mutable.MapLike[String, String, JPropertiesWrapper] { + + override def size = underlying.size + + def get(k: String) = { + val v = underlying get k + if (v != null) Some(v.asInstanceOf[String]) else None + } + + def +=(kv: (String, String)): this.type = { underlying.put(kv._1, kv._2); this } + def -=(key: String): this.type = { underlying remove key; this } + + override def put(k: String, v: String): Option[String] = { + val r = underlying.put(k, v) + if (r != null) Some(r.asInstanceOf[String]) else None + } + + override def update(k: String, v: String) { underlying.put(k, v) } + + override def remove(k: String): Option[String] = { + val r = underlying remove k + if (r != null) Some(r.asInstanceOf[String]) else None + } + + def iterator: Iterator[(String, String)] = new AbstractIterator[(String, String)] { + val ui = underlying.entrySet.iterator + def hasNext = ui.hasNext + def next() = { + val e = ui.next() + (e.getKey.asInstanceOf[String], e.getValue.asInstanceOf[String]) + } + } + + override def clear() = underlying.clear() + + override def empty = JPropertiesWrapper(new ju.Properties) + + def getProperty(key: String) = underlying.getProperty(key) + + def getProperty(key: String, defaultValue: String) = + underlying.getProperty(key, defaultValue) + + def setProperty(key: String, value: String) = + underlying.setProperty(key, value) + } +} + +object Wrappers extends Wrappers diff --git a/src/library/scala/collection/convert/package.scala b/src/library/scala/collection/convert/package.scala new file mode 100644 index 0000000000..2f8bca1e1f --- /dev/null +++ b/src/library/scala/collection/convert/package.scala @@ -0,0 +1,18 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.collection + +package object convert { + val decorateAsJava = new DecorateAsJava { } + val decorateAsScala = new DecorateAsScala { } + val decorateAll = new DecorateAsJava with DecorateAsScala { } + val wrapAsJava = new WrapAsJava { } + val wrapAsScala = new WrapAsScala { } + val wrapAll = new WrapAsJava with WrapAsScala { } +} diff --git a/src/library/scala/collection/mutable/WeakHashMap.scala b/src/library/scala/collection/mutable/WeakHashMap.scala index 89d7c7a695..4e09755acf 100644 --- a/src/library/scala/collection/mutable/WeakHashMap.scala +++ b/src/library/scala/collection/mutable/WeakHashMap.scala @@ -6,14 +6,11 @@ ** |/ ** \* */ - - package scala.collection package mutable -import JavaConversions._ import generic._ - +import convert.Wrappers._ /** A hash map with references to entries which are weakly reachable. Entries are * removed from this map when the key is no longer (strongly) referenced. This class wraps diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala index dd1de2025e..8ac745fd25 100644 --- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala +++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala @@ -19,7 +19,7 @@ import scala.collection.mutable.Stack -class ExecutionContextImpl(val executorService: AnyRef) extends ExecutionContext { +private[scala] class ExecutionContextImpl(val executorService: AnyRef) extends ExecutionContext { import ExecutionContextImpl._ def execute(runnable: Runnable): Unit = executorService match { diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala index 9466761d4d..b4385ea34a 100644 --- a/src/library/scala/concurrent/impl/Future.scala +++ b/src/library/scala/concurrent/impl/Future.scala @@ -12,7 +12,7 @@ import scala.concurrent.{Awaitable, ExecutionContext} import scala.util.{ Try, Success, Failure } //import scala.util.continuations._ -trait Future[+T] extends scala.concurrent.Future[T] with Awaitable[T] { +private[concurrent] trait Future[+T] extends scala.concurrent.Future[T] with Awaitable[T] { implicit def executor: ExecutionContextImpl diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala index 3d40ae6930..4a983b5001 100644 --- a/src/library/scala/concurrent/impl/Promise.scala +++ b/src/library/scala/concurrent/impl/Promise.scala @@ -22,7 +22,7 @@ import scala.annotation.tailrec -trait Promise[T] extends scala.concurrent.Promise[T] with Future[T] { +private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with Future[T] { def future = this diff --git a/src/library/scala/parallel/Future.scala b/src/library/scala/parallel/Future.scala index af06852b32..f61d376093 100644 --- a/src/library/scala/parallel/Future.scala +++ b/src/library/scala/parallel/Future.scala @@ -8,11 +8,14 @@ package scala.parallel + + /** A future is a function without parameters that will block the caller if * the parallel computation associated with the function is not completed. * * @since 2.9 */ +@deprecated("Use `scala.concurrent.Future` instead.", "2.10.0") trait Future[@specialized +R] extends (() => R) { /** Returns a result once the parallel computation completes. If the * computation produced an exception, an exception is forwarded. diff --git a/src/library/scala/reflect/api/Positions.scala b/src/library/scala/reflect/api/Positions.scala index 181e7c1525..4c8c33bec8 100644 --- a/src/library/scala/reflect/api/Positions.scala +++ b/src/library/scala/reflect/api/Positions.scala @@ -1,9 +1,21 @@ package scala.reflect package api -trait Positions { +trait Positions { self: Universe => + /** TreeAnnotation is a generalisation of Position. + * + * TreeAnnotation cannot be an upperbound of Position since the corresponding classes + * must live outside of the universe for backwards compatibility (see scala.tools.nsc.util.Position). + * Thus, represent subtyping as coercions. + * + * Typically, positionToAnnotation is the identity, and annotationToPosition returns annot.pos + */ + type TreeAnnotation // <: { def pos: Position } + val NoTreeAnnotation: TreeAnnotation + implicit def positionToAnnotation(pos: Position): TreeAnnotation // = pos + def annotationToPosition(annot: TreeAnnotation): Position // = annot.pos + def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = () // check that annot may overwrite tree.annot - type Position + type Position // <: TreeAnnotation, but not practical to enforce this (would require moving Position, SourceFile, Reporter,... into the universe) val NoPosition: Position - }
\ No newline at end of file diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 466c380cef..4ee13adf52 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -74,17 +74,24 @@ trait Trees { self: Universe => val id = nodeCount nodeCount += 1 - private[this] var rawpos: Position = NoPosition - /** Prefix under which to print this tree type. Defaults to product * prefix (e.g. DefTree) but because that is used in reification * it cannot be altered without breaking reflection. */ def printingPrefix = productPrefix - def pos = rawpos - def pos_=(pos: Position) = rawpos = pos - def setPos(pos: Position): this.type = { rawpos = pos; this } + def pos: Position = annotationToPosition(rawannot) + def pos_=(pos: Position): Unit = annotation = pos + def setPos(newpos: Position): this.type = { pos = newpos; this } + + private[this] var rawannot: TreeAnnotation = NoTreeAnnotation + def annotation: TreeAnnotation = rawannot + def annotation_=(annot: TreeAnnotation): Unit = { + _checkSetAnnotation(this, annot) + rawannot = annot + } + + def setAnnotation(annot: TreeAnnotation): this.type = { annotation = annot; this } private[this] var rawtpe: Type = _ @@ -223,7 +230,7 @@ trait Trees { self: Universe => duplicateTree(this).asInstanceOf[this.type] private[scala] def copyAttrs(tree: Tree): this.type = { - pos = tree.pos + annotation = tree.annotation tpe = tree.tpe if (hasSymbol) symbol = tree.symbol this |