Skip to content

Commit

Permalink
Plumb module doc comments through to reflection
Browse files Browse the repository at this point in the history
Summary: Adds a field to ReflectionModule to get the doc comment for the module, and plumbs that back through to HackC.

Reviewed By: oulgen

Differential Revision: D40104245

fbshipit-source-id: 3d3230544a6815cfc4431a5460a7e8ad750b9908
  • Loading branch information
Paul Vick authored and facebook-github-bot committed Oct 7, 2022
1 parent b3690a0 commit ef6a563
Show file tree
Hide file tree
Showing 23 changed files with 120 additions and 3 deletions.
1 change: 1 addition & 0 deletions hphp/hack/src/hackc/bytecode_printer/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ fn print_module_def<'arena>(
print_span(w, &module_def.span)?;
w.write_all(b" {")?;
newline(w)?;
print_doc_comment(ctx, w, module_def.doc_comment.as_ref())?;
w.write_all(b"}")?;
newline(w)
}
Expand Down
2 changes: 2 additions & 0 deletions hphp/hack/src/hackc/emitter/emit_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ pub fn emit_module<'a, 'arena, 'decl>(
let attributes = emit_attribute::from_asts(emitter, &ast_module.user_attributes)?;
let name = ClassName::from_ast_name_and_mangle(alloc, &ast_module.name.1);
let span = Span::from_pos(&ast_module.span);
let doc_comment = ast_module.doc_comment.clone();
Ok(Module {
attributes: Slice::fill_iter(alloc, attributes.into_iter()),
name,
span,
doc_comment: Maybe::from(doc_comment.map(|c| Str::new_str(alloc, &(c.0).1))),
})
}

Expand Down
2 changes: 2 additions & 0 deletions hphp/hack/src/hackc/hackc/assemble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,13 @@ fn assemble_module<'arena>(
let name = assemble_class_name(alloc, token_iter)?;
let span = assemble_span(token_iter)?;
token_iter.expect(Token::into_open_curly)?;
let doc_comment = assemble_doc_comment(alloc, token_iter)?;
token_iter.expect(Token::into_close_curly)?;
Ok(hhbc::Module {
attributes,
name,
span,
doc_comment,
})
}

Expand Down
3 changes: 3 additions & 0 deletions hphp/hack/src/hackc/hackc/cmp_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,16 +792,19 @@ fn cmp_module(a: &Module<'_>, b: &Module<'_>) -> Result<()> {
attributes: a_attributes,
name: a_name,
span: a_span,
doc_comment: a_doc_comment,
} = a;
let Module {
attributes: b_attributes,
name: b_name,
span: b_span,
doc_comment: b_doc_comment,
} = b;

cmp_eq(a_name, b_name).qualified("name")?;
cmp_attributes(a_attributes, b_attributes).qualified("attributes")?;
cmp_eq(a_span, b_span).qualified("span")?;
cmp_eq(a_doc_comment, b_doc_comment).qualified("doc_comment")?;
Ok(())
}

Expand Down
3 changes: 3 additions & 0 deletions hphp/hack/src/hackc/hhbc/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the "hack" directory of this source tree.

use ffi::Maybe;
use ffi::Slice;
use ffi::Str;
use serde::Serialize;

use crate::Attribute;
Expand All @@ -16,4 +18,5 @@ pub struct Module<'arena> {
pub attributes: Slice<'arena, Attribute<'arena>>,
pub name: ClassName<'arena>,
pub span: Span,
pub doc_comment: Maybe<Str<'arena>>,
}
1 change: 1 addition & 0 deletions hphp/hack/src/hackc/ir/conversions/bc_to_ir/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub fn bc_to_ir<'a>(unit: &'_ Unit<'a>, filename: &Path) -> ir::Unit<'a> {
attributes: module.attributes.iter().map(convert_attribute).collect(),
name: ir::ClassId::from_hhbc(module.name, &mut strings),
src_loc: ir::SrcLoc::from_span(filename, &module.span),
doc_comment: module.doc_comment.into(),
})
.collect();

Expand Down
1 change: 1 addition & 0 deletions hphp/hack/src/hackc/ir/conversions/ir_to_bc/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub fn ir_to_bc<'a>(alloc: &'a bumpalo::Bump, ir_unit: ir::Unit<'a>) -> hhbc::Un
attributes: convert_attributes(alloc, module.attributes),
name: strings.lookup_class_name(module.name),
span: module.src_loc.to_span(),
doc_comment: module.doc_comment.into(),
}),
);
unit.module_use = ir_unit.module_use.into();
Expand Down
3 changes: 3 additions & 0 deletions hphp/hack/src/hackc/ir/ir_core/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the "hack" directory of this source tree.

