Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[READY] feat: add type parameters to class name #3488

Open
wants to merge 50 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
e9f3e48
Feat/add type parameters to class name
deleonio Jul 26, 2022
fc5b0b8
test: add tests for generate component types
deleonio Jul 26, 2022
008d1dd
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Jul 26, 2022
f1b7b06
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Aug 2, 2022
f609d63
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Aug 3, 2022
66a6f50
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Aug 6, 2022
ba899bf
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Aug 17, 2022
23e2a90
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Aug 23, 2022
c292b3e
Merge branch 'feat/add-type-parameters-to-class-name' into feat/add-t…
deleonio Aug 31, 2022
c02a426
chore: fix conflict
deleonio Aug 31, 2022
5737f0d
Merge pull request #7 from deleonio/feat/add-type-parameters-to-class…
deleonio Aug 31, 2022
e2d3cf4
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Sep 1, 2022
aaa96cd
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Sep 7, 2022
9ea5b90
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Sep 11, 2022
a186a86
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Sep 13, 2022
43144ed
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Sep 13, 2022
1a30d31
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Sep 18, 2022
1642cff
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Sep 23, 2022
85a6ffc
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Sep 28, 2022
1109e74
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Oct 4, 2022
654acb7
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Oct 4, 2022
440926c
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Oct 6, 2022
e1db60e
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Oct 11, 2022
599f612
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Oct 13, 2022
f619b19
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Oct 14, 2022
1ae9d52
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Oct 17, 2022
d816105
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Oct 18, 2022
c6b6e6b
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Oct 23, 2022
3acd3fc
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Oct 25, 2022
3fd8f4c
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Oct 29, 2022
d42ef0a
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Nov 3, 2022
a792e0e
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Nov 12, 2022
3a190e7
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Nov 17, 2022
335460b
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Nov 26, 2022
65027a7
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Nov 29, 2022
6bc2ecf
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Dec 2, 2022
6a535af
Merge branch 'main' of https://github.com/ionic-team/stencil into fea…
deleonio Dec 16, 2022
014c4cd
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Dec 22, 2022
e901536
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Jan 10, 2023
c389d78
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Jan 18, 2023
54579c0
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Jan 27, 2023
397ae66
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Feb 21, 2023
1642ebd
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Mar 1, 2023
093b0cd
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Mar 6, 2023
c9dae6f
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Mar 8, 2023
83e3787
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Mar 14, 2023
8abfbec
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Mar 31, 2023
37f23f7
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Apr 28, 2023
7a4ba9f
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio May 18, 2023
5e16a05
Merge branch 'main' into feat/add-type-parameters-to-class-name
deleonio Jun 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/compiler/build/build-stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ function getComponentsFileMap(config: d.Config, buildCtx: d.BuildCtx) {
source: relativePath(config, component.sourceFilePath),
elementRef: component.elementRef,
componentClassName: component.componentClassName,
componentClassTypeParameters: component.componentClassTypeParameters,
assetsDirs: component.assetsDirs,
dependencies: component.dependencies,
dependents: component.dependents,
Expand Down
29 changes: 29 additions & 0 deletions src/compiler/transformers/static-to-meta/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const parseStaticComponentMeta = (
excludeFromCollection: moduleFile.excludeFromCollection,
isCollectionDependency,
componentClassName: cmpNode.name ? cmpNode.name.text : '',
componentClassTypeParameters: [],
elementRef: parseStaticElementRef(staticMembers),
encapsulation,
shadowDelegatesFocus: parseStaticShadowDelegatesFocus(encapsulation, staticMembers),
Expand Down Expand Up @@ -134,6 +135,34 @@ export const parseStaticComponentMeta = (
potentialCmpRefs: [],
};

/**
* This code add a component class name with the type
* parameters. Later in the compiler execution there
* will this name used to named the interfaces in the
* component.d.ts.
*
* Addressed issue(s):
* - https://github.com/ionic-team/stencil/issues/2895
*
* TypeScript implementation:
* - https://github.com/microsoft/TypeScript/blob/7584e6aad6b21f7334562bfd9d8c3c80aafed064/src/services/services.ts#L326
*/
if (
typeof symbol === 'object' &&
symbol !== null &&
typeof symbol.getDeclarations === 'function'
) {
const declarations = symbol.getDeclarations();
if (Array.isArray(declarations) && declarations.length > 0) {
const declaration = declarations[0] as ts.ClassDeclaration;
if (Array.isArray(declaration.typeParameters)) {
declaration.typeParameters.forEach((typeParameter) =>
cmp.componentClassTypeParameters.push(typeParameter.name.text)
);
}
}
}

const visitComponentChildNode = (node: ts.Node) => {
if (ts.isCallExpression(node)) {
parseCallExpression(cmp, node);
Expand Down
27 changes: 18 additions & 9 deletions src/compiler/types/generate-component-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ export const generateComponentTypes = (
): d.TypesModule => {
const tagName = cmp.tagName.toLowerCase();
const tagNameAsPascal = dashToPascalCase(tagName);
const classTypeParams =
cmp.componentClassTypeParameters.length > 0 ? `<${cmp.componentClassTypeParameters.join(',')}>` : '';
const classTypeParamsAny =
cmp.componentClassTypeParameters.length > 0
? `<${cmp.componentClassTypeParameters.map(() => 'any').join(',')}>`
: '';
const htmlElementName = `HTML${tagNameAsPascal}Element`;

const propAttributes = generatePropTypes(cmp, typeImportData);
Expand All @@ -35,23 +41,26 @@ export const generateComponentTypes = (

const element = [
addDocBlock(
` interface ${htmlElementName} extends Components.${tagNameAsPascal}, HTMLStencilElement {`,
` interface ${htmlElementName}${classTypeParams} extends Components.${tagNameAsPascal}${classTypeParams}, HTMLStencilElement {`,
cmp.docs,
4
),
` prototype: ${htmlElementName}${classTypeParams};`,
` new (): ${htmlElementName}${classTypeParams};`,
` }`,
` var ${htmlElementName}: {`,
` prototype: ${htmlElementName};`,
` new (): ${htmlElementName};`,
` };`,
` var ${htmlElementName}: ${htmlElementName}${classTypeParamsAny};`,
];
return {
isDep,
tagName,
tagNameAsPascal,
htmlElementName,
component: addDocBlock(` interface ${tagNameAsPascal} {\n${componentAttributes} }`, cmp.docs, 4),
jsx: ` interface ${tagNameAsPascal} {\n${jsxAttributes} }`,
tagNameAsPascal: `${tagNameAsPascal}${classTypeParamsAny}`,
htmlElementName: `${htmlElementName}${classTypeParamsAny}`,
component: addDocBlock(
` interface ${tagNameAsPascal}${classTypeParams} {\n${componentAttributes} }`,
cmp.docs,
4
),
jsx: ` interface ${tagNameAsPascal}${classTypeParams} {\n${jsxAttributes} }`,
element: element.join(`\n`),
};
};
Expand Down
1 change: 1 addition & 0 deletions src/compiler/types/tests/ComponentCompilerMeta.stub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const stubComponentCompilerMeta = (
): d.ComponentCompilerMeta => ({
assetsDirs: [],
componentClassName: 'StubCmp',
componentClassTypeParameters: [],
dependencies: [],
dependents: [],
directDependencies: [],
Expand Down
61 changes: 61 additions & 0 deletions src/compiler/types/tests/generate-component-types.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type * as d from '../../../declarations';
import { generateComponentTypes } from '../generate-component-types';
import { stubComponentCompilerMeta } from './ComponentCompilerMeta.stub';
import { stubTypesImportData } from './TypesImportData.stub';

describe('generate-component-types', () => {
describe('generateComponentTypes', () => {
it('default', () => {
// given
const componentCompilerMeta = stubComponentCompilerMeta();
const typeImportData = stubTypesImportData();

// when
const typesModule: d.TypesModule = generateComponentTypes(componentCompilerMeta, typeImportData, false);

// then
expect(typesModule).toEqual<d.TypesModule>({
component: ` interface StubCmp {
}`,
element: ` interface HTMLStubCmpElement extends Components.StubCmp, HTMLStencilElement {
prototype: HTMLStubCmpElement;
new (): HTMLStubCmpElement;
}
var HTMLStubCmpElement: HTMLStubCmpElement;`,
htmlElementName: `HTMLStubCmpElement`,
isDep: false,
jsx: ` interface StubCmp {
}`,
tagName: 'stub-cmp',
tagNameAsPascal: 'StubCmp',
});
});

it('with type parameters', () => {
// given
const componentCompilerMeta = stubComponentCompilerMeta();
const typeImportData = stubTypesImportData();
componentCompilerMeta.componentClassTypeParameters = ['a', 'b'];

// when
const typesModule: d.TypesModule = generateComponentTypes(componentCompilerMeta, typeImportData, false);

// then
expect(typesModule).toEqual<d.TypesModule>({
component: ` interface StubCmp<a,b> {
}`,
element: ` interface HTMLStubCmpElement<a,b> extends Components.StubCmp<a,b>, HTMLStencilElement {
prototype: HTMLStubCmpElement<a,b>;
new (): HTMLStubCmpElement<a,b>;
}
var HTMLStubCmpElement: HTMLStubCmpElement<any,any>;`,
htmlElementName: `HTMLStubCmpElement<any,any>`,
isDep: false,
jsx: ` interface StubCmp<a,b> {
}`,
tagName: 'stub-cmp',
tagNameAsPascal: 'StubCmp<any,any>',
});
});
});
});
1 change: 1 addition & 0 deletions src/declarations/stencil-private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,7 @@ export interface ComponentCompilerFeatures {
export interface ComponentCompilerMeta extends ComponentCompilerFeatures {
assetsDirs: CompilerAssetDir[];
componentClassName: string;
componentClassTypeParameters: string[];
elementRef: string;
encapsulation: Encapsulation;
shadowDelegatesFocus: boolean;
Expand Down
Loading