This is an automated email from the ASF dual-hosted git repository. mbeckerle pushed a commit to branch daf-2975 in repository https://gitbox.apache.org/repos/asf/daffodil.git
commit 27b00b7c765ecb6a7fb65fa423c97b3dbd2565dc Author: Michael Beckerle <[email protected]> AuthorDate: Thu Feb 27 00:36:57 2025 -0500 Checkpoint - eliminated all macros. Working through errors. Lots of XML pattern matching and destructuring is no longer supported by scala 3.x. --- .../org/apache/daffodil/io/DataInputStream.scala | 19 ++- .../daffodil/io/DataOutputStreamImplMixin.scala | 10 +- .../main/scala/org/apache/daffodil/io/Dump.scala | 4 +- .../processors/charset/BitsCharsetDefinition.scala | 4 +- .../io/processors/charset/CharsetUtils.scala | 2 +- .../apache/daffodil/lib/exceptions/Assert.scala | 2 +- .../apache/daffodil/lib/exceptions/ThrowsSDE.scala | 58 ++++++--- .../org/apache/daffodil/lib/util/MStack.scala | 2 +- .../scala/org/apache/daffodil/lib/util/Misc.scala | 4 +- .../scala/org/apache/daffodil/lib/util/Timer.scala | 33 ++++- .../lib/xml/test/unit/TestXMLLiterals.scala | 2 +- .../daffodil/lib/xml/test/unit/TestXMLLoader.scala | 2 +- .../scala/org/apache/daffodil/io/IOMacros.scala | 62 ---------- .../apache/daffodil/lib/exceptions/SDEMacros.scala | 133 --------------------- .../org/apache/daffodil/lib/util/TimerMacros.scala | 67 ----------- .../parsers/PointOfUncertaintyMacros.scala | 98 --------------- .../runtime1/debugger/InteractiveDebugger.scala | 22 ++-- .../daffodil/runtime1/infoset/InfosetImpl.scala | 16 +-- .../runtime1/processors/ProcessorStateBases.scala | 8 +- .../runtime1/processors/parsers/PState.scala | 40 +++---- .../schematron/SchematronValidator.scala | 2 +- .../validation/schematron/Transforms.scala | 4 +- .../org/apache/daffodil/tdml/TDMLRunner.scala | 6 +- 23 files changed, 149 insertions(+), 451 deletions(-) diff --git a/daffodil-io/src/main/scala/org/apache/daffodil/io/DataInputStream.scala b/daffodil-io/src/main/scala/org/apache/daffodil/io/DataInputStream.scala index 413874369..2d9bb029d 100644 --- a/daffodil-io/src/main/scala/org/apache/daffodil/io/DataInputStream.scala +++ b/daffodil-io/src/main/scala/org/apache/daffodil/io/DataInputStream.scala @@ -548,8 +548,23 @@ trait DataInputStream extends DataStreamCommon { * Note that length limits in lengthUnits Characters are not implemented * this way. See fillCharBuffer(cb) method. */ - final def withBitLengthLimit(lengthLimitInBits: Long)(body: => Unit): Boolean = - macro IOMacros.withBitLengthLimitMacroForInput + final inline def withBitLengthLimit(lengthLimitInBits: Long)(body: => Unit): Boolean = { + import org.apache.daffodil.lib.util.MaybeULong + + val dStream = this + val newLengthLimit = lengthLimitInBits + val savedLengthLimit = dStream.bitLimit0b + + if (!dStream.setBitLimit0b(MaybeULong(dStream.bitPos0b + newLengthLimit))) false + else { + try { + body + } finally { + dStream.resetBitLimit0b(savedLengthLimit) + } + true + } + } /** * Closes any underlying I/O streams/channels that are part of the implementation diff --git a/daffodil-io/src/main/scala/org/apache/daffodil/io/DataOutputStreamImplMixin.scala b/daffodil-io/src/main/scala/org/apache/daffodil/io/DataOutputStreamImplMixin.scala index d7bea15c2..4e2fa6d01 100644 --- a/daffodil-io/src/main/scala/org/apache/daffodil/io/DataOutputStreamImplMixin.scala +++ b/daffodil-io/src/main/scala/org/apache/daffodil/io/DataOutputStreamImplMixin.scala @@ -277,7 +277,7 @@ trait DataOutputStreamImplMixin * Returns false if the set was unsuccessful, meaning one is setting a limit that * extends past a pre-existing limit. */ - protected def setMaybeRelBitLimit0b( + def setMaybeRelBitLimit0b( newMaybeRelBitLimit0b: MaybeULong, reset: Boolean = false ): Boolean = { @@ -330,7 +330,7 @@ trait DataOutputStreamImplMixin * Always between 0 and 7 inclusive. */ private var fragmentLastByteLimit_ : Int = 0 - def fragmentLastByteLimit = fragmentLastByteLimit_ + def fragmentLastByteLimit: Int = fragmentLastByteLimit_ def setFragmentLastByte(newFragmentByte: Int, nBitsInUse: Int): Unit = { Assert.usage(nBitsInUse >= 0 && nBitsInUse <= 7) @@ -375,7 +375,7 @@ trait DataOutputStreamImplMixin protected def getJavaOutputStream(): java.io.OutputStream - final protected def cst = this + final def cst: DataOutputStreamImplMixin = this protected def assignFrom(other: DataOutputStreamImplMixin): Unit = { Assert.usage(isWritable) @@ -711,7 +711,7 @@ trait DataOutputStreamImplMixin ): Long = { Assert.usage(isWritable) if (isEndOnByteBoundary) { - val nBytes = + val nBytes: Long = if (exceedsBitLimit(lengthInBytes)) { val n = (maybeRelBitLimit0b.getULong - relBitPos0b) / 8 Assert.invariant(n >= 0) @@ -849,7 +849,7 @@ trait DataOutputStreamImplMixin private def putByteBuffer(bb: java.nio.ByteBuffer, finfo: FormatInfo): Long = { Assert.usage(isWritable) - val nTransferred = + val nTransferred : Long = if (bb.hasArray) { putBytes(bb.array, bb.arrayOffset + bb.position(), bb.remaining(), finfo) } else { diff --git a/daffodil-io/src/main/scala/org/apache/daffodil/io/Dump.scala b/daffodil-io/src/main/scala/org/apache/daffodil/io/Dump.scala index 8eeb067fe..be6517f67 100644 --- a/daffodil-io/src/main/scala/org/apache/daffodil/io/Dump.scala +++ b/daffodil-io/src/main/scala/org/apache/daffodil/io/Dump.scala @@ -617,14 +617,14 @@ class DataDumper { Assert.invariant(cb.hasArray) val allChars = cb.array - val uCodePoint = + val uCodePoint: Int = if (allChars.length > 1) { if (UCharacter.isSurrogatePair(allChars(0), allChars(1))) { UCharacter.getCodePoint(allChars(0), allChars(1)) } else { INVALID_CODEPOINT } - } else allChars(0) + } else allChars(0).toInt val (r: String, n: Int) = if (allChars.length > 1) { diff --git a/daffodil-io/src/main/scala/org/apache/daffodil/io/processors/charset/BitsCharsetDefinition.scala b/daffodil-io/src/main/scala/org/apache/daffodil/io/processors/charset/BitsCharsetDefinition.scala index c6af1fb95..5b295b941 100644 --- a/daffodil-io/src/main/scala/org/apache/daffodil/io/processors/charset/BitsCharsetDefinition.scala +++ b/daffodil-io/src/main/scala/org/apache/daffodil/io/processors/charset/BitsCharsetDefinition.scala @@ -22,8 +22,6 @@ package org.apache.daffodil.io.processors.charset * org.apache.daffodil.runtime1.processors.charset.BitsCharsetDefinition file in * daffodil-io/src/main/resources/META-INF/services. name() must return a fully capitalized string */ -abstract class BitsCharsetDefinition(charset: BitsCharset, alias: Option[String] = None) { +abstract class BitsCharsetDefinition(final val charset: BitsCharset, alias: Option[String] = None) { final def name(): String = alias.getOrElse(charset.name).toUpperCase() - - final def charset(): BitsCharset = charset } diff --git a/daffodil-io/src/main/scala/org/apache/daffodil/io/processors/charset/CharsetUtils.scala b/daffodil-io/src/main/scala/org/apache/daffodil/io/processors/charset/CharsetUtils.scala index 53429f990..234b203d2 100644 --- a/daffodil-io/src/main/scala/org/apache/daffodil/io/processors/charset/CharsetUtils.scala +++ b/daffodil-io/src/main/scala/org/apache/daffodil/io/processors/charset/CharsetUtils.scala @@ -38,7 +38,7 @@ object CharsetUtils { if (cs == null) null else - cs.charset() + cs.charset } def supportedEncodingsString = BitsCharsetDefinitionRegistry.supportedEncodingsString diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/Assert.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/Assert.scala index f96610c05..ee3032de0 100644 --- a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/Assert.scala +++ b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/Assert.scala @@ -131,7 +131,7 @@ object Assert extends Assert { * This is for more complex invariants than the simple 'impossible' case. */ inline def invariant(testAbortsIfFalse: => Boolean): Unit = - if (!(testAbortsIfFalse)) { + if (!(testAbortsIfFalse)) Assert.abort("Invariant broken: " + code"testAbortsIfFalse") /** diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/ThrowsSDE.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/ThrowsSDE.scala index dc5df76c3..0cef09e41 100644 --- a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/ThrowsSDE.scala +++ b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/exceptions/ThrowsSDE.scala @@ -59,23 +59,35 @@ trait ThrowsSDE { SDE(str, args: _*) // long form synonym /** - * * - * These functions are now macros as the original code: - * final def schemaDefinitionUnless(testThatWillThrowIfFalse: Boolean, str: => String, args: => Any*) = if (!testThatWillThrowIfFalse) SDE(str, args: _*) - * would cause expensive object allocation, even when the - * test would be true and even when the function was inlined + * We are hoping that the inline combined with + * lazy by-name args allows these methods + * to avoid constructing the message string or + * args list items unless the test has been + * evaluated and indicates we WILL issue the SDE. + * + * That way when we're not issuing an SDE there + * will not be a bunch of overhead associated with + * gathering error/diagnostic info. */ - final def schemaDefinitionUnless( + final inline def schemaDefinitionUnless( testThatWillThrowIfFalse: Boolean, - str: String, - args: Any* - ): Unit = macro SDEMacros.schemaDefinitionUnlessMacro + str: => String, + args: => Any* + ): Unit = { + if (!(testThatWillThrowIfFalse)) { + SDE(str, args : _*) + } + } - final def schemaDefinitionWhen( + final inline def schemaDefinitionWhen( testThatWillThrowIfTrue: Boolean, - str: String, - args: Any* - ): Unit = macro SDEMacros.schemaDefinitionWhenMacro + str: => String, + args: => Any* + ): Unit = { + if (testThatWillThrowIfTrue) { + SDE(str, args : _*) + } + } final def notYetImplemented(msg: String, args: Any*): Nothing = SDE("Feature not yet implemented: " + msg, args: _*) @@ -85,7 +97,7 @@ trait ThrowsSDE { * not to implement. Not merely short term (haven't coded it yet, but intending to), * more like things we've chosen to defer intentionally to some future release. */ - def subset(testThatWillThrowIfFalse: Boolean, msg: String, args: Any*) = { + inline def subset(testThatWillThrowIfFalse: Boolean, msg: => String, args: => Any*) = { if (!testThatWillThrowIfFalse) subsetError(msg, args: _*) } @@ -126,12 +138,16 @@ trait SavesErrorsAndWarnings { /** * Conditionally issue a warning. The WarnID allows warning suppression. */ - def schemaDefinitionWarningUnless( + inline def schemaDefinitionWarningUnless( warnID: WarnID, testThatWillWarnIfFalse: Boolean, - str: String, - args: Any* - ): Unit = macro SDEMacros.schemaDefinitionWarningUnlessSuppressMacro + str: => String, + args: => Any* + ): Unit = { + if (!(testThatWillWarnIfFalse)) { + SDW(warnID, str, args : _*) + } + } /** * Conditionally issue a warning. The WarnID allows warning suppression. @@ -141,7 +157,11 @@ trait SavesErrorsAndWarnings { testThatWillWarnIfTrue: Boolean, str: String, args: Any* - ): Unit = macro SDEMacros.schemaDefinitionWarningWhenSuppressMacro + ): Unit = { + if (testThatWillWarnIfTrue) { + SDW(warnID, str, args : _*) + } + } /** * SDE special case when we're blaming the error on the value of a property. diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/MStack.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/MStack.scala index e8e68845e..1e0c3561b 100644 --- a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/MStack.scala +++ b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/MStack.scala @@ -117,7 +117,7 @@ final class MStackOfMaybe[T <: AnyRef] { @inline final def isEmpty = delegate.isEmpty def clear() = delegate.clear() - def toListMaybe = delegate.toList.map { x: AnyRef => + def toListMaybe = delegate.toList.map { (x: AnyRef) => Maybe(x) // Scala compiler bug without this cast } } diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Misc.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Misc.scala index 7679f0be2..22adfbb92 100644 --- a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Misc.scala +++ b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Misc.scala @@ -487,7 +487,7 @@ object Misc { ): Char = { val URC = 0x2426 // Unicode control picture character for substitution (also looks like arabic q-mark) - val code = c.toInt match { + val code: Int = c.toInt match { // // C0 Control pictures case n if (n <= 0x1f) => n + 0x2400 @@ -535,7 +535,7 @@ object Misc { // on these being preserved. So we have a flag to control this. // case n if (n > 0x2400 && n < 0x2423 && replaceControlPictures) => URC - case _ => c + case x => x } code.toChar } diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Timer.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Timer.scala index 43e69c9d7..a969d3b02 100644 --- a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Timer.scala +++ b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Timer.scala @@ -208,10 +208,39 @@ object TimeTracker { * // code to track goes here * } * - * Once processing is complete, a call to logTimes will dispaly the stats + * Once processing is complete, a call to logTimes will display the stats * about the tracked sections. + * + * inline so as to avoid the overhead of allocating a closure for the body + * lazy arg. */ - def track[A](name: String)(body: => A): A = macro TimeTrackerMacros.trackMacro + inline def track[A](name: String)(body: => A): A = { + val startTime = System.nanoTime + TimeTracker.childrenTimeStack.push(0) + + val result = try { + body + } finally { + val endTime = System.nanoTime + val timeTaken = endTime - startTime + val childrenTime = TimeTracker.childrenTimeStack.pop() + val selfTime = timeTaken - childrenTime + + val key = name + val sectionTime = TimeTracker.sectionTimes.get(key) + if (sectionTime == null) { + TimeTracker.sectionTimes.put(key, new TimeTracker.SectionTime(selfTime, 1)) + } else { + sectionTime.time += selfTime + sectionTime.count += 1 + } + + if (!TimeTracker.childrenTimeStack.isEmpty) { + TimeTracker.childrenTimeStack.push(TimeTracker.childrenTimeStack.pop + timeTaken) + } + } + result + } /** * Output the results of the tracked sections in sorted columnar format. diff --git a/daffodil-lib/src/test/scala/org/apache/daffodil/lib/xml/test/unit/TestXMLLiterals.scala b/daffodil-lib/src/test/scala/org/apache/daffodil/lib/xml/test/unit/TestXMLLiterals.scala index 65cea1132..977e603f9 100644 --- a/daffodil-lib/src/test/scala/org/apache/daffodil/lib/xml/test/unit/TestXMLLiterals.scala +++ b/daffodil-lib/src/test/scala/org/apache/daffodil/lib/xml/test/unit/TestXMLLiterals.scala @@ -32,7 +32,7 @@ class TestXMLLiterals { // val actual = <x><![CDATA[a b]]></x> - val <x>{xbody @ _*}</x> = actual + val <x>{ xbody* }</x> = actual assertEquals(1, xbody.length) val body = xbody(0) val txt = body.text diff --git a/daffodil-lib/src/test/scala/org/apache/daffodil/lib/xml/test/unit/TestXMLLoader.scala b/daffodil-lib/src/test/scala/org/apache/daffodil/lib/xml/test/unit/TestXMLLoader.scala index 9b2fdb93c..ca0e67b33 100644 --- a/daffodil-lib/src/test/scala/org/apache/daffodil/lib/xml/test/unit/TestXMLLoader.scala +++ b/daffodil-lib/src/test/scala/org/apache/daffodil/lib/xml/test/unit/TestXMLLoader.scala @@ -106,7 +106,7 @@ class TestXMLLoader { val data = "<x><![CDATA[a\nb&\"<>]]></x>" val node = scala.xml.XML.loadString(data) - val <x>{xbody @ _*}</x> = node + val <x>{ xbody * }</x> = node assertEquals(1, xbody.length) val body = xbody(0) val txt = body.text diff --git a/daffodil-macro-lib/src/main/scala/org/apache/daffodil/io/IOMacros.scala b/daffodil-macro-lib/src/main/scala/org/apache/daffodil/io/IOMacros.scala deleted file mode 100644 index ca25b7c2b..000000000 --- a/daffodil-macro-lib/src/main/scala/org/apache/daffodil/io/IOMacros.scala +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.daffodil.io - -import scala.reflect.macros.blackbox.Context - -object IOMacros { - - /** - * For Data Input Streams - * - * Used to temporarily vary the bit length limit. - * - * Implementing as a macro eliminates the creation of a downward function object every time this - * is called. - * - */ - def withBitLengthLimitMacroForInput(c: Context)(lengthLimitInBits: c.Tree)(body: c.Tree) = { - - import c.universe._ - - val dStream = TermName(c.freshName()) - val newLengthLimit = TermName(c.freshName()) - val savedLengthLimit = TermName(c.freshName()) - // c.prefix is the expression this macro was expanded on. Not quite same thing as 'this' because we have to be - // careful not to use it more than once or it will evaluate more than once. - val selfExp = c.prefix - - q"""{ - import org.apache.daffodil.lib.util.MaybeULong - - val $dStream = $selfExp - val $newLengthLimit = $lengthLimitInBits - val $savedLengthLimit = $dStream.bitLimit0b - - if (!$dStream.setBitLimit0b(MaybeULong($dStream.bitPos0b + $newLengthLimit))) false - else { - try { - $body - } finally { - $dStream.resetBitLimit0b($savedLengthLimit) - } - true - } - }""" - } -} diff --git a/daffodil-macro-lib/src/main/scala/org/apache/daffodil/lib/exceptions/SDEMacros.scala b/daffodil-macro-lib/src/main/scala/org/apache/daffodil/lib/exceptions/SDEMacros.scala deleted file mode 100644 index 2d73ab39a..000000000 --- a/daffodil-macro-lib/src/main/scala/org/apache/daffodil/lib/exceptions/SDEMacros.scala +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.daffodil.lib.exceptions - -import scala.reflect.macros.blackbox.Context - -object SDEMacros { - - def schemaDefinitionUnlessMacro(c: Context)( - testThatWillThrowIfFalse: c.Expr[Boolean], - str: c.Expr[String], - args: c.Expr[Any]* - ): c.Expr[Unit] = { - import c.universe._ - - val selfExp = c.prefix - - c.Expr(q""" - { - if (!($testThatWillThrowIfFalse)) { - $selfExp.SDE($str, ..$args) - } - } - """) - } - - def schemaDefinitionWhenMacro(c: Context)( - testThatWillThrowIfTrue: c.Expr[Boolean], - str: c.Expr[String], - args: c.Expr[Any]* - ): c.Expr[Unit] = { - import c.universe._ - - val selfExp = c.prefix - - c.Expr(q""" - { - if ($testThatWillThrowIfTrue) { - $selfExp.SDE($str, ..$args) - } - } - """) - } - - def schemaDefinitionWarningUnlessMacro(c: Context)( - testThatWillWarnIfFalse: c.Expr[Boolean], - str: c.Expr[String], - args: c.Expr[Any]* - ): c.Expr[Unit] = { - import c.universe._ - - val selfExp = c.prefix - - c.Expr(q""" - { - if (!($testThatWillWarnIfFalse)) { - $selfExp.SDW($str, ..$args) - } - } - """) - } - - def schemaDefinitionWarningUnlessSuppressMacro(c: Context)( - warnID: c.Tree, - testThatWillWarnIfFalse: c.Expr[Boolean], - str: c.Expr[String], - args: c.Expr[Any]* - ): c.Expr[Unit] = { - import c.universe._ - - val selfExp = c.prefix - - c.Expr(q""" - { - if (!($testThatWillWarnIfFalse)) { - $selfExp.SDW($warnID, $str, ..$args) - } - } - """) - } - - def schemaDefinitionWarningWhenMacro(c: Context)( - testThatWillWarnIfTrue: c.Expr[Boolean], - str: c.Expr[String], - args: c.Expr[Any]* - ): c.Expr[Unit] = { - import c.universe._ - - val selfExp = c.prefix - - c.Expr(q""" - { - if ($testThatWillWarnIfTrue) { - $selfExp.SDW($str, ..$args) - } - } - """) - } - - def schemaDefinitionWarningWhenSuppressMacro(c: Context)( - warnID: c.Tree, - testThatWillWarnIfTrue: c.Expr[Boolean], - str: c.Expr[String], - args: c.Expr[Any]* - ): c.Expr[Unit] = { - import c.universe._ - - val selfExp = c.prefix - - c.Expr(q""" - { - if ($testThatWillWarnIfTrue) { - $selfExp.SDW($warnID, $str, ..$args) - } - } - """) - } -} diff --git a/daffodil-macro-lib/src/main/scala/org/apache/daffodil/lib/util/TimerMacros.scala b/daffodil-macro-lib/src/main/scala/org/apache/daffodil/lib/util/TimerMacros.scala deleted file mode 100644 index 92f0cfed0..000000000 --- a/daffodil-macro-lib/src/main/scala/org/apache/daffodil/lib/util/TimerMacros.scala +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.daffodil.lib.util - -import scala.reflect.macros.blackbox.Context - -object TimeTrackerMacros { - - def trackMacro(c: Context)(name: c.Tree)(body: c.Tree) = { - import c.universe._ - - val startTime = TermName(c.freshName()) - val endTime = TermName(c.freshName()) - val childrenTime = TermName(c.freshName()) - val timeTaken = TermName(c.freshName()) - val selfTime = TermName(c.freshName()) - val sectionTime = TermName(c.freshName()) - val result = TermName(c.freshName()) - val key = TermName(c.freshName()) - - q""" - { - val $startTime = System.nanoTime - TimeTracker.childrenTimeStack.push(0) - - val $result = try { - $body - } finally { - val $endTime = System.nanoTime - val $timeTaken = $endTime - $startTime - val $childrenTime = TimeTracker.childrenTimeStack.pop() - val $selfTime = $timeTaken - $childrenTime - - val $key = $name - val $sectionTime = TimeTracker.sectionTimes.get($key) - if ($sectionTime == null) { - TimeTracker.sectionTimes.put($key, new TimeTracker.SectionTime($selfTime, 1)) - } else { - $sectionTime.time += $selfTime - $sectionTime.count += 1 - } - - if (!TimeTracker.childrenTimeStack.isEmpty) { - TimeTracker.childrenTimeStack.push(TimeTracker.childrenTimeStack.pop + $timeTaken) - } - } - - $result - } - """ - } -} diff --git a/daffodil-macro-lib/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/PointOfUncertaintyMacros.scala b/daffodil-macro-lib/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/PointOfUncertaintyMacros.scala deleted file mode 100644 index 32305731d..000000000 --- a/daffodil-macro-lib/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/PointOfUncertaintyMacros.scala +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.daffodil.runtime1.processors.parsers - -import scala.reflect.macros.blackbox.Context - -object PointOfUncertaintyMacros { - - /** - * For creating a point of uncertainty and ensuring that it is cleaned up - * appropriately. This allows the use of standard scala-style syntax to - * create and use points of uncertainties, while avoiding allocating - * functions. Thus, this allows something like this: - * - * pstate.withPointOfUncertainty { pou => - * // code that implements parsing, and may potentially reset to, - * // discard, or resolve this pou variable - * } - * - * Upon completion of the block, if the new point of uncertainty has not been - * discarded, reset to, or resovled, this pou will then be discarded, - * ensuring that Marks are always cleaned up appropriately. - */ - def withPointOfUncertainty[A, B]( - c: Context - )(pouID: c.Expr[String], context: c.Tree)(func: c.Expr[A => B]) = { - - import c.universe._ - - val state = TermName(c.freshName("state")) - val id = TermName(c.freshName("id")) - val pou = TermName(c.freshName("pou")) - val ctx = TermName(c.freshName("context")) - - func.tree match { - - // The func tree is something like (param => body), where param is the - // name the caller wants to name the point of uncertainty mark, and body - // is the code that uses this point of uncertainty. We transform this - // code to create a new point of uncertainty, evaluate the body, and then - // use a finally block to ensure we discard the PoU if it has not been - // resolved. - case q"""($param: $_) => $body""" => { - - // The "body" uses the "param" variable name, and scala doesn't like it - // if we just create a new variable with this name, with a very unclear - // error message. Instead, we need to create a "fresh" variable name to - // hold the new point of uncertainty, and then transform the body so - // that all instances of "param" are replaced with our new fresh name. - val transformer = new Transformer { - override def transform(tree: Tree): Tree = tree match { - case Ident(`param`) => Ident(pou) - case other => super.transform(other) - } - } - val newBody = transformer.transform(c.untypecheck(body)) - - q"""{ - // ensure we do not evaluate passed in parameters more than once - val $state = ${c.prefix} - val $id = $pouID - val $ctx = $context - - // create our new point of uncertainty - val $pou = $state.createPointOfUncertainty($id, $ctx) - try { - // evalute the transformed body, which can use this new point of uncertainty - $newBody - } finally { - // if the pou still exists at this point, then simply discard it. - // This is likely because an exception occurred, or just because we - // do not require that parsers discard PoUs, with the understanding - // that it will always happen here - if (!$state.isPointOfUncertaintyResolved($pou)) { - $state.discardPointOfUncertainty($pou) - } - } - }""" - } - } - - } -} diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/debugger/InteractiveDebugger.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/debugger/InteractiveDebugger.scala index a086b7f91..6a645612f 100644 --- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/debugger/InteractiveDebugger.scala +++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/debugger/InteractiveDebugger.scala @@ -568,7 +568,7 @@ class InteractiveDebugger( case _ => { val subcmd = args.head val subcmdArgs = args.tail - subcommands.find(_ == subcmd) match { + subcommands.find(_.name == subcmd) match { case Some(cmd) => cmd.help(subcmdArgs) case None => throw new DebugException("unknown command: %s".format(subcmd)) } @@ -604,7 +604,7 @@ class InteractiveDebugger( } val subcmd = args.head val subcmdArgs = args.tail - subcommands.find(_ == subcmd) match { + subcommands.find(_.name == subcmd) match { case Some(c) => c.validate(subcmdArgs) case None => { throw new DebugException("undefined command: %s".format(subcmd)) @@ -697,7 +697,7 @@ class InteractiveDebugger( ): DebugState.Type = { val subcmd = args.head val subcmdArgs = args.tail - val subcmdActor = subcommands.find(_ == subcmd).get + val subcmdActor = subcommands.find(_.name == subcmd).get val newState = subcmdActor.act(subcmdArgs, state, processor) newState } @@ -855,7 +855,7 @@ class InteractiveDebugger( ): DebugState.Type = { val subcmd = args.head val subcmdArgs = args.tail - subcommands.find(_ == subcmd).get.act(subcmdArgs, state, processor) + subcommands.find(_.name == subcmd).get.act(subcmdArgs, state, processor) DebugState.Pause } @@ -926,7 +926,7 @@ class InteractiveDebugger( ): DebugState.Type = { val subcmd = args.head val subcmdArgs = args.tail - subcommands.find(_ == subcmd).get.act(subcmdArgs, state, processor) + subcommands.find(_.name == subcmd).get.act(subcmdArgs, state, processor) DebugState.Pause } @@ -1021,7 +1021,7 @@ class InteractiveDebugger( ): DebugState.Type = { val subcmd = args.head val subcmdArgs = args.tail - subcommands.find(_ == subcmd).get.act(subcmdArgs, state, processor) + subcommands.find(_.name == subcmd).get.act(subcmdArgs, state, processor) DebugState.Pause } @@ -1353,7 +1353,7 @@ class InteractiveDebugger( private def buildInfoCommands(args: Seq[String]): Seq[Seq[String]] = { val backwardsInfoCommands = args.foldLeft(Seq.empty[Seq[String]]) { case (infoCmds, arg) => - val cmd = subcommands.find(_ == arg) + val cmd = subcommands.find(_.name == arg) if (cmd.isDefined || infoCmds.isEmpty) { // Found a new info subcommand, or we don't have an info commands // yet. Create a new Seq to hold the subcommand + args and @@ -1383,7 +1383,7 @@ class InteractiveDebugger( val infocmds = buildInfoCommands(args) infocmds.foreach { cmds => val cmd :: args = cmds - subcommands.find(_ == cmd) match { + subcommands.find(_.name == cmd) match { case Some(c) => c.validate(args) case None => throw new DebugException("undefined info command: %s".format(cmd)) } @@ -1398,7 +1398,7 @@ class InteractiveDebugger( val infocmds = buildInfoCommands(args) infocmds.foreach { cmds => val cmd :: args = cmds - val action = subcommands.find(_ == cmd).get + val action = subcommands.find(_.name == cmd).get action.act(args, state, processor) } DebugState.Pause @@ -2044,7 +2044,7 @@ class InteractiveDebugger( | |Example: set breakOnlyOnCreation false | set dataLength 100""".stripMargin - override val subcommands = Seq( + override val subcommands: Seq[DebugCommand] = Seq( SetBreakOnFailure, SetBreakOnlyOnCreation, SetDataLength, @@ -2064,7 +2064,7 @@ class InteractiveDebugger( ): DebugState.Type = { val subcmd = args.head val subcmdArgs = args.tail - subcommands.find(_ == subcmd).get.act(subcmdArgs, state, processor) + subcommands.find(_.name == subcmd).get.act(subcmdArgs, state, processor) DebugState.Pause } diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/InfosetImpl.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/InfosetImpl.scala index 0ac7b1063..db7fede97 100644 --- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/InfosetImpl.scala +++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/infoset/InfosetImpl.scala @@ -454,13 +454,13 @@ sealed trait DITerm { final lazy val parserEvalCache = new EvalCache final lazy val unparserEvalCache = new EvalCache - def evalCache(state: ParseOrUnparseState) = state match { + def evalCache(state: ParseOrUnparseState): EvalCache = state match { case p: PState => parserEvalCache case _ => unparserEvalCache } def trd: TermRuntimeData - final def termRuntimeData = trd + final def termRuntimeData: TermRuntimeData = trd } /** @@ -1034,8 +1034,8 @@ sealed trait DIElement def isArray: Boolean final def name: String = erd.name - override final def namedQName = erd.namedQName - override final def trd = erd + override final def namedQName: NamedQName = erd.namedQName + override final def trd: TermRuntimeData = erd /** * Used to prevent the infoset walker from walking into an infoset element. @@ -1058,7 +1058,7 @@ sealed trait DIElement */ override def toString = { val cl = Misc.getNameFromClass(this) - val n = trd.name + val n = erd.name val clStr = if (_contentLength eq null) "" else " " + contentLength.toString() val vlStr = if (_valueLength eq null) "" else " " + valueLength.toString() val validStr = @@ -1107,12 +1107,12 @@ sealed trait DIElement _isHidden = true } - final def runtimeData = erd + final def runtimeData: ElementRuntimeData = erd protected final var _parent: DIComplex = null - def parent = _parent + def parent: DIComplex = _parent - def diParent = _parent.asInstanceOf[DIComplex] + def diParent: DIComplex = _parent.asInstanceOf[DIComplex] def setParent(p: DIComplex): Unit = { Assert.invariant(_parent eq null) diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/ProcessorStateBases.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/ProcessorStateBases.scala index 43f9e7b24..90030c109 100644 --- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/ProcessorStateBases.scala +++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/ProcessorStateBases.scala @@ -375,8 +375,8 @@ abstract class ParseOrUnparseState protected ( * * The exception to this is the interactive debugger. */ - final protected def variableMap = variableBox.vmap - final protected def setVariableMap(newMap: VariableMap): Unit = { + final def variableMap = variableBox.vmap + final def setVariableMap(newMap: VariableMap): Unit = { variableBox.setVMap(newMap) } @@ -404,8 +404,8 @@ abstract class ParseOrUnparseState protected ( */ final def variableMapForDebugger = variableMap - final protected var _processorStatus: ProcessorResult = Success - final protected var _validationStatus: Boolean = true + final var _processorStatus: ProcessorResult = Success + final var _validationStatus: Boolean = true final def processorStatus = _processorStatus final def validationStatus = _validationStatus diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/PState.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/PState.scala index 1285d9d46..b2106c0d8 100644 --- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/PState.scala +++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/parsers/PState.scala @@ -237,7 +237,7 @@ final class PState private ( } override def hasInfoset = true - def thisElement = infoset + def thisElement: DIElement = infoset override def groupPos = mpstate.groupPos override def arrayIterationPos = mpstate.arrayIterationPos @@ -403,28 +403,24 @@ final class PState private ( variableMap.removeVariableInstance(vrd) } - /** - * Creates a new point of uncertainty and binds it to a variable where it can - * be used. The PoU can be reset, discarded, or resolved, via helper - * functions. If at the end of the func block, the PoU was not reset, - * discarded or resolved, it will automatically be discarded. Example usage - * of this is: - * - * pstate.withPointOfUncertainty { pou => - * // perform parsing logic that uses the "pou" variable - * } - * - * Note that this is implemented via a macro, and part of this macro magic - * will munges with variable names in the "func" variable. Thus, this is - * potentially fragile, e.g. reflection on the pou variable name will fail. - * It is recommend to keep the func body as small as possible and avoid - * things like reflection that could cause breakage. - */ - def withPointOfUncertainty[B](pouID: String, context: RuntimeData)( - func: PState.Mark => B - ): B = - macro PointOfUncertaintyMacros.withPointOfUncertainty[PState.Mark, B] + inline def withPointOfUncertainty[B](id: String, ctx: RuntimeData)(func: PState.Mark => B): B = { + // create our new point of uncertainty + val pou = createPointOfUncertainty(id, ctx) + try { + // evaluate the using this new point of uncertainty + func(pou) + } finally { + // if the pou still exists at this point, then simply discard it. + // This is likely because an exception occurred, or just because we + // do not require that parsers discard PoUs, with the understanding + // that it will always happen here + if (!isPointOfUncertaintyResolved(pou)) { + discardPointOfUncertainty(pou) + } + } + } + /** * This function creates a mark, which represents a point of uncertainty. This * function should never be used, and is only public so that the diff --git a/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/SchematronValidator.scala b/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/SchematronValidator.scala index b467da892..6414f068e 100644 --- a/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/SchematronValidator.scala +++ b/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/SchematronValidator.scala @@ -35,7 +35,7 @@ final class SchematronValidator(engine: Schematron, svrlPath: Option[Path]) exte def validateXML(document: InputStream): ValidationResult = { val svrl = XML.loadString(engine.validate(document)) val valErr: Seq[ValidationFailure] = - for (f @ <svrl:failed-assert>{msg @ _*}</svrl:failed-assert> <- svrl.child) yield { + for (f @ <svrl:failed-assert>{ msg* }</svrl:failed-assert> <- svrl.child) yield { SchematronValidationError(msg.text.trim, { f \\ "@location" }.text) } diff --git a/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/Transforms.scala b/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/Transforms.scala index dd1986cf6..c4f557092 100644 --- a/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/Transforms.scala +++ b/daffodil-schematron/src/main/scala/org/apache/daffodil/validation/schematron/Transforms.scala @@ -84,10 +84,10 @@ object SchSource { } case object Sch extends SchSource { - lazy val stages = + lazy val stages: Seq[String] = List("iso_dsdl_include.xsl", "iso_abstract_expand.xsl", "iso_svrl_for_xslt2.xsl") } case object Xsd extends SchSource { - lazy val stages: Seq[String] = "ExtractSchFromXSD-2.xsl" :: Sch.stages + lazy val stages: Seq[String] = "ExtractSchFromXSD-2.xsl" +: Sch.stages } } diff --git a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala index c1053f171..b1d7bd4f3 100644 --- a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala +++ b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala @@ -2266,11 +2266,11 @@ case class Document(d: NodeSeq, parent: TestCase) { } } - private lazy val Seq(<document>{children @ _*}</document>) = d + private lazy val Seq(<document>{ children * }</document>) = d private val actualDocumentPartElementChildren = children.toList.flatMap { child => child match { - case <documentPart>{_*}</documentPart> => { + case <documentPart>{ _ * }</documentPart> => { List((child \ "@type").toString match { case "text" => new TextDocumentPart(child, this) case "byte" => new ByteDocumentPart(child, this) @@ -2290,7 +2290,7 @@ case class Document(d: NodeSeq, parent: TestCase) { if (actualDocumentPartElementChildren.nonEmpty) { children.foreach { child => child match { - case <documentPart>{_*}</documentPart> => // ok + case <documentPart>{ _ *}</documentPart> => // ok case scala.xml.Text(s) if (s.matches("""\s+""")) => // whitespace text nodes ok case scala.xml.Comment(_) => // ok case scala.xml.PCData(s) => // ok
