Skip to content

Commit

Permalink
Add extractComments option that uses leading comments message descrip…
Browse files Browse the repository at this point in the history
…tions
  • Loading branch information
ephys committed Oct 27, 2017
1 parent 1c79470 commit e1441ad
Show file tree
Hide file tree
Showing 4 changed files with 249 additions and 16 deletions.
162 changes: 162 additions & 0 deletions src/__tests__/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,73 @@ m({
"
`;

exports[`default - leading comment 1`] = `
"
import { defineMessages } from 'react-intl'
export default defineMessages({
// The main Hello of our app.
hello: 'hello',
// Another Hello,
// multiline this time
world: {
id: 'hello.world',
defaultMessage: 'hello world',
}
})
↓ ↓ ↓ ↓ ↓ ↓
import { defineMessages } from 'react-intl';
export default defineMessages({
// The main Hello of our app.
hello: {
'id': 'src.__fixtures__.hello',
'defaultMessage': 'hello'
},
// Another Hello,
// multiline this time
world: {
id: 'hello.world',
defaultMessage: 'hello world'
}
});
"
`;

exports[`default - leading comment with description 1`] = `
"
import { defineMessages } from 'react-intl'
export default defineMessages({
// This comment should not be used
world: {
defaultMessage: 'hello world',
description: 'The hello world',
}
})
↓ ↓ ↓ ↓ ↓ ↓
import { defineMessages } from 'react-intl';
export default defineMessages({
// This comment should not be used
world: {
'id': 'src.__fixtures__.world',
defaultMessage: 'hello world',
description: 'The hello world'
}
});
"
`;

exports[`default - multi export 1`] = `
"
import { defineMessages } from 'react-intl'
Expand Down Expand Up @@ -287,6 +354,101 @@ hello({
"
`;
exports[`extractComments = true - default 1`] = `
"
import { defineMessages } from 'react-intl'
export default defineMessages({
hello: 'hello',
world: 'hello world',
})
↓ ↓ ↓ ↓ ↓ ↓
import { defineMessages } from 'react-intl';
export default defineMessages({
hello: {
'id': 'src.__fixtures__.hello',
'defaultMessage': 'hello'
},
world: {
'id': 'src.__fixtures__.world',
'defaultMessage': 'hello world'
}
});
"
`;
exports[`extractComments = true - leading comment 1`] = `
"
import { defineMessages } from 'react-intl'
export default defineMessages({
// The main Hello of our app.
hello: 'hello',
// Another Hello,
// multiline this time
world: {
id: 'hello.world',
defaultMessage: 'hello world',
}
})
↓ ↓ ↓ ↓ ↓ ↓
import { defineMessages } from 'react-intl';
export default defineMessages({
// The main Hello of our app.
hello: {
'id': 'src.__fixtures__.hello',
'defaultMessage': 'hello',
'description': 'The main Hello of our app.'
},
// Another Hello,
// multiline this time
world: {
id: 'hello.world',
defaultMessage: 'hello world',
'description': 'Another Hello,\\\\nmultiline this time'
}
});
"
`;
exports[`extractComments = true - leading comment with description 1`] = `
"
import { defineMessages } from 'react-intl'
export default defineMessages({
// This comment should not be used
world: {
defaultMessage: 'hello world',
description: 'The hello world',
}
})
↓ ↓ ↓ ↓ ↓ ↓
import { defineMessages } from 'react-intl';
export default defineMessages({
// This comment should not be used
world: {
'id': 'src.__fixtures__.world',
defaultMessage: 'hello world',
description: 'The hello world'
}
});
"
`;
exports[`filebase = true - default 1`] = `
"
import { defineMessages } from 'react-intl'
Expand Down
43 changes: 43 additions & 0 deletions src/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,41 @@ export default defineMessages({
`,
}

const leadingCommentTest = {
title: 'leading comment',
code: `
import { defineMessages } from 'react-intl'
export default defineMessages({
// The main Hello of our app.
hello: 'hello',
// Another Hello,
// multiline this time
world: {
id: 'hello.world',
defaultMessage: 'hello world',
}
})
`,
}

const leadingCommentWithDescriptionTest = {
title: 'leading comment with description',
code: `
import { defineMessages } from 'react-intl'
export default defineMessages({
// This comment should not be used
world: {
defaultMessage: 'hello world',
description: 'The hello world',
}
})
`,
}

const tests = [
defaultTest,
{
Expand Down Expand Up @@ -159,6 +194,8 @@ import { defineMessages } from 'react-intl'
export default defineMessages(messages)
`,
},
leadingCommentTest,
leadingCommentWithDescriptionTest,
]

type PTestOpts = {
Expand Down Expand Up @@ -229,3 +266,9 @@ pTest({
tests: [defaultTest, multiExportTest],
pluginOptions: { removePrefix: true, includeExportName: 'all' },
})

pTest({
title: 'extractComments = true',
tests: [defaultTest, leadingCommentTest, leadingCommentWithDescriptionTest],
pluginOptions: { extractComments: true },
})
59 changes: 43 additions & 16 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,46 +85,73 @@ const isValidate = (path: Object, state: State): boolean => {
return true
}

const getLeadingComment = prop => {
const commentNodes = prop.node.leadingComments
return commentNodes
? commentNodes.map(node => node.value.trim()).join('\n')
: null
}

const replaceProperties = (
properties: $ReadOnlyArray<Object>,
state,
state: State,
exportName: string | null
) => {
const prefix = getPrefix(state, exportName)

for (const prop of properties) {
const propValue = prop.get('value')

const messageDescriptorProperties = []

// { defaultMessage: 'hello', description: 'this is hello' }
if (propValue.isObjectExpression()) {
const objProps = propValue.get('properties')

// { id: 'already has id', defaultMessage: 'hello' }
const isNotHaveId = objProps.every(v => v.get('key').node.name !== 'id')
if (!isNotHaveId) {
continue // eslint-disable-line
}
if (isNotHaveId) {
const id = getId(prop.get('key'), prefix)

const id = getId(prop.get('key'), prefix)
messageDescriptorProperties.push(
t.objectProperty(t.stringLiteral('id'), t.stringLiteral(id))
)
}

propValue.replaceWith(
t.objectExpression([
t.objectProperty(t.stringLiteral('id'), t.stringLiteral(id)),
...objProps.map(v => v.node),
])
)
messageDescriptorProperties.push(...objProps.map(v => v.node))

// 'hello' or `hello ${user}`
} else if (isLiteral(propValue)) {
const id = getId(prop.get('key'), prefix)

propValue.replaceWith(
t.objectExpression([
t.objectProperty(t.stringLiteral('id'), t.stringLiteral(id)),
t.objectProperty(t.stringLiteral('defaultMessage'), propValue.node),
])
messageDescriptorProperties.push(
t.objectProperty(t.stringLiteral('id'), t.stringLiteral(id)),
t.objectProperty(t.stringLiteral('defaultMessage'), propValue.node)
)
}

if (state.opts.extractComments) {
const hasDescription = messageDescriptorProperties.find((v: Object) => {
return v.key.name === 'description'
})

if (!hasDescription) {
const description = getLeadingComment(prop)

if (description) {
messageDescriptorProperties.push(
t.objectProperty(
t.stringLiteral('description'),
t.stringLiteral(description)
)
)
}
}
}

if (messageDescriptorProperties.length > 0) {
propValue.replaceWith(t.objectExpression(messageDescriptorProperties))
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ export type State = {
removePrefix?: string,
filebase?: boolean,
includeExportName?: boolean | 'all',
extractComments?: boolean,
},
}

0 comments on commit e1441ad

Please sign in to comment.