Skip to content

Commit 092ffc4

Browse files
committed
Fix some more collection errors
- fix implicit Array to Seq error using ArraySeq.unsafeWrapArray - fix inheritance shadowing error by renaming function and using this._ - fix deprecated Array to Scala varargs - add MultiMap class since MultiMaps and extending HashMaps are deprecated - Map.mapValues -> new RichMap.mapValues - Map.filterKeys -> new RichMap.filterKeys - moved util.{collections} into util.collections.{collections} - remove deprecated Either.right since it's the default view now DAFFODIL-2152
1 parent 42fb76c commit 092ffc4

File tree

30 files changed

+198
-65
lines changed

30 files changed

+198
-65
lines changed

build.sbt

+5-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,11 @@ def buildScalacOptions(scalaVersion: String) = {
293293
Seq(
294294
"-Xlint:inaccessible",
295295
"-Xlint:infer-any",
296-
"-Xlint:nullary-unit"
296+
"-Xlint:nullary-unit",
297+
// TODO: scala 2.12 phase out
298+
// the import is needed for Scala 2.12 but issues an unused import warning under 2.13, so we add this to
299+
// suppresss the warning
300+
"-Wconf:origin=scala.collection.compat.*:s"
297301
)
298302
case _ => Seq.empty
299303
}

daffodil-codegen-c/src/main/scala/org/apache/daffodil/codegen/c/generators/CodeGeneratorState.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import org.apache.daffodil.core.dsom.SchemaComponent
2828
import org.apache.daffodil.lib.api.WarnID
2929
import org.apache.daffodil.lib.cookers.ChoiceBranchKeyCooker
3030
import org.apache.daffodil.lib.schema.annotation.props.gen.OccursCountKind
31-
import org.apache.daffodil.lib.util.Stack
31+
import org.apache.daffodil.lib.util.collections.Stack
3232
import org.apache.daffodil.runtime1.dpath.NodeInfo.PrimType
3333

