Skip to content

Commit

Permalink
refactor(types)!: enhance type definitions for resolved CSS and JS va…
Browse files Browse the repository at this point in the history
…lues (#2912)
  • Loading branch information
idoros authored Oct 2, 2023
1 parent d56e5f5 commit 7a8b399
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 49 deletions.
8 changes: 4 additions & 4 deletions packages/core/src/features/st-mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export class StylablePublicApi {
name,
kind: 'js-func',
args: [],
func: resolvedSymbols.js[name].symbol,
func: resolvedSymbols.js[name].symbol as (...args: any[]) => any,
};
for (const arg of Object.values(data.options)) {
mixRef.args.push(arg.value);
Expand Down Expand Up @@ -374,10 +374,10 @@ function appendMixin(context: FeatureTransformContext, config: ApplyMixinContext
handleCSSMixin(context, config, resolveChain);
return;
} else if (resolvedType === `js`) {
const resolvedMixin = resolvedSymbols.js[symbolName];
if (typeof resolvedMixin.symbol === 'function') {
const jsValue = resolvedSymbols.js[symbolName].symbol;
if (typeof jsValue === 'function') {
try {
handleJSMixin(context, config, resolvedMixin.symbol);
handleJSMixin(context, config, jsValue as (...args: any[]) => any);
} catch (e) {
context.diagnostics.report(diagnostics.FAILED_TO_APPLY_MIXIN(String(e)), {
node: config.rule,
Expand Down
17 changes: 6 additions & 11 deletions packages/core/src/features/st-var.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,21 +400,16 @@ function evaluateValueCall(
const type = resolvedSymbols.mainNamespace[varName];
if (type === `js`) {
const deepResolve = resolvedSymbols.js[varName];
const importedType = typeof deepResolve.symbol;
if (importedType === 'string') {
const jsValue = deepResolve.symbol;
if (typeof jsValue === 'string') {
parsedNode.resolvedValue = context.evaluator.valueHook
? context.evaluator.valueHook(
deepResolve.symbol,
varName,
false,
passedThrough
)
: deepResolve.symbol;
? context.evaluator.valueHook(jsValue, varName, false, passedThrough)
: jsValue;
} else if (node) {
// unsupported Javascript value
// ToDo: provide actual exported id (default/named as x)
context.diagnostics.report(
diagnostics.CANNOT_USE_JS_AS_VALUE(importedType, varName),
diagnostics.CANNOT_USE_JS_AS_VALUE(typeof jsValue, varName),
{
node,
word: varName,
Expand Down Expand Up @@ -480,7 +475,7 @@ export function resolveReferencedVarNames(
break;
case 'import': {
const resolved = context.resolver.deepResolve(symbol);
if (resolved?._kind === 'css' && resolved.symbol._kind === 'var') {
if (resolved?._kind === 'css' && resolved.symbol?._kind === 'var') {
varsToCheck.push({ meta: resolved.meta, name: resolved.symbol.name });
}
break;
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,10 @@ export function processDeclarationValue(
const formatter = resolvedSymbols.js[value];
const formatterArgs = getFormatterArgs(parsedNode);
try {
parsedNode.resolvedValue = formatter.symbol.apply(null, formatterArgs);
// ToDo: check if function instead of calling on a non function
parsedNode.resolvedValue = (formatter.symbol as (...args: any[]) => any)(
...formatterArgs
);
if (evaluator.valueHook && typeof parsedNode.resolvedValue === 'string') {
parsedNode.resolvedValue = evaluator.valueHook(
parsedNode.resolvedValue,
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/index-internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ export {
EmitDiagnosticsContext,
reportDiagnostic,
} from './report-diagnostic';
export { StylableResolver, StylableResolverCache } from './stylable-resolver';
export {
StylableResolver,
StylableResolverCache,
isValidCSSResolve,
CSSResolveMaybe,
} from './stylable-resolver';
export { CacheItem, FileProcessor, cachedProcessFile, processFn } from './cached-process-file';
export { createStylableFileProcessor } from './create-stylable-processor';
export { packageNamespaceFactory } from './resolve-namespace-factories';
Expand Down
40 changes: 28 additions & 12 deletions packages/core/src/stylable-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,26 @@ export type CachedModuleEntity =

export type StylableResolverCache = Map<string, CachedModuleEntity>;

export interface CSSResolveMaybe<
T extends StylableSymbol | STStructure.PartSymbol = StylableSymbol
> {
_kind: 'css';
symbol: T | undefined;
meta: StylableMeta;
}
export interface CSSResolve<T extends StylableSymbol | STStructure.PartSymbol = StylableSymbol> {
_kind: 'css';
symbol: T;
meta: StylableMeta;
}
export function isValidCSSResolve(resolved: CSSResolveMaybe): resolved is CSSResolve {
return resolved.symbol !== undefined;
}
export type CSSResolvePath = Array<CSSResolve<ClassSymbol | ElementSymbol>>;

export interface JSResolve {
_kind: 'js';
symbol: any;
symbol: unknown;
meta: null;
}

Expand All @@ -91,7 +101,7 @@ export interface MetaResolvedSymbols {
}

export type ReportError = (
res: CSSResolve | JSResolve | null,
res: CSSResolveMaybe | JSResolve | null,
extend: ImportSymbol | ClassSymbol | ElementSymbol,
extendPath: Array<CSSResolve<ClassSymbol | ElementSymbol>>,
meta: StylableMeta,
Expand Down Expand Up @@ -192,7 +202,7 @@ export class StylableResolver {
imported: Imported,
name: string,
subtype: 'mappedSymbols' | 'mappedKeyframes' | STSymbol.Namespaces = 'mappedSymbols'
): CSSResolve | JSResolve | null {
): CSSResolveMaybe | JSResolve | null {
const res = this.getModule(imported);
if (res.value === null) {
return null;
Expand Down Expand Up @@ -226,7 +236,7 @@ export class StylableResolver {
const name = importSymbol.type === 'named' ? importSymbol.name : '';
return this.resolveImported(importSymbol.import, name);
}
public resolve(maybeImport: StylableSymbol | undefined): CSSResolve | JSResolve | null {
public resolve(maybeImport: StylableSymbol | undefined): CSSResolveMaybe | JSResolve | null {
if (!maybeImport || maybeImport._kind !== 'import') {
if (
maybeImport &&
Expand Down Expand Up @@ -261,7 +271,7 @@ export class StylableResolver {
public deepResolve(
maybeImport: StylableSymbol | undefined,
path: StylableSymbol[] = []
): CSSResolve | JSResolve | null {
): CSSResolveMaybe | JSResolve | null {
let resolved = this.resolve(maybeImport);
while (
resolved &&
Expand Down Expand Up @@ -334,7 +344,7 @@ export class StylableResolver {
};
// resolve main namespace
for (const [name, symbol] of Object.entries(meta.getAllSymbols())) {
let deepResolved: CSSResolve | JSResolve | null;
let deepResolved: CSSResolveMaybe | JSResolve | null;
if (symbol._kind === `import` || (symbol._kind === `cssVar` && symbol.alias)) {
deepResolved = this.deepResolve(symbol);
if (!deepResolved || !deepResolved.symbol) {
Expand Down Expand Up @@ -366,13 +376,19 @@ export class StylableResolver {
} else {
deepResolved = { _kind: `css`, meta, symbol };
}
switch (deepResolved.symbol._kind) {
// deepResolved symbol is resolved by this point
switch (deepResolved.symbol!._kind) {
case `class`:
resolvedSymbols.class[name] = this.resolveExtends(
meta,
deepResolved.symbol,
deepResolved.symbol!,
false,
validateClassResolveExtends(meta, name, diagnostics, deepResolved)
validateClassResolveExtends(
meta,
name,
diagnostics,
deepResolved as CSSResolve<ClassSymbol>
)
);
break;
case `element`:
Expand All @@ -385,7 +401,7 @@ export class StylableResolver {
resolvedSymbols.cssVar[name] = deepResolved as CSSResolve<CSSVarSymbol>;
break;
}
resolvedSymbols.mainNamespace[name] = deepResolved.symbol._kind;
resolvedSymbols.mainNamespace[name] = deepResolved.symbol!._kind;
}
// resolve keyframes
for (const [name, symbol] of Object.entries(CSSKeyframes.getAll(meta))) {
Expand Down Expand Up @@ -497,7 +513,7 @@ function validateClassResolveExtends(
meta: StylableMeta,
name: string,
diagnostics: Diagnostics,
deepResolved: CSSResolve<StylableSymbol> | JSResolve | null
deepResolved: CSSResolve<ClassSymbol>
): ReportError | undefined {
return (res, extend) => {
const decl = findRule(meta.sourceAst, '.' + name);
Expand All @@ -520,7 +536,7 @@ function validateClassResolveExtends(
});
}
} else {
if (deepResolved?.symbol.alias) {
if (deepResolved.symbol.alias) {
meta.sourceAst.walkRules(new RegExp('\\.' + name), (rule) => {
diagnostics.report(CSSClass.diagnostics.UNKNOWN_IMPORT_ALIAS(name), {
node: rule,
Expand Down
1 change: 1 addition & 0 deletions packages/language-service/src/lib/completion-providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ export const ExtendCompletionPlugin: LangServicePlugin = {
return (
res &&
res._kind === 'css' &&
res.symbol &&
(res.symbol._kind === 'class' || res.symbol._kind === 'element')
);
})
Expand Down
32 changes: 14 additions & 18 deletions packages/language-service/src/lib/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import {
ImportSymbol,
Stylable,
StylableMeta,
JSResolve,
Diagnostics,
} from '@stylable/core';
import {
safeParse,
StylableProcessor,
STCustomSelector,
MappedStates,
type StylableResolver,
isValidCSSResolve,
} from '@stylable/core/dist/index-internal';
import type {
Location,
Expand Down Expand Up @@ -202,7 +203,7 @@ export class Provider {
break;
}
case 'import': {
let resolved: CSSResolve | JSResolve | null = null;
let resolved: ReturnType<StylableResolver['resolve']> = null;
try {
resolved = this.stylable.resolver.resolve(symbol);
} catch {
Expand Down Expand Up @@ -321,29 +322,24 @@ export class Provider {
state: string
): CSSResolve | null {
const importedSymbol = origMeta.getClass(elementName)![`-st-extends`];
let res: CSSResolve | JSResolve | null = null;
let res: ReturnType<StylableResolver['resolveImport']> = null;

if (importedSymbol && importedSymbol._kind === 'import') {
res = this.stylable.resolver.resolveImport(importedSymbol);
}

const localSymbol = origMeta.getSymbol(elementName)!;
if (
res &&
res._kind === 'css' &&
Object.keys((res.symbol as ClassSymbol)[`-st-states`]!).includes(state)
) {
return res;
} else if (
res &&
res._kind === 'css' &&
(localSymbol._kind === 'class' || localSymbol._kind === 'element') &&
localSymbol[`-st-extends`]
) {
return this.findMyState(res.meta, res.symbol.name, state);
} else {
return null;
if (res && res._kind === 'css' && isValidCSSResolve(res)) {
if (Object.keys((res.symbol as ClassSymbol)[`-st-states`]!).includes(state)) {
return res;
} else if (
(localSymbol._kind === 'class' || localSymbol._kind === 'element') &&
localSymbol[`-st-extends`]
) {
return this.findMyState(res.meta, res.symbol.name, state);
}
}
return null;
}

public getSignatureHelp(
Expand Down
5 changes: 3 additions & 2 deletions packages/webpack-extensions/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { CSSResolve, Imported, JSResolve, StylableMeta } from '@stylable/core';
import type { Imported, JSResolve, StylableMeta } from '@stylable/core';
import type { CSSResolveMaybe } from '@stylable/core/dist/index-internal';

export interface Metadata {
entry: string;
Expand All @@ -24,5 +25,5 @@ export type MetadataList = Array<{

export type ResolvedImport = {
stImport: Imported;
resolved: CSSResolve | JSResolve | null;
resolved: CSSResolveMaybe | JSResolve | null;
};

0 comments on commit 7a8b399

Please sign in to comment.