-
Notifications
You must be signed in to change notification settings - Fork 0
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] Review according to own guide #2
Conversation
7e5da65
to
41cce0f
Compare
import { splitForEachDIff } from "./diff.js"; | ||
import { chat } from "./openai.js"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import文の型指定がありません。型指定を追加してください。
function add(x, y) { | ||
return x + y; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数addの引数xとyに明示的な型を指定してください。
const buildPrompt = (rule: string) => { | ||
return prompt.replace("{{CODING_GUIDE}}", rule); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数buildPrompt
の引数rule
に型を指定しましょう。
function getUser(id: string): Promise<User> { | ||
return fetch(`/api/users/${id}`) | ||
.then((response) => response.json()) | ||
.then((user) => user) | ||
.catch((error) => { | ||
throw new Error(error); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
非同期操作の取り扱いに関するコーディングガイドに従っていません。Promiseチェーンを使用していますが、async/awaitパターンを使用するように改善してください。
const readRules = () => { | ||
const getRule = (node: MarkdownSectionNode) => { | ||
let rule = `${node.title}\n\n${node.content}`; | ||
if (node.children.length > 0) { | ||
for (const child of node.children) { | ||
rule += getRule(child); | ||
} | ||
} | ||
return rule; | ||
}; | ||
|
||
const markdown = readFileSync("GUIDE.md", "utf-8"); | ||
const parsed = parseMarkdown(markdown); | ||
const rules: string[] = []; | ||
for (const level1 of parsed.children) { | ||
for (const level2 of level1.children) { | ||
const rule = getRule(level2); | ||
if (rule.match(/AI Review.*ON/g)) { | ||
rules.push(getRule(level2)); | ||
} | ||
} | ||
} | ||
return rules; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数readRules
に明示的な型を指定しましょう。
for (const rule of rules) { | ||
promises.push(async () => { | ||
const response = await chat([ | ||
{ | ||
content: buildPrompt(rule), | ||
role: "system", | ||
}, | ||
{ | ||
content: source.diff, | ||
role: "user", | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数の引数と戻り値に明示的な型を指定しましょう。
41cce0f
to
5921eb6
Compare
import { splitForEachDIff } from "./diff.js"; | ||
import { chat } from "./openai.js"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import文の型指定がありません。型指定を追加してください。
Reference: ## 型定義の適用
function add(x, y) { | ||
return x + y; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数addの引数xとyに明示的な型を指定してください。
Reference: ## 型定義の適用
{{CODING_GUIDE}} | ||
|
||
--- | ||
|
||
回答形式は以下です。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
コーディングガイドが記載されていません。コーディングガイドを記載する必要があります。
Reference: ## 非同期操作の取り扱い
以下のdiffに対して以下のコーディングガイドに従っているかをレビューしてください。 | ||
コーディングガイドに従っている場合は "OK" とコメントしてください。 | ||
コーディングガイドに従っていない場合は改善方法をコメントしてください。 | ||
diffの各行の先頭には行番号がついていることに注意してください。 | ||
回答形式は以下です。 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
コーディングガイドに従っていません。コーディングガイドに従っているかどうかを判断するためのコメントが必要です。
Reference: ## 非同期操作の取り扱い
import { chat } from "./openai.js"; | ||
import { promiseAllWithConcurrencyLimit } from "./concurrent.js"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
非同期操作の取り扱いのコーディングガイドに従っていません。async/await
パターンを使用して非同期操作を実装する必要があります。
Reference: ## 非同期操作の取り扱い
function getUser(id: string): Promise<User> { | ||
return fetch(`/api/users/${id}`) | ||
.then((response) => response.json()) | ||
.then((user) => user) | ||
.catch((error) => { | ||
throw new Error(error); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
非同期操作の取り扱いに関するコーディングガイドに従っていません。非同期操作はasync/await
パターンを使用して実装する必要がありますが、80行目から86行目ではPromiseチェーンを使用しています。async/await
パターンに書き換える必要があります。
Reference: ## 非同期操作の取り扱い
const buildPrompt = (rule: string) => { | ||
return prompt.replace("{{CODING_GUIDE}}", rule); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数の引数と戻り値に明示的な型を指定しましょう。
Reference: ## 型定義の適用
for (const rule of rules) { | ||
promises.push(async () => { | ||
const response = await chat([ | ||
{ | ||
content: buildPrompt(rule), | ||
role: "system", | ||
}, | ||
{ | ||
content: source.diff, | ||
role: "user", | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数内の非同期処理をPromise.allで実行するように修正しましょう。
Reference: ## 型定義の適用
const readRules = () => { | ||
const getRule = (node: MarkdownSectionNode) => { | ||
let rule = `${node.title}\n\n${node.content}`; | ||
if (node.children.length > 0) { | ||
for (const child of node.children) { | ||
rule += getRule(child); | ||
} | ||
} | ||
return rule; | ||
}; | ||
|
||
const markdown = readFileSync("GUIDE.md", "utf-8"); | ||
const parsed = parseMarkdown(markdown); | ||
const rules: string[] = []; | ||
for (const level1 of parsed.children) { | ||
for (const level2 of level1.children) { | ||
const rule = getRule(level2); | ||
if (rule.match(/AI Review.*ON/g)) { | ||
rules.push(getRule(level2)); | ||
} | ||
} | ||
} | ||
return rules; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数readRules
に明示的な型を指定しましょう。
Reference: ## 型定義の適用
d606773
to
63a29a3
Compare
import { splitForEachDIff } from "./diff.js"; | ||
import { chat } from "./openai.js"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import
文の順番が間違っています。node:fs
モジュールは先にインポートする必要があります。
Reference: ## 非同期操作の取り扱い
import { splitForEachDIff } from "./diff.js"; | ||
import { chat } from "./openai.js"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import文の型指定がありません。型指定を追加してください。
Reference: ## 型定義の適用
const buildPrompt = (rule: string) => { | ||
return prompt.replace("{{CODING_GUIDE}}", rule); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数の引数と戻り値に明示的な型を指定しましょう。
Reference: ## 型定義の適用
const buildPrompt = (rule: string) => { | ||
return prompt.replace("{{CODING_GUIDE}}", rule); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
buildPrompt
関数の中でprompt.replace
を使用しているが、prompt
の中には{{CODING_GUIDE}}
が含まれていないため、置換が行われない可能性がある。prompt
の中に{{CODING_GUIDE}}
が含まれていることを確認する必要があります。
Reference: ## 非同期操作の取り扱い
import { chat } from "./openai.js"; | ||
import { promiseAllWithConcurrencyLimit } from "./concurrent.js"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
コーディングガイドに従っていません。コーディングガイドでは非同期操作はasync/await
パターンを使用するように指示されていますが、このコードではimport
文が使用されています。import
文は非同期操作ではないため、async/await
パターンを使用する必要があります。
Reference: ## 非同期操作の取り扱い
dae1950
to
d8eadf2
Compare
const buildPrompt = (rule: string) => { | ||
return prompt.replace("{{CODING_GUIDE}}", rule); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数buildPrompt
の引数rule
に型が指定されていません。rule
は文字列として扱われているので、型をstring
として明示してください。
Reference: ## 型定義の適用
const readRules = () => { | ||
const getRule = (node: MarkdownSectionNode) => { | ||
let rule = `${node.title}\n\n${node.content}`; | ||
if (node.children.length > 0) { | ||
for (const child of node.children) { | ||
rule += getRule(child); | ||
} | ||
} | ||
return rule; | ||
}; | ||
|
||
const markdown = readFileSync("GUIDE.md", "utf-8"); | ||
const parsed = parseMarkdown(markdown); | ||
const rules: string[] = []; | ||
for (const level1 of parsed.children) { | ||
for (const level2 of level1.children) { | ||
const rule = getRule(level2); | ||
if (rule.match(/AI Review.*ON/g)) { | ||
rules.push(getRule(level2)); | ||
} | ||
} | ||
} | ||
return rules; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数readRules
の戻り値に型が指定されていません。この関数は文字列の配列を返しているので、戻り値の型をstring[]
として明示してください。
Reference: ## 型定義の適用
d8eadf2
to
35d8596
Compare
const getRule = (node: MarkdownSectionNode) => { | ||
let rule = `${node.title}\n\n${node.content}`; | ||
if (node.children.length > 0) { | ||
for (const child of node.children) { | ||
rule += getRule(child); | ||
} | ||
} | ||
return rule; | ||
}; | ||
|
||
const markdown = readFileSync("GUIDE.md", "utf-8"); | ||
const parsed = parseMarkdown(markdown); | ||
const rules: string[] = []; | ||
for (const level1 of parsed.children) { | ||
for (const level2 of level1.children) { | ||
const rule = getRule(level2); | ||
if (rule.match(/AI Review.*ON/g)) { | ||
rules.push(getRule(level2)); | ||
} | ||
} | ||
} | ||
return rules; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
この部分のコードでは、ファイルの読み込みやMarkdownのパースなど非同期操作が含まれていますが、これらの操作はasync/await
パターンを使用して実装するべきです。現在のコードでは同期的なファイル読み込み関数readFileSync
が使用されていますが、これを非同期のreadFile
に変更し、関数readRules
を非同期関数に変更することを推奨します。
改善後のコードは以下のようになります。
const readRules = async () => {
const getRule = (node: MarkdownSectionNode) => {
let rule = `${node.title}\n\n${node.content}`;
if (node.children.length > 0) {
for (const child of node.children) {
rule += getRule(child);
}
}
return rule;
};
const markdown = await fs.promises.readFile("GUIDE.md", "utf-8");
const parsed = parseMarkdown(markdown);
const rules: string[] = [];
for (const level1 of parsed.children) {
for (const level2 of level1.children) {
const rule = getRule(level2);
if (rule.match(/AI Review.*ON/g)) {
rules.push(getRule(level2));
}
}
}
return rules;
};
ここではfs.promises.readFile
を使用してファイルを非同期に読み込んでいます。また、関数readRules
は非同期関数として定義されているため、この関数を呼び出す際にはawait
を使用する必要があります。
Reference: ## 非同期操作の取り扱い
const buildPrompt = (rule: string) => { | ||
return prompt.replace("{{CODING_GUIDE}}", rule); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数 buildPrompt
の引数 rule
に型が指定されていません。rule
は文字列として扱われているので、型を string
として明示的に指定してください。
Reference: ## 型定義の適用
const getRule = (node: MarkdownSectionNode) => { | ||
let rule = `${node.title}\n\n${node.content}`; | ||
if (node.children.length > 0) { | ||
for (const child of node.children) { | ||
rule += getRule(child); | ||
} | ||
} | ||
return rule; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数 getRule
の引数 node
と戻り値に型が指定されていません。node
の型と getRule
の戻り値の型を明示的に指定してください。
Reference: ## 型定義の適用
const splitComments = ( | ||
response: string | ||
): { start: number; end: number; comment: string }[] => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数 splitComments
の引数 response
と戻り値に型が指定されていません。response
は文字列として扱われているので、型を string
として明示的に指定してください。また、この関数はオブジェクトの配列を返しているので、戻り値の型を { start: number; end: number; comment: string }[]
として明示的に指定してください。
Reference: ## 型定義の適用
const readRules = () => { | ||
const getRule = (node: MarkdownSectionNode) => { | ||
let rule = `${node.title}\n\n${node.content}`; | ||
if (node.children.length > 0) { | ||
for (const child of node.children) { | ||
rule += getRule(child); | ||
} | ||
} | ||
return rule; | ||
}; | ||
|
||
const markdown = readFileSync("GUIDE.md", "utf-8"); | ||
const parsed = parseMarkdown(markdown); | ||
const rules: string[] = []; | ||
for (const level1 of parsed.children) { | ||
for (const level2 of level1.children) { | ||
const rule = getRule(level2); | ||
if (rule.match(/AI Review.*ON/g)) { | ||
rules.push(getRule(level2)); | ||
} | ||
} | ||
} | ||
return rules; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数 readRules
の戻り値に型が指定されていません。この関数は文字列の配列を返しているので、戻り値の型を string[]
として明示的に指定してください。
Reference: ## 型定義の適用
35d8596
to
0c52b24
Compare
const readRules = () => { | ||
const getRule = (node: MarkdownSectionNode) => { | ||
let rule = `${node.title}\n\n${node.content}`; | ||
if (node.children.length > 0) { | ||
for (const child of node.children) { | ||
rule += getRule(child); | ||
} | ||
} | ||
return rule; | ||
}; | ||
|
||
const markdown = readFileSync("GUIDE.md", "utf-8"); | ||
const parsed = parseMarkdown(markdown); | ||
const rules: string[] = []; | ||
for (const level1 of parsed.children) { | ||
for (const level2 of level1.children) { | ||
const rule = getRule(level2); | ||
if (rule.match(/AI Review.*ON/g)) { | ||
rules.push(getRule(level2)); | ||
} | ||
} | ||
} | ||
return rules; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数readRules
の戻り値に型が指定されていません。この関数は文字列の配列を返しているので、戻り値の型をstring[]
と明示してください。
Reference: ## 型定義の適用
,,,| Meta | Content |,| --------- | ------------------------------------------------------------------ |,| Level | 必須 |,| Link | https://www.typescriptlang.org/docs/handbook/2/everyday-types.html |,| AI Review | ON |,### 説明,,,,全ての変数、関数の引数、および戻り値には明示的な型またはインターフェースを指定すること。,### 理由,,,,型を明示的に宣言することで、コンパイル時の型チェックの恩恵を受けられ、ランタイムエラーのリスクを減らします。また、コードの意図が明確になり、他の開発者がコードを理解しやすくなります。,### 例,,,,```typescript,// 良いコードの例,function add(x: number, y: number): number {, return x + y;,},,// 悪いコードの例,function add(x, y) {, return x + y;,},```,### 例外ケース,,,,- ライブラリが提供する関数や変数の型が any である場合は、適宜型アサーションを使用する。,### リファクタリングガイドライン,,,,既存のコードでは、任意の型が使われていた場合、それを具体的な型に置き換えていく。新規コードでは初めから型を適用する。,,---,const buildPrompt = (rule: string) => { | ||
return prompt.replace("{{CODING_GUIDE}}", rule); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数buildPrompt
の引数rule
に型が指定されていません。rule
は文字列として扱われているので、型をstring
と明示してください。
Reference: ## 型定義の適用
,,,| Meta | Content |,| --------- | ------------------------------------------------------------------ |,| Level | 必須 |,| Link | https://www.typescriptlang.org/docs/handbook/2/everyday-types.html |,| AI Review | ON |,### 説明,,,,全ての変数、関数の引数、および戻り値には明示的な型またはインターフェースを指定すること。,### 理由,,,,型を明示的に宣言することで、コンパイル時の型チェックの恩恵を受けられ、ランタイムエラーのリスクを減らします。また、コードの意図が明確になり、他の開発者がコードを理解しやすくなります。,### 例,,,,```typescript,// 良いコードの例,function add(x: number, y: number): number {, return x + y;,},,// 悪いコードの例,function add(x, y) {, return x + y;,},```,### 例外ケース,,,,- ライブラリが提供する関数や変数の型が any である場合は、適宜型アサーションを使用する。,### リファクタリングガイドライン,,,,既存のコードでは、任意の型が使われていた場合、それを具体的な型に置き換えていく。新規コードでは初めから型を適用する。,,---,const splitComments = ( | ||
response: string | ||
): { start: number; end: number; comment: string }[] => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数splitComments
の引数response
と戻り値に型が指定されていません。response
は文字列として扱われているので、型をstring
と明示してください。また、この関数はオブジェクトの配列を返しているので、戻り値の型を{ start: number; end: number; comment: string }[]
と明示してください。
Reference: ## 型定義の適用
,,,| Meta | Content |,| --------- | ------------------------------------------------------------------ |,| Level | 必須 |,| Link | https://www.typescriptlang.org/docs/handbook/2/everyday-types.html |,| AI Review | ON |,### 説明,,,,全ての変数、関数の引数、および戻り値には明示的な型またはインターフェースを指定すること。,### 理由,,,,型を明示的に宣言することで、コンパイル時の型チェックの恩恵を受けられ、ランタイムエラーのリスクを減らします。また、コードの意図が明確になり、他の開発者がコードを理解しやすくなります。,### 例,,,,```typescript,// 良いコードの例,function add(x: number, y: number): number {, return x + y;,},,// 悪いコードの例,function add(x, y) {, return x + y;,},```,### 例外ケース,,,,- ライブラリが提供する関数や変数の型が any である場合は、適宜型アサーションを使用する。,### リファクタリングガイドライン,,,,既存のコードでは、任意の型が使われていた場合、それを具体的な型に置き換えていく。新規コードでは初めから型を適用する。,,---,response.match(/.*?((#+)?\s*改善点[\s\S]*)/m)?.[0].split("\n") ?? []; | ||
for (const line of lines) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここでは非同期操作が行われていますが、async/await
パターンが使用されていません。コーディングガイドに従って、非同期操作はasync/await
パターンを使用して実装するように改善してください。
例えば、以下のように修正できます。
async function splitComments() {
try {
const response = await fetchResponse();
const lines = response.match(/.*?((#+)?\s*改善点[\s\S]*)/m)?.[0].split("\n") ?? [];
// 以下、同様の処理を続ける
} catch (error) {
throw new Error(error);
}
}
ここで、fetchResponse()
は非同期でレスポンスを取得する関数とします。
Reference: ## 非同期操作の取り扱い
,,,| Meta | Content |,| --------- | ------------------------------------------------------------------------------------------- |,| Level | 必須 |,| Link | https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function |,| AI Review | ON |,### 説明,,,,非同期操作は`async/await`パターンを使用して実装すること。コールバックや`.then()`、`.catch()`メソッドを用いた Promise チェーンは避ける。,### 理由,,,,`async/await`は非同期コードをより読みやすく、同期的な流れで記述できるためです。コードの可読性とメンテナンス性が向上します。,### 例,,,,```typescript,// 良いコードの例,async function getUser(id: string): Promise {, try {, const response = await fetch(`/api/users/${id}`);, const user = await response.json();, return user;, } catch (error) {, throw new Error(error);, },},,// 悪いコードの例,function getUser(id: string): Promise {, return fetch(`/api/users/${id}`), .then((response) => response.json()), .then((user) => user), .catch((error) => {, throw new Error(error);, });,},```,### 例外ケース,,,,- 既存のコードベースで`Promise`チェーンが広範に使用されている場合は、段階的に`async/await`にリファクタリングする。,### リファクタリングガイドライン,,,,新規プロジェクトや新規機能では`async/await`を用いること。既存のコードは、重要なバグ修正や機能追加の際に、この新しいパターンに徐々に置き換えていく。,0c52b24
to
96a0606
Compare
const getRule = (node: MarkdownSectionNode) => { | ||
let rule = `${node.title}\n\n${node.content}`; | ||
if (node.children.length > 0) { | ||
for (const child of node.children) { | ||
rule += getRule(child); | ||
} | ||
} | ||
return rule; | ||
}; | ||
|
||
const markdown = readFileSync("GUIDE.md", "utf-8"); | ||
const parsed = parseMarkdown(markdown); | ||
const rules: string[] = []; | ||
for (const level1 of parsed.children) { | ||
for (const level2 of level1.children) { | ||
const rule = getRule(level2); | ||
if (rule.match(/AI Review.*ON/g)) { | ||
rules.push(getRule(level2)); | ||
} | ||
} | ||
} | ||
return rules; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
この部分のコードでは、ファイルを読み込むためにreadFileSync
を使用していますが、これは同期的な操作です。非同期操作の取り扱いに関するコーディングガイドに従うためには、readFile
を使用し、その結果をawait
で待つように変更するべきです。また、そのためにはreadRules
関数を非同期関数(async function
)にする必要があります。
以下に改善後のコードを示します。
const readRules = async () => {
const getRule = (node: MarkdownSectionNode) => {
let rule = `${node.title}\n\n${node.content}`;
if (node.children.length > 0) {
for (const child of node.children) {
rule += getRule(child);
}
}
return rule;
};
const markdown = await fs.promises.readFile("GUIDE.md", "utf-8");
const parsed = parseMarkdown(markdown);
const rules: string[] = [];
for (const level1 of parsed.children) {
for (const level2 of level1.children) {
const rule = getRule(level2);
if (rule.match(/AI Review.*ON/g)) {
rules.push(getRule(level2));
}
}
}
return rules;
};
この変更により、ファイルの読み込みが非同期になり、他の操作がブロックされることなく実行できるようになります。
Reference: ## 非同期操作の取り扱い
Meta | Content |
---|---|
Level | 必須 |
Link | https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function |
AI Review | ON |
説明
非同期操作はasync/await
パターンを使用して実装すること。コールバックや.then()
、.catch()
メソッドを用いた Promise チェーンは避ける。
理由
async/await
は非同期コードをより読みやすく、同期的な流れで記述できるためです。コードの可読性とメンテナンス性が向上します。
例
// 良いコードの例
async function getUser(id: string): Promise<User> {
try {
const response = await fetch(`/api/users/${id}`);
const user = await response.json();
return user;
} catch (error) {
throw new Error(error);
}
}
// 悪いコードの例
function getUser(id: string): Promise<User> {
return fetch(`/api/users/${id}`)
.then((response) => response.json())
.then((user) => user)
.catch((error) => {
throw new Error(error);
});
}
例外ケース
- 既存のコードベースで
Promise
チェーンが広範に使用されている場合は、段階的にasync/await
にリファクタリングする。
リファクタリングガイドライン
新規プロジェクトや新規機能ではasync/await
を用いること。既存のコードは、重要なバグ修正や機能追加の際に、この新しいパターンに徐々に置き換えていく。
const readRules = () => { | ||
const getRule = (node: MarkdownSectionNode) => { | ||
let rule = `${node.title}\n\n${node.content}`; | ||
if (node.children.length > 0) { | ||
for (const child of node.children) { | ||
rule += getRule(child); | ||
} | ||
} | ||
return rule; | ||
}; | ||
|
||
const markdown = readFileSync("GUIDE.md", "utf-8"); | ||
const parsed = parseMarkdown(markdown); | ||
const rules: string[] = []; | ||
for (const level1 of parsed.children) { | ||
for (const level2 of level1.children) { | ||
const rule = getRule(level2); | ||
if (rule.match(/AI Review.*ON/g)) { | ||
rules.push(getRule(level2)); | ||
} | ||
} | ||
} | ||
return rules; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数readRules
の戻り値に型が指定されていません。この関数は文字列の配列を返しているので、戻り値の型をstring[]
と明示してください。
Reference: ## 型定義の適用
Meta | Content |
---|---|
Level | 必須 |
Link | https://www.typescriptlang.org/docs/handbook/2/everyday-types.html |
AI Review | ON |
説明
全ての変数、関数の引数、および戻り値には明示的な型またはインターフェースを指定すること。
理由
型を明示的に宣言することで、コンパイル時の型チェックの恩恵を受けられ、ランタイムエラーのリスクを減らします。また、コードの意図が明確になり、他の開発者がコードを理解しやすくなります。
例
// 良いコードの例
function add(x: number, y: number): number {
return x + y;
}
// 悪いコードの例
function add(x, y) {
return x + y;
}
例外ケース
- ライブラリが提供する関数や変数の型が any である場合は、適宜型アサーションを使用する。
リファクタリングガイドライン
既存のコードでは、任意の型が使われていた場合、それを具体的な型に置き換えていく。新規コードでは初めから型を適用する。
const splitComments = ( | ||
response: string | ||
): { start: number; end: number; comment: string }[] => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数splitComments
の引数response
と戻り値に型が指定されていません。response
は文字列として扱われているので、型をstring
と明示してください。また、この関数はオブジェクトの配列を返しているので、戻り値の型を{ start: number; end: number; comment: string }[]
と明示してください。
Reference: ## 型定義の適用
Meta | Content |
---|---|
Level | 必須 |
Link | https://www.typescriptlang.org/docs/handbook/2/everyday-types.html |
AI Review | ON |
説明
全ての変数、関数の引数、および戻り値には明示的な型またはインターフェースを指定すること。
理由
型を明示的に宣言することで、コンパイル時の型チェックの恩恵を受けられ、ランタイムエラーのリスクを減らします。また、コードの意図が明確になり、他の開発者がコードを理解しやすくなります。
例
// 良いコードの例
function add(x: number, y: number): number {
return x + y;
}
// 悪いコードの例
function add(x, y) {
return x + y;
}
例外ケース
- ライブラリが提供する関数や変数の型が any である場合は、適宜型アサーションを使用する。
リファクタリングガイドライン
既存のコードでは、任意の型が使われていた場合、それを具体的な型に置き換えていく。新規コードでは初めから型を適用する。
const buildPrompt = (rule: string) => { | ||
return prompt.replace("{{CODING_GUIDE}}", rule); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数buildPrompt
の引数rule
に型が指定されていません。rule
は文字列として扱われているので、型をstring
と明示してください。
Reference: ## 型定義の適用
Meta | Content |
---|---|
Level | 必須 |
Link | https://www.typescriptlang.org/docs/handbook/2/everyday-types.html |
AI Review | ON |
説明
全ての変数、関数の引数、および戻り値には明示的な型またはインターフェースを指定すること。
理由
型を明示的に宣言することで、コンパイル時の型チェックの恩恵を受けられ、ランタイムエラーのリスクを減らします。また、コードの意図が明確になり、他の開発者がコードを理解しやすくなります。
例
// 良いコードの例
function add(x: number, y: number): number {
return x + y;
}
// 悪いコードの例
function add(x, y) {
return x + y;
}
例外ケース
- ライブラリが提供する関数や変数の型が any である場合は、適宜型アサーションを使用する。
リファクタリングガイドライン
既存のコードでは、任意の型が使われていた場合、それを具体的な型に置き換えていく。新規コードでは初めから型を適用する。
packages/ai-craftsman/src/ci.ts
Outdated
const buildComment = (comment: string, rule: string) => { | ||
const [name, ...rest] = rule.split("\n"); | ||
const detail = `\ | ||
<details> | ||
<summary>Reference: ${name}</summary> | ||
${rest.join("\n")} | ||
</details>`; | ||
|
||
return `${comment}\n\n${detail}`; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
関数buildComment
の引数comment
とrule
、戻り値に型が指定されていません。それぞれ適切な型を指定してください。例えば、以下のように修正できます。
const buildComment = (comment: string, rule: string): string => {
// ...
};
Reference: ## 型定義の適用
Meta | Content |
---|---|
Level | 必須 |
Link | https://www.typescriptlang.org/docs/handbook/2/everyday-types.html |
AI Review | ON |
説明
全ての変数、関数の引数、および戻り値には明示的な型またはインターフェースを指定すること。
理由
型を明示的に宣言することで、コンパイル時の型チェックの恩恵を受けられ、ランタイムエラーのリスクを減らします。また、コードの意図が明確になり、他の開発者がコードを理解しやすくなります。
例
// 良いコードの例
function add(x: number, y: number): number {
return x + y;
}
// 悪いコードの例
function add(x, y) {
return x + y;
}
例外ケース
- ライブラリが提供する関数や変数の型が any である場合は、適宜型アサーションを使用する。
リファクタリングガイドライン
既存のコードでは、任意の型が使われていた場合、それを具体的な型に置き換えていく。新規コードでは初めから型を適用する。
96a0606
to
321896c
Compare
No description provided.