Browse Source

go for several todos

Marcelo Fornet 6 years ago
parent
commit
97f09d5fc5
8 changed files with 82 additions and 47 deletions
  1. 13 8
      package.json
  2. 3 1
      src/conn.ts
  3. 9 9
      src/core.ts
  4. 41 17
      src/extension.ts
  5. 2 0
      src/parsers/codeforces.ts
  6. 3 2
      src/test/extension.test.ts
  7. 7 0
      src/types.ts
  8. 4 10
      todo.md

+ 13 - 8
package.json

@@ -24,6 +24,7 @@
         "onCommand:extension.coding",
         "onCommand:extension.stress",
         "onCommand:extension.upgrade",
+        "onCommand:extension.compile",
         "onCommand:extension.debugTest"
     ],
     "main": "./out/extension",
@@ -31,35 +32,39 @@
         "commands": [
             {
                 "command": "extension.addProblem",
-                "title": "ACMH: New Problem"
+                "title": "ACMX: New Problem"
             },
             {
                 "command": "extension.addContest",
-                "title": "ACMH: New Contest"
+                "title": "ACMX: New Contest"
             },
             {
                 "command": "extension.runSolution",
-                "title": "ACMH: Run"
+                "title": "ACMX: Run"
             },
             {
                 "command": "extension.openTestcase",
-                "title": "ACMH: Open Test Case"
+                "title": "ACMX: Open Test Case"
             },
             {
                 "command": "extension.addTestcase",
-                "title": "ACMH: Add Test Case"
+                "title": "ACMX: Add Test Case"
             },
             {
                 "command": "extension.coding",
-                "title": "ACMH: View: Code"
+                "title": "ACMX: View: Code"
             },
             {
                 "command": "extension.stress",
-                "title": "ACMH: Stress"
+                "title": "ACMX: Stress"
             },
             {
                 "command": "extension.upgrade",
-                "title": "ACMH: Upgrade"
+                "title": "ACMX: Upgrade"
+            },
+            {
+                "command": "extension.compile",
+                "title": "ACMX: Compile"
             }
         ]
     },

+ 3 - 1
src/conn.ts

@@ -9,6 +9,8 @@ import { CODEFORCES } from "./parsers/codeforces";
 const PERSONAL = new SiteDescription(
     "personal",
     "Not a site. Custom problems and contest.",
+    "Contest name",
+    "Problem name",
     async numProblems => {
         let total = Number.parseInt(numProblems);
 
@@ -21,7 +23,7 @@ const PERSONAL = new SiteDescription(
         return new Contest(problems);
     },
     async problemId => {
-        return new Problem("W", "W", ["0\n", "2\n", "9\n"], ["2\n", "4\n", "11\n"]);
+        return new Problem(problemId, problemId, ["0\n", "2\n", "9\n"], ["2\n", "4\n", "11\n"]);
     }
 );
 

+ 9 - 9
src/core.ts

@@ -4,8 +4,7 @@ import { mkdirSync, existsSync, copyFileSync, openSync, readSync, readdirSync, w
 import { dirname, join, extname, basename } from "path";
 import * as child_process from 'child_process';
 import * as gwen from './gwen';
-import { TestcaseResult, Veredict, SolutionResult, Problem, Contest } from "./types";
-import { getSite } from "./conn";
+import { TestcaseResult, Veredict, SolutionResult, Problem, Contest, SiteDescription } from "./types";
 
 export const TESTCASES = 'testcases';
 export const ATTIC = 'attic';
@@ -182,12 +181,14 @@ function newProblem(path: string, problem: Problem){
     });
 }
 
