Skip to content

Commit 6b50738

Browse files
committed
feat: add go quality rules
1 parent 805e70e commit 6b50738

File tree

4 files changed

+63
-19
lines changed

4 files changed

+63
-19
lines changed

src/code-quality/code-quality.service.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ import { Injectable } from '@nestjs/common';
22
import { QualityDTO } from './dto/quality.dto';
33
import { CPPQualityVisitor } from './languages/cpp/cpp.vistor';
44
import { PythonVisitor } from './languages/python/python.visitor';
5+
import { GoQualityVisitor } from './languages/golang/go.visitor';
56

67
@Injectable()
78
export class CodeQualityService {
89
public run(source: string, language: string): QualityDTO {
910
const cppVisitor = new CPPQualityVisitor();
1011
const pyVisitor = new PythonVisitor();
12+
const goVisitor = new GoQualityVisitor();
13+
1114
const ret = {
1215
score: 100,
1316
};
@@ -17,6 +20,8 @@ export class CodeQualityService {
1720
return cppVisitor.run(source);
1821
case 'py':
1922
return pyVisitor.run(source);
23+
case 'go':
24+
return goVisitor.run(source);
2025
default:
2126
return ret;
2227
}

src/code-quality/languages/golang/generated/GoParser.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,6 @@ import { VocabularyImpl } from 'antlr4ts/VocabularyImpl';
1414
import * as Utils from 'antlr4ts/misc/Utils';
1515
import { GoParserVisitor } from './GoParserVisitor';
1616
import { Parser } from 'antlr4ts/Parser';
17-
// import { NotNull } from 'antlr4ts/Decorators';
18-
// import { Override } from 'antlr4ts/Decorators';
19-
// import { Parser } from 'antlr4ts/Parser';
20-
// import { ParseTreeListener } from 'antlr4ts/tree/ParseTreeListener';
21-
// import { ParseTreeVisitor } from 'antlr4ts/tree/ParseTreeVisitor';
22-
// import { RuleVersion } from "antlr4ts/RuleVersion";
2317

2418
export class GoParser extends Parser {
2519
public static readonly BREAK = 1;

src/code-quality/languages/golang/go.visitor.ts

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,76 @@
11
import { AbstractParseTreeVisitor } from 'antlr4ts/tree/AbstractParseTreeVisitor';
2-
import { CharStreams, CommonTokenStream } from 'antlr4ts';
32
import { GoParserVisitor } from './generated/GoParserVisitor';
43
import { QualityDTO } from '../../dto/quality.dto';
5-
import { GoLexer } from './generated/GoLexer';
6-
import { FunctionDeclContext, GoParser } from './generated/GoParser';
4+
import { CommonQualityFunction } from '../common/CommonQualityFunction';
75

8-
export class GoQualityVistor
6+
export class GoQualityVisitor
97
extends AbstractParseTreeVisitor<void>
108
implements GoParserVisitor<void>
119
{
1210
private codeQuality: QualityDTO;
1311

1412
run(source: string): QualityDTO {
15-
const inputStream = CharStreams.fromString(source);
16-
const lexer = new GoLexer(inputStream);
17-
const tokenStream = new CommonTokenStream(lexer);
18-
const parser = new GoParser(tokenStream);
19-
2013
this.codeQuality = {
2114
score: 100,
2215
};
2316

24-
const context = parser.functionDecl();
25-
this.visit(context);
17+
const lines = source.split('\n');
18+
19+
this.qualityEvalFunctionName(lines);
20+
21+
this.qualityEvalFunctionBody(lines);
2622

2723
return this.codeQuality;
2824
}
2925

30-
visitFunctionDecl(context: FunctionDeclContext): void {
31-
context.IDENTIFIER();
26+
/**
27+
* Applying quality rules on function name
28+
* @param lines
29+
* @private
30+
*/
31+
private qualityEvalFunctionName(lines: string[]): void {
32+
// Applying rules on function name
33+
lines
34+
.filter((line) => line.startsWith('func'))
35+
.map((line) => line.substring(5, line.indexOf('(')).trim())
36+
// If function name name is greater than 25 character => quality -1
37+
.map((functionName) => {
38+
if (functionName.length > 25) {
39+
this.codeQuality.score -= 1;
40+
}
41+
return functionName;
42+
})
43+
// If function name is not written is snake case => quality -3
44+
.map((functionName) => {
45+
if (!CommonQualityFunction.isSnakeCase(functionName)) {
46+
this.codeQuality.score -= 3;
47+
}
48+
return functionName;
49+
});
50+
}
51+
52+
/**
53+
* Applying quality rules on function body
54+
* @param lines
55+
* @private
56+
*/
57+
private qualityEvalFunctionBody(lines: string[]): void {
58+
let counter = 0;
59+
let isInFunction = false;
60+
lines.forEach((line) => {
61+
if (line.startsWith('func') && line.endsWith('{')) {
62+
isInFunction = true;
63+
} else if (isInFunction) {
64+
counter += 1;
65+
}
66+
if (line.trim().endsWith('}')) {
67+
if (counter > 30) {
68+
this.codeQuality.score -= 5;
69+
}
70+
isInFunction = false;
71+
counter = 0;
72+
}
73+
});
3274
}
3375

3476
// eslint-disable-next-line @typescript-eslint/no-empty-function

src/submissions/submissions.controller.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ export class SubmissionsController {
5555
case 'cpp':
5656
qualityScore = this.qualityService.run(createSubmissionDTO.code, 'cpp');
5757
break;
58+
case 'go':
59+
qualityScore = this.qualityService.run(createSubmissionDTO.code, 'go');
60+
break;
5861
default:
5962
lintScore = { score: 0 };
6063
qualityScore = { score: 0 };

0 commit comments

Comments
 (0)