Получить комментарии javascript в javascript или, как мне разобрать js в js? - PullRequest
3 голосов
/ 19 ноября 2010

Я ищу способ получить доступ к комментариям JavaScript из некоторого (другого) кода JavaScript.Я планирую использовать это для отображения справочной информации низкого уровня для элементов на странице, которые вызывают различные функции js, без дублирования этой информации в нескольких местах.

mypage.html:

...
<script src="foo.js"></script>
...
<span onclick="foo(bar);">clickme</span>
<span onclick="showhelpfor('foo');>?</span>
...

foo.js:

/**
 * This function does foo.
 * Call it with bar.  Yadda yadda "groo".
 */
function foo(x)
{
    ...
}

Я полагаю, я могу использовать getElementsByTagName, чтобы получить тег script, а затем загрузить файл с запросом AJAX, чтобы получить его текстовое содержимое.Однако тогда мне нужен способ надежного анализа javascript (то есть не кучка взломанных вместе регулярных выражений), который сохраняет символы, которые просто оценивают его, отбрасывают.

Я думалпросто поместить документацию после функции в строку js, но это неудобно, и у меня есть чувство, что получить кислород, чтобы поднять это, будет трудно.

function foo(x) { ... }
foo.comment = "\
This functions does foo.\
Call it with bar.  Yadda yadda \"groo\".\
";

Ответы [ 2 ]

8 голосов
/ 20 ноября 2010

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

Есть генератор синтаксического анализатора JS с именем PEG.js , который может сделать это довольно легко. Грамматика может выглядеть так:

{
var functions = {};
var buffer = '';
}

start
  =  unit* {return functions;}

unit
  =  func
  /  string
  /  multi_line_comment
  /  single_line_comment
  /  any_char

func
  =  m:multi_line_comment spaces? "function" spaces id:identifier {functions[id] = m;}
  /  "function" spaces id:identifier                              {functions[id] = null;}

multi_line_comment
  =  "/*" 
     ( !{return buffer.match(/\*\//)} c:. {buffer += c;} )*               
     {
       var temp = buffer; 
       buffer = ''; 
       return "/*" + temp.replace(/\s+/g, ' ');
     }

single_line_comment
  =  "//" [^\r\n]*

identifier
  =  a:([a-z] / [A-Z] / "_") b:([a-z] / [A-Z] / [0-9] /"_")* {return a + b.join("");}

spaces
  =  [ \t\r\n]+ {return "";}

string
  =  "\"" ("\\" . / [^"])* "\""
  /  "'" ("\\" . / [^'])* "'"

any_char
  =  .

Когда вы анализируете следующий источник сгенерированным парсером:

/**
 * This function does foo.
 * Call it with bar.  Yadda yadda "groo".
 */
function foo(x)
{
    ...
}

var s = " /* ... */ function notAFunction() {} ... ";

// function alsoNotAFunction() 
// { ... }

function withoutMultiLineComment() {
}

var t = ' /* ... */ function notAFunction() {} ... ';

/**
 * BAR!
 * Call it?
 */





            function doc_way_above(x, y, z) {
    ...
}

// function done(){};

функция синтаксического анализатора start() возвращает следующую карту:

{
   "foo": "/** * This function does foo. * Call it with bar. Yadda yadda \"groo\". */",
   "withoutMultiLineComment": null,
   "doc_way_above": "/** * BAR! * Call it? */"
}

Я понимаю, что есть некоторые пробелы, которые нужно заполнить (например, this.id = function() { ... }), но после прочтения документов из PEG.js немного, это не должно быть большой проблемой (если вы знаете немного парсер генераторов). Если это проблема, отправьте сообщение обратно, и я добавлю его в грамматику и немного объясню, что происходит в грамматике.

Вы можете даже проверить грамматику , размещенную выше онлайн!

0 голосов
/ 19 ноября 2010

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

...