Skip to content

Commit

Permalink
feat(styled-components): Implement pure option (swc-project#238)
Browse files Browse the repository at this point in the history
This implements `pure` option in styled-components plugin. 

cf. vercel/next.js#30802
  • Loading branch information
ciffelia committed Nov 26, 2023
1 parent 1e5e738 commit 66f0b1b
Show file tree
Hide file tree
Showing 82 changed files with 298 additions and 259 deletions.
18 changes: 9 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/constify/package.json
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-constify",
"version": "0.1.33",
"version": "0.1.34",
"description": "SWC plugin for optimization",
"main": "swc_plugin_constify.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/constify/transform/Cargo.toml
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
name = "swc_constify"
repository = "https://github.com/swc-project/plugins.git"
version = "0.28.0"
version = "0.29.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
2 changes: 1 addition & 1 deletion packages/emotion/package.json
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-emotion",
"version": "2.5.103",
"version": "2.5.104",
"description": "SWC plugin for emotion css-in-js library",
"main": "swc_plugin_emotion.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/emotion/transform/Cargo.toml
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
name = "swc_emotion"
repository = "https://github.com/swc-project/plugins.git"
version = "0.64.0"
version = "0.65.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
2 changes: 1 addition & 1 deletion packages/jest/package.json
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-jest",
"version": "1.5.103",
"version": "1.5.104",
"description": "SWC plugin for jest",
"main": "swc_plugin_jest.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/loadable-components/package.json
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-loadable-components",
"version": "0.3.103",
"version": "0.3.104",
"description": "SWC plugin for `@loadable/components`",
"main": "swc_plugin_loadable_components.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/noop/package.json
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-noop",
"version": "1.5.101",
"version": "1.5.102",
"description": "Noop SWC plugin, for debugging",
"main": "swc_plugin_noop.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-remove-properties/package.json
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-react-remove-properties",
"version": "1.5.103",
"version": "1.5.104",
"description": "SWC plugin for https://www.npmjs.com/package/babel-plugin-react-remove-properties",
"main": "swc_plugin_react_remove_properties.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-remove-properties/transform/Cargo.toml
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
name = "react_remove_properties"
repository = "https://github.com/swc-project/plugins.git"
version = "0.16.0"
version = "0.17.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
2 changes: 1 addition & 1 deletion packages/relay/package.json
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-relay",
"version": "1.5.103",
"version": "1.5.104",
"description": "SWC plugin for relay",
"main": "swc_plugin_relay.wasm",
"types": "./types.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/relay/transform/Cargo.toml
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
name = "swc_relay"
repository = "https://github.com/swc-project/plugins.git"
version = "0.36.0"
version = "0.37.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
2 changes: 1 addition & 1 deletion packages/remove-console/package.json
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-remove-console",
"version": "1.5.103",
"version": "1.5.104",
"description": "SWC plugin for https://www.npmjs.com/package/babel-plugin-remove-console",
"main": "swc_plugin_remove_console.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/remove-console/transform/Cargo.toml
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
name = "remove_console"
repository = "https://github.com/swc-project/plugins.git"
version = "0.17.0"
version = "0.18.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
2 changes: 1 addition & 1 deletion packages/styled-components/package.json
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-styled-components",
"version": "1.5.103",
"version": "1.5.104",
"description": "SWC plugin for styled-components",
"main": "swc_plugin_styled_components.wasm",
"scripts": {
Expand Down
8 changes: 5 additions & 3 deletions packages/styled-components/src/lib.rs
Expand Up @@ -6,8 +6,9 @@ use swc_core::{
common::FileName,
ecma::{ast::Program, visit::VisitMutWith},
plugin::{
metadata::TransformPluginMetadataContextKind, plugin_transform,
proxies::TransformPluginProgramMetadata,
metadata::TransformPluginMetadataContextKind,
plugin_transform,
proxies::{PluginCommentsProxy, TransformPluginProgramMetadata},
},
};

Expand All @@ -28,7 +29,8 @@ fn styled_components(mut program: Program, data: TransformPluginProgramMetadata)
let pos = data.source_map.lookup_char_pos(program.span().lo);
let hash = pos.file.src_hash;

let mut pass = styled_components::styled_components(file_name, hash, config);
let mut pass =
styled_components::styled_components(file_name, hash, config, PluginCommentsProxy);

program.visit_mut_with(&mut pass);

Expand Down
2 changes: 1 addition & 1 deletion packages/styled-components/transform/Cargo.toml
Expand Up @@ -6,7 +6,7 @@ include = ["Cargo.toml", "src/**/*.rs"]
license = "Apache-2.0"
name = "styled_components"
repository = "https://github.com/swc-project/plugins.git"
version = "0.88.0"
version = "0.89.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
28 changes: 17 additions & 11 deletions packages/styled-components/transform/src/lib.rs
Expand Up @@ -4,14 +4,15 @@ use std::{cell::RefCell, rc::Rc};

use serde::Deserialize;
use swc_atoms::JsWord;
use swc_common::{chain, pass::Optional, FileName};
use swc_common::{chain, comments::Comments, pass::Optional, FileName};
use swc_ecma_visit::{Fold, VisitMut};

pub use crate::{
utils::{analyze, analyzer, State},
visitors::{
display_name_and_id::display_name_and_id, minify::visitor::minify,
template_literals::template_literals, transpile_css_prop::transpile::transpile_css_prop,
pure_annotation::pure_annotation, template_literals::template_literals,
transpile_css_prop::transpile::transpile_css_prop,
},
};

Expand Down Expand Up @@ -40,10 +41,10 @@ pub struct Config {
#[serde(default)]
pub top_level_import_paths: Vec<JsWord>,

#[serde(default)]
#[serde(default = "true_by_default")]
pub transpile_template_literals: bool,

#[serde(default)]
#[serde(default = "true_by_default")]
pub minify: bool,

#[serde(default)]
Expand All @@ -70,14 +71,15 @@ impl Config {
}
}

/// NOTE: **This is not complete**.
///
/// [pure] is not implemented.
pub fn styled_components(
pub fn styled_components<C>(
file_name: FileName,
src_file_hash: u128,
config: Config,
) -> impl Fold + VisitMut {
comments: C,
) -> impl Fold + VisitMut
where
C: Comments,
{
let state: Rc<RefCell<State>> = Default::default();
let config = Rc::new(config);

Expand All @@ -94,7 +96,11 @@ pub fn styled_components(
display_name_and_id(file_name, src_file_hash, config.clone(), state.clone()),
Optional {
enabled: config.transpile_template_literals,
visitor: template_literals(state)
}
visitor: template_literals(state.clone())
},
Optional {
enabled: config.pure,
visitor: pure_annotation(comments, state)
},
)
}
8 changes: 8 additions & 0 deletions packages/styled-components/transform/src/utils/mod.rs
Expand Up @@ -262,6 +262,14 @@ impl State {
|| self.is_with_theme_helper(e)
}

pub(crate) fn is_pure_helper(&self, e: &Expr) -> bool {
self.is_create_global_style_helper(e)
|| self.is_css_helper(e)
|| self.is_use_theme(e)
|| self.is_keyframes_helper(e)
|| self.is_with_theme_helper(e)
}

fn is_css_helper(&self, e: &Expr) -> bool {
match e {
Expr::Ident(e) => Some(e.to_id()) == self.import_local_name("css", None),
Expand Down
1 change: 1 addition & 0 deletions packages/styled-components/transform/src/visitors/mod.rs
@@ -1,5 +1,6 @@
pub mod assign_style_required;
pub mod display_name_and_id;
pub mod minify;
pub mod pure_annotation;
pub mod template_literals;
pub mod transpile_css_prop;
@@ -0,0 +1,58 @@
//! Port of https://github.com/styled-components/babel-plugin-styled-components/blob/4e2eb388d9c90f2921c306c760657d059d01a518/src/visitors/pure.js

use std::{cell::RefCell, rc::Rc};

use swc_common::{comments::Comments, Span};
use swc_ecma_ast::*;
use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith};

use crate::utils::State;

pub fn pure_annotation<C>(comments: C, state: Rc<RefCell<State>>) -> impl Fold + VisitMut
where
C: Comments,
{
as_folder(PureAnnotation { comments, state })
}

#[derive(Debug)]
struct PureAnnotation<C>
where
C: Comments,
{
comments: C,
state: Rc<RefCell<State>>,
}

impl<C> VisitMut for PureAnnotation<C>
where
C: Comments,
{
noop_visit_mut_type!();

fn visit_mut_expr(&mut self, expr: &mut Expr) {
expr.visit_mut_children_with(self);

let (callee_or_tag, span) = match expr {
Expr::Call(CallExpr {
span,
callee: Callee::Expr(callee),
..
}) => (callee, span),
Expr::TaggedTpl(TaggedTpl { span, tag, .. }) => (tag, span),
_ => return,
};
if !self.state.borrow().is_styled(callee_or_tag)
&& !self.state.borrow().is_pure_helper(callee_or_tag)
{
return;
}

if span.is_dummy_ignoring_cmt() {
*span = Span::dummy_with_cmt();
}
if !self.comments.has_flag(span.lo, "PURE") {
self.comments.add_pure_comment(span.lo);
}
}
}
7 changes: 6 additions & 1 deletion packages/styled-components/transform/tests/fixture.rs
Expand Up @@ -26,7 +26,12 @@ fn fixture(input: PathBuf) {

chain!(
resolver(Mark::new(), Mark::new(), false),
styled_components(fm.name.clone(), fm.src_hash, config.clone())
styled_components(
fm.name.clone(),
fm.src_hash,
config.clone(),
t.comments.clone()
)
)
},
&input,
Expand Down

0 comments on commit 66f0b1b

Please sign in to comment.