Skip to content

Commit

Permalink
Use Preprocessor from interface module
Browse files Browse the repository at this point in the history
  • Loading branch information
alexarchambault committed Jan 14, 2021
1 parent f9fe98c commit 5d6e8d5
Show file tree
Hide file tree
Showing 13 changed files with 119 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,28 @@ abstract class CodeWrapper {
indexedWrapper: Name,
extraCode: String
): (String, String, Int)

def wrapCode(codeSource: CodeSource,
indexedWrapperName: Name,
code: String,
printCode: String,
imports: Imports,
extraCode: String,
markScript: Boolean) = {

//we need to normalize topWrapper and bottomWrapper in order to ensure
//the snippets always use the platform-specific newLine
val extraCode0 =
if (markScript) extraCode + "/*</generated>*/"
else extraCode
val (topWrapper, bottomWrapper, userCodeNestingLevel) =
apply(code, codeSource, imports, printCode, indexedWrapperName, extraCode0)
val (topWrapper0, bottomWrapper0) =
if (markScript) (topWrapper + "/*<script>*/", "/*</script>*/ /*<generated>*/" + bottomWrapper)
else (topWrapper, bottomWrapper)
val importsLen = topWrapper0.length

(topWrapper0 + code + bottomWrapper0, importsLen, userCodeNestingLevel)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ammonite.compiler

import java.io.OutputStream

import ammonite.compiler.iface.Preprocessor
import ammonite.util.{Classpath, ImportData, Imports, Printer}
import ammonite.util.Util.newLine

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ammonite.compiler

import ammonite.compiler.iface.Preprocessor
import ammonite.util.Util._
import ammonite.util.{Classpath, Frame, Printer}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ammonite.compiler

import ammonite.compiler.iface.CodeWrapper
import ammonite.compiler.iface.{CodeWrapper, Preprocessor}
import ammonite.util._
import ammonite.util.Util.{CodeSource, newLine}

Expand Down Expand Up @@ -38,10 +38,10 @@ class DefaultPreprocessor(parse: => String => Either[String, Seq[G#Tree]],
assert(codeSource.pkgName.head == Name("ammonite"))
for{
Expanded(code, printer) <- expandStatements(stmts, resultIndex, skipEmpty)
(wrappedCode, importsLength, userCodeNestingLevel) = Preprocessor.wrapCode(
(wrappedCode, importsLength, userCodeNestingLevel) = codeWrapper.wrapCode(
codeSource, indexedWrapperName, leadingSpaces + code,
printerTemplate(printer.mkString(", ")),
imports, extraCode, markScript, codeWrapper
imports, extraCode, markScript
)
} yield Preprocessor.Output(wrappedCode, importsLength, userCodeNestingLevel)
}
Expand Down
79 changes: 78 additions & 1 deletion amm/compiler/src/main/scala/ammonite/compiler/Parsers.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package ammonite.compiler

import ammonite.util.ImportTree
import ammonite.util.Util.CodeSource
import ammonite.util.Util.{CodeSource, newLine, windowsPlatform}

import scala.collection.mutable

Expand Down Expand Up @@ -148,4 +148,81 @@ object Parsers {
}
(hookedStmts.toSeq, importTrees.toSeq)
}
def formatFastparseError(fileName: String, rawCode: String, f: Parsed.Failure) = {

val lineColIndex = f.extra.input.prettyIndex(f.index)
val expected = f.trace().failure.label
val locationString = {
val (first, last) = rawCode.splitAt(f.index)
val lastSnippet = last.split(newLine).headOption.getOrElse("")
val firstSnippet = first.reverse
.split(newLine.reverse)
.lift(0).getOrElse("").reverse
firstSnippet + lastSnippet + newLine + (" " * firstSnippet.length) + "^"
}
s"$fileName:$lineColIndex expected $expected$newLine$locationString"
}


/**
* Splits up a script file into its constituent blocks, each of which
* is a tuple of (leading-whitespace, statements). Leading whitespace
* is returned separately so we can later manipulate the statements e.g.
* by adding `val res2 = ` without the whitespace getting in the way
*/
def splitScript(
rawCode: String,
fileName: String
): Either[String, IndexedSeq[(String, Seq[String])]] = {
Parsers.splitScript(rawCode) match {
case f: Parsed.Failure =>
Left(formatFastparseError(fileName, rawCode, f))

case s: Parsed.Success[Seq[(String, Seq[(Int, String)])]] =>

var offset = 0
val blocks = mutable.ArrayBuffer[(String, Seq[String])]()

// comment holds comments or empty lines above the code which is not caught along with code
for( (comment, codeWithStartIdx) <- s.value){
val code = codeWithStartIdx.map(_._2)

//ncomment has required number of newLines appended based on OS and offset
//since fastparse has hardcoded `\n`s, while parsing strings with `\r\n`s it
//gives out one extra `\r` after '@' i.e. block change
//which needs to be removed to get correct line number (It adds up one extra line)
//thats why the `comment.substring(1)` thing is necessary
val ncomment =
if(windowsPlatform && blocks.nonEmpty && !comment.isEmpty){
comment.substring(1) + newLine * offset
}else{
comment + newLine * offset
}

// 1 is added as Separator parser eats up the newLine char following @
offset = offset + (comment.split(newLine, -1).length - 1) +
code.map(_.split(newLine, -1).length - 1).sum + 1
blocks.append((ncomment, code))
}

Right(blocks.toIndexedSeq)
}
}

def splitScriptWithStart(
rawCode: String,
fileName: String
): Either[Parsed.Failure, IndexedSeq[(Int, String, Seq[(Int, String)])]] = {
Parsers.splitScriptWithStart(rawCode) match {
case f: Parsed.Failure =>
Left(f)

case Parsed.Success(value, _) =>
val blocks = value.toVector.map {
case (startIdx, (comment, code)) =>
(startIdx, comment, code)
}
Right(blocks)
}
}
}
154 changes: 0 additions & 154 deletions amm/compiler/src/main/scala/ammonite/compiler/Preprocessor.scala

This file was deleted.

6 changes: 3 additions & 3 deletions amm/interp/src/main/scala/ammonite/interp/Interpreter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import java.io.{File, OutputStream, PrintStream}
import java.util.regex.Pattern

import ammonite.compiler._
import ammonite.compiler.iface.CodeWrapper
import ammonite.compiler.iface.{CodeWrapper, Preprocessor}
import ammonite.interp.api.{InterpAPI, InterpLoad, LoadJar}

import scala.collection.mutable
Expand Down Expand Up @@ -377,7 +377,7 @@ class Interpreter(val printer: Printer,
// and none of it's blocks end up needing to be re-compiled. We don't know up
// front if any blocks will need re-compilation, because it may import $file
// another script which gets changed, and we'd only know when we reach that block
lazy val splittedScript = Preprocessor.splitScript(
lazy val splittedScript = Parsers.splitScript(
Interpreter.skipSheBangLine(code),
codeSource.fileName
)
Expand Down Expand Up @@ -422,7 +422,7 @@ class Interpreter(val printer: Printer,
val wrapperName = Name("cmd" + currentLine)
val fileName = wrapperName.encoded + ".sc"
for {
blocks <- Res(Preprocessor.splitScript(Interpreter.skipSheBangLine(code), fileName))
blocks <- Res(Parsers.splitScript(Interpreter.skipSheBangLine(code), fileName))

metadata <- processAllScriptBlocks(
blocks.map(_ => None),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package ammonite.interp.script

import java.io.File

import ammonite.compiler.{DefaultCodeWrapper, Parsers, Preprocessor}
import ammonite.compiler.{DefaultCodeWrapper, Parsers}
import ammonite.compiler.iface.CodeWrapper
import ammonite.interp.{DependencyLoader, Interpreter}
import ammonite.runtime.{Frame, ImportHook, Storage}
Expand Down Expand Up @@ -30,7 +30,7 @@ final case class ScriptProcessor(

val rawCode = Interpreter.skipSheBangLine(code)
lazy val offsetToPos = PositionOffsetConversion.offsetToPos(rawCode)
val splittedScript = Preprocessor.splitScriptWithStart(
val splittedScript = Parsers.splitScriptWithStart(
rawCode,
codeSource.fileName
).left.map { f =>
Expand Down
4 changes: 2 additions & 2 deletions amm/repl/src/main/scala/ammonite/repl/AmmoniteFrontEnd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import GUILikeFilters.SelectionFilter
import ammonite.terminal._
import fastparse.Parsed
import ammonite.util.{Colors, Res}
import ammonite.compiler.{Parsers, Preprocessor}
import ammonite.compiler.Parsers
case class AmmoniteFrontEnd(extraFilters: Filter = Filter.empty) extends FrontEnd{

def width = FrontEndUtils.width
Expand All @@ -32,7 +32,7 @@ case class AmmoniteFrontEnd(extraFilters: Filter = Filter.empty) extends FrontEn
Res.Success((code, value.map(_._2)))
case f @ Parsed.Failure(_, index, extra) =>
Res.Failure(
Preprocessor.formatFastparseError("(console)", code, f)
Parsers.formatFastparseError("(console)", code, f)
)
}
}
Expand Down
4 changes: 2 additions & 2 deletions amm/repl/src/main/scala/ammonite/repl/FrontEnds.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import org.jline.terminal._
import org.jline.utils.AttributedString
import ammonite.util.{Catching, Colors, Res}
import ammonite.repl.api.FrontEnd
import ammonite.compiler.{Highlighter, Parsers, Preprocessor}
import ammonite.compiler.{Highlighter, Parsers}
import org.jline.reader.impl.DefaultParser


Expand Down Expand Up @@ -158,7 +158,7 @@ class AmmParser extends Parser {
if (context == Parser.ParseContext.ACCEPT_LINE) {
addHistory(line)
throw new SyntaxError(
Preprocessor.formatFastparseError("(console)", line, f)
Parsers.formatFastparseError("(console)", line, f)
)
} else {
new AmmoniteParsedLine(line, words, wordIndex, wordCursor, cursor)
Expand Down
Loading

0 comments on commit 5d6e8d5

Please sign in to comment.