mirror of
https://github.com/danog/dart-sass.git
synced 2025-01-22 05:41:14 +01:00
Add a module class and a way to create it from an Environment
This commit is contained in:
parent
5d4db9eb17
commit
7a7aea95b3
@ -6,11 +6,14 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:source_span/source_span.dart';
|
import 'package:source_span/source_span.dart';
|
||||||
|
|
||||||
|
import 'ast/css.dart';
|
||||||
import 'ast/node.dart';
|
import 'ast/node.dart';
|
||||||
|
import 'async_module.dart';
|
||||||
import 'callable.dart';
|
import 'callable.dart';
|
||||||
import 'functions.dart';
|
import 'functions.dart';
|
||||||
import 'value.dart';
|
import 'util/public_member_map.dart';
|
||||||
import 'utils.dart';
|
import 'utils.dart';
|
||||||
|
import 'value.dart';
|
||||||
|
|
||||||
/// The lexical environment in which Sass is executed.
|
/// The lexical environment in which Sass is executed.
|
||||||
///
|
///
|
||||||
@ -399,4 +402,34 @@ class AsyncEnvironment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a module that represents the top-level members defined in [this],
|
||||||
|
/// and that contains [css] as its CSS tree.
|
||||||
|
AsyncModule toModule(CssStylesheet css) => _EnvironmentModule(this, css);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A module that represents the top-level members defined in an [Environment].
|
||||||
|
class _EnvironmentModule implements AsyncModule {
|
||||||
|
final Map<String, Value> variables;
|
||||||
|
final Map<String, AstNode> variableNodes;
|
||||||
|
final Map<String, AsyncCallable> functions;
|
||||||
|
final Map<String, AsyncCallable> mixins;
|
||||||
|
final CssStylesheet css;
|
||||||
|
|
||||||
|
/// The environment that defines this module's members.
|
||||||
|
final AsyncEnvironment _environment;
|
||||||
|
|
||||||
|
// TODO(nweiz): Use custom [UnmodifiableMapView]s that forbid access to
|
||||||
|
// private members.
|
||||||
|
_EnvironmentModule(this._environment, this.css)
|
||||||
|
: variables = PublicMemberMap(_environment._variables.first),
|
||||||
|
variableNodes = _environment._variableNodes == null
|
||||||
|
? null
|
||||||
|
: PublicMemberMap(_environment._variableNodes.first),
|
||||||
|
functions = PublicMemberMap(_environment._functions.first),
|
||||||
|
mixins = PublicMemberMap(_environment._mixins.first);
|
||||||
|
|
||||||
|
void setVariable(String name, Value value, AstNode nodeWithSpan) {
|
||||||
|
_environment.setVariable(name, value, nodeWithSpan, global: true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
51
lib/src/async_module.dart
Normal file
51
lib/src/async_module.dart
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 2019 Google Inc. Use of this source code is governed by an
|
||||||
|
// MIT-style license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
import 'package:source_span/source_span.dart';
|
||||||
|
|
||||||
|
import 'ast/css.dart';
|
||||||
|
import 'ast/node.dart';
|
||||||
|
import 'callable.dart';
|
||||||
|
import 'value.dart';
|
||||||
|
|
||||||
|
/// The interface for a Sass module.
|
||||||
|
abstract class AsyncModule {
|
||||||
|
/// The module's variables.
|
||||||
|
Map<String, Value> get variables;
|
||||||
|
|
||||||
|
/// The nodes where each variable in [_variables] was defined.
|
||||||
|
///
|
||||||
|
/// This is `null` if source mapping is disabled.
|
||||||
|
///
|
||||||
|
/// This stores [AstNode]s rather than [FileSpan]s so it can avoid calling
|
||||||
|
/// [AstNode.span] if the span isn't required, since some nodes need to do
|
||||||
|
/// real work to manufacture a source span.
|
||||||
|
///
|
||||||
|
/// Implementations must ensure that this has the same keys as [variables] if
|
||||||
|
/// it's not `null`.
|
||||||
|
Map<String, AstNode> get variableNodes;
|
||||||
|
|
||||||
|
/// The module's functions.
|
||||||
|
///
|
||||||
|
/// Implementations must ensure that each [Callable] is stored under its own
|
||||||
|
/// name.
|
||||||
|
Map<String, AsyncCallable> get functions;
|
||||||
|
|
||||||
|
/// The module's mixins.
|
||||||
|
///
|
||||||
|
/// Implementations must ensure that each [Callable] is stored under its own
|
||||||
|
/// name.
|
||||||
|
Map<String, AsyncCallable> get mixins;
|
||||||
|
|
||||||
|
/// The module's CSS tree.
|
||||||
|
CssStylesheet get css;
|
||||||
|
|
||||||
|
/// Sets the variable named [name] to [value], associated with
|
||||||
|
/// [nodeWithSpan]'s source span.
|
||||||
|
///
|
||||||
|
/// This takes an [AstNode] rather than a [FileSpan] so it can avoid calling
|
||||||
|
/// [AstNode.span] if the span isn't required, since some nodes need to do
|
||||||
|
/// real work to manufacture a source span.
|
||||||
|
void setVariable(String name, Value value, AstNode nodeWithSpan);
|
||||||
|
}
|
@ -5,17 +5,20 @@
|
|||||||
// DO NOT EDIT. This file was generated from async_environment.dart.
|
// DO NOT EDIT. This file was generated from async_environment.dart.
|
||||||
// See tool/synchronize.dart for details.
|
// See tool/synchronize.dart for details.
|
||||||
//
|
//
|
||||||
// Checksum: 449ed8a8ad29fe107656a666e6e6005ef539b834
|
// Checksum: e8d50e36818b44b30e9ff78b6c22b4eceb7a7607
|
||||||
//
|
//
|
||||||
// ignore_for_file: unused_import
|
// ignore_for_file: unused_import
|
||||||
|
|
||||||
import 'package:source_span/source_span.dart';
|
import 'package:source_span/source_span.dart';
|
||||||
|
|
||||||
|
import 'ast/css.dart';
|
||||||
import 'ast/node.dart';
|
import 'ast/node.dart';
|
||||||
|
import 'module.dart';
|
||||||
import 'callable.dart';
|
import 'callable.dart';
|
||||||
import 'functions.dart';
|
import 'functions.dart';
|
||||||
import 'value.dart';
|
import 'util/public_member_map.dart';
|
||||||
import 'utils.dart';
|
import 'utils.dart';
|
||||||
|
import 'value.dart';
|
||||||
|
|
||||||
/// The lexical environment in which Sass is executed.
|
/// The lexical environment in which Sass is executed.
|
||||||
///
|
///
|
||||||
@ -402,4 +405,34 @@ class Environment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a module that represents the top-level members defined in [this],
|
||||||
|
/// and that contains [css] as its CSS tree.
|
||||||
|
Module toModule(CssStylesheet css) => _EnvironmentModule(this, css);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A module that represents the top-level members defined in an [Environment].
|
||||||
|
class _EnvironmentModule implements Module {
|
||||||
|
final Map<String, Value> variables;
|
||||||
|
final Map<String, AstNode> variableNodes;
|
||||||
|
final Map<String, Callable> functions;
|
||||||
|
final Map<String, Callable> mixins;
|
||||||
|
final CssStylesheet css;
|
||||||
|
|
||||||
|
/// The environment that defines this module's members.
|
||||||
|
final Environment _environment;
|
||||||
|
|
||||||
|
// TODO(nweiz): Use custom [UnmodifiableMapView]s that forbid access to
|
||||||
|
// private members.
|
||||||
|
_EnvironmentModule(this._environment, this.css)
|
||||||
|
: variables = PublicMemberMap(_environment._variables.first),
|
||||||
|
variableNodes = _environment._variableNodes == null
|
||||||
|
? null
|
||||||
|
: PublicMemberMap(_environment._variableNodes.first),
|
||||||
|
functions = PublicMemberMap(_environment._functions.first),
|
||||||
|
mixins = PublicMemberMap(_environment._mixins.first);
|
||||||
|
|
||||||
|
void setVariable(String name, Value value, AstNode nodeWithSpan) {
|
||||||
|
_environment.setVariable(name, value, nodeWithSpan, global: true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
58
lib/src/module.dart
Normal file
58
lib/src/module.dart
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Copyright 2019 Google Inc. Use of this source code is governed by an
|
||||||
|
// MIT-style license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
// DO NOT EDIT. This file was generated from async_module.dart.
|
||||||
|
// See tool/synchronize.dart for details.
|
||||||
|
//
|
||||||
|
// Checksum: 6cb2d5ca89346a8deddb51bd8b4bee7d5620d870
|
||||||
|
//
|
||||||
|
// ignore_for_file: unused_import
|
||||||
|
|
||||||
|
import 'package:source_span/source_span.dart';
|
||||||
|
|
||||||
|
import 'ast/css.dart';
|
||||||
|
import 'ast/node.dart';
|
||||||
|
import 'callable.dart';
|
||||||
|
import 'value.dart';
|
||||||
|
|
||||||
|
/// The interface for a Sass module.
|
||||||
|
abstract class Module {
|
||||||
|
/// The module's variables.
|
||||||
|
Map<String, Value> get variables;
|
||||||
|
|
||||||
|
/// The nodes where each variable in [_variables] was defined.
|
||||||
|
///
|
||||||
|
/// This is `null` if source mapping is disabled.
|
||||||
|
///
|
||||||
|
/// This stores [AstNode]s rather than [FileSpan]s so it can avoid calling
|
||||||
|
/// [AstNode.span] if the span isn't required, since some nodes need to do
|
||||||
|
/// real work to manufacture a source span.
|
||||||
|
///
|
||||||
|
/// Implementations must ensure that this has the same keys as [variables] if
|
||||||
|
/// it's not `null`.
|
||||||
|
Map<String, AstNode> get variableNodes;
|
||||||
|
|
||||||
|
/// The module's functions.
|
||||||
|
///
|
||||||
|
/// Implementations must ensure that each [Callable] is stored under its own
|
||||||
|
/// name.
|
||||||
|
Map<String, Callable> get functions;
|
||||||
|
|
||||||
|
/// The module's mixins.
|
||||||
|
///
|
||||||
|
/// Implementations must ensure that each [Callable] is stored under its own
|
||||||
|
/// name.
|
||||||
|
Map<String, Callable> get mixins;
|
||||||
|
|
||||||
|
/// The module's CSS tree.
|
||||||
|
CssStylesheet get css;
|
||||||
|
|
||||||
|
/// Sets the variable named [name] to [value], associated with
|
||||||
|
/// [nodeWithSpan]'s source span.
|
||||||
|
///
|
||||||
|
/// This takes an [AstNode] rather than a [FileSpan] so it can avoid calling
|
||||||
|
/// [AstNode.span] if the span isn't required, since some nodes need to do
|
||||||
|
/// real work to manufacture a source span.
|
||||||
|
void setVariable(String name, Value value, AstNode nodeWithSpan);
|
||||||
|
}
|
28
lib/src/util/public_member_map.dart
Normal file
28
lib/src/util/public_member_map.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2019 Google Inc. Use of this source code is governed by an
|
||||||
|
// MIT-style license that can be found in the LICENSE file or at
|
||||||
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
|
import '../utils.dart';
|
||||||
|
|
||||||
|
/// An unmodifiable map view that hides keys from the original map whose names
|
||||||
|
/// begin with `_` or `-`.
|
||||||
|
///
|
||||||
|
/// Note that [PublicMemberMap.length] is *not* `O(1)`.
|
||||||
|
class PublicMemberMap<V> extends UnmodifiableMapBase<String, V> {
|
||||||
|
/// The wrapped map.
|
||||||
|
final Map<String, V> _inner;
|
||||||
|
|
||||||
|
Iterable<String> get keys => _inner.keys.where(isPublic);
|
||||||
|
|
||||||
|
PublicMemberMap(this._inner);
|
||||||
|
|
||||||
|
bool containsKey(Object key) =>
|
||||||
|
key is String && isPublic(key) && _inner.containsKey(key);
|
||||||
|
|
||||||
|
V operator [](Object key) {
|
||||||
|
if (key is String && isPublic(key)) return _inner[key];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -105,6 +105,14 @@ int _lastNonWhitespace(String string, {bool excludeEscape = false}) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether [member] is a public member name.
|
||||||
|
///
|
||||||
|
/// Assumes that [member] is a valid Sass identifier.
|
||||||
|
bool isPublic(String member) {
|
||||||
|
var start = member.codeUnitAt(0);
|
||||||
|
return start != $dash && start != $underscore;
|
||||||
|
}
|
||||||
|
|
||||||
/// Flattens the first level of nested arrays in [iterable].
|
/// Flattens the first level of nested arrays in [iterable].
|
||||||
///
|
///
|
||||||
/// The return value is ordered first by index in the nested iterable, then by
|
/// The return value is ordered first by index in the nested iterable, then by
|
||||||
|
@ -17,7 +17,8 @@ final sources = const {
|
|||||||
'lib/src/visitor/async_evaluate.dart': 'lib/src/visitor/evaluate.dart',
|
'lib/src/visitor/async_evaluate.dart': 'lib/src/visitor/evaluate.dart',
|
||||||
'lib/src/async_compile.dart': 'lib/src/compile.dart',
|
'lib/src/async_compile.dart': 'lib/src/compile.dart',
|
||||||
'lib/src/async_environment.dart': 'lib/src/environment.dart',
|
'lib/src/async_environment.dart': 'lib/src/environment.dart',
|
||||||
'lib/src/async_import_cache.dart': 'lib/src/import_cache.dart'
|
'lib/src/async_import_cache.dart': 'lib/src/import_cache.dart',
|
||||||
|
'lib/src/async_module.dart': 'lib/src/module.dart'
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Classes that are defined in the async version of a file and used as-is in
|
/// Classes that are defined in the async version of a file and used as-is in
|
||||||
|
Loading…
x
Reference in New Issue
Block a user