use ffi::Str;

use crate::Attribute;
use crate::ClassId;
use crate::SrcLoc;
Expand All @@ -11,4 +13,5 @@ pub struct Module<'a> {
pub attributes: Vec<Attribute<'a>>,
pub name: ClassId,
pub src_loc: SrcLoc,
pub doc_comment: Option<Str<'a>>,
}
3 changes: 3 additions & 0 deletions hphp/hack/src/hackc/sem_diff/sem_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,16 +491,19 @@ fn sem_diff_module<'arena>(
attributes: a_attributes,
name: a_name,
span: a_span,
doc_comment: a_doc_comment,
} = a;
let Module {
attributes: b_attributes,
name: b_name,
span: b_span,
doc_comment: b_doc_comment,
} = b;

sem_diff_eq(&path.qualified("name"), a_name, b_name)?;
sem_diff_attributes(&path.qualified("attributes"), a_attributes, b_attributes)?;
sem_diff_eq(&path.qualified("span"), a_span, b_span)?;
sem_diff_eq(&path.qualified("doc_comment"), a_doc_comment, b_doc_comment)?;
Ok(())
}

Expand Down
7 changes: 7 additions & 0 deletions hphp/hack/test/tast/module_doccomment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?hh

<<file:__EnableUnstableFeatures('modules')>>

