Scala Interpreter: в любом случае, чтобы получить строку об ошибке компиляции? - PullRequest
4 голосов
/ 28 сентября 2011

Я использую интерпретатор scala для запуска определенного пользователем сценария. для этого я использую класс "IMain". Работает как талисман, за исключением случаев, когда сообщается о строке, где произошла ошибка компиляции. Чтобы получить номер строки ошибки, я просто анализирую выходное сообщение интерпретатора в форме : lineNumber : error: ...

Проблема в том, что номер строки меняется в зависимости от характера ошибки и объема (в пределах определения или нет).

Это также происходит с REPL, например:

Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Server VM, Java 1.6.0_24).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val a=7
a: Int = 7

scala> a.toString2
<console>:9: error: value toString2 is not a member of Int
              a.toString2
                ^

scala> a2.toString
<console>:8: error: not found: value a2
              a2.toString
              ^

scala> a.toString.length3
<console>:9: error: value length3 is not a member of java.lang.String
              a.toString.length3
                         ^

Я ожидаю, что все сообщения об ошибках начинаются с ": 1", поскольку ошибка находится в первой строке кода для интерпретации ...

Используя класс IMain, есть ли другой способ получить номер строки ошибки? (в дополнение к неверным результатам при разборе выходных данных возникает нечто вроде хака ...)

1 Ответ

1 голос
/ 29 сентября 2011

Отчасти ответ заключается в том, что вы вводите не то, что действительно запускает интерпретатор Scala.

Это можно увидеть с помощью scala -Xprint:parser: (Я использую Scala 2.8.1, так чтоучитывает некоторые различия)

scala> a.toString2
[[syntax trees at end of parser]]// Scala source: <console>
package <empty> {
  object line2$object extends scala.ScalaObject {
    def <init>() = {
      super.<init>();
      ()
    };
    object $iw extends scala.ScalaObject {
      def <init>() = {
        super.<init>();
        ()
      };
      import line0$object.$iw.$iw.a;
      object $iw extends scala.ScalaObject {
        def <init>() = {
          super.<init>();
          ()
        };
        val res0 = a.toString2
      }
    }
  }
}

<console>:7: error: value toString2 is not a member of Int
       a.toString2
         ^

против:

scala> a2.toString
[[syntax trees at end of parser]]// Scala source: <console>
package <empty> {
  object line3$object extends scala.ScalaObject {
    def <init>() = {
      super.<init>();
      ()
    };
    object $iw extends scala.ScalaObject {
      def <init>() = {
        super.<init>();
        ()
      };
      object $iw extends scala.ScalaObject {
        def <init>() = {
          super.<init>();
          ()
        };
        val res1 = a2.toString
      }
    }
  }
}

<console>:6: error: not found: value a2
       a2.toString
       ^

Сравните выходные данные после обеих строк.Смотрите дополнительную строку в первом бите вывода, который говорит:

 import line0$object.$iw.$iw.a;

?Эта дополнительная строка импорта учитывает разницу, которую вы видите в номерах строк.

Так что теперь вам нужен какой-то способ для класса IMain, чтобы сказать вам, сколько вещей он добавил в начало кода перед тем, какошибка.(Это все еще не полностью исправит ситуацию - посмотрите строку ошибки, которую вы получите для g})

...