diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b40721b9b63..d823c6552ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: [prism] + branches: [prism, prism-squashed] pull_request: - branches: [prism] + branches: [prism, prism-squashed] jobs: tests: runs-on: ubuntu-latest diff --git a/parser/prism/Translator.cc b/parser/prism/Translator.cc index 9a12c8a8db3..3f4c216147d 100644 --- a/parser/prism/Translator.cc +++ b/parser/prism/Translator.cc @@ -302,8 +302,7 @@ unique_ptr Translator::translate(pm_node_t *node) { // Unlike `-[Integer]`, Prism treats `~[Integer]` as a method call // But Sorbet's legacy parser treats both `~[Integer]` and `-[Integer]` as integer literals if (name == "~" && parser::cast_node(receiver.get())) { - std::string valueString(reinterpret_cast(callNode->base.location.start), - callNode->base.location.end - callNode->base.location.start); + std::string valueString(sliceLocation(callNode->base.location)); return std::make_unique(location, std::move(valueString)); } @@ -582,12 +581,7 @@ unique_ptr Translator::translate(pm_node_t *node) { } case PM_FLOAT_NODE: { // A floating point number literal, e.g. `1.23` auto floatNode = down_cast(node); - auto nodeLoc = floatNode->base.location; - - auto *start = nodeLoc.start; - auto *end = nodeLoc.end; - - std::string valueString(reinterpret_cast(start), end - start); + std::string valueString(sliceLocation(floatNode->base.location)); return make_unique(location, move(valueString)); } @@ -675,13 +669,9 @@ unique_ptr Translator::translate(pm_node_t *node) { } case PM_IMAGINARY_NODE: { // An imaginary number literal, like `1.0i`, `+1.0i`, or `-1.0i` auto imaginaryNode = down_cast(node); - pm_location_t loc = imaginaryNode->base.location; - - const uint8_t *start = loc.start; - const uint8_t *end = loc.end; - // Create a string_view of the value without the trailing 'i' - auto value = std::string_view(reinterpret_cast(start), end - start - 1); + auto value = sliceLocation(imaginaryNode->base.location); + value = value.substr(0, value.size() - 1); ENFORCE(!value.empty()); @@ -761,13 +751,8 @@ unique_ptr Translator::translate(pm_node_t *node) { } case PM_INTEGER_NODE: { // An integer literal, e.g., `123`, `0xcafe`, `0b1010`, etc. auto intNode = down_cast(node); - auto nodeLoc = intNode->base.location; - - auto *start = nodeLoc.start; - auto *end = nodeLoc.end; - // For normal integers, retain the original valueString including any sign - std::string valueString(reinterpret_cast(start), end - start); + std::string valueString(sliceLocation(intNode->base.location)); ENFORCE(!valueString.empty()); @@ -1124,13 +1109,10 @@ unique_ptr Translator::translate(pm_node_t *node) { // Note: in `1/2r`, only the `2r` is part of the `PM_RATIONAL_NODE`. // The `1/` is just divison of an integer. auto *rationalNode = down_cast(node); - pm_location_t loc = rationalNode->base.location; - - const uint8_t *start = loc.start; - const uint8_t *end = loc.end; // `-1` drops the trailing `r` end of the value - auto value = std::string_view(reinterpret_cast(start), end - start - 1); + auto value = sliceLocation(rationalNode->base.location); + value = value.substr(0, value.size() - 1); return make_unique(location, value); } @@ -1920,10 +1902,15 @@ template unique_ptr Translator::translateSimpl // Translate the options from a Regexp literal, if any. E.g. the `i` in `/foo/i` unique_ptr Translator::translateRegexpOptions(pm_location_t closingLoc) { - auto start = closingLoc.start + 1; // one character after the closing `/` - auto length = closingLoc.end - start; + auto length = closingLoc.end - closingLoc.start; + + std::string_view options; - auto options = (length > 0) ? std::string_view(reinterpret_cast(start), length) : std::string_view(); + if (length > 0) { + options = sliceLocation(closingLoc).substr(1); // one character after the closing `/` + } else { + options = std::string_view(); + } return make_unique(translateLoc(closingLoc), options); } @@ -1945,6 +1932,10 @@ unique_ptr Translator::translateRegexp(pm_string_t unescaped, co return make_unique(location, move(parts), move(options)); } +std::string_view Translator::sliceLocation(pm_location_t loc) { + return std::string_view(reinterpret_cast(loc.start), loc.end - loc.start); +} + // Creates a `parser::Mlhs` for either a `PM_MULTI_WRITE_NODE` or `PM_MULTI_TARGET_NODE`. template std::unique_ptr Translator::translateMultiTargetLhs(PrismNode *node) { static_assert( diff --git a/parser/prism/Translator.h b/parser/prism/Translator.h index 4b2a74289ca..30e9c9cb1ef 100644 --- a/parser/prism/Translator.h +++ b/parser/prism/Translator.h @@ -95,6 +95,8 @@ class Translator final { parser::NodeVec patternTranslateMulti(pm_node_list prismNodes); void patternTranslateMultiInto(NodeVec &sorbetNodes, absl::Span prismNodes); + std::string_view sliceLocation(pm_location_t loc); + // Context management helpers. These return a copy of `this` with some change to the context. Translator enterMethodDef(); };