mirror of
https://github.com/sass/sass.git
synced 2024-09-21 10:37:22 +00:00
[Module System] Define how locally-scoped member resolution works
Closes #66
This commit is contained in:
parent
3d46ea12dd
commit
5921ac35fd
@ -22,6 +22,8 @@
|
||||
* Explicitly define that `*-exists()` functions should throw an error for
|
||||
conflicting member names from global modules.
|
||||
|
||||
* Explicitly define how members are resolved locally versus globally.
|
||||
|
||||
* Syntactically forbid namespaced references to private identifiers (as in
|
||||
`foo.-bar`). This is never valid, so making it a syntax error rather than just
|
||||
a runtime error ensures that the user will be notified as eagerly as possible.
|
||||
|
@ -1083,19 +1083,26 @@ Given a source file `file`, a [configuration](#configuration) `config`, and an
|
||||
|
||||
* Append `css` to `module`'s CSS.
|
||||
|
||||
* When a variable declaration `variable` is encountered:
|
||||
* When a variable declaration `declaration` is encountered:
|
||||
|
||||
* If `variable`'s name is a [namespaced identifier](#member-references) *and*
|
||||
it has a `!global` flag, throw an error.
|
||||
> This algorithm is intended to replace [the existing algorithm][old
|
||||
> assigning-to-a-variable] for assigning to a variable.
|
||||
>
|
||||
> [old assigning-to-a-variable]: ../spec/variables.md#assigning-to-a-variable
|
||||
|
||||
* If `variable` is at the top level of `file`, *or* its name is a namespaced
|
||||
identifier, *or* it has a `!global` flag:
|
||||
* Let `name` be `declaration`'s [`Variable`](#member-references)'s name.
|
||||
|
||||
* If `name` is a [namespaced identifier](#member-references) *and*
|
||||
`declaration` has a `!global` flag, throw an error.
|
||||
|
||||
* Otherwise, if `declaration` is outside of any block of statements, *or*
|
||||
`declaration` has a `!global` flag, *or* `name` is a namespaced identifier:
|
||||
|
||||
* Let `resolved` be the result of [resolving `variable`](#resolving-members)
|
||||
using `file`, `uses`, `config`, and `import`.
|
||||
|
||||
* If `variable` has a `!default` flag, *and* `resolved` isn't null, *and*
|
||||
`resolved`'s value isn't null, do nothing.
|
||||
`resolved`'s value isn't `null`, do nothing.
|
||||
|
||||
* Otherwise, if `resolved` is a variable in another module:
|
||||
|
||||
@ -1110,23 +1117,75 @@ Given a source file `file`, a [configuration](#configuration) `config`, and an
|
||||
|
||||
* Add `variable` to `import`.
|
||||
|
||||
* Otherwise, evaluate it as usual.
|
||||
* Otherwise, if `declaration` is within one or more blocks associated with
|
||||
`@if`, `@each`, `@for`, and/or `@while` rules *and no other blocks*:
|
||||
|
||||
* When a top-level mixin or function declaration `member` is encountered:
|
||||
* Let `resolved` be the result of [resolving `variable`](#resolving-members)
|
||||
using `file`, `uses`, `config`, and `import`.
|
||||
|
||||
* If `resolved` is not `null`:
|
||||
|
||||
* If `variable` has a `!default` flag and `resolved`'s value isn't `null`,
|
||||
do nothing.
|
||||
|
||||
* Otherwise, if `resolved` is a variable in another module:
|
||||
|
||||
* Set `resolved`'s value to `variable`'s value.
|
||||
|
||||
* Otherwise:
|
||||
|
||||
* If `variable`'s name *doesn't* begin with `-` or `_`, add `variable`
|
||||
to `module`.
|
||||
|
||||
> This overrides the previous definition, if one exists.
|
||||
|
||||
* Add `variable` to `import`.
|
||||
|
||||
> This makes it possible to write
|
||||
>
|
||||
> ```scss
|
||||
> $variable: value1;
|
||||
> @if $condition {
|
||||
> $variable: value2;
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> without needing to use `!global`.
|
||||
|
||||
* Otherwise, if no block containing `declaration` has a [scope][] with a
|
||||
variable named `name`, set the innermost block's scope's variable `name` to
|
||||
`value`.
|
||||
|
||||
[scope]: ../spec/variables.md#scope
|
||||
|
||||
* Otherwise, let `scope` be the scope of the innermost block such that `scope`
|
||||
already has a variable named `name`. Set `scope`'s variable `name` to `value`.
|
||||
|
||||
* When a top-level mixin or function declaration `declaration` is encountered:
|
||||
|
||||
> Mixins and functions defined within rules are never part of a module's API.
|
||||
|
||||
* If `member`'s name *doesn't* begin with `-` or `_`, add `member` to
|
||||
* If `declaration`'s name *doesn't* begin with `-` or `_`, add `declaration` to
|
||||
`module`.
|
||||
|
||||
> This overrides the previous definition, if one exists.
|
||||
|
||||
* Add `member` to `import`.
|
||||
* Add `declaration` to `import`.
|
||||
|
||||
> This happens regardless of whether or not it begins with `-` or `_`.
|
||||
|
||||
* When a member use is encountered, [resolve it](#resolving-members) using
|
||||
`file`, `uses`, `config`, and `import`. If this returns null, throw an error.
|
||||
* When a member use `member` is encountered:
|
||||
|
||||
* Let `scope` be the [scope](#scope) of the innermost block containing
|
||||
`member` such that `scope` has a member of `member`'s name and type, or
|
||||
`null` if no such scope exists.
|
||||
|
||||
* If `scope` is not `null`, return `scope`'s member of `member`'s name and
|
||||
type.
|
||||
|
||||
* Otherwise, return the result of [resolving `member`](#resolving-members)
|
||||
using `file`, `uses`, `config`, and `import`. If this returns null, throw an
|
||||
error.
|
||||
|
||||
* Finally:
|
||||
|
||||
@ -1219,6 +1278,10 @@ given name. Given a source file `file`, a map `uses` from `@use` rules to the
|
||||
type `type`, a [configuration](#configuration) `config`, and an [import
|
||||
context](#import-context) `import`:
|
||||
|
||||
> Note that this procedure only covers non-local member resolution. Local
|
||||
> members that are scoped to individual blocks are covered in [Executing
|
||||
> Files](#executing-files).
|
||||
|
||||
* If `name` is a [namespaced identifier](#member-references)
|
||||
`namespace.raw-name`:
|
||||
|
||||
@ -1235,6 +1298,9 @@ context](#import-context) `import`:
|
||||
* If `type` is "variable" and `config` contains a variable named `name`, return
|
||||
it.
|
||||
|
||||
> In this case, the current module is guaranteed to define a top-level
|
||||
> variable named `name`. Otherwise, the config creation would have failed.
|
||||
|
||||
* If `file` defines a member `member` of `type` named `name`:
|
||||
|
||||
* If `member`'s definition has already been evaluated, return it.
|
||||
|
Loading…
Reference in New Issue
Block a user