Skip to content

Commit 818d2b2

Browse files
authored
Merge pull request #10 from CODESPACE-CE-PROJECT/CE-008-Compiler
add: analyze code
2 parents 34b4ffc + 9183366 commit 818d2b2

File tree

3 files changed

+96
-15
lines changed

3 files changed

+96
-15
lines changed

src/controllers/compiler.controller.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { Request, Response } from "express";
2-
import { ISubmissionLearnify, ISubmissionRequest } from "../interfaces/submission.interface";
2+
import {
3+
ISubmissionLearnify,
4+
ISubmissionRequest,
5+
} from "../interfaces/submission.interface";
36
import { ICompileRequest } from "../interfaces/compiler.interface";
47
import { rabbitMQService } from "../services/rabbitmq.service";
58
import { RequestWithUser } from "../interfaces/auth.interface";
69
import { redisClient } from "../services/redis.service";
10+
import { analyzeCode } from "../utils/analyze.util";
711

812
export const compilerController = {
913
addSubmissionToRabbitMQ: async (req: Request, res: Response) => {
@@ -13,11 +17,24 @@ export const compilerController = {
1317
message: "Missing Required Fields",
1418
});
1519
}
20+
1621
submission.token = (req as RequestWithUser).user.token;
17-
submission.username = (req as RequestWithUser).user.username
22+
submission.username = (req as RequestWithUser).user.username;
23+
const resultAnalyzeCode = await analyzeCode(submission);
24+
if (
25+
resultAnalyzeCode.imports.length > 0 ||
26+
resultAnalyzeCode.functions.length > 0
27+
) {
28+
return res.status(406).json({
29+
message: "Has Constraint In Your Code",
30+
data: resultAnalyzeCode,
31+
});
32+
}
1833
await rabbitMQService.sendDataToQueue("submission", submission);
1934

20-
redisClient.set(`submissionState-${submission.username}`, "true", { EX: 240 })
35+
redisClient.set(`submissionState-${submission.username}`, "true", {
36+
EX: 240,
37+
});
2138

2239
return res.status(200).json({
2340
message: "Add To Queue Successfully",
@@ -37,11 +54,11 @@ export const compilerController = {
3754
});
3855
},
3956
compilerCodeLearnify: async (req: Request, res: Response) => {
40-
const data: ISubmissionLearnify = req.body
57+
const data: ISubmissionLearnify = req.body;
4158
// check valid user in learnify database
42-
await rabbitMQService.sendDataToQueue("learnify-submission", data)
59+
await rabbitMQService.sendDataToQueue("learnify-submission", data);
4360
return res.status(200).json({
4461
message: "Add To Queue Successfully",
45-
})
46-
}
62+
});
63+
},
4764
};

src/interfaces/testcase.interface.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,24 @@ export interface ITestCase {
22
message: string;
33
data: {
44
testCases: {
5-
testCaseId: string,
5+
testCaseId: string;
66
input: string;
77
output: string;
88
isHidden: boolean;
9-
}[],
9+
}[];
1010
constraint: {
11-
constraintId: string,
12-
type: ConstraintType,
13-
keyword: string,
14-
qunatities: number,
15-
problemId: string
16-
}[]
11+
constraintId: string;
12+
type: ConstraintType;
13+
keyword: string;
14+
qunatities: number;
15+
problemId: string;
16+
}[];
17+
isRegex: boolean;
1718
};
1819
}
1920

2021
export enum ConstraintType {
2122
FUNCTION = "FUNCTION",
2223
METHOD = "METHOD",
24+
CLASS = "CLASS",
2325
}

src/utils/analyze.util.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { languageType } from "../interfaces/compiler.interface";
2+
import { ISubmissionRequest } from "../interfaces/submission.interface";
3+
import { ConstraintType, ITestCase } from "../interfaces/testcase.interface";
4+
import { problemService } from "../services/problem.service";
5+
6+
export const analyzeCode = async (submission: ISubmissionRequest) => {
7+
let functionRegex: RegExp;
8+
let importRegex: RegExp;
9+
10+
const testCase: ITestCase = await problemService.getTestCases(
11+
submission.problemId,
12+
submission.token,
13+
);
14+
15+
const targetFunctions: string[] = testCase.data.constraint.flatMap((item) =>
16+
item.type === ConstraintType.FUNCTION ? [item.keyword] : [],
17+
);
18+
19+
const targetImports: string[] = testCase.data.constraint.flatMap((item) =>
20+
item.type === ConstraintType.CLASS ? [item.keyword] : [],
21+
);
22+
23+
switch (submission.language) {
24+
case languageType.PYTHON:
25+
functionRegex = new RegExp(
26+
`\\b(${targetFunctions.join("|")})\\s*\\(`,
27+
"g",
28+
);
29+
importRegex = /^(?:import\s+(\w+)|from\s+(\w+)\s+import)/gm;
30+
break;
31+
case languageType.C:
32+
case languageType.CPP:
33+
functionRegex = new RegExp(
34+
`\\b(${targetFunctions.join("|")})\\s*\\(`,
35+
"g",
36+
);
37+
importRegex = /^#include\s*[<"]([^">]+)[>"]/gm;
38+
break;
39+
case languageType.JAVA:
40+
functionRegex = new RegExp(
41+
`\\b(${targetFunctions.join("|")})\\s*\\(`,
42+
"g",
43+
);
44+
importRegex = /^import\s+([\w.*]+);/gm;
45+
break;
46+
default:
47+
throw new Error("Unsupported language!");
48+
}
49+
50+
const functionMatches = [
51+
...submission.sourceCode.matchAll(functionRegex),
52+
].map((match) => match[1]);
53+
54+
const importMatches = [...submission.sourceCode.matchAll(importRegex)]
55+
.map((match) => match[1] || match[2])
56+
.filter((importName) => targetImports.includes(importName));
57+
58+
return {
59+
functions: functionMatches,
60+
imports: importMatches,
61+
};
62+
};

0 commit comments

Comments
 (0)