/** this is a doc comment */
new module a.b {
}
4 changes: 4 additions & 0 deletions hphp/hack/test/tast/module_doccomment.php.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[(Module
{ md_annotation = (); md_name = ([6:12-15], "a.b"); md_user_attributes = [];
md_span = [6:1-7:2]; md_mode = Mstrict; md_doc_comment = (Some ([5:1-29], "/** this is a doc comment */"));
md_exports = None; md_imports = None })
1 change: 1 addition & 0 deletions hphp/hhbbc/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,7 @@ void emit_constant(UnitEmitter& ue, const php::Constant& constant) {
void emit_module(UnitEmitter& ue, const php::Module& module) {
Module m {
module.name,
module.srcInfo.docComment,
(int)std::get<0>(module.srcInfo.loc),
(int)std::get<1>(module.srcInfo.loc),
module.attrs,
Expand Down
5 changes: 4 additions & 1 deletion hphp/hhbbc/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,10 @@ std::unique_ptr<php::Constant> parse_constant(const Constant& c) {
std::unique_ptr<php::Module> parse_module(const Module& m) {
return std::unique_ptr<php::Module>(new php::Module{
m.name,
php::SrcInfo {{m.line0, m.line1}},
php::SrcInfo {
{m.line0, m.line1},
m.docComment()
},
m.attrs | AttrUnique | AttrPersistent,
m.userAttributes
});
Expand Down
14 changes: 14 additions & 0 deletions hphp/runtime/ext/reflection/ext_reflection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,19 @@ static Array HHVM_METHOD(ReflectionModule, getAttributesNamespaced) {
return ai.toArray();
}

static TypedValue HHVM_METHOD(ReflectionModule, getDocComment) {
auto const module = ReflectionModuleHandle::GetModuleFor(this_);
assertx(module);

auto const comment = module->docComment();
if (comment == nullptr || comment->empty()) {
return make_tv<KindOfBoolean>(false);
} else {
assertx(!comment->isRefCounted());
return make_tv<KindOfPersistentString>(const_cast<StringData*>(comment));
}
}

// ------------------------- class ReflectionFunction

// helper for __construct
Expand Down Expand Up @@ -2291,6 +2304,7 @@ struct ReflectionExtension final : Extension {

HHVM_ME(ReflectionModule, __init);
HHVM_ME(ReflectionModule, getAttributesNamespaced);
HHVM_ME(ReflectionModule, getDocComment);

HHVM_ME(ReflectionTypeConstant, __init);
HHVM_ME(ReflectionTypeConstant, getName);
Expand Down
3 changes: 3 additions & 0 deletions hphp/runtime/ext/reflection/ext_reflection_hni.php
Original file line number Diff line number Diff line change
Expand Up @@ -2528,6 +2528,9 @@ final public function getAttributesNamespaced(

use ReflectionTypedAttribute;

<<__Native>>
public function getDocComment()[]: mixed;

/**
* Get the name of the file.
*
Expand Down
27 changes: 27 additions & 0 deletions hphp/runtime/vm/as.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2941,6 +2941,18 @@ void parse_class(AsmState& as) {
as.finishClass();
}

/*
* directive-doccomment : long-string-literal ';'
* ;
*
*/
StringData* parse_module_doccomment(AsmState& as) {
auto const doc = parse_long_string(as);
as.in.expectWs(';');

return makeDocComment(doc);
}

/*
* directive-module : attribute-list identifier '{}'
* ;
Expand All @@ -2959,11 +2971,26 @@ void parse_module(AsmState& as) {
int line0;
int line1;
parse_line_range(as, line0, line1);

as.in.expectWs('{');

StringData* docComment = nullptr;
std::string directive;

while (as.in.readword(directive)) {
if (directive == ".doc") {
docComment = parse_module_doccomment(as);
continue;
}

as.error("unrecognized directive `" + directive + "' in module");
}

as.in.expectWs('}');

as.ue->addModule(std::move(Module{
makeStaticString(name),
docComment,
line0,
line1,
attrs,
Expand Down
5 changes: 5 additions & 0 deletions hphp/runtime/vm/disas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,11 @@ void print_module(Output& out, const Module& m) {
m.name,
m.line0,
m.line1);
if (RuntimeOption::EvalDisassemblerDocComments) {
if (m.docComment() && !m.docComment()->empty()) {
out.fmtln(".doc {};", escaped_long(m.docComment()));
}
}
out.fmtln("}}");
out.nl();
}
Expand Down
6 changes: 6 additions & 0 deletions hphp/runtime/vm/hackc-translator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1309,8 +1309,14 @@ void translateModule(TranslationState& ts, const hhbc::Module& m) {
UserAttributeMap userAttrs;
translateUserAttributes(m.attributes, userAttrs);

// auto const dc = maybe(b.doc_comment);
// if (dc) ts.fe->docComment = makeDocComment(dc.value());

ts.ue->addModule(HPHP::Module{
toStaticString(m.name._0),
maybeOrElse(m.doc_comment,
[&](Str& s) {return makeDocComment(s);},
[&]() {return staticEmptyString();}),
static_cast<int>(m.span.line_begin),
static_cast<int>(m.span.line_end),
Attr(AttrNone),
Expand Down
7 changes: 5 additions & 2 deletions hphp/runtime/vm/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,16 @@ namespace HPHP {
*/
struct Module {
LowStringPtr name;
LowStringPtr m_docComment;
int line0; // start line number on the src file
int line1; // end line number on the src file
Attr attrs;
UserAttributeMap userAttributes;

template<class SerDe>
void serde(SerDe& sd) {
sd(line0)
sd(m_docComment)
(line0)
(line1)
(attrs)
(userAttributes)
Expand All @@ -45,6 +47,8 @@ struct Module {

void prettyPrint(std::ostream& out) const;

const StringData* docComment() const { return m_docComment; }

/*
* Look up the defined Module in this request with name `name'.
* Return nullptr if the module is not yet defined in this request.
Expand Down Expand Up @@ -80,4 +84,3 @@ bool will_symbol_raise_module_boundary_violation(

///////////////////////////////////////////////////////////////////////////////
}

9 changes: 9 additions & 0 deletions hphp/test/slow/modules/reflection-5.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?hh

<<file:__EnableUnstableFeatures('modules')>>

/** This is a module doc comment
* It has multiple lines.
* It has more than 2 lines.
*/
new module A.B {}
11 changes: 11 additions & 0 deletions hphp/test/slow/modules/reflection-5.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?hh

<<file:__EnableUnstableFeatures('modules')>>

<<__EntryPoint>>
function main() {
include 'reflection-5.inc';

$m = new ReflectionModule('A.B');
var_dump($m->getDocComment());
}
4 changes: 4 additions & 0 deletions hphp/test/slow/modules/reflection-5.php.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
string(91) "/** This is a module doc comment
* It has multiple lines.
* It has more than 2 lines.
*/"
1 change: 1 addition & 0 deletions hphp/test/slow/modules/reflection-5.php.hphp_opts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--inputs=hphp/test/slow/modules/reflection-5.inc

0 comments on commit ef6a563

Please sign in to comment.