Skip to content

KingSejong Linter 규칙 가이드 ​

버전: v0.5.0 총 규칙 수: 13개 최종 업데이트: 2025-11-21


목차 ​

  1. 개요
  2. 규칙 목록
  3. 기본 규칙 (8개)
  4. 추가 규칙 (5개)
  5. 설정 방법
  6. 커스텀 규칙 작성

개요 ​

KingSejong Linter는 코드 품질을 향상시키기 위한 정적 분석 도구입니다. .ksjlint.json 파일로 규칙을 설정할 수 있습니다.

심각도 레벨 ​

  • error: 치명적 오류, 빌드 실패
  • warning: 경고, 주의 필요
  • hint: 힌트, 개선 권장

규칙 목록 ​

기본 규칙 (구현 완료) ✅ ​

  1. unused-variable - 사용하지 않는 변수 감지
  2. dead-code - 도달 불가능한 코드 감지
  3. no-self-comparison - 자기 자신과 비교 금지
  4. constant-condition - 상수 조건문 경고
  5. empty-block - 빈 블록 경고
  6. no-magic-number - 매직 넘버 사용 경고
  7. no-shadowing - 변수 섀도잉 경고
  8. no-unused-parameter - 사용하지 않는 매개변수 경고

추가 규칙 (구현 완료) ✅ ​

  1. naming-convention - 식별자 이름 규칙
  2. function-complexity - 함수 복잡도 상한
  3. unused-import - 사용하지 않는 가져오기
  4. import-order - 가져오기 순서
  5. josa-agreement - 조사가 앞 명사의 받침과 맞는지 (배열를 → 배열을). 실행기는 틀린 조사도 받아들이므로 린터가 알려 준다

규칙은 Linter::addDefaultRules() 가 모두 등록하며 kingsejong lint 와 테스트가 이것을 쓴다. 아래 상세 설명 중 9~13번은 예전 계획(camelcase-naming 등)을 적은 것이라 실제 규칙 이름과 다르다.


기본 규칙 (8개) ​

1. unused-variable ​

설명: 선언했지만 사용하지 않는 변수를 감지합니다.

나쁜 예:

ksj
x = 10  # x를 사용하지 않음
출력("Hello")

좋은 예:

ksj
x = 10
출력(x)

설정:

json
{
  "rules": {
    "unused-variable": "warning"
  }
}

2. dead-code ​

설명: 실행되지 않는 코드를 감지합니다.

나쁜 예:

ksj
함수 테스트() {
    반환 10
    출력("이 코드는 실행되지 않음")  # 도달 불가능
}

좋은 예:

ksj
함수 테스트() {
    출력("정상 실행")
    반환 10
}

3. no-self-comparison ​

설명: 자기 자신과의 비교를 금지합니다.

나쁜 예:

ksj
x = 10
만약 (x == x) {  # 항상 참
    출력("항상 참")
}

좋은 예:

ksj
x = 10
y = 10
만약 (x == y) {
    출력("같음")
}

4. constant-condition ​

설명: 항상 참 또는 거짓인 조건문을 경고합니다.

나쁜 예:

ksj
만약 (참) {  # 항상 참
    출력("항상 실행")
}

i가 0부터 10 미만 {
    만약 (거짓) {  # 절대 실행 안 됨
        출력("실행되지 않음")
    }
}

좋은 예:

ksj
x = 10
만약 (x > 5) {  # 변수 기반 조건
    출력("조건부 실행")
}

5. empty-block ​

설명: 빈 블록을 경고합니다.

나쁜 예:

ksj
만약 (x > 5) {
    # 빈 블록
}

함수 처리() {
    # 구현 없음
}

좋은 예:

ksj
만약 (x > 5) {
    출력("x는 5보다 큽니다")
}

함수 처리() {
    # TODO: 나중에 구현
    반환 null
}

6. no-magic-number ​

설명: 매직 넘버 사용을 경고합니다. 의미 있는 상수를 사용하세요.

나쁜 예:

ksj
면적 = 반지름 * 반지름 * 3.14159

좋은 예:

ksj
PI = 3.14159
면적 = 반지름 * 반지름 * PI