3434
/**

daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/ElementBase.scala

+5-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import org.apache.daffodil.lib.schema.annotation.props._
2929
import org.apache.daffodil.lib.schema.annotation.props.gen._
3030
import org.apache.daffodil.lib.util.MaybeULong
3131
import org.apache.daffodil.lib.util.Misc
32+
import org.apache.daffodil.lib.util.collections.RichMap
3233
import org.apache.daffodil.lib.xml._
3334
import org.apache.daffodil.runtime1.dpath.InvalidPrimitiveDataException
3435
import org.apache.daffodil.runtime1.dpath.NodeInfo
@@ -256,15 +257,17 @@ trait ElementBase
256257

257258
// Creates a Map[prefix, Set[NS]]. Duplicate NS's will be removed from the
258259
// Set, since it's a Set
259-
val bindingsGroupedByPrefix = allBindings.groupBy { _._1 }.mapValues { _.map { _._2 } }
260+
val bindingsGroupedByPrefix = new RichMap(allBindings.groupBy { _._1 }).mapValues {
261+
_.map { _._2 }
262+
}
260263

261264
// Any Set with size > 1 has different namespaces for the same prefix, filter them out
262265
val bindingsNoConflictsMap = bindingsGroupedByPrefix.filter { case (prefix, bindings) =>
263266
bindings.size == 1
264267
}
265268

266269
// Create a Map[prefix, NS] now that conflicts are removed
267-
val bindingsSingleNSMap = bindingsNoConflictsMap.mapValues { _.head }
270+
val bindingsSingleNSMap = new RichMap(bindingsNoConflictsMap).mapValues { _.head }
268271

269272
// Convert back to a set
270273
val bindings = bindingsSingleNSMap.toSet

daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/ChoiceCombinator.scala

+13-11
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import org.apache.daffodil.lib.exceptions.Assert
3232
import org.apache.daffodil.lib.schema.annotation.props.gen.ChoiceLengthKind
3333
import org.apache.daffodil.lib.util.MaybeInt
3434
import org.apache.daffodil.lib.util.ProperlySerializableMap._
35+
import org.apache.daffodil.lib.util.collections.RichMap
3536
import org.apache.daffodil.runtime1.infoset.ChoiceBranchEvent
3637
import org.apache.daffodil.runtime1.processors.RangeBound
3738
import org.apache.daffodil.runtime1.processors.parsers._
@@ -236,17 +237,18 @@ case class ChoiceCombinator(ch: ChoiceTermBase, alternatives: Seq[Gram])
236237
}
237238
})
238239

239-
val dispatchBranchKeyMap = dispatchBranchKeyValueTuples.toMap.mapValues { gram =>
240-
val isRepresented =
241-
true // choice branches are, currently, always represented (cannot have inputValueCalc).
242-
val gramParser = gram.parser
243-
val parser =
244-
if (gramParser.isEmpty) {
245-
new ChoiceBranchEmptyParser(gram.context.runtimeData)
246-
} else {
247-
gramParser
248-
}
249-
(parser, isRepresented)
240+
val dispatchBranchKeyMap = new RichMap(dispatchBranchKeyValueTuples.toMap).mapValues {
241+
gram =>
242+
val isRepresented =
243+
true // choice branches are, currently, always represented (cannot have inputValueCalc).
244+
val gramParser = gram.parser
245+
val parser =
246+
if (gramParser.isEmpty) {
247+
new ChoiceBranchEmptyParser(gram.context.runtimeData)
248+
} else {
249+
gramParser
250+
}
251+
(parser, isRepresented)
250252
}
251253

252254
val serializableMap: ProperlySerializableMap[String, (Parser, Boolean)] =

daffodil-core/src/main/scala/org/apache/daffodil/core/runtime1/ChoiceTermRuntime1Mixin.scala

+7-4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import org.apache.daffodil.core.grammar.Gram
2626
import org.apache.daffodil.lib.api.WarnID
2727
import org.apache.daffodil.lib.exceptions.Assert
2828
import org.apache.daffodil.lib.util.Delay
29+
import org.apache.daffodil.lib.util.collections.RichMap
2930
import org.apache.daffodil.runtime1.dpath.NodeInfo
3031
import org.apache.daffodil.runtime1.infoset.ChoiceBranchEndEvent
3132
import org.apache.daffodil.runtime1.infoset.ChoiceBranchEvent
@@ -121,10 +122,12 @@ trait ChoiceTermRuntime1Mixin { self: ChoiceTermBase =>
121122
}
122123

123124
// converts a sequence of tuples into a multi-map
124-
val eventMap = eventTuples
125-
.groupBy {
126-
_._1
127-
}
125+
val eventMap = new RichMap(
126+
eventTuples
127+
.groupBy {
128+
_._1
129+
}
130+
)
128131
.mapValues {
129132
_.map(_._2)
130133
}

daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/OnStack.scala

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package org.apache.daffodil.lib.util
1919

2020
import java.util.regex.Matcher
2121

22+
import org.apache.daffodil.lib.util.collections.Stack
23+
2224
sealed abstract class LocalStackBase[T](constructorFunc: => T, optionalResetFunc: (T => Unit)) {
2325

2426
protected def stack: Stack[T]

daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Timer.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package org.apache.daffodil.lib.util
1919

2020
import scala.jdk.CollectionConverters._
2121

22+
import org.apache.daffodil.lib.util.collections.Stack
23+
2224
object Timer {
2325

2426
def printTime(message: String, nanos: Long, units: String): Unit = {
@@ -188,7 +190,7 @@ object TimeTracker {
188190
*
189191
* TODO: not covered by tests
190192
*/
191-
val childrenTimeStack = new org.apache.daffodil.lib.util.Stack[Long]()
193+
val childrenTimeStack = new Stack[Long]()
192194

193195
/**
194196
* Used to measure a section of code that might get called multiple times.

daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/ArrayBuffer1.scala daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/collections/ArrayBuffer1.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
* limitations under the License.
1616
*/
1717

18-
package org.apache.daffodil.lib.util
18+
package org.apache.daffodil.lib.util.collections
1919

2020
import java.util
2121
import scala.collection.mutable.ArrayBuffer
2222

