Как scalac помечает скомпилированные файлы?

Посмотрите на этот вопрос. Когда вы открываете файл .class с включенным плагином scala (Intellij Idea), он показывает вам код scala, но когда он отключен, плагин декомпиляции Java показывает вам декомпилированный код Java. Обратите внимание, что файлы .class, скомпилированные с помощью javac, декомпилируются, даже если подключаемый модуль scala включен. Это означает, что плагин scala «смотрит» на какой-то маркер внутри файлов классов и перехватывает показ содержимого файла.

Какой маркер он на самом деле использует? Есть ли способ открыть файл .class и изменить компилятор (и/или) другую информацию, чтобы эти классы выглядели так, как будто они скомпилированы javac?


person Cherry    schedule 19.01.2018    source источник
comment
Вы не предоставили много подробностей (например, какая IDE, например, как вы прикрепили зависимость к своему проекту, например, прикреплен ли к файлу jar исходный файл jar). При поиске в Интернете не похоже, что там даже есть декомпилятор scala, поэтому, скорее всего, подключаемый модуль Scala в вашей среде IDE знает, что нужно искать в исходном jar-файле исходные файлы с расширением файла scala, а не с расширением файла java.   -  person Erwin Bolwidt    schedule 19.01.2018
comment
Посмотрите на исходный вопрос. IDE - это интеллектуальная идея (вопрос обновлен), файл jar содержит только .class скомпилированные файлы. В нем нет файлов с расширением java или scala.   -  person Cherry    schedule 19.01.2018
comment
Исходный код, который вы видите с включенным подключаемым модулем scala, содержит ли вообще какие-либо комментарии? Заявление об отказе от авторских прав, javadoc, многострочные комментарии, встроенные комментарии? Если это так, он не декомпилируется, потому что не существует декомпилятора, который мог бы это сделать, поскольку комментарии не хранятся в файле .class.   -  person Erwin Bolwidt    schedule 19.01.2018


Ответы (2)


Каждый файл класса может иметь SourceFile атрибут, который содержит имя файла исходного кода. Поскольку это произвольная строка, это немного о соглашениях, например. для исходного кода Java он обычно содержит только имя файла без каких-либо конкретных каталогов пакета.

Таким образом, все еще есть небольшая интерпретация информации, например. если указанное имя заканчивается на .java, IDE должна искать в известном исходном дереве соответствующий файл в подкаталогах, соответствующих фактическому пакету.

Определить, что исходный файл не является Java, так же просто, как признать, что он имеет другое окончание имени файла, а затем можно использовать любое соглашение, используемое для конкретного языка, если плагин, знающий об этом, был установлен. В противном случае большинство IDE будут просто искать любой текстовый файл с таким именем и отображать его. Могут быть LineNumberTable атрибуты< /a>, рассказывая, как инструкции байт-кода сопоставляются с номерами строк исходного кода, позволяя отладчикам выполнять код даже без понимания синтаксиса исходного кода. Я уже прошел через код, скомпилированный из XSLT-файла таким образом.

Конечно, шаблон указанного имени файла исходного кода также может быть использован для принятия решения о том, какой декомпилятор использовать, когда исходный файл не найден.

person Holger    schedule 19.01.2018
comment
В самом деле? Вы можете сделать это? - person Eugene; 19.01.2018
comment
@Eugene Я также отлаживал перенесенный код Java 8 с помощью Eclipse тогда, когда у него не было поддержки Java 8. Отладка просто работала через сопоставление имени файла и номера строки. Он даже пытался выделить код, но на красное подчеркивание приходилось не обращать внимания… - person Holger; 19.01.2018
comment
сколько жизней ты прожил? Я даже сейчас боюсь это пробовать, так привыкла к нестандартным вещам... - person Eugene; 19.01.2018
comment
@Eugene, в случае отладки XSLT это было даже не преднамеренно. Я отлаживал Java-код с помощью процессора xslt (скорее всего, xalan) и внезапно перешел к коду, сгенерированному процессором xslt, и оказался в соответствующем месте моего XSLT-файла, даже будучи в состоянии распознать примененную цепочку правил из трассировки стека. - person Holger; 19.01.2018

Интеллидж Идея

Intellij IDEA (при условии, что ваш вопрос касается этой IDE) просто выясняет, из какого исходного файла был скомпилирован двоичный файл, а затем отображает соответствующий источник.

Он не извлекает исходный код из двоичного файла. Он просто может найти источник для данного двоичного файла. Вы можете сделать это, сопоставив имена файлов и пути. Однако Intellij, вероятно, делает немного больше.

В целом

В общем, почти наверняка не существует хорошего декомпилятора, который мог бы создавать исходники Scala из файлов классов. Кроме того, исходный код не встроен, поэтому все, что вы можете сделать, это попытаться сопоставить файлы исходного кода с двоичными файлами.

Код Java, полученный в результате декомпиляции, отображается, когда среда IDE не может найти соответствующий исходный файл.

person ziggystar    schedule 19.01.2018
comment
просто выясняет, из какого исходного файла был скомпилирован бинарный файл и... Как он это делает? В class должна быть какая-то информация. Вот в чем вопрос. - person Cherry; 19.01.2018
comment
@Cherry Если у вас есть исходные файлы, вы хорошо знаете, как будут называться сгенерированные классы. Таким образом, начиная с исходного кода, вы можете построить сопоставление и обратить его. Дело в том, что вы можете сделать это без каких-либо тегов в файле класса. Вам просто нужно знать, как работает процесс сборки. И IDE должна это знать. - person ziggystar; 19.01.2018