-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathUpgradeToBeginnerProgram.ts
83 lines (61 loc) · 2.91 KB
/
UpgradeToBeginnerProgram.ts
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
75
76
77
78
79
80
81
82
83
import { Project } from "@atomist/rug/model/Project";
import { Editor, Tags } from "@atomist/rug/operations/Decorators";
import { EditProject } from "@atomist/rug/operations/ProjectEditor";
import { ElmProgram , addDeclaration } from "./elm/ElmProgram";
/**
* Sample TypeScript editor used by AddUpgradeToBeginnerProgram.
*/
@Editor("UpgradeToBeginnerProgram", "Turn a static page into an interactive page")
@Tags("elm")
export class UpgradeToBeginnerProgram implements EditProject {
public edit(project: Project) {
const pxe = project.context.pathExpressionEngine;
verifyElmProject(project);
const program = ElmProgram.parse(project);
if (program.programLevel !== "static") {
// nothing to do here, it's already a Program
return;
}
// Copy in the beginner program. We will change it. Then we will copy its body into Main.
project.copyEditorBackingFileOrFailToDestination("src/BeginnerProgram.elm", "deleteme/BeginnerProgram.elm");
const beginnerProgram = ElmProgram.parse(project, "deleteme/BeginnerProgram.elm");
// put the body of the current main into the new view function
const existingMain = program.getFunction("main");
beginnerProgram.getFunction("view").body.update(existingMain.body.value());
beginnerProgram.reparse();
const fullTypeOfMain : string = existingMain.declaredType.value();
// the stuff we need from the existing program
const existingModuleBody = (program.moduleNode as any).moduleBody.value();
const everythingButMain: string = existingModuleBody.replace(
existingMain._whole.value(), "").replace(
new RegExp(fullTypeOfMain, "g"), "Html Msg"
);
// TODO: could remove some whitespace too
// add the rest of Main.elm to the view section
const newViewSection = beginnerProgram.getSection("VIEW");
newViewSection.body.update(
newViewSection.body.value() + "\n\n" + everythingButMain);
beginnerProgram.reparse();
moveTypeAliasesFromViewToModelSection(beginnerProgram);
beginnerProgram.reparse();
program.moduleNode.moduleBody.update(beginnerProgram.moduleNode.moduleBody.value());
project.deleteFile("deleteme/BeginnerProgram.elm");
}
}
function moveTypeAliasesFromViewToModelSection(p: ElmProgram) {
const viewSection = p.getSection("VIEW");
const modelSection = p.getSection("MODEL");
viewSection.typeAliases.forEach(t => {
addDeclaration(modelSection, t);
t._whole.update("");
});
}
/**
* Throw a useful exception if we're in the wrong place
*/
function verifyElmProject(project: Project): void {
if (!project.fileExists("elm-package.json")) {
throw new Error("I don't see elm-package.json. Are you at the root of an Elm project?");
}
}
export const upgradeToBeginnerProgram = new UpgradeToBeginnerProgram();