2323
/**
24+
* TODO: scala 2.12 phase out
2425
* Compatibility ArrayBuffer class for 2.12 and 2.13 since reduceToSize
2526
* has been removed in 2.13. This allows us to maintain the same
2627
* functionality as 2.12 while upgraded to 2.13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.daffodil.lib.util.collections
19+
20+
import scala.collection.mutable
21+
22+
/**
23+
* TODO: scala 2.12 phase out
24+
* Compatibility class for 2.12 and 2.13 since MultiMap and inheritance
25+
* from class mutable.HashMap have been deprecated in 2.13.
26+
*/
27+
class MultiMap[K, V] {
28+
private val underlying = mutable.Map.empty[K, mutable.Set[V]]
29+
30+
def addBinding(key: K, value: V): Unit =
31+
underlying.getOrElseUpdate(key, mutable.Set.empty) += value
32+
33+
def addBinding(key: K, values: mutable.Set[V]): Unit = {
34+
values.foreach(addBinding(key, _))
35+
}
36+
37+
def removeBinding(key: K, value: V): Unit =
38+
underlying.get(key).foreach { values =>
39+
values -= value
40+
if (values.isEmpty) underlying -= key
41+
}
42+
43+
def get(key: K): Option[mutable.Set[V]] = underlying.get(key)
44+
45+
def keys: Iterable[K] = underlying.keys
46+
47+
def iterator: Iterator[(K, mutable.Set[V])] = underlying.iterator
48+
49+
def filter(func: (K, mutable.Set[V]) => Boolean): MultiMap[K, V] = {
50+
val filtered = new MultiMap[K, V]
51+
for ((key, values) <- underlying) {
52+
if (func(key, values)) {
53+
filtered.addBinding(key, values)
54+
}
55+
}
56+
filtered
57+
}
58+
59+
def map[T](func: (K, mutable.Set[V]) => T): collection.Seq[T] = {
60+
val ret = mutable.ListBuffer.empty[T]
61+
for ((key, values) <- underlying) {
62+
ret.append(func(key, values))
63+
}
64+
ret
65+
}
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.daffodil.lib.util.collections
19+
20+
import scala.language.implicitConversions
21+
22+
// TODO scala 2.12 phase out
23+
// Define RichMap to add mapValues and filterKeys method
24+
class RichMap[K, V](val underlying: Map[K, V]) extends AnyVal {
25+
implicit def mapValues[V2](f: V => V2): Map[K, V2] = underlying.map { case (k, v) =>
26+
k -> f(v)
27+
}
28+
29+
implicit def filterKeys(f: K => Boolean): Map[K, V] = underlying.filter { case (k, _) =>
30+
f(k)
31+
}
32+
}

daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Stack.scala daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/collections/Stack.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
* limitations under the License.
1616
*/
1717

18-
package org.apache.daffodil.lib.util
18+
package org.apache.daffodil.lib.util.collections
1919

2020
import scala.collection.mutable.ListBuffer
2121

2222
/**
23+
* TODO: scala 2.12 phase out
2324
* Compatibility class for 2.12 and 2.13 since ArrayStack and Stack
2425
* have been deprecated in 2.13. This allows us to maintain the same
2526
* functionality as stack while using ListBuffer instead

daffodil-lib/src/test/scala/org/apache/daffodil/lib/util/TestXMLCatalogAndValidate.scala

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import scala.xml.parsing.NoBindingFactoryAdapter
3333

3434
import org.apache.daffodil.lib.exceptions.Assert
3535
import org.apache.daffodil.lib.util.Implicits.using
36+
import org.apache.daffodil.lib.util.collections.Stack
3637
import org.apache.daffodil.lib.xml.DaffodilSAXParserFactory
3738
import org.apache.daffodil.lib.xml.NS
3839
import org.apache.daffodil.lib.xml.NS.implicitNStoString

daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/debugger/InteractiveDebugger.scala

+7-6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.daffodil.runtime1.debugger
1919

2020
import java.io.File
21+
import scala.collection.compat.immutable.ArraySeq
2122

2223
import org.apache.daffodil.lib.api.DaffodilTunables
2324
import org.apache.daffodil.lib.api.WarnID
@@ -279,7 +280,7 @@ class InteractiveDebugger(
279280
input
280281
}
281282
}
282-
cmd.split(" ").filter(_ != "")
283+
ArraySeq.unsafeWrapArray(cmd.split(" ").filter(_ != ""))
283284
}
284285

285286
private val debuggerQName = GlobalQName(Some("daf"), "debugger", XMLUtils.dafintURI)
@@ -1862,7 +1863,7 @@ class InteractiveDebugger(
18621863
}
18631864

18641865
abstract class InfoProcessorBase extends DebugCommand with DebugCommandValidateZeroArgs {
1865-
val desc = "display the current Daffodil " + name
1866+
val desc = "display the current Daffodil " + this.name
18661867
val longDesc = desc
18671868
def act(
18681869
args: Seq[String],
@@ -1871,15 +1872,15 @@ class InteractiveDebugger(
18711872
): DebugState.Type = {
18721873
state match {
18731874
case pstate: PState => {
1874-
if (name == "parser") {
1875-
debugPrintln("%s: %s".format(name, processor.toBriefXML(2)))
1875+
if (this.name == "parser") {
1876+
debugPrintln("%s: %s".format(this.name, processor.toBriefXML(2)))
18761877
} else {
18771878
debugPrintln("unparser: not available")
18781879
}
18791880
}
18801881
case ustate: UState => {
1881-
if (name == "unparser") {
1882-
debugPrintln("%s: %s".format(name, processor.toBriefXML(2)))
1882+
if (this.name == "unparser") {
1883+
debugPrintln("%s: %s".format(this.name, processor.toBriefXML(2)))
18831884
} else {
18841885
debugPrintln("parser: not available")
18851886
}

daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DFDLXFunctions.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ case class DFDLXTrace(recipe: CompiledDPath, msg: String)
235235

236236
// This is toXML for the case class object, not the infoset node it is
237237
// dealing with.
238-
override def toXML = toXML(recipe.toXML)
238+
override def toXML = toXMLVarargs(recipe.toXML)
239239

240240
}
241241

daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DPathRuntime.scala

+6-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.daffodil.runtime1.dpath
1919

2020
import java.lang.{ Number => JNumber }
21+
import scala.collection.compat.immutable.ArraySeq
2122
import scala.xml.NodeSeq.seqToNodeSeq
2223

2324
import org.apache.daffodil.lib.api.DaffodilTunables
@@ -43,7 +44,7 @@ import org.apache.daffodil.runtime1.processors.VariableRuntimeData
4344

4445
class CompiledDPath(val ops: RecipeOp*) extends Serializable {
4546

46-
def this(ops: List[RecipeOp]) = this(ops.toArray: _*)
47+
def this(ops: List[RecipeOp]) = this(ArraySeq.unsafeWrapArray(ops.toArray): _*)
4748

4849
override def toString =
4950
toXML.toString
@@ -157,9 +158,9 @@ abstract class RecipeOp extends Serializable {
157158

158159
protected def subRecipes: Seq[CompiledDPath] = Nil
159160

160-
protected def toXML(s: String): scala.xml.Node = toXML(new scala.xml.Text(s))
161+
protected def toXML(s: String): scala.xml.Node = toXMLVarargs(new scala.xml.Text(s))
161162

162-
protected def toXML(children: scala.xml.Node*): scala.xml.Node = toXML(children.toSeq)
163+
protected def toXMLVarargs(children: scala.xml.Node*): scala.xml.Node = toXML(children.toSeq)
163164

164165
protected def toXML(children: scala.xml.NodeSeq): scala.xml.Node = {
165166
val name = Misc.getNameFromClass(this)
@@ -246,7 +247,8 @@ trait BinaryOpMixin { self: RecipeOp =>
246247
def right: CompiledDPath
247248
override def subRecipes: Seq[CompiledDPath] = Seq(left, right)
248249

249-
override def toXML: scala.xml.Node = toXML(new scala.xml.Text(op), left.toXML, right.toXML)
250+
override def toXML: scala.xml.Node =
251+
toXMLVarargs(new scala.xml.Text(op), left.toXML, right.toXML)
250252
}
251253

252254
case class CompareOperator(cop: CompareOpBase, left: CompiledDPath, right: CompiledDPath)

daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/FNBases.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ abstract class FNOneArg(recipe: CompiledDPath, argType: NodeInfo.Kind)
124124
dstate.setCurrentValue(computeValue(arg, dstate))
125125
}
126126

127-
override def toXML = toXML(recipe.toXML)
127+
override def toXML = toXMLVarargs(recipe.toXML)
128128

129129
def computeValue(str: DataValuePrimitive, dstate: DState): DataValuePrimitive
130130
}

0 commit comments

Comments
 (0)