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

feat(@Mixin): new decorator #2921

Closed
wants to merge 47 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
5752b53
chore(mixin) - rebase
Apr 8, 2021
91fa507
Mixin decorator - make quits earlier & checks if we resolve imported …
johnjenkins May 14, 2021
d12d79a
End-to-end tests init.
johnjenkins May 17, 2021
c7cefa3
Added mixin-spec test. Amended omit and pick tests
johnjenkins May 18, 2021
22e318d
feat(@Mixin) - made mixins works for single modules and so spec tests…
johnjenkins May 28, 2021
2d0a535
feat(platform): add setPlatformHelpers() api
adamdbradley May 27, 2021
71810ab
🚌 2.6.0-0
adamdbradley May 27, 2021
913a73d
chore(mixin) - rebase
Apr 8, 2021
ff812a7
Mixin decorator - make quits earlier & checks if we resolve imported …
johnjenkins May 14, 2021
c9a3227
End-to-end tests init.
johnjenkins May 17, 2021
47f920f
Added mixin-spec test. Amended omit and pick tests
johnjenkins May 18, 2021
ab27dfd
feat(@Mixin) - made mixins works for single modules and so spec tests…
johnjenkins May 28, 2021
ed277ec
Merge branch 'feat-mixin-decorator' of github.com:johnjenkins/stencil…
johnjenkins Jun 3, 2021
b644e76
fix(cloneNode): stop stripping out questionDotTokens
johnjenkins Jun 9, 2021
a819d71
Merge branch 'master' into feat-mixin-decorator
johnjenkins Jun 28, 2021
1bbd5a7
fix(@Mixin): stop cloning nodes in components not using @Mixin
johnjenkins Jul 19, 2021
7ca2a47
remove temporary clone fix for property access chains
johnjenkins Jul 19, 2021
b0a97cb
fix mixin tests for node 12. Install ionic via gitpkg
johnjenkins Jul 19, 2021
b68161f
fix karma mixin tests
johnjenkins Jul 19, 2021
0849b64
fix - stop resolving node_modules with relative paths
johnjenkins Jul 29, 2021
57a7217
chore(format): add prettier
rwaskiewicz Jul 1, 2021
4680f76
format codebase
johnjenkins Aug 6, 2021
9558602
chore(mixin) - rebase
Apr 8, 2021
c5d880b
Mixin decorator - make quits earlier & checks if we resolve imported …
johnjenkins May 14, 2021
394495d
End-to-end tests init.
johnjenkins May 17, 2021
a468dbf
Added mixin-spec test. Amended omit and pick tests
johnjenkins May 18, 2021
32e354b
feat(@Mixin) - made mixins works for single modules and so spec tests…
johnjenkins May 28, 2021
ebe0474
Mixin decorator - make quits earlier & checks if we resolve imported …
johnjenkins May 14, 2021
feee2f1
Added mixin-spec test. Amended omit and pick tests
johnjenkins May 18, 2021
7ea27e6
feat(@Mixin) - made mixins works for single modules and so spec tests…
johnjenkins May 28, 2021
26b56bb
feat(platform): add setPlatformHelpers() api
adamdbradley May 27, 2021
39e4fe3
fix(cloneNode): stop stripping out questionDotTokens
johnjenkins Jun 9, 2021
6d17285
fix(@Mixin): stop cloning nodes in components not using @Mixin
johnjenkins Jul 19, 2021
0e7cffc
remove temporary clone fix for property access chains
johnjenkins Jul 19, 2021
0664765
fix mixin tests for node 12. Install ionic via gitpkg
johnjenkins Jul 19, 2021
8f37068
fix karma mixin tests
johnjenkins Jul 19, 2021
ab6c841
fix - stop resolving node_modules with relative paths
johnjenkins Jul 29, 2021
51cc724
fix jest --coverage with mixin (output inline source maps to fix babe…
johnjenkins Sep 6, 2021
6fd1cf3
Merge branch 'feat-mixin-decorator-rebase' into feat-mixin-decorator
johnjenkins Sep 6, 2021
ac7609b
rv extra prettier git workflow
johnjenkins Sep 6, 2021
974faa3
Merge branch 'master' into feat-mixin-decorator
johnjenkins Sep 7, 2021
78e9977
Merge branch 'stencil-main' into feat-mixin-decorator
Nov 25, 2021
5ab66d8
rm mixin external lib tests - flaky with ionic git
Nov 26, 2021
6aae006
revert test settings
Nov 26, 2021
9e89a56
fix karma test
Nov 26, 2021
1d8f564
Merge branch 'main' into feat-mixin-decorator
johnjenkins Dec 2, 2021
8b48a21
Merge branch 'main' into feat-mixin-decorator
johnjenkins Dec 7, 2021
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
12,866 changes: 59 additions & 12,807 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"@types/ws": "^7.4.0",
"@types/yarnpkg__lockfile": "^1.1.5",
"@yarnpkg/lockfile": "^1.1.0",
"ts-clone-node": "^0.3.24",
"ansi-colors": "4.1.1",
"autoprefixer": "10.2.5",
"concurrently": "^6.0.0",
Expand Down
1 change: 1 addition & 0 deletions src/compiler/build/compiler-ctx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export const getModuleLegacy = (_config: d.Config, compilerCtx: d.CompilerCtx, s
potentialCmpRefs: [],
staticSourceFile: null,
staticSourceFileText: '',
mixinFilePaths: [],
sourceMapPath: null,
sourceMapFileText: null,
};
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/sys/typescript/typescript-sys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ const patchTsSystemWatch = (stencilSys: d.CompilerSystem, tsSys: ts.System) => {
export const patchTypescript = (config: d.Config, inMemoryFs: d.InMemoryFileSystem) => {
if (!(ts as any).__patched) {
if (config.sys) {
patchTsSystemFileSystem(config, config.sys, inMemoryFs, ts.sys);
if (inMemoryFs) patchTsSystemFileSystem(config, config.sys, inMemoryFs, ts.sys);
patchTsSystemWatch(config.sys, ts.sys);
}
patchTypeScriptResolveModule(config, inMemoryFs);
if (inMemoryFs) patchTypeScriptResolveModule(config, inMemoryFs);
patchTypeScriptGetParsedCommandLineOfConfigFile();
(ts as any).__patched = true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type * as d from '../../../declarations';
import { augmentDiagnosticWithNode, buildError, validateComponentTag, isString, buildWarn } from '@utils';
import { getDeclarationParameters } from './decorator-utils';
import { getDeclarationParameters, isDecoratorNamed } from './decorator-utils';
import { convertValueToLiteral, createStaticGetter } from '../transform-utils';
import { styleToStatic } from './style-to-static';
import ts from 'typescript';
Expand Down Expand Up @@ -87,12 +87,14 @@ const validateComponent = (
}

// check if class has more than one decorator
const otherDecorator = cmpNode.decorators && cmpNode.decorators.find((d) => d !== componentDecorator);
if (otherDecorator) {
const mixinDecs = cmpNode.decorators && cmpNode.decorators.filter(isDecoratorNamed('Mixin'));
const otherDecorator =
cmpNode.decorators && cmpNode.decorators.filter((d) => d !== componentDecorator && !mixinDecs.includes(d));
if (otherDecorator.length) {
const err = buildError(diagnostics);
err.messageText = `Classes decorated with @Component can not be decorated with more decorators.
Stencil performs extensive static analysis on top of your components in order to generate the necessary metadata, runtime decorators at the components level make this task very hard.`;
augmentDiagnosticWithNode(err, otherDecorator);
augmentDiagnosticWithNode(err, otherDecorator[0]);
return false;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
import type * as d from '../../../declarations';
import { CLASS_DECORATORS_TO_REMOVE, MEMBER_DECORATORS_TO_REMOVE } from './decorators-constants';
import { mixinClassMembers, hasMixins, mixinStatements, VisitedFiles, FoundMixins } from './mixin-decorator';
import { componentDecoratorToStatic } from './component-decorator';
import { elementDecoratorsToStatic } from './element-decorator';
import { eventDecoratorsToStatic } from './event-decorator';
import { listenDecoratorsToStatic } from './listen-decorator';
import { isDecoratorNamed } from './decorator-utils';
import { cloneNode } from '../transform-utils';
import { methodDecoratorsToStatic, validateMethods } from './method-decorator';
import { propDecoratorsToStatic } from './prop-decorator';
import { stateDecoratorsToStatic } from './state-decorator';
import { watchDecoratorsToStatic } from './watch-decorator';
import ts from 'typescript';

const visitedFiles: VisitedFiles = new Map();
const allMixins: FoundMixins = new Map();

export const convertDecoratorsToStatic = (
config: d.Config,
diagnostics: d.Diagnostic[],
typeChecker: ts.TypeChecker
typeChecker: ts.TypeChecker,
compilerHost?: ts.CompilerHost
): ts.TransformerFactory<ts.SourceFile> => {
return (transformCtx) => {
const visit = (node: ts.Node): ts.VisitResult<ts.Node> => {
Expand All @@ -25,11 +31,29 @@ export const convertDecoratorsToStatic = (
};

return (tsSourceFile) => {
return ts.visitEachChild(tsSourceFile, visit, transformCtx);
const sourceFile = visitSourceFile(tsSourceFile, diagnostics, compilerHost);
return ts.visitEachChild(sourceFile, visit, transformCtx);
};
};
};

export const visitSourceFile = (
sourceNode: ts.SourceFile,
diagnostics: d.Diagnostic[],
compilerHost?: ts.CompilerHost
) => {
visitedFiles.set(sourceNode.fileName, sourceNode);
const mixinsFound = hasMixins(sourceNode, diagnostics, visitedFiles, compilerHost);
if (!mixinsFound) {
return sourceNode;
}

const statements = mixinStatements(sourceNode, mixinsFound, diagnostics);
allMixins.set(sourceNode.fileName, mixinsFound);

return ts.factory.updateSourceFile(sourceNode, statements);
};

export const visitClassDeclaration = (
config: d.Config,
diagnostics: d.Diagnostic[],
Expand All @@ -45,7 +69,9 @@ export const visitClassDeclaration = (
return classNode;
}

const classMembers = classNode.members;
const didReplace = mixinClassMembers(classNode, allMixins);
const classMembers = !!didReplace ? didReplace : classNode.members;

const decoratedMembers = classMembers.filter(
(member) => Array.isArray(member.decorators) && member.decorators.length > 0
);
Expand All @@ -69,14 +95,14 @@ export const visitClassDeclaration = (

validateMethods(diagnostics, classMembers);

return ts.updateClassDeclaration(
return ts.factory.updateClassDeclaration(
classNode,
removeDecorators(classNode, CLASS_DECORATORS_TO_REMOVE),
classNode.modifiers,
classNode.name,
classNode.typeParameters,
classNode.heritageClauses,
newMembers
didReplace ? newMembers.map((member) => cloneNode(member)) : newMembers
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ const getDeclarationParameter = (arg: ts.Expression): any => {
throw new Error(`invalid decorator argument: ${arg.getText()}`);
};

export const isDecoratorNamed = (propName: string) => {
export const isDecoratorNamed = (propName: string, sourceFile?: ts.SourceFile) => {
return (dec: ts.Decorator): boolean => {
return ts.isCallExpression(dec.expression) && dec.expression.expression.getText() === propName;
return ts.isCallExpression(dec.expression) && dec.expression.expression.getText(sourceFile) === propName;
};
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const CLASS_DECORATORS_TO_REMOVE = new Set(['Component']);
export const CLASS_DECORATORS_TO_REMOVE = new Set(['Component', 'Mixin']);

export const MEMBER_DECORATORS_TO_REMOVE = new Set([
'Element',
Expand Down
Loading