Skip to content

Commit 0e4910e

Browse files
committed
refactor: use the same logic for inserting refactorings
1 parent c989fdc commit 0e4910e

File tree

8 files changed

+148
-211
lines changed

8 files changed

+148
-211
lines changed

backend/src/api/serve/refactorings.ts

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,20 @@
11
import { Request, Response } from 'express'
2-
import { commitPlaceholder, RefactoringMeta, RefactoringType } from '../../../../common/common.js'
3-
import { commitUrl } from '../../utils.js'
4-
import { commitsCol, refCol, repoCol } from '../../mongo.js'
5-
import { mergeCommitMetadataIntoRefactorings, updateCommitRefactoringMetadata } from '../../jobs/metadata.js'
2+
import { PureRefactoringMeta } from '../../../../common/common.js'
3+
import { commitsCol, repoCol } from '../../mongo.js'
4+
import { transformAndInsertRefactorings } from '../../jobs/process.js'
65

76
interface PostRequest extends Request {
87
body: {
98
repository: string
109
commit: string
1110

12-
refactorings: {
13-
type: string
14-
description: string
15-
16-
meta: {
17-
tool?: string
18-
}
19-
}[]
11+
refactorings: PureRefactoringMeta[]
2012
}
2113
}
2214

2315
export const postRefactoringsHandler = async (req: PostRequest, res: Response) => {
2416
const body = req.body
2517

26-
const refactorings = body.refactorings.map((r): RefactoringMeta => {
27-
return {
28-
...r,
29-
type: r.type as RefactoringType, // ignore type-check
30-
31-
sha1: body.commit,
32-
repository: body.repository,
33-
url: commitUrl(body.repository, body.commit),
34-
35-
commit: commitPlaceholder(),
36-
}
37-
})
38-
3918
{
4019
// Check repository and commits existence
4120
const actualCommit = await commitsCol.findOne({ _id: body.commit })
@@ -54,16 +33,7 @@ export const postRefactoringsHandler = async (req: PostRequest, res: Response) =
5433
}
5534

5635
// Insert
57-
const insertRes = await refCol.insertMany(refactorings)
58-
if (!insertRes.acknowledged) {
59-
return res.status(500).json({
60-
message: 'Internal error',
61-
})
62-
}
63-
64-
// Update metadata
65-
await updateCommitRefactoringMetadata(body.commit)
66-
await mergeCommitMetadataIntoRefactorings(body.commit)
36+
const insertRes = await transformAndInsertRefactorings(body.repository, body.commit, body.refactorings)
6737

6838
return res.status(200).json({
6939
message: `Inserted ${insertRes.insertedCount} document(s)`,

backend/src/jobs/process.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { JobWithId } from '../jobs.js'
2-
import { commitsCol } from '../mongo.js'
3-
import { readAllFromCursor } from '../utils.js'
2+
import { commitsCol, refCol } from '../mongo.js'
3+
import { commitUrl, readAllFromCursor } from '../utils.js'
44
import { processRMiner, rminerToolName } from './runner/rminer.js'
55
import { processRefDiff, refDiffToolName } from './runner/refdiff.js'
66
import {
@@ -9,12 +9,12 @@ import {
99
updateCommitToolsMetadata,
1010
} from './metadata.js'
1111
import { formatTime } from '../../../common/utils.js'
12-
import { CommitProcessState } from '../../../common/common.js'
13-
import { JobData } from '../../../common/jobs'
12+
import { commitPlaceholder, CommitProcessState, PureRefactoringMeta, RefactoringMeta } from '../../../common/common.js'
13+
import { JobData } from '../../../common/jobs.js'
1414

1515
type CommitId = string
1616
type ToolName = string
17-
type Processor = (repoUrl: string, commit: string) => Promise<void>
17+
type Processor = (repoUrl: string, commit: string) => Promise<PureRefactoringMeta[]>
1818
const processors: Record<ToolName, Processor> = {
1919
[rminerToolName]: processRMiner,
2020
[refDiffToolName]: processRefDiff,
@@ -23,13 +23,14 @@ const processors: Record<ToolName, Processor> = {
2323
const processCommit = async (repoUrl: string, commitId: CommitId, tools: Record<string, CommitProcessState>, retryError: boolean) => {
2424
const newTools = Object.assign({}, tools)
2525

26+
let pureRefs: PureRefactoringMeta[] = []
2627
for (const [tool, process] of Object.entries(processors)) {
2728
const toProcess = !(tool in tools) || retryError && tools[tool] === CommitProcessState.NG
2829
if (!toProcess) continue
2930

3031
try {
3132
const start = performance.now()
32-
await process(repoUrl, commitId)
33+
pureRefs.push(...(await process(repoUrl, commitId)))
3334
newTools[tool] = CommitProcessState.OK
3435
console.log(` -> ${tool} in ${formatTime(start)}`)
3536
} catch (e) {
@@ -39,9 +40,31 @@ const processCommit = async (repoUrl: string, commitId: CommitId, tools: Record<
3940
}
4041
}
4142

42-
await updateCommitRefactoringMetadata(commitId)
4343
await updateCommitToolsMetadata(commitId, newTools)
44-
await mergeCommitMetadataIntoRefactorings(commitId)
44+
await transformAndInsertRefactorings(repoUrl, commitId, pureRefs)
45+
}
46+
47+
export const transformAndInsertRefactorings = async (repoUrl: string, commit: string, pureRefs: PureRefactoringMeta[]): Promise<{ insertedCount: number }> => {
48+
const refactorings = pureRefs.map((r): RefactoringMeta => {
49+
return {
50+
...r,
51+
sha1: commit,
52+
repository: repoUrl,
53+
url: commitUrl(repoUrl, commit),
54+
commit: commitPlaceholder(),
55+
}
56+
})
57+
58+
let insertedCount = 0
59+
if (refactorings.length > 0) { // Running insertMany with empty array results in an error
60+
const insertRes = await refCol.insertMany(refactorings)
61+
insertedCount = insertRes.insertedCount
62+
}
63+
64+
await updateCommitRefactoringMetadata(commit)
65+
await mergeCommitMetadataIntoRefactorings(commit)
66+
67+
return { insertedCount }
4568
}
4669

4770
export const processCommits = async (job: JobWithId, jobData: JobData) => {

backend/src/jobs/processor/refdiff.ts

Lines changed: 61 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
import equal from 'fast-deep-equal'
22
import {
33
ProcessedRefDiffRefactoring,
4-
RefDiffCommit,
54
RefDiffLocation,
65
RefDiffLocationWithLines,
76
RefDiffNode,
87
RefDiffNodeWithLines,
9-
RefDiffOutput,
108
RefDiffRefactoring,
119
} from '../../../../common/refdiff.js'
12-
import { commitPlaceholder, RefactoringMeta, RefactoringType, RefactoringTypes } from '../../../../common/common.js'
13-
import { commitUrl } from '../../utils.js'
10+
import {
11+
PureRefactoringMeta,
12+
RefactoringType,
13+
RefactoringTypes,
14+
} from '../../../../common/common.js'
1415
import { refDiffToolName } from '../runner/refdiff.js'
1516

16-
type R = RefactoringMeta & ProcessedRefDiffRefactoring
17+
type R = PureRefactoringMeta & ProcessedRefDiffRefactoring
1718

1819
const formatTypeAndDescription = (ref: RefDiffRefactoring): [typ: RefactoringType, desc: string] => {
1920
switch (ref.type) {
@@ -62,8 +63,8 @@ const formatTypeAndDescription = (ref: RefDiffRefactoring): [typ: RefactoringTyp
6263
}
6364
}
6465

65-
const extractedMethods = (c: RefDiffCommit): RefDiffRefactoring[] => {
66-
return c.refactorings
66+
const extractedMethods = (refs: RefDiffRefactoring[]): RefDiffRefactoring[] => {
67+
return refs
6768
.filter((r) => r.type === 'EXTRACT' && r.after.type === 'Method')
6869
}
6970

@@ -83,75 +84,68 @@ const process = (ref: RefDiffRefactoring): ProcessedRefDiffRefactoring => ({
8384
after: processNode(ref.after),
8485
})
8586

86-
export const processRefDiffOutput = (repoUrl: string, output: RefDiffOutput): R[] => {
87-
return output.map((c): RefDiffCommit => {
88-
c.refactorings = c.refactorings.flatMap((ref): RefDiffRefactoring[] => {
89-
switch (ref.type) {
90-
case 'INTERNAL_MOVE_RENAME':
91-
return [
92-
{ ...ref, type: 'INTERNAL_MOVE' },
93-
{ ...ref, type: 'RENAME' },
94-
ref,
95-
]
96-
case 'MOVE_RENAME':
97-
return [
98-
{ ...ref, type: 'MOVE' },
99-
{ ...ref, type: 'RENAME' },
100-
ref,
101-
]
102-
case 'EXTRACT_MOVE':
103-
return [
104-
{ ...ref, type: 'EXTRACT' },
105-
{ ...ref, type: 'MOVE' },
106-
ref,
107-
]
108-
default:
109-
return [ref]
110-
}
111-
})
112-
return c
113-
}).flatMap((c): R[] => {
114-
const extractMethodRefactorings = extractedMethods(c)
87+
export const processRefDiffOutput = (refs: RefDiffRefactoring[]): R[] => {
88+
// Expand some composite refactorings
89+
const refactorings = refs.flatMap((ref): RefDiffRefactoring[] => {
90+
switch (ref.type) {
91+
case 'INTERNAL_MOVE_RENAME':
92+
return [
93+
{ ...ref, type: 'INTERNAL_MOVE' },
94+
{ ...ref, type: 'RENAME' },
95+
ref,
96+
]
97+
case 'MOVE_RENAME':
98+
return [
99+
{ ...ref, type: 'MOVE' },
100+
{ ...ref, type: 'RENAME' },
101+
ref,
102+
]
103+
case 'EXTRACT_MOVE':
104+
return [
105+
{ ...ref, type: 'EXTRACT' },
106+
{ ...ref, type: 'MOVE' },
107+
ref,
108+
]
109+
default:
110+
return [ref]
111+
}
112+
})
115113

116-
return c.refactorings.map((ref): R => {
117-
const [typ, description] = formatTypeAndDescription(ref)
114+
const extractMethodRefactorings = extractedMethods(refs)
118115

119-
const ret: R = {
120-
type: typ,
121-
description,
116+
return refactorings.map((ref): R => {
117+
const [typ, description] = formatTypeAndDescription(ref)
122118

123-
sha1: c.sha1,
124-
repository: repoUrl,
125-
url: commitUrl(repoUrl, c.sha1),
119+
const ret: R = {
120+
type: typ,
121+
description,
126122

127-
meta: {
128-
tool: refDiffToolName,
129-
},
130-
commit: commitPlaceholder(),
123+
meta: {
124+
tool: refDiffToolName,
125+
},
131126

132-
...process(ref),
133-
}
127+
...process(ref),
128+
}
134129

135-
// Pre-compute needed information
136-
if (typ === RefactoringTypes.ExtractMethod) {
137-
ret.extractMethod = {
138-
// Use-case 1: 重複の処理が無い / あるextract
139-
sourceMethodsCount: extractSourceMethodsCount(ref, extractMethodRefactorings),
140-
// Use-case 2: 数行のみのextract, extractする前の行数
141-
sourceMethodLines: ret.before.location.lines,
142-
extractedLines: ret.after.location.lines,
143-
}
130+
// Pre-compute needed information
131+
if (typ === RefactoringTypes.ExtractMethod) {
132+
ret.extractMethod = {
133+
// Use-case 1: 重複の処理が無い / あるextract
134+
sourceMethodsCount: extractSourceMethodsCount(ref, extractMethodRefactorings),
135+
// Use-case 2: 数行のみのextract, extractする前の行数
136+
sourceMethodLines: ret.before.location.lines,
137+
extractedLines: ret.after.location.lines,
144138
}
139+
}
145140

146-
// Use-case 3: 具体的なrenameした単語
147-
if (ref.type === 'RENAME') {
148-
ret.rename = {
149-
from: ref.before.name,
150-
to: ref.after.name,
151-
}
141+
// Use-case 3: 具体的なrenameした単語
142+
if (ref.type === 'RENAME') {
143+
ret.rename = {
144+
from: ref.before.name,
145+
to: ref.after.name,
152146
}
147+
}
153148

154-
return ret
155-
})
149+
return ret
156150
})
157151
}

0 commit comments

Comments
 (0)