diff --git a/doc/autogen/types/bytes.rst b/doc/autogen/types/bytes.rst index 6c8e51719..83c989797 100644 --- a/doc/autogen/types/bytes.rst +++ b/doc/autogen/types/bytes.rst @@ -5,7 +5,7 @@ Returns an iterator representing the offset *i* inside the bytes value. -.. spicy:method:: bytes::decode bytes decode False string ([ charset: spicy::Charset = hilti::Charset::UTF8 ], [ errors: spicy::DecodeErrorStrategy = hilti::DecodeErrorStrategy::REPLACE ]) +.. spicy:method:: bytes::decode bytes decode False string ([ charset: spicy::Charset = spicy::Charset::UTF8 ], [ errors: spicy::DecodeErrorStrategy = spicy::DecodeErrorStrategy::REPLACE ]) Interprets the ``bytes`` as representing an binary string encoded with the given character set, and converts it into a UTF8 string. If data @@ -29,7 +29,7 @@ as printable strings. The portions will be separated by the bytes value to which this method is invoked as a member. -.. spicy:method:: bytes::lower bytes lower False bytes ([ charset: spicy::Charset = hilti::Charset::UTF8 ], [ errors: spicy::DecodeErrorStrategy = hilti::DecodeErrorStrategy::REPLACE ]) +.. spicy:method:: bytes::lower bytes lower False bytes ([ charset: spicy::Charset = spicy::Charset::UTF8 ], [ errors: spicy::DecodeErrorStrategy = spicy::DecodeErrorStrategy::REPLACE ]) Returns a lower-case version of the bytes value, assuming it is encoded in character set *charset*. If data is encountered that @@ -139,7 +139,7 @@ conversion fails, throws a `RuntimeError` exception, this can happen when ``bytes`` is empty or its size is larger than 8 bytes. -.. spicy:method:: bytes::upper bytes upper False bytes ([ charset: spicy::Charset = hilti::Charset::UTF8 ], [ errors: spicy::DecodeErrorStrategy = hilti::DecodeErrorStrategy::REPLACE ]) +.. spicy:method:: bytes::upper bytes upper False bytes ([ charset: spicy::Charset = spicy::Charset::UTF8 ], [ errors: spicy::DecodeErrorStrategy = spicy::DecodeErrorStrategy::REPLACE ]) Returns an upper-case version of the bytes value, assuming it is encoded in character set *charset*. If data is encountered that diff --git a/doc/autogen/types/string.rst b/doc/autogen/types/string.rst index 05045427c..b3624ef8a 100644 --- a/doc/autogen/types/string.rst +++ b/doc/autogen/types/string.rst @@ -1,6 +1,6 @@ .. rubric:: Methods -.. spicy:method:: string::encode string encode False bytes ([ charset: spicy::Charset = hilti::Charset::UTF8 ]) +.. spicy:method:: string::encode string encode False bytes ([ charset: spicy::Charset = spicy::Charset::UTF8 ]) Converts the string into a binary representation encoded with the given character set. diff --git a/spicy/toolchain/include/compiler/detail/printer.h b/spicy/toolchain/include/compiler/detail/printer.h index 17b8bbebc..50435d818 100644 --- a/spicy/toolchain/include/compiler/detail/printer.h +++ b/spicy/toolchain/include/compiler/detail/printer.h @@ -18,4 +18,11 @@ namespace spicy::detail::printer { */ bool print(hilti::printer::Stream& stream, Node* root); +/** + * Prints out an AST ID. This only prints the ID if the Spicy-side output needs + * to be different from the default HILTI output. Returns true in that case, + * otherwise false. + */ +bool printID(hilti::printer::Stream& out, const ID& id); + } // namespace spicy::detail::printer diff --git a/spicy/toolchain/src/compiler/plugin.cc b/spicy/toolchain/src/compiler/plugin.cc index e90ae0ba1..de6aa320b 100644 --- a/spicy/toolchain/src/compiler/plugin.cc +++ b/spicy/toolchain/src/compiler/plugin.cc @@ -86,6 +86,8 @@ hilti::Plugin spicy::detail::createSpicyPlugin() { .ast_print = [](Node* node, hilti::printer::Stream& out) { return printer::print(out, node); }, + .ast_print_id = [](const ID& id, hilti::printer::Stream& out) { return printer::printID(out, id); }, + .ast_transform = [](hilti::Builder* builder, hilti::ASTRoot* m) -> bool { auto spicy_builder = static_cast(builder); return CodeGen(spicy_builder).compileAST(m); diff --git a/spicy/toolchain/src/compiler/printer.cc b/spicy/toolchain/src/compiler/printer.cc index 65c36d518..a49d26660 100644 --- a/spicy/toolchain/src/compiler/printer.cc +++ b/spicy/toolchain/src/compiler/printer.cc @@ -16,6 +16,26 @@ using namespace spicy; +bool spicy::detail::printer::printID(hilti::printer::Stream& out, const ID& id) { + // In user-visible output, replace any `hilti` prefix with `spicy`. This is + // a bit of a hammer: it's assuming that any HILTI types showing up there + // have a corresponding Spicy type. The alternative would be to explicitly + // identify valid mappings somehow (e.g., through a shared `&cxxname`). + // However, that's neither easy nor is it clear that that's worth it. For + // one, we currently do indeed maintain only such 1:1 mappings (i.e., we + // don't rename IDs existing at both layers other than the namespace). And + // second, when displaying Spicy code to users, there should really never + // be any HILTI identifier showing up anyways; so if we still end up with + // any, printing them with a `spicy` prefix is probably still a better + // solution than just printing them as-is. + if ( out.state().user_visible && id.namespace_() && id.sub(0) == ID("hilti") ) { + out << ID("spicy", id.sub(1, -1)); + return true; + } + + return false; +} + namespace { struct VisitorPrinter : visitor::PreOrder { diff --git a/tests/Baseline/spicy.tools.spicyc-hilti-free-output-2/output b/tests/Baseline/spicy.tools.spicyc-hilti-free-output-2/output new file mode 100644 index 000000000..80b7c1752 --- /dev/null +++ b/tests/Baseline/spicy.tools.spicyc-hilti-free-output-2/output @@ -0,0 +1,10 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +module Test { + +import spicy; +import hilti; +import spicy_rt; + +hilti::print(b"xxx".decode(spicy::Charset::UTF8, hilti::DecodeErrorStrategy::REPLACE), True); + +} diff --git a/tests/Baseline/spicy.tools.spicyc-hilti-free-output/output b/tests/Baseline/spicy.tools.spicyc-hilti-free-output/output new file mode 100644 index 000000000..6f914c5e7 --- /dev/null +++ b/tests/Baseline/spicy.tools.spicyc-hilti-free-output/output @@ -0,0 +1,5 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +[error] <...>/spicyc-hilti-free-output.spicy:8:7-8:28: call does not match any method: .decode() +[error] <...>/spicyc-hilti-free-output.spicy:8:7-8:28: candidates: +[error] <...>/spicyc-hilti-free-output.spicy:8:7-8:28: - .decode([charset: spicy::Charset = spicy::Charset::UTF8], [errors: spicy::DecodeErrorStrategy = spicy::DecodeErrorStrategy::REPLACE]) +[error] spicyc: aborting after errors diff --git a/tests/spicy/tools/spicyc-hilti-free-output.spicy b/tests/spicy/tools/spicyc-hilti-free-output.spicy new file mode 100644 index 000000000..884e7f014 --- /dev/null +++ b/tests/spicy/tools/spicyc-hilti-free-output.spicy @@ -0,0 +1,16 @@ +# @TEST-EXEC: spicyc -p -d %INPUT >output 2>&1; true +# @TEST-EXEC: btest-diff output +# +# @TEST-DOC: Checks that HILTI-level identifiers are not showing up in compiler errors, but do show up when printing generated HILTI code; regression test for #1803 + +module Test; + +print b"xxx".decode("utf-8"); + +# @TEST-START-NEXT + +module Test; + +import spicy; + +print b"xxx".decode(spicy::Charset::UTF8);