Skip to content

Commit

Permalink
Display and allow editing of typedef parameter kinds (#1020)
Browse files Browse the repository at this point in the history
  • Loading branch information
georgefst authored Aug 8, 2023
2 parents 5033b1d + 9d38f53 commit 0c52d29
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 36 deletions.
2 changes: 1 addition & 1 deletion argocd/base/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ spec:
# Note: use the *dev* version of the package here, so that
# PRs can deploy `primer-service` container images that have
# not yet been merged to `primer` `main`.
image: ghcr.io/hackworthltd/primer-service-dev:git-cdac69ab9a82e6099d6cc52c8c42a8cc1b1cc674
image: ghcr.io/hackworthltd/primer-service-dev:git-e603e61697d00a76c52252d154a5179fc9779417
ports:
- containerPort: 8081
env:
Expand Down
8 changes: 4 additions & 4 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

# Note: don't override any of primer's Nix flake inputs, or else
# we won't hit its binary cache.
primer.url = github:hackworthltd/primer/cdac69ab9a82e6099d6cc52c8c42a8cc1b1cc674;
primer.url = github:hackworthltd/primer/e603e61697d00a76c52252d154a5179fc9779417;

flake-parts.url = "github:hercules-ci/flake-parts";
};
Expand Down
18 changes: 18 additions & 0 deletions src/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ export const actionName = (action: NoInputAction | InputAction): Name => {
return prose("+");
case "DeleteConField":
return prose("p⌫");
case "MakeKType":
return prose("*");
case "MakeKFun":
return prose("→");
case "DeleteKind":
return prose("⌫");
}
};

Expand Down Expand Up @@ -234,6 +240,12 @@ export const actionDescription = (
return "Add a parameter to this constructor";
case "DeleteConField":
return "Delete this parameter";
case "MakeKType":
return "Construct a type kind";
case "MakeKFun":
return "Construct a function kind";
case "DeleteKind":
return "Delete this kind";
}
};

Expand Down Expand Up @@ -341,5 +353,11 @@ export const actionType = (action: NoInputAction | InputAction): ActionType => {
return "Primary";
case "DeleteConField":
return "Destructive";
case "MakeKType":
return "Primary";
case "MakeKFun":
return "Primary";
case "DeleteKind":
return "Destructive";
}
};
7 changes: 6 additions & 1 deletion src/components/TreeReactFlow/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ export const primerNodeWith = <T>(n: PrimerNode, x: T): PrimerNode<T> =>
/** Data corresponding to a node from the backend.
* This is not used by special nodes, like term definition names or most parts of type definitions,
* but only in places where the backend allows an arbitrarily nested (term or type) expression.
* These are: the bodies and signatures of term defs, and the types of constructor fields in type defs.
* These are: the bodies and signatures of term defs, the types of constructor fields in type defs,
* and the kinds of typedef parameters.
* */
export type NodeData =
| {
Expand All @@ -148,6 +149,10 @@ export type NodeData =
tag: "typeDefFieldNode";
con: GlobalName;
index: number;
}
| {
tag: "typeDefParamKindNode";
name: string;
};