7. no-shadowing ​

설명: 외부 스코프의 변수를 가리는 것을 경고합니다.

나쁜 예:

ksj
x = 10

함수 테스트() {
    x = 20  # 외부 x를 가림
    출력(x)
}

좋은 예:

ksj
x = 10

함수 테스트() {
    y = 20  # 다른 이름 사용
    출력(y)
}

8. no-unused-parameter ​

설명: 사용하지 않는 함수 매개변수를 경고합니다.

나쁜 예:

ksj
함수 계산(a, b) {  # b를 사용하지 않음
    반환 a * 2
}

좋은 예:

ksj
함수 계산(a, b) {
    반환 a * b
}

# 또는 필요 없으면 제거
함수 계산(a) {
    반환 a * 2
}

추가 규칙 (5개) ​

9. camelcase-naming ✨ 새 규칙 ​

설명: camelCase 네이밍 컨벤션을 권장합니다.

나쁜 예:

ksj
사용자_이름 = "철수"  # snake_case
MAXVALUE = 100        # UPPER_CASE

좋은 예:

ksj
사용자이름 = "철수"   # camelCase (한글)
maxValue = 100       # camelCase (영문)
MAX_VALUE = 100      # 상수는 허용

설정:

json
{
  "rules": {
    "camelcase-naming": "hint"
  },
  "settings": {
    "naming-convention": "camelCase"
  }
}

10. max-line-length ✨ 새 규칙 ​

설명: 한 줄의 최대 길이를 제한합니다.

나쁜 예:

ksj
# 120자 초과
출력("이것은 매우 긴 문자열입니다. 이것은 매우 긴 문자열입니다. 이것은 매우 긴 문자열입니다. 이것은 매우 긴 문자열입니다. 이것은 매우 긴 문자열입니다.")

좋은 예:

ksj
# 여러 줄로 분할
메시지 = "이것은 매우 긴 문자열입니다. " +
         "이것은 매우 긴 문자열입니다. " +
         "이것은 매우 긴 문자열입니다."
출력(메시지)

설정:

json
{
  "rules": {
    "max-line-length": "hint"
  },
  "settings": {
    "max-line-length": 120
  }
}

11. no-trailing-spaces ✨ 새 규칙 ​

설명: 행 끝의 불필요한 공백을 제거합니다.

나쁜 예:

ksj
x = 10   ␣␣␣
출력(x)␣␣

좋은 예:

ksj
x = 10
출력(x)

자동 수정: Formatter가 자동으로 제거합니다.


12. prefer-const ✨ 새 규칙 ​

설명: 재할당하지 않는 변수는 상수로 선언하는 것을 권장합니다.

나쁜 예:

ksj
x = 10
y = x * 2
출력(y)  # x는 재할당하지 않음

좋은 예:

ksj
상수 X = 10
y = X * 2
출력(y)

13. no-duplicate-imports ✨ 새 규칙 ​

설명: 같은 모듈을 중복으로 임포트하는 것을 경고합니다.

나쁜 예:

ksj
가져오기 "math"
가져오기 "string"
가져오기 "math"  # 중복!

좋은 예:

ksj
가져오기 "math"
가져오기 "string"

설정 방법 ​

.ksjlint.json 파일 ​

프로젝트 루트에 .ksjlint.json 파일을 생성합니다:

json
{
  "rules": {
    "unused-variable": "warning",
    "dead-code": "warning",
    "no-self-comparison": "error",
    "constant-condition": "warning",
    "empty-block": "warning",
    "no-magic-number": "hint",
    "no-shadowing": "warning",
    "no-unused-parameter": "hint",
    "camelcase-naming": "hint",
    "max-line-length": "hint",
    "no-trailing-spaces": "hint",
    "prefer-const": "hint",
    "no-duplicate-imports": "warning"
  },
  "settings": {
    "max-line-length": 120,
    "naming-convention": "camelCase"
  }
}

명령줄 실행 ​

bash
# Lint 실행
kingsejong lint myfile.ksj

