Skip to content

Commit

Permalink
Merge branch 'master' into ido/improve-resolve-symbol-type
Browse files Browse the repository at this point in the history
  • Loading branch information
idoros authored Oct 2, 2023
2 parents 6213ccc + d56e5f5 commit a2f42f6
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 60 deletions.
2 changes: 1 addition & 1 deletion packages/cli/src/build-stylable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export async function buildStylable(
watchOptions = {},
}: BuildStylableContext = {}
) {
const { config } = resolveConfig(rootDir, configFilePath, fs) || {};
const { config } = resolveConfig(rootDir, fs, configFilePath) || {};
validateDefaultConfig(config?.defaultConfig);

const projects = await projectsConfig(rootDir, overrideBuildOptions, defaultOptions, config);
Expand Down
3 changes: 1 addition & 2 deletions packages/cli/src/config/projects-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ export async function projectsConfig(
return projects;
}

// todo: make fs not optional next major version
export function resolveConfig(context: string, request?: string, fs?: IFileSystem) {
export function resolveConfig(context: string, fs: IFileSystem, request?: string) {
return request ? requireConfigFile(request, context, fs) : resolveConfigFile(context, fs);
}

Expand Down
82 changes: 60 additions & 22 deletions packages/core/src/helpers/custom-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import postcssValueParser, {
type FunctionNode,
} from 'postcss-value-parser';
import cssesc from 'cssesc';
import type { PseudoClass, SelectorNode } from '@tokey/css-selector-parser';
import type { PseudoClass, SelectorList, SelectorNode } from '@tokey/css-selector-parser';
import { createDiagnosticReporter, Diagnostics } from '../diagnostics';
import {
parseSelectorWithCache,
Expand Down Expand Up @@ -338,7 +338,21 @@ function defineTemplateState(
const template = stripQuotation(postcssValueParser.stringify(templateDef));
if (argsFullValue.length === 1) {
// simple template with no params
mappedStates[stateName] = template.trim().replace(/\\["']/g, '"');
const selectorStr = template.trim().replace(/\\["']/g, '"');
const selectorAst = parseSelectorWithCache(selectorStr, { clone: true });
if (
!validateTemplateSelector({
stateName,
selectorStr,
selectorAst,
cssNode: decl,
diagnostics,
})
) {
return;
} else {
mappedStates[stateName] = selectorStr;
}
} else if (argsFullValue.length === 2) {
// single parameter template
if (!template.includes('$0')) {
Expand Down Expand Up @@ -1075,30 +1089,57 @@ function transformMappedStateWithParam({
selectorNode?: postcss.Node;
diagnostics: Diagnostics;
}) {
const targetSelectorStr = template.replace(/\$0/g, param);
const selectorAst = parseSelectorWithCache(targetSelectorStr, { clone: true });
const selectorStr = template.replace(/\$0/g, param);
const selectorAst = parseSelectorWithCache(selectorStr, { clone: true });
if (
!validateTemplateSelector({
stateName,
selectorStr,
selectorAst,
cssNode: selectorNode,
diagnostics,
})
) {
return;
}
convertToSelector(node).nodes = selectorAst[0].nodes;
}

function validateTemplateSelector({
stateName,
selectorStr,
selectorAst,
cssNode,
diagnostics,
}: {
stateName: string;
selectorStr: string;
selectorAst: SelectorList;
cssNode?: postcss.Node;
diagnostics: Diagnostics;
}): boolean {
if (selectorAst.length > 1) {
if (selectorNode) {
if (cssNode) {
diagnostics.report(
stateDiagnostics.UNSUPPORTED_MULTI_SELECTOR(stateName, targetSelectorStr),
stateDiagnostics.UNSUPPORTED_MULTI_SELECTOR(stateName, selectorStr),
{
node: selectorNode,
node: cssNode,
}
);
}
return;
return false;
} else {
const firstSelector = selectorAst[0].nodes.find(({ type }) => type !== 'comment');
if (firstSelector?.type === 'type' || firstSelector?.type === 'universal') {
if (selectorNode) {
if (cssNode) {
diagnostics.report(
stateDiagnostics.UNSUPPORTED_INITIAL_SELECTOR(stateName, targetSelectorStr),
stateDiagnostics.UNSUPPORTED_INITIAL_SELECTOR(stateName, selectorStr),
{
node: selectorNode,
node: cssNode,
}
);
}
return;
return false;
}
let unexpectedSelector: undefined | SelectorNode = undefined;
for (const node of selectorAst[0].nodes) {
Expand All @@ -1108,33 +1149,30 @@ function transformMappedStateWithParam({
}
}
if (unexpectedSelector) {
if (selectorNode) {
if (cssNode) {
switch (unexpectedSelector.type) {
case 'combinator':
diagnostics.report(
stateDiagnostics.UNSUPPORTED_COMPLEX_SELECTOR(
stateName,
targetSelectorStr
),
stateDiagnostics.UNSUPPORTED_COMPLEX_SELECTOR(stateName, selectorStr),
{
node: selectorNode,
node: cssNode,
}
);
break;
case 'invalid':
diagnostics.report(
stateDiagnostics.INVALID_SELECTOR(stateName, targetSelectorStr),
stateDiagnostics.INVALID_SELECTOR(stateName, selectorStr),
{
node: selectorNode,
node: cssNode,
}
);
break;
}
}
return;
return false;
}
}
convertToSelector(node).nodes = selectorAst[0].nodes;
return true;
}

function resolveParam(
Expand Down
21 changes: 0 additions & 21 deletions packages/core/src/stylable-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
StylableSymbol,
CSSClass,
STSymbol,
STCustomSelector,
VarSymbol,
CSSVarSymbol,
KeyframesSymbol,
Expand All @@ -20,7 +19,6 @@ import {
CSSContains,
STStructure,
} from './features';
import type { StylableTransformer } from './stylable-transformer';
import { findRule } from './helpers/rule';
import type { ModuleResolver } from './types';
import { CustomValueExtension, isCustomValue, stTypes } from './custom-values';
Expand Down Expand Up @@ -385,7 +383,6 @@ export class StylableResolver {
meta,
deepResolved.symbol!,
false,
undefined,
validateClassResolveExtends(
meta,
name,
Expand Down Expand Up @@ -445,7 +442,6 @@ export class StylableResolver {
meta: StylableMeta,
nameOrSymbol: string | ClassSymbol | ElementSymbol,
isElement = false,
transformer?: StylableTransformer,
reportError?: ReportError
): CSSResolvePath {
const name = typeof nameOrSymbol === `string` ? nameOrSymbol : nameOrSymbol.name;
Expand All @@ -456,23 +452,6 @@ export class StylableResolver {
: meta.getClass(nameOrSymbol)
: nameOrSymbol;

const customSelector = isElement
? null
: STCustomSelector.getCustomSelectorExpended(meta, name);

if (!symbol && !customSelector) {
return [];
}

if (customSelector && transformer) {
const parsed = transformer.resolveSelectorElements(meta, customSelector);
if (parsed.length === 1) {
return parsed[0][parsed[0].length - 1].resolved;
} else {
return [];
}
}

if (!symbol) {
return [];
}
Expand Down
50 changes: 44 additions & 6 deletions packages/core/test/features/css-pseudo-class.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,50 @@ describe('features/css-pseudo-class', () => {
.root:static(unknown-param) {}
`);
});
it('should report invalid template selector', () => {
testStylableCore(`
.a {
/*
@analyze-error(not-compound) ${stCustomStateDiagnostics.UNSUPPORTED_COMPLEX_SELECTOR(
'notCompound',
'.x .y'
)}
*/
-st-states: notCompound(".x .y");
}
.b {
/*
@analyze-error(multi) ${stCustomStateDiagnostics.UNSUPPORTED_MULTI_SELECTOR(
'multi',
'.x, .y'
)}
*/
-st-states: multi(".x, .y");
}
.c {
/*
@analyze-error(invalid) ${stCustomStateDiagnostics.INVALID_SELECTOR(
'invalid',
':unclosed('
)}
*/
-st-states: invalid(":unclosed(");
}
.d {
/*
@analyze-error(invalidStart) ${stCustomStateDiagnostics.UNSUPPORTED_INITIAL_SELECTOR(
'invalidStartElement',
'div.x'
)}
@analyze-error(invalidStart) ${stCustomStateDiagnostics.UNSUPPORTED_INITIAL_SELECTOR(
'invalidStartWildcard',
'*.x'
)}
*/
-st-states: invalidStartElement("div.x"), invalidStartWildcard("*.x");
}
`);
});
});
describe('custom mapped parameter', () => {
it('should transform mapped state (quoted)', () => {
Expand Down Expand Up @@ -517,12 +561,6 @@ describe('features/css-pseudo-class', () => {
shouldReportNoDiagnostics(meta);
});
it('should report invalid template selector', () => {
/**
* currently only checks template with parameter
* for backwards compatibility standalone template can accept
* any kind of selector - we might want to limit this in a future
* major version.
*/
testStylableCore(`
.root {
-st-states: classAndThenParam(".x$0", string),
Expand Down
4 changes: 2 additions & 2 deletions packages/esbuild/src/stylable-esbuild-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ export const stylablePlugin = (initialPluginOptions: ESBuildOptions = {}): Plugi
const projectRoot = build.initialOptions.absWorkingDir || process.cwd();
const configFromFile = resolveConfig(
projectRoot,
typeof configFile === 'string' ? configFile : undefined,
fs
fs,
typeof configFile === 'string' ? configFile : undefined
);
const stConfig = stylableConfig(
{
Expand Down
4 changes: 2 additions & 2 deletions packages/rollup-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ export function stylableRollupPlugin({
});
configFromFile = resolveStcConfig(
stConfig.projectRoot,
typeof stcConfig === 'string' ? stcConfig : undefined,
fs
fs,
typeof stcConfig === 'string' ? stcConfig : undefined
);

stylable = new Stylable({
Expand Down
2 changes: 1 addition & 1 deletion packages/schema-extract/test/test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ describe('Stylable JSON Schema Extractor', () => {

it('schema with mapped states', () => {
const css = `.root{
-st-states: state("custom");
-st-states: state(".custom");
}`;

const res = extractSchema(css, '/entry.st.css', '/', path);
Expand Down
9 changes: 6 additions & 3 deletions packages/webpack-plugin/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,8 @@ export class StylableWebpackPlugin {
private getStylableConfig(compiler: Compiler) {
const configuration = resolveStcConfig(
compiler.context,
typeof this.options.stcConfig === 'string' ? this.options.stcConfig : undefined,
getTopLevelInputFilesystem(compiler)
getTopLevelInputFilesystem(compiler),
typeof this.options.stcConfig === 'string' ? this.options.stcConfig : undefined
);

return configuration;
Expand Down Expand Up @@ -359,7 +359,10 @@ export class StylableWebpackPlugin {
return;
}

const resolverOptions: Omit<ResolveOptionsWebpackOptions, 'fileSystem' | 'resolver' | 'plugins'> = {
const resolverOptions: Omit<
ResolveOptionsWebpackOptions,
'fileSystem' | 'resolver' | 'plugins'
> = {
...compiler.options.resolve,
aliasFields:
compiler.options.resolve.byDependency?.esm?.aliasFields ||
Expand Down

0 comments on commit a2f42f6

Please sign in to comment.