summaryrefslogtreecommitdiff
path: root/extension/src/languages/python/index.ts
blob: 50282b452286c4196ff0705bc152bdfd4a663f62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import path = require("path");
import { LanguageLibrary } from "../index.d";

const tracebackStart = "Traceback (most recent call last):";
const tracebackEnd = (buf: string): string | undefined => {
  let lines = buf
    .split("\n")
    .filter((line: string) => line.trim() !== "~~^~~")
    .filter((line: string) => line.trim() !== "");
  for (let i = 0; i < lines.length; i++) {
    if (
      lines[i].startsWith("  File") &&
      i + 2 < lines.length &&
      lines[i + 2][0] !== " "
    ) {
      return lines.slice(0, i + 3).join("\n");
    }
  }
  return undefined;
};

function parseFirstStacktrace(stdout: string): string | undefined {
  let startIdx = stdout.indexOf(tracebackStart);
  if (startIdx < 0) return undefined;
  stdout = stdout.substring(startIdx);
  return tracebackEnd(stdout);
}

function lineIsFunctionDef(line: string): boolean {
  return line.startsWith("def ");
}

function parseFunctionDefForName(line: string): string {
  return line.split("def ")[1].split("(")[0];
}

function lineIsComment(line: string): boolean {
  return line.trim().startsWith("#");
}

function writeImport(
  sourcePath: string,
  pathToImport: string,
  namesToImport: string[] | undefined = undefined
): string {
  let segs = path.relative(sourcePath, pathToImport).split(path.sep);
  let importFrom = "";
  for (let seg of segs) {
    if (seg === "..") {
      importFrom = "." + importFrom;
    } else {
      if (!importFrom.endsWith(".")) {
        importFrom += ".";
      }
      importFrom += seg.split(".").slice(0, -1).join(".");
    }
  }

  return `from ${importFrom} import ${
    namesToImport ? namesToImport.join(", ") : "*"
  }`;
}

const pythonLangaugeLibrary: LanguageLibrary = {
  language: "python",
  fileExtensions: [".py"],
  parseFirstStacktrace,
  lineIsFunctionDef,
  parseFunctionDefForName,
  lineIsComment,
  writeImport,
};

export default pythonLangaugeLibrary;