# 여러 파일 검사
kingsejong lint src/*.ksj

# 설정 파일 지정
kingsejong lint --config .ksjlint.json myfile.ksj

오류 등급 이슈가 하나라도 있으면 종료 코드 1, 경고만 있으면 0 입니다. 자동 수정(--fix)은 없습니다.

편집기(LSP)에서 보기 ​

언어 서버(kingsejong --lsp)는 구문 오류가 없는 문서에 같은 규칙을 돌려 결과를 진단으로 보냅니다. VS Code 확장에서는 경고 밑줄로 보이며, 출처는 kingsejong-lint, 코드는 규칙 이름(unused-variable 등)입니다. 구문 오류가 있는 동안에는 구문 진단만 나옵니다.

  • 설정 파일은 문서가 있는 디렉터리부터 상위로 올라가며 찾은 첫 .ksjlint.json 이고, 없으면 기본 설정입니다. 문서를 열거나 고칠 때마다 다시 읽고, VS Code 확장은 .ksjlint.json 이 바뀌면 서버에 알려(workspace/didChangeWatchedFiles) 열린 문서를 바로 다시 검사합니다.
  • 편집기에서 린터 결과를 끄려면 VS Code 설정 kingsejong.lint.enable 을 false 로 둡니다(재시작 없이 반영). 다른 LSP 클라이언트는 initializationOptions 또는 workspace/didChangeConfiguration 의 settings.kingsejong 에 {"lint": {"enable": false}} 를 넘깁니다.

CI/CD 통합 ​

GitHub Actions ​

yaml
name: Lint

on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run KingSejong Linter
        run: |
          kingsejong lint src/*.ksj

Pre-commit Hook ​

.git/hooks/pre-commit:

bash
#!/bin/bash

echo "Running KingSejong Linter..."
kingsejong lint src/*.ksj

if [ $? -ne 0 ]; then
    echo "Linting failed. Please fix the issues before committing."
    exit 1
fi

커스텀 규칙 작성 ​

규칙 템플릿 ​

새 규칙을 작성하려면 다음 템플릿을 사용하세요:

src/linter/rules/MyCustomRule.h:

cpp
#pragma once

#include "linter/Rule.h"

namespace kingsejong {
namespace linter {

class MyCustomRule : public Rule {
public:
    MyCustomRule();

    void check(const ast::Node* node, LintContext& context) override;

    std::string getName() const override { return "my-custom-rule"; }
    std::string getDescription() const override {
        return "Custom rule description";
    }
};

} // namespace linter
} // namespace kingsejong

src/linter/rules/MyCustomRule.cpp:

cpp
#include "linter/rules/MyCustomRule.h"

namespace kingsejong {
namespace linter {

MyCustomRule::MyCustomRule()
    : Rule("my-custom-rule", "Custom rule description")
{}

void MyCustomRule::check(const ast::Node* node, LintContext& context) {
    // 규칙 로직 구현

    // 문제 발견 시 보고
    if (/* 조건 */) {
        context.report(
            node->location(),
            Severity::WARNING,
            "Warning message"
        );
    }
}

} // namespace linter
} // namespace kingsejong

규칙 등록 ​

src/linter/Linter.cpp에 규칙을 등록합니다:

cpp
#include "linter/rules/MyCustomRule.h"

void Linter::addDefaultRules()
{
    // ... 기존 규칙들 ...
    addRule(std::make_unique<rules::MyCustomRule>());
}

CMakeLists.txt 의 LIB_SOURCES 에 새 .cpp 를 추가해야 빌드됩니다.


규칙 우선순위 ​

  1. error: 즉시 수정 필요
  2. warning: 가능한 빨리 수정
  3. hint: 시간 날 때 개선

규칙 비활성화 ​

특정 줄에서 규칙을 비활성화하려면:

ksj
# ksjlint-disable-next-line no-magic-number
면적 = 반지름 * 반지름 * 3.14159

# 또는 블록 전체
# ksjlint-disable no-magic-number
계산1 = x * 3.14
계산2 = y * 2.71
# ksjlint-enable no-magic-number

추가 자료 ​


작성자: KingSejong Team 최종 수정: 2025-11-21 피드백: https://github.com/anthropics/kingsejong-lang/issues

MIT License