Skip to content

Commit

Permalink
fix(parse): parse decorator shorthand property assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdbradley committed Aug 12, 2020
1 parent 62ea511 commit 6b9e035
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 73 deletions.
12 changes: 12 additions & 0 deletions src/compiler/transformers/test/parse-styles.spec.ts
Expand Up @@ -71,4 +71,16 @@ describe('parse styles', () => {
md: 'p{color:red}',
});
});

it('add static "styles" const', () => {
const t = transpileModule(`
const styles = 'p{color:red}';
@Component({
tag: 'cmp-a',
styles,
})
export class CmpA {}
`);
expect(t.outputText).toEqual(`const styles = 'p{color:red}';export class CmpA { static get is() { return "cmp-a"; } static get styles() { return styles; }}`);
});
});
109 changes: 57 additions & 52 deletions src/compiler/transformers/transform-utils.ts
Expand Up @@ -182,63 +182,68 @@ export const arrayLiteralToArray = (arr: ts.ArrayLiteralExpression) => {
});
};

export const objectLiteralToObjectMap = (objectLiteral: ts.ObjectLiteralExpression): ObjectMap => {
const attrs: ts.ObjectLiteralElementLike[] = objectLiteral.properties as any;
export const objectLiteralToObjectMap = (objectLiteral: ts.ObjectLiteralExpression) => {
const properties = objectLiteral.properties;
const final: ObjectMap = {};

return attrs.reduce((final: ObjectMap, attr: ts.PropertyAssignment) => {
const attrName = getTextOfPropertyName(attr.name);
for (const propAssignment of properties) {
const propName = getTextOfPropertyName(propAssignment.name);
let val: any;

switch (attr.initializer.kind) {
case ts.SyntaxKind.ArrayLiteralExpression:
val = arrayLiteralToArray(attr.initializer as ts.ArrayLiteralExpression);
break;

case ts.SyntaxKind.ObjectLiteralExpression:
val = objectLiteralToObjectMap(attr.initializer as ts.ObjectLiteralExpression);
break;

case ts.SyntaxKind.StringLiteral:
val = (attr.initializer as ts.StringLiteral).text;
break;

case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
val = (attr.initializer as ts.StringLiteral).text;
break;

case ts.SyntaxKind.TrueKeyword:
val = true;
break;

case ts.SyntaxKind.FalseKeyword:
val = false;
break;

case ts.SyntaxKind.Identifier:
const escapedText = (attr.initializer as ts.Identifier).escapedText;
if (escapedText === 'String') {
val = String;
} else if (escapedText === 'Number') {
val = Number;
} else if (escapedText === 'Boolean') {
val = Boolean;
} else if (escapedText === 'undefined') {
val = undefined;
} else if (escapedText === 'null') {
val = null;
} else {
val = getIdentifierValue((attr.initializer as ts.Identifier).escapedText);
}
break;

case ts.SyntaxKind.PropertyAccessExpression:
default:
val = attr.initializer;
if (ts.isShorthandPropertyAssignment(propAssignment)) {
val = getIdentifierValue(propName);
} else if (ts.isPropertyAssignment(propAssignment)) {
switch (propAssignment.initializer.kind) {
case ts.SyntaxKind.ArrayLiteralExpression:
val = arrayLiteralToArray(propAssignment.initializer as ts.ArrayLiteralExpression);
break;

case ts.SyntaxKind.ObjectLiteralExpression:
val = objectLiteralToObjectMap(propAssignment.initializer as ts.ObjectLiteralExpression);
break;

case ts.SyntaxKind.StringLiteral:
val = (propAssignment.initializer as ts.StringLiteral).text;
break;

case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
val = (propAssignment.initializer as ts.StringLiteral).text;
break;

case ts.SyntaxKind.TrueKeyword:
val = true;
break;

case ts.SyntaxKind.FalseKeyword:
val = false;
break;

case ts.SyntaxKind.Identifier:
const escapedText = (propAssignment.initializer as ts.Identifier).escapedText;
if (escapedText === 'String') {
val = String;
} else if (escapedText === 'Number') {
val = Number;
} else if (escapedText === 'Boolean') {
val = Boolean;
} else if (escapedText === 'undefined') {
val = undefined;
} else if (escapedText === 'null') {
val = null;
} else {
val = getIdentifierValue((propAssignment.initializer as ts.Identifier).escapedText);
}
break;

case ts.SyntaxKind.PropertyAccessExpression:
default:
val = propAssignment.initializer;
}
}
final[propName] = val;
}

final[attrName] = val;
return final;
}, <ObjectMap>{});
return final;
};

const getIdentifierValue = (escapedText: any) => {
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/update-component.ts
Expand Up @@ -24,7 +24,7 @@ export const scheduleUpdate = (hostRef: d.HostRef, isInitialLoad: boolean) => {
}
attachToAncestor(hostRef, hostRef.$ancestorComponent$);

// there is no ancestorc omponent or the ancestor component
// there is no ancestor component or the ancestor component
// has already fired off its lifecycle update then
// fire off the initial update
const dispatch = () => dispatchHooks(hostRef, isInitialLoad);
Expand Down
9 changes: 3 additions & 6 deletions test/hello-vdom/src/components/hello-vdom.tsx
@@ -1,15 +1,12 @@
import { Component, h } from '@stencil/core';
import styles from './styles.css';

@Component({
tag: 'hello-vdom',
styleUrl: 'styles.css'
styles: styles,
})
export class HelloWorld {
render() {
return (
<h1>
Hello VaasA! dfhj
</h1>
);
return <h1>Hello VDom!</h1>;
}
}
4 changes: 2 additions & 2 deletions test/hello-vdom/src/components/styles.css
@@ -1,3 +1,3 @@
div {
color: red;
h1 {
color: blue;
}
15 changes: 3 additions & 12 deletions test/hello-vdom/stencil.config.ts
Expand Up @@ -2,20 +2,11 @@ import { Config } from '../../internal';

export const config: Config = {
namespace: 'HelloVDom',
outputTargets: [
{ type: 'dist' },
{ type: 'www', serviceWorker: null },
],
outputTargets: [{ type: 'dist' }, { type: 'www', serviceWorker: null }],
devServer: {
logRequests: true
logRequests: true,
},
hashFileNames: false,
hydratedFlag: null,
extras: {
cssVarsShim: false,
dynamicImportShim: false,
safari10: false,
scriptDataOpts: false,
shadowDomShim: false,
}
taskQueue: 'immediate',
};

0 comments on commit 6b9e035

Please sign in to comment.