-export async function newProblemFromId(path: string, site: string, problemId: string){
-    let siteDesc = getSite(site);
+export async function newProblemFromId(path: string, site: SiteDescription, problemId: string){
+    let problem = await site.problemParser(problemId);
 
-    let problem = await siteDesc.problemParser(problemId);
+    path = join(path, problem.identifier!);
 
     newProblem(path, problem);
+
+    return path;
 }
 
 function newContest(path: string, contest: Contest){
@@ -201,10 +202,9 @@ function newContest(path: string, contest: Contest){
  *
  * @param contestId Can be a number if the site is `personal` and this number denote number of problems
  */
-export async function newContestFromId(path: string, site: string, contestId: string){
+export async function newContestFromId(path: string, site: SiteDescription, contestId: string){
     createFolder(path);
-    let siteDesc = getSite(site);
-    let contest = await siteDesc.contestParser(contestId);
+    let contest = await site.contestParser(contestId);
     newContest(path, contest);
 }
 
@@ -255,7 +255,7 @@ export function timedRun(path: string, tcName: string, timeout = TESTCASE_TIMEOU
     }
 }
 
-function compileCode(pathCode: string, pathOutput: string){
+export function compileCode(pathCode: string, pathOutput: string){
     // TODO: 002
     return child_process.spawnSync("g++", ["-std=c++11", `${pathCode}`, "-o", `${pathOutput}`]);
 }

+ 41 - 17
src/extension.ts

@@ -4,8 +4,9 @@ import { existsSync, writeFileSync, readdirSync } from 'fs';
 import { join, extname } from 'path';
 import { SITES } from './conn';
 import { newContestFromId, testSolution, veredictName, stressSolution, upgradeArena, newProblemFromId, removeExtension } from './core';
-import { Veredict } from './types';
-import { currentProblem } from './core';
+import { Veredict, SiteDescription } from './types';
+import { currentProblem, compileCode, ATTIC } from './core';
+import { getSite } from "./conn";
 
 const TESTCASES = 'testcases';
 
@@ -39,21 +40,18 @@ async function addProblem() {
         return;
     }
 
-    let site = site_info.target;
+    let site: SiteDescription = getSite(site_info.target);
 
-    // TODO: 006
-    let id = await vscode.window.showInputBox({placeHolder: "Problem ID"});
+    let id = await vscode.window.showInputBox({placeHolder: site.problemIdPlaceholder});
 
     if (id === undefined){
         vscode.window.showErrorMessage("Problem ID not provided.");
         return;
     }
 
-    path = join(path, `${id}`);
+    let problemPath = await newProblemFromId(path, site, id);
 
-    await newProblemFromId(path, site, id);
-
-    await vscode.commands.executeCommand("vscode.openFolder", vscode.Uri.file(path));
+    await vscode.commands.executeCommand("vscode.openFolder", vscode.Uri.file(problemPath));
     // TODO: 007
     // Just want to run two commands below
     // await vscode.commands.executeCommand("vscode.open", vscode.Uri.file("sol.cpp"));
@@ -75,11 +73,11 @@ async function addContest() {
         return;
     }
 
-    let site = site_info.target;
+    let site = getSite(site_info.target);
     let id = undefined;
 
-    if (site === "personal"){
-        let name= await vscode.window.showInputBox({placeHolder: "Contest Name"});
+    if (site.name === "personal"){
+        let name= await vscode.window.showInputBox({placeHolder: site.contestIdPlaceholder});
 
         if (name === undefined){
             vscode.window.showErrorMessage("Name not provided.");
@@ -98,8 +96,7 @@ async function addContest() {
         id = probCountStr!;
     }
     else{
-        // TODO: 008
-        id = await vscode.window.showInputBox({placeHolder: "Contest ID"});
+        id = await vscode.window.showInputBox({placeHolder: site.contestIdPlaceholder});
 
         if (id === undefined){
             vscode.window.showErrorMessage("Contest ID not provided.");
@@ -152,6 +149,32 @@ async function runSolution(){
     }
 }
 
+async function compile(){
+    let path = currentProblem();
+
+    if (path === undefined){
+        vscode.window.showErrorMessage("No active problem");
+        return;
+    }
+
+    let sol = join(path, 'sol.cpp');
+    let out = join(path, ATTIC, 'sol');
+
+    if (!existsSync(sol)){
+        throw new Error("Open a coding environment first.");
+    }
+
+    // Compile solution
+    let xresult = compileCode(sol, out);
+
+    if (xresult.status !== 0){
+        throw new Error("Compilation Error. sol.cpp");
+    }
+    else{
+        vscode.window.showInformationMessage("Compilation successfully.");
+    }
+}
+
 async function openTestcase() {
     let path = currentProblem();
 
@@ -257,9 +280,7 @@ async function upgrade(){
 }
 
 async function debugTest(){
-    // let contest = await parseContest("1081");
-    console.log("HEY");
-    // await parseProblem("1081-E");
+    console.log("no bugs :O");
 }
 
 // this method is called when your extension is activated
@@ -273,6 +294,7 @@ export function activate(context: vscode.ExtensionContext) {
     let codingCommand = vscode.commands.registerCommand('extension.coding', coding);
     let stressCommand = vscode.commands.registerCommand('extension.stress', stress);
     let upgradeCommand = vscode.commands.registerCommand('extension.upgrade', upgrade);
+    let compileCommand = vscode.commands.registerCommand('extension.compile', compile);
 
     let debugTestCommand = vscode.commands.registerCommand('extension.debugTest', debugTest);
 
@@ -284,6 +306,8 @@ export function activate(context: vscode.ExtensionContext) {
     context.subscriptions.push(codingCommand);
     context.subscriptions.push(stressCommand);
     context.subscriptions.push(upgradeCommand);
+    context.subscriptions.push(compileCommand);
+
     context.subscriptions.push(debugTestCommand);
 }
 

+ 2 - 0
src/parsers/codeforces.ts

@@ -85,6 +85,8 @@ export async function parseProblem(problemId: string) {
 export const CODEFORCES = new SiteDescription(
         "codeforces",
         "codeforces.com",
+        "{contest id} (Ex: 1095)",
+        "{contest id}-{problem id} (Ex: 1095-A)",
         parseContest,
         parseProblem,
     );

+ 3 - 2
src/test/extension.test.ts

@@ -9,6 +9,7 @@ import { dirname, join } from 'path';
 import { timedRun, testcasesName, testSolution, newArena, ATTIC, TESTCASES, upgradeArena, stressSolution, newProblemFromId, newContestFromId } from '../core';
 import { TestcaseResult, Veredict } from '../types';
 import { rmdirSync, existsSync, readdirSync, unlinkSync, openSync, writeSync, closeSync } from 'fs';
+import { getSite } from '../conn';
 
 const SRC = join(dirname(dirname(dirname(__filename))), 'src', 'test');
 const ARENA = join(SRC, 'arena');
@@ -108,7 +109,7 @@ suite("Extension Tests", function () {
         let path = join(ARENA, problemId);
 
         assert.equal(existsSync(path), false);
-        await newProblemFromId(path, 'personal', problemId);
+        await newProblemFromId(ARENA, getSite('personal'), problemId);
 
         assert.equal(existsSync(join(path, 'sol.cpp')), true, "Solution not found.");
         assert.equal(existsSync(join(path, ATTIC)), true, "Attic not found.");
@@ -127,7 +128,7 @@ suite("Extension Tests", function () {
 
         assert.equal(existsSync(path), false);
 
-        await newContestFromId(path, 'personal', "5");
+        await newContestFromId(path, getSite('personal'), "5");
 
         assert.equal(readdirSync(path).length, "5");
 

+ 7 - 0
src/types.ts

@@ -54,14 +54,21 @@ export class Contest{
 export class SiteDescription{
     name: string;
     description: string;
+    contestIdPlaceholder: string;
+    problemIdPlaceholder: string;
     contestParser: (contestId: string) => Promise<Contest>;
     problemParser: (problemId: string) => Promise<Problem>;
 
     constructor(name: string, description: string,
+                contestIdPlaceholder: string, problemIdPlaceholder: string,
                 contestParser: (contestId: string) => Promise<Contest>,
                 problemParser: (problemId: string) => Promise<Problem>){
         this.name = name;
         this.description = description;
+
+        this.contestIdPlaceholder = contestIdPlaceholder;
+        this.problemIdPlaceholder = problemIdPlaceholder;
+
         this.contestParser = contestParser;
         this.problemParser = problemParser;
     }

+ 4 - 10
todo.md

@@ -1,23 +1,17 @@
 # List of TODO
 
-* Use this tool: https://github.com/slycelote/caide-cpp-inliner.  Suggestion from jcg
-* Add How to Use (in the README.) How to add own template etc...
-* **NEXT** Create custom settings. Add (TimeLimit, Checker)
-* **IMPORTANT** When a new view is activated (after run or view:code) close all open tabs. (also (maybe) collapse everything not related to the problem)
-* Implement parser for codeforces to test on real cases
-* **INTERNET** Learn how to move static files from `src` to `out`. Make this extension works.
+* **IMPORTANT** Add How to Use (in the README.) How to add own template etc...
+* **IMPORTANT** Create custom settings. Add (TimeLimit, Checker)
+* **WOW** Use this tool: [caide-cpp-inliner](https://github.com/slycelote/caide-cpp-inliner).  Suggestion from jcg
+* When a new view is activated (after run or view:code) close all open tabs. (also (maybe) collapse everything not related to the problem)
 * Allow programming in other languages than c++
 * Figure out something for interactive problems.
 * Allow stopping a running program (such as sol.cpp/brute.cpp/gen.py/etc...)
 * Allow custom checker easily
 * Add several checkers and try to infer which is the correct!
-* Fix name of new problems after calling addProblem
-* Add Compile command
-* Find small case where the code is failing
 
 * [001](/src/core.ts): Revisit this constant. Show specific error to know when this is an issue. Add in settings
 * [002](/src/core.ts): Avoid this hardcoded line. Use personalized compile line. increase stack by default. This involve allowing different languages
 * [004](/src/core.ts): Make crossplatform call. Solution: Configure path to python in global settings
 * [005](/src/core.ts): Restrict brute in time, and capture errors
-* [006](/src/extension.ts): **PARSING** Provide custom problem and contest id example in placeholder per different site
 * [007](/src/extension.ts): How can I have access to new proccess created using `openFolder`?