Skip to content

Commit

Permalink
Added support for parsing messages with advanced structures inside `t…
Browse files Browse the repository at this point in the history
…()` calls.
  • Loading branch information
ma2ciek committed Apr 28, 2020
1 parent 74f542e commit d0a3bea
Showing 1 changed file with 81 additions and 44 deletions.
125 changes: 81 additions & 44 deletions packages/ckeditor5-dev-utils/lib/translations/findmessages.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,68 +26,105 @@ module.exports = function findMessages( source, sourceFile, onMessageFound, onEr

walk.simple( ast, {
CallExpression: node => {
// Log a warning for the `editor.t()` calls and similar which aren't supported yet.
if ( isTMethodCallExpression( node ) ) {
const objName = node.callee.object.name;
const propName = node.callee.property.name;

onErrorFound(
// TODO - ${ objName }.${ propName } is naive.
`Found '${ objName }.${ propName }()' in the ${ sourceFile }. ` +
'Only messages from direct \'t()\' calls will be handled by CKEditor 5 translation mechanisms.'
);
try {
findMessagesInNode( node );
} catch ( err ) {
onErrorFound( 'CKEditor5 Translation tool found problem. \n' + err.stack );
}
}
} );

if ( !isTFunctionCallExpression( node ) ) {
return;
}
function findMessagesInNode( node ) {
// Log a warning for the `editor.t()` calls and similar which aren't supported yet.
if ( isTMethodCallExpression( node ) ) {
const objName = node.callee.object.name;
const propName = node.callee.property.name;

const firstArgument = node.arguments[ 0 ];
onErrorFound(
// TODO - ${ objName }.${ propName } is naive.
`Found '${ objName }.${ propName }()' in the ${ sourceFile }. ` +
'Only messages from direct \'t()\' calls will be handled by CKEditor 5 translation mechanisms.'
);
}

if ( firstArgument.type === 'ObjectExpression' ) {
const properties = firstArgument.properties || [];
if ( !isTFunctionCallExpression( node ) ) {
return;
}

const idProperty = properties.find( p => p.key.type === 'Identifier' && p.key.name === 'id' );
const stringProperty = properties.find( p => p.key.type === 'Identifier' && p.key.name === 'string' );
const pluralProperty = properties.find( p => p.key.type === 'Identifier' && p.key.name === 'plural' );
const firstArgument = node.arguments[ 0 ];

// TODO - value assertions.
findMessageInArgument( firstArgument );
}

/** @type {Message} */
const message = {
string: stringProperty.value.value,
id: stringProperty.value.value
};
function findMessageInArgument( node ) {
// Matches t( { string: 'foo' } ) and t( { 'string': 'foo' } ).
// (also `plural` and `id` properties)
if ( node.type === 'ObjectExpression' ) {
const properties = node.properties || [];

if ( idProperty ) {
message.id = idProperty.value.value;
}
const idProperty = getProperty( properties, 'id' );
const stringProperty = getProperty( properties, 'string' );
const pluralProperty = getProperty( properties, 'plural' );

if ( pluralProperty ) {
message.plural = pluralProperty.value.value;
}
// TODO - value assertions.

onMessageFound( message );
/** @type {Message} */
const message = {
string: stringProperty.value.value,
id: stringProperty.value.value
};

return;
if ( idProperty ) {
message.id = idProperty.value.value;
}

if ( firstArgument.type === 'Literal' ) {
onMessageFound( {
string: firstArgument.value,
id: firstArgument.value
} );

return;
if ( pluralProperty ) {
message.plural = pluralProperty.value.value;
}

onErrorFound(
`First t() call argument should be a string literal or an object literal (${ sourceFile }).`
);
onMessageFound( message );

return;
}
} );

// Matches t( 'foo' )
if ( node.type === 'Literal' ) {
onMessageFound( {
string: node.value,
id: node.value
} );

return;
}

// Matches t( foo ? 'bar' : { string: 'baz', plural: 'biz' } );
if ( node.type === 'ConditionalExpression' ) {
findMessageInArgument( node.consequent );
findMessageInArgument( node.alternate );

return;
}

onErrorFound(
`First t() call argument should be a string literal or an object literal (${ sourceFile }).`
);
}
};

// Get property from the list of properties
// It supports both forms: `{ propertyName: foo }` and `{ 'propertyName': 'foo' }`
function getProperty( properties, propertyName ) {
return properties.find( property => {
if ( property.key.type === 'Identifier' ) {
return property.key.name === propertyName;
}

if ( property.key.type === 'Literal' ) {
return property.key.value === propertyName;
}
} );
}

function isTFunctionCallExpression( node ) {
return node.callee.name === 't';
}
Expand Down

0 comments on commit d0a3bea

Please sign in to comment.