Open lan-lyu opened 1 year ago
Should the tree be simple
spec ___ mark
|___ data
|___ encode ____ x
|____ y
|____ color
or having reference types as leaves, and creating methods for these reference types?
spec ___ mark
|___ data
|___ encode ____ x ____ position
|____ y ____ position
|____ color ____ field
|____ value
If using the latter one, the final output will be like this
class Color extends BaseObject{
// constructor(private field?: string, private type?: "quantitative" | "ordinal", private value?: string) {}
constructor(...args) {
super();
init(this);
assign(this, ...args);
}
field(field: {field:string, type:"quantitative" | "ordinal"} | string ){
if (arguments.length) {
const obj = copy(this);
set(obj, "color", field);
return obj;
} else {
return get(this, "color");
}
}
}
Code Structure
Statements[]
Statements[]
into the Internal Representation, replace type reference with exact typesInput & Output Example
For each step, the example input and output are:
step 1
input:
output:
step 2
build a tree that the root node is Spec
output is a tree like this
At the same time, replace the TypeReference with the exact type based on
children
of thestatement
. For example: turn mark's member into "type: bar | area | line | { bar| area | line}" input (statement we have in step 1)output (mark object in the tree)
step 3
Traverse the tree and generate classes and functions
generate "class Spec" and "export function spec"
mark, data, encode, x, y, color
toSpec and toJSON
need to add method chaining
}
export function spec(mark: Mark, data: string, encode: Encoding){ return new Spec(mark, data, encode); }
class Mark { constructor(private type: "bar" | "area" | "line" | { type: "bar" | "area" | "line"}) {}
}
export function mark(type: "bar" | "area" | "line" | { type: "bar" | "area" | "line"}){ return new Mark(type); }
class Data { constructor(private type: string) {}
}
export function data(type: string) { return new Data(type); }
class X { constructor(private field?: string, private type?: "quantitative" | "ordinal") {}
}
export function x(field?: string, type?: "quantitative" | "ordinal"){ return new X(field, type); }
class Y { constructor(private field?: string, private type?: "quantitative" | "ordinal") {}
}
export function y(field?: string, type?: "quantitative" | "ordinal"){ return new Y(field, type); }
// TODO: optimize the color argument class Color { constructor(private field?: string, private type?: "quantitative" | "ordinal", private value?: string) {}
}
export function color(field?: string, type?: "quantitative" | "ordinal", value?: string){ return new Color(field, type, value); }
class Encoding { constructor(private x?: X, private y?: Y, private color?: Color) {}
}
export function encode(x?: X, y?: Y, color?: Color){ return new Encoding(x, y, color); }
export function toSpec(obj: any){ return obj; }
export function toJSON(obj: any){ return JSON.stringify(obj); }