/** Node properties. */
Expand Down
103 changes: 76 additions & 27 deletions src/components/TreeReactFlow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ const makeSelectionFromNode = (
def: node.data.def,
node: {
tag: "TypeDefParamNodeSelection",
contents: node.data.name,
contents: { param: node.data.name },
},
},
};
Expand Down Expand Up @@ -763,31 +763,46 @@ const makeSelectionFromNodeData = (
const id = Number(id0);
// Non-numeric IDs correspond to non-selectable nodes (those with no ID in backend) e.g. pattern constructors.
if (!isNaN(id)) {
if (nodeData.tag == "termDefNode") {
return {
tag: "SelectionDef",
contents: {
def,
node: { meta: id, nodeType: nodeData.nodeType },
},
};
} else {
return {
tag: "SelectionTypeDef",
contents: {
def,
node: {
tag: "TypeDefConsNodeSelection",
contents: {
con: nodeData.con,
field: {
index: nodeData.index,
meta: id,
switch (nodeData.tag) {
case "termDefNode":
return {
tag: "SelectionDef",
contents: {
def,
node: { meta: id, nodeType: nodeData.nodeType },
},
};
case "typeDefFieldNode":
return {
tag: "SelectionTypeDef",
contents: {
def,
node: {
tag: "TypeDefConsNodeSelection",
contents: {
con: nodeData.con,
field: {
index: nodeData.index,
meta: id,
},
},
},
},
},
};
};
case "typeDefParamKindNode":
return {
tag: "SelectionTypeDef",
contents: {
def,
node: {
tag: "TypeDefParamNodeSelection",
contents: {
param: nodeData.name,
kindMeta: id,
},
},
},
};
}
} else {
return undefined;
Expand Down Expand Up @@ -877,10 +892,35 @@ const typeDefToTree = async (
type E = PrimerEdge;
type T = Tree<N, E>;

const paramKindTrees = await Promise.all(
def.params.map(({ name, kind }) =>
augmentTree(kind, (n0) =>
makePrimerNode(
n0,
p,
p.layout,
0,
{ tag: "typeDefParamKindNode", name },
def.name
).then(([n, e, nested]) => [
primerNodeWith(n, {
def: def.name,
nested: nested.map((g) =>
graphMap(g, ({ position, ...n }) => ({
...primerNodeWith(n, { def: def.name }),
position,
}))
),
}),
e,
])
).then((kind) => ({ name, kind }))
)
);
const rootId = typeDefNameToNodeId(def.name.baseName);
const paramsTree = def.params.reduceRight<
const paramsTree = paramKindTrees.reduceRight<
[T, (parentId: string) => E] | undefined
>((child, name) => {
>((child, { name, kind }) => {
const id =
"typedef-param-" + JSON.stringify({ def: def.name.baseName, name });
const node: N = {
Expand All @@ -898,17 +938,26 @@ const typeDefToTree = async (
def: def.name,
node: {
tag: "TypeDefParamNodeSelection",
contents: name,
contents: { param: name },
},
},
}),
},
zIndex: 0,
};
const kindEdge: E = {
id: JSON.stringify([id, kind.node.id]),
source: id,
target: kind.node.id,
sourceHandle: Position.Bottom,
targetHandle: Position.Top,
zIndex: 0,
type: "primer-def",
};
return [
{
node,
childTrees: [],
childTrees: [[kind, kindEdge]],
...(child
? { rightChild: mapSnd((f: (parentId: string) => E) => f(id))(child) }
: {}),
Expand Down
2 changes: 2 additions & 0 deletions src/primer-api/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,13 @@ export * from './typeDefNodeSelectionOneOf';
export * from './typeDefNodeSelectionOneOfTag';
export * from './typeDefNodeSelectionOneOfThree';
export * from './typeDefNodeSelectionOneOfThreeTag';
export * from './typeDefParamSelection';
export * from './typeDefSelection';
export * from './typeOrKind';
export * from './typeOrKindOneOf';
export * from './typeOrKindOneOfTag';
export * from './typeOrKindOneOfThree';
export * from './typeOrKindOneOfThreeTag';
export * from './typeParam';
export * from './uuid';
export * from './valCon';
3 changes: 3 additions & 0 deletions src/primer-api/model/noInputAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@ export const NoInputAction = {
AddConField: 'AddConField',
DeleteConField: 'DeleteConField',
DeleteTypeParam: 'DeleteTypeParam',
MakeKType: 'MakeKType',
MakeKFun: 'MakeKFun',
DeleteKind: 'DeleteKind',
} as const;
3 changes: 2 additions & 1 deletion src/primer-api/model/typeDef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
*/
import type { ValCon } from './valCon';
import type { GlobalName } from './globalName';
import type { TypeParam } from './typeParam';

export interface TypeDef {
constructors?: ValCon[];
name: GlobalName;
nameHints: string[];
params: string[];
params: TypeParam[];
}
3 changes: 2 additions & 1 deletion src/primer-api/model/typeDefNodeSelectionOneOf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
* A backend service implementing a pedagogic functional programming language.
* OpenAPI spec version: 0.7
*/
import type { TypeDefParamSelection } from './typeDefParamSelection';
import type { TypeDefNodeSelectionOneOfTag } from './typeDefNodeSelectionOneOfTag';

export type TypeDefNodeSelectionOneOf = {
contents: string;
contents: TypeDefParamSelection;
tag: TypeDefNodeSelectionOneOfTag;
};
12 changes: 12 additions & 0 deletions src/primer-api/model/typeDefParamSelection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Generated by orval v6.17.0 🍺
* Do not edit manually.
* Primer backend API
* A backend service implementing a pedagogic functional programming language.
* OpenAPI spec version: 0.7
*/

export interface TypeDefParamSelection {
kindMeta?: number;
param: string;
}
13 changes: 13 additions & 0 deletions src/primer-api/model/typeParam.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Generated by orval v6.17.0 🍺
* Do not edit manually.
* Primer backend API
* A backend service implementing a pedagogic functional programming language.
* OpenAPI spec version: 0.7
*/
import type { Tree } from './tree';

export interface TypeParam {
kind: Tree;
name: string;
}

0 comments on commit 0c52d29

Please sign in to comment.