Resolving the enclosing scope | sourcemaps-lookup | Spatie

 SPATIE

sourcemaps-lookup
=================

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Sourcemaps-lookup](https://spatie.be/docs/sourcemaps-lookup/v1)  Advanced-usage  Resolving the enclosing scope

 Version   v1

 Other versions for crawler [v1](https://spatie.be/docs/sourcemaps-lookup/v1)

  Resolving the enclosing scope
- [ Introduction ](https://spatie.be/docs/sourcemaps-lookup/v1/introduction)
- [ Support us ](https://spatie.be/docs/sourcemaps-lookup/v1/support-us)
- [ Requirements ](https://spatie.be/docs/sourcemaps-lookup/v1/requirements)
- [ Installation &amp; setup ](https://spatie.be/docs/sourcemaps-lookup/v1/installation-setup)
- [ Benchmarks ](https://spatie.be/docs/sourcemaps-lookup/v1/benchmarks)
- [ Questions and issues ](https://spatie.be/docs/sourcemaps-lookup/v1/questions-issues)
- [ About us ](https://spatie.be/docs/sourcemaps-lookup/v1/about-us)
- [ Changelog ](https://spatie.be/docs/sourcemaps-lookup/v1/changelog)

Basic usage
-----------

- [ Looking up a position ](https://spatie.be/docs/sourcemaps-lookup/v1/basic-usage/looking-up-a-position)
- [ Reading inlined source content ](https://spatie.be/docs/sourcemaps-lookup/v1/basic-usage/reading-source-content)
- [ Error handling ](https://spatie.be/docs/sourcemaps-lookup/v1/basic-usage/error-handling)
- [ Complete example ](https://spatie.be/docs/sourcemaps-lookup/v1/basic-usage/complete-example)

Advanced usage
--------------

- [ Reverse lookup ](https://spatie.be/docs/sourcemaps-lookup/v1/advanced-usage/reverse-lookup)
- [ Resolving the enclosing scope ](https://spatie.be/docs/sourcemaps-lookup/v1/advanced-usage/resolving-the-enclosing-scope)
- [ Marking third-party sources ](https://spatie.be/docs/sourcemaps-lookup/v1/advanced-usage/marking-third-party-sources)
- [ Listing the source files ](https://spatie.be/docs/sourcemaps-lookup/v1/advanced-usage/listing-source-files)
- [ Tips for bulk lookups ](https://spatie.be/docs/sourcemaps-lookup/v1/advanced-usage/tips-for-bulk-lookups)
- [ Supported source map features ](https://spatie.be/docs/sourcemaps-lookup/v1/advanced-usage/supported-features)
- [ Under the hood ](https://spatie.be/docs/sourcemaps-lookup/v1/advanced-usage/under-the-hood)

 Resolving the enclosing scope
=============================

###  On this page

1. [ The ](#content-the-scope-object)

`scopeAt()` resolves a generated position to the enclosing source language scope, modeled after the consumer semantics of the [ECMA-426 Scopes proposal](https://github.com/tc39/source-map/blob/main/proposals/scopes.md). Because no bundler currently emits the `scopes` field, the implementation today is a heuristic polyfill that walks inlined `sourcesContent` backward looking for enclosing function declarations. When bundlers start producing `scopes`, the same API will be backed natively.

```
$scope = $map->scopeAt(line: 42, column: 17);

echo $scope->name;                  // "onClick", or null for an anonymous function boundary
echo $scope->position->sourceLine;  // where the frame actually executed
echo $scope->parent?->name;         // lexically enclosing scope (for example, the React component)
```

The walk back recognises `function NAME`, `const/let/var NAME = (…) => …`, `const NAME = async function`, and class or object method shorthand. An anonymous arrow passed as a callback yields a `Scope` with `$name === null`, signalling that there is a function boundary here but no binding to report. Single line strings, line comments, block comments, and template literals are skipped when counting brace depth. Multiline strings and block comments spanning multiple lines are a known limitation.

`scopeAt()` returns `null` when the generated position resolves to nothing at all. A fallback single level `Scope` is returned when only the mapping's `name` is available (no inlined `sourcesContent` on which to walk).

A per call `$maxLinesBack` argument bounds how far back the walker looks (default: `SourceMapLookup::DEFAULT_WALKBACK_LINES`, currently 60).

```
$scope = $map->scopeAt(42, 17, maxLinesBack: 200);
```

The `Scope` object
----------------------------------------------------------------------------------------------------------

```
readonly class Scope
{
    public ?string $name;      // identifier of the enclosing scope, or null for an anonymous function boundary
    public Position $position; // innermost: the queried position; outer: the declaration line
    public ?Scope $parent;     // lexically enclosing scope, or null at the top level
}
```

Walk `$parent` outward to display the enclosing chain. For anonymous callbacks like `arr.map(() => { … })`, `$name` is `null` but the `Scope` is still returned. The function boundary is real, the binding name just isn't recoverable from source.

 A good
match?
-------------

### What we do best

- All things Laravel
- Custom frontend components
- Building APIs
- AI-powered features
- Simplifying things
- Clean solutions
- Integrating services

### Not our cup of tea

- WordPress themes
- Cutting corners
- Free mockups to win a job
- "Just execute the briefing"

 In short: we'd like to be a **substantial part** of your project.

 [ Get in touch via email ](mailto:info@spatie.be?subject=A%20good%20match%21&body=Tell%20us%20as%20much%20as%20you%20can%20about%0A-%20your%20online%20project%0A-%20your%20planning%0A-%20your%20budget%0A-%20%E2%80%A6%0A%0AAnything%20that%20helps%20us%20to%20start%20straightforward%21)
