Skip to content

Commit

Permalink
Publish 32.0.1 (#56)
Browse files Browse the repository at this point in the history
Fix for optional chaining.
  • Loading branch information
StephenCooper authored Jul 4, 2024
2 parents a475d4a + 751fc7a commit 0e13da0
Show file tree
Hide file tree
Showing 59 changed files with 1,137 additions and 710 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ jobs:
- name: Checkout Git repository
uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v4
with:
version: 9
- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 20.x
registry-url: https://registry.npmjs.org
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ jobs:
- name: Checkout Git repository
uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v4
with:
version: 9
- name: Install Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: pnpm
Expand Down
6 changes: 6 additions & 0 deletions .vscode/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
__fixtures__
coverage
docs
dist
pnpm-lock.yaml
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"cSpell.words": ["Codemod", "codemods", "organised"],
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",

"prettier.ignorePath": ".vscode/.prettierignore"
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
"glob": "10.4.2",
"prettier": "3.3.2",
"typedoc": "^0.26.3",
"typescript": "5.5.2",
"vite": "5.3.2",
"typescript": "5.5.3",
"vite": "5.3.3",
"vitest": "1.6.0",
"@vitest/coverage-v8": "1.6.0"
}
Expand Down
28 changes: 27 additions & 1 deletion packages/ast/src/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,34 @@ const TEMPLATE_OPTIONS: TemplateBuilderOptions = {

export function expression<T extends Expression = Expression>(
literals: TemplateStringsArray,
...interpolations: Array<AstNode>
...interpolations: Array<AstNode | string>
): T {
// If interpolations contains a string, we need to merge it with the literal and excluding it from the interpolations
if (interpolations.some((interpolation) => typeof interpolation === 'string')) {
const newRawLiterals: string[] = [];
const newLiterals: string[] & { raw: string[] } = [] as any;
newLiterals.raw = newRawLiterals;
const newInterpolations: Array<AstNode> = [];

let currentLiteral = literals[0];
for (let i = 0; i < interpolations.length; i++) {
const interpolation = interpolations[i];
if (typeof interpolation === 'string') {
currentLiteral += interpolation + literals[i + 1];
} else {
newRawLiterals.push(currentLiteral);
newLiterals.push(currentLiteral);
newInterpolations.push(interpolation);
currentLiteral = literals[i + 1];
}
}
newRawLiterals.push(currentLiteral);
newLiterals.push(currentLiteral);

literals = newLiterals;
interpolations = newInterpolations;
}

return stripTopLevelExpressionParentheses(
template.expression(TEMPLATE_OPTIONS).ast(literals, ...interpolations) as T,
);
Expand Down
11 changes: 8 additions & 3 deletions packages/ast/src/scope.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { NodePath, getModuleRoot } from './parse';
import { generateUniqueScopeBinding, getAccessorExpressionPaths } from './scope';
import { AccessorKey, AccessorReference, type AccessorPath, type Types } from './types';
import { match, unreachable } from '@ag-grid-devtools/utils';
import { OptionalMemberExpression } from '@babel/types';

type Class = Types.Class;
type ClassBody = Types.ClassBody;
Expand Down Expand Up @@ -371,15 +372,19 @@ function formatPropertyAccessorClassName(target: NodePath<Class | ObjectExpressi
return target.isClass() && target.node.id ? target.node.id.name : '{}';
}

function formatPropertyAccessorFieldName(accessor: NodePath<Property | MemberExpression>): string {
function formatPropertyAccessorFieldName(
accessor: NodePath<Property | MemberExpression | OptionalMemberExpression>,
): string {
if (accessor.isProperty()) {
const key = accessor.get('key');
const computed = isPublicProperty(accessor) ? accessor.node.computed : false;
return formatPropertyAccessorKey(key, computed);
}
if (accessor.isMemberExpression()) {
const key = accessor.get('property');
return formatPropertyAccessorKey(key, accessor.node.computed);
return formatPropertyAccessorKey(accessor.get('property'), accessor.node.computed);
}
if (accessor.isOptionalMemberExpression()) {
return formatPropertyAccessorKey(accessor.get('property'), accessor.node.computed);
}
return '[]';
}
Expand Down
24 changes: 13 additions & 11 deletions packages/ast/src/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Literal = Types.Literal;
type Method = Types.Method;
type LVal = Types.LVal;
type MemberExpression = Types.MemberExpression;
type OptionalMemberExpression = Types.OptionalMemberExpression;
type ObjectExpression = Types.ObjectExpression;
type ObjectPattern = Types.ObjectPattern;
type PrivateName = Types.PrivateName;
Expand All @@ -45,6 +46,7 @@ export function getAccessorExpressionPaths(
): Array<AccessorPath> | null {
if (expression.isIdentifier()) return getIdentifierAccessorPaths(expression);
if (expression.isMemberExpression()) return getMemberExpressionAccessorPaths(expression);
if (expression.isOptionalMemberExpression()) return getMemberExpressionAccessorPaths(expression);
if (expression.isAssignmentExpression()) {
return getAccessorExpressionPaths(expression.get('right'));
}
Expand All @@ -54,7 +56,7 @@ export function getAccessorExpressionPaths(
}

function getMemberExpressionAccessorPaths(
expression: NodePath<MemberExpression>,
expression: NodePath<MemberExpression | OptionalMemberExpression>,
): Array<AccessorPath> | null {
const object = expression.get('object');
const property = expression.get('property');
Expand All @@ -76,7 +78,7 @@ function getMemberExpressionAccessorPaths(

function getClassMemberExpressionAccessorPaths(
classDefinition: NodePath<Class | ObjectExpression>,
accessor: NodePath<MemberExpression>,
accessor: NodePath<MemberExpression | OptionalMemberExpression>,
): Array<AccessorPath> | null {
const property = accessor.get('property');
const computed = accessor.node.computed;
Expand All @@ -99,7 +101,7 @@ function getClassMemberExpressionAccessorPaths(
.filter(nonNull);
const reassignments = accessors
.map((accessor) => {
if (accessor.isMemberExpression()) {
if (accessor.isMemberExpression() || accessor.isOptionalMemberExpression()) {
// FIXME: support nested member expression assignments (e.g. this.foo.bar.baz = qux)
if (
accessor.parentPath.isAssignmentExpression() &&
Expand Down Expand Up @@ -140,9 +142,9 @@ function getClassMemberExpressionAccessorPaths(

export function findClassMemberAccessorExpressions(
classDefinition: NodePath<Class | ObjectExpression>,
property: NodePath<MemberExpression['property']>,
property: NodePath<MemberExpression['property']> | NodePath<OptionalMemberExpression['property']>,
computed: boolean,
): Array<NodePath<Property | MemberExpression>> | null {
): Array<NodePath<Property | MemberExpression | OptionalMemberExpression>> | null {
if (!computed && property.isIdentifier()) {
return findNamedClassMemberAccessorExpressions(classDefinition, property.node.name);
}
Expand All @@ -158,10 +160,10 @@ export function findClassMemberAccessorExpressions(
export function findNamedClassMemberAccessorExpressions(
classDefinition: NodePath<Class | ObjectExpression>,
fieldName: string,
): Array<NodePath<Property | MemberExpression>> {
): Array<NodePath<Property | MemberExpression | OptionalMemberExpression>> {
return findClassMemberAccessors(classDefinition, null, (path) => {
if (path.isProperty()) return matchNamedClassMemberPropertyExpression(fieldName, path);
if (path.isMemberExpression()) {
if (path.isMemberExpression() || path.isOptionalMemberExpression()) {
const property = path.get('property');
const computed = path.node.computed;
return matchNamedPropertyKeyExpression(fieldName, property, computed);
Expand All @@ -181,7 +183,7 @@ function matchNamedClassMemberPropertyExpression(
function findPrivateClassMemberAccessorExpressions(
classDefinition: NodePath<Class | ObjectExpression>,
fieldName: NodePath<PrivateName>,
): Array<NodePath<Property | MemberExpression>> {
): Array<NodePath<Property | MemberExpression | OptionalMemberExpression>> {
return findClassMemberAccessors(classDefinition, null, (path) => {
if (path.isProperty()) return matchPrivateClassMemberPropertyExpression(fieldName, path);
if (path.isMemberExpression()) {
Expand All @@ -205,12 +207,12 @@ function matchPrivateClassMemberPropertyExpression(
function findLiteralClassMemberAccessorExpressions(
classDefinition: NodePath<Class | ObjectExpression>,
fieldName: NodePath<Literal>,
): Array<NodePath<Property | MemberExpression>> | null {
): Array<NodePath<Property | MemberExpression | OptionalMemberExpression>> | null {
const propertyKey = getLiteralPropertyKey(fieldName.node);
if (typeof propertyKey !== 'string') return null;
return findClassMemberAccessors(classDefinition, null, (path) => {
if (path.isProperty()) return matchComputedClassMemberPropertyExpression(propertyKey, path);
if (path.isMemberExpression()) {
if (path.isMemberExpression() || path.isOptionalMemberExpression()) {
const property = path.get('property');
const computed = path.node.computed;
return getStaticPropertyKey(property.node, computed) === propertyKey;
Expand Down Expand Up @@ -435,7 +437,7 @@ function getDestructuredPropertyPath(
if (propertyPath.isIdentifier()) {
return propertyPath.node.name === id.name ? parentPattern.path : null;
}
if (propertyPath.isMemberExpression()) {
if (propertyPath.isMemberExpression() || propertyPath.isOptionalMemberExpression()) {
// FIXME: Support extended destructuring syntax
return null;
}
Expand Down
3 changes: 2 additions & 1 deletion packages/ast/src/types/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type Class = Types.Class;
type Expression = Types.Expression;
type Identifier = Types.Identifier;
type MemberExpression = Types.MemberExpression;
type OptionalMemberExpression = Types.OptionalMemberExpression;
type ObjectExpression = Types.ObjectExpression;
type Property = Types.Property;

Expand Down Expand Up @@ -129,7 +130,7 @@ export type AccessorReference = Enum<{
};
Property: {
target: NodePath<Class | ObjectExpression>;
accessor: NodePath<Property | MemberExpression>;
accessor: NodePath<Property | MemberExpression | OptionalMemberExpression>;
};
}>;

Expand Down
10 changes: 5 additions & 5 deletions packages/build-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
"eslint-plugin-vitest": "0.4.1",
"prettier": "3.3.2",
"rollup-plugin-preserve-shebang": "1.0.1",
"typescript": "5.5.2",
"vite": "^5.3.2",
"vite-plugin-dts": "3.7.0",
"vite-plugin-node-polyfills": "0.19.0",
"vite-plugin-static-copy": "1.0.0",
"typescript": "5.5.3",
"vite": "^5.3.3",
"vite-plugin-dts": "3.9.1",
"vite-plugin-node-polyfills": "0.22.0",
"vite-plugin-static-copy": "1.0.6",
"vitest": "1.6.0"
}
}
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@ag-grid-devtools/cli",
"version": "32.0.0",
"version": "32.0.1",
"license": "MIT",
"description": "AG Grid developer toolkit",
"author": "AG Grid <[email protected]>",
Expand Down
54 changes: 36 additions & 18 deletions packages/codemod-utils/src/agGridHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import { VueComponentCliContext } from './transform';

type AssignmentExpression = Types.AssignmentExpression;
type CallExpression = Types.CallExpression;
type OptionalCallExpression = Types.OptionalCallExpression;
type Class = Types.Class;
type ClassMethod = Types.ClassMethod;
type Expression = Types.Expression;
Expand All @@ -69,6 +70,7 @@ type JSXExpressionContainer = Types.JSXExpressionContainer;
type JSXIdentifier = Types.JSXIdentifier;
type JSXSpreadAttribute = Types.JSXSpreadAttribute;
type MemberExpression = Types.MemberExpression;
type OptionalMemberExpression = Types.OptionalMemberExpression;
type ObjectExpression = Types.ObjectExpression;
type ObjectMethod = Types.ObjectMethod;
type ObjectProperty = Types.ObjectProperty;
Expand Down Expand Up @@ -186,9 +188,13 @@ export type VueGridApiDefinition = EnumVariant<GridApiDefinition, 'Vue'>;

export type PropertyInitializerNode = ObjectProperty | ObjectMethod;
export type PropertyAssignmentNode = AssignmentExpression & {
left: MemberExpression;
left: MemberExpression | OptionalMemberExpression;
};
export type PropertyAccessorNode = Identifier | MemberExpression | ObjectProperty;
export type PropertyAccessorNode =
| Identifier
| MemberExpression
| OptionalMemberExpression
| ObjectProperty;

export function isPropertyInitializerNode(
value: NodePath<AstNode>,
Expand All @@ -202,7 +208,9 @@ export function isPropertyInitializerNode(
export function isPropertyAssignmentNode(
value: NodePath<AstNode>,
): value is NodePath<PropertyAssignmentNode> {
return value.isAssignmentExpression() && value.get('left').isMemberExpression();
if (!value.isAssignmentExpression()) return false;
const left = value.get('left');
return left.isMemberExpression() || left.isOptionalMemberExpression();
}

export function isPropertyAccessorNode(
Expand All @@ -211,6 +219,7 @@ export function isPropertyAccessorNode(
return (
value.isIdentifier() ||
value.isMemberExpression() ||
value.isOptionalMemberExpression() ||
(value.isObjectProperty() && value.parentPath.isObjectPattern())
);
}
Expand Down Expand Up @@ -247,17 +256,20 @@ export function visitObjectExpression<
export function visitGridOptionsProperties<
S extends AstTransformContext<AstCliContext & VueComponentCliContext>,
>(visitor: ObjectPropertyVisitor<S>): AstNodeVisitor<S> {
function CallExpression(path: NodePath, context: S) {
const gridInitializer = matchJsGridApiInitializer(path);
if (!gridInitializer) return;
const { options } = gridInitializer;
if (!options) return;
const accessors = getAccessorExpressionPaths(options);
if (!accessors) return;
accessors.forEach((accessor) => visitObjectAccessor(accessor, visitor, context));
}

return {
// Traverse plain JS grid API instances
CallExpression(path, context) {
const gridInitializer = matchJsGridApiInitializer(path);
if (!gridInitializer) return;
const { options } = gridInitializer;
if (!options) return;
const accessors = getAccessorExpressionPaths(options);
if (!accessors) return;
accessors.forEach((accessor) => visitObjectAccessor(accessor, visitor, context));
},
CallExpression,
OptionalCallExpression: CallExpression,
// Traverse React grid elements
JSXElement(path, context) {
if (!isAgGridJsxElement(path)) return;
Expand Down Expand Up @@ -409,10 +421,13 @@ function visitObjectAccessor<S>(
});
references.forEach((reference) => {
// Determine whether the reference is accessing a field on the object
if (reference.accessor.parentPath.isMemberExpression()) {
if (
reference.accessor.parentPath.isMemberExpression() ||
reference.accessor.parentPath.isOptionalMemberExpression()
) {
const propertyAccessor = reference.accessor.parentPath;
const object = propertyAccessor.get('object');
if (reference.accessor.node !== object.node) return;
if (Array.isArray(object) || reference.accessor.node !== object.node) return;
// Determine whether the reference is setting the object field
if (isPropertyAssignmentNode(propertyAccessor.parentPath)) {
// FIXME: add tests for (optionally nested) renamed property assignments
Expand Down Expand Up @@ -646,8 +661,9 @@ export function getJsGridApiReferences(
}

function matchJsGridApiInitializer(path: NodePath<AstNode>): JsGridApiDefinition | null {
if (!path.isCallExpression()) return null;
const callee = path.get('callee');
if (!path.isCallExpression() && !path.isOptionalCallExpression()) return null;
const typedPath = path as NodePath<CallExpression | OptionalCallExpression>;
const callee = typedPath.get('callee');
if (!callee.isExpression()) return null;
const gridApiImport = getNamedModuleImportExpression(
callee,
Expand All @@ -656,12 +672,14 @@ function matchJsGridApiInitializer(path: NodePath<AstNode>): JsGridApiDefinition
AG_GRID_JS_CONSTRUCTOR_EXPORT_NAME,
);
if (!gridApiImport) return null;
const { element, options } = parseJsGridApiInitializerArguments(path.get('arguments'));
const { element, options } = parseJsGridApiInitializerArguments(typedPath.get('arguments'));
return GridApiDefinition.Js({ initializer: path, element, options });
}

function parseJsGridApiInitializerArguments(
args: Array<NodePath<CallExpression['arguments'][number]>>,
args: Array<
NodePath<CallExpression['arguments'][number] | OptionalCallExpression['arguments'][number]>
>,
): {
element: NodePath<Expression> | null;
options: NodePath<Expression> | null;
Expand Down
Loading

0 comments on commit 0e13da0

Please sign in to comment.