Skip to content

Commit

Permalink
feat: improve variable type subclassing (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
prevwong authored Oct 26, 2023
1 parent 6e9a337 commit ceca2c7
Show file tree
Hide file tree
Showing 18 changed files with 228 additions and 192 deletions.
7 changes: 7 additions & 0 deletions .changeset/fresh-dodos-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@rekajs/parser': patch
'@rekajs/types': patch
'@rekajs/core': patch
---

Improve variables types subclassing
5 changes: 1 addition & 4 deletions packages/core/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,7 @@ export class ComponentViewEvaluator {
if (!this.rekaComponentStateComputation) {
this.rekaComponentStateComputation = computed(() => {
component.state.forEach((val) => {
this.env.set(val.name, {
value: this.evaluator.computeExpr(val.init, this.env),
readonly: false,
});
this.evaluator.computeExpr(val, this.env);
});
});
}
Expand Down
10 changes: 6 additions & 4 deletions packages/core/src/expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,12 @@ export const computeExpression = (
}

if (expr instanceof t.Val) {
const value = computeExpression(expr.init, reka, env, {
...ctx,
untrackIdentifier: true,
});
const value = expr.init
? computeExpression(expr.init, reka, env, {
...ctx,
untrackIdentifier: true,
})
: null;

env.set(expr.name, {
value,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export type ScopeDescription = {
id: string;
};

export type VariableWithScope = {
variable: t.Variable;
export type IdentifiableWithScope = {
identifiable: t.Identifiable;
scope: ScopeDescription;
};
8 changes: 4 additions & 4 deletions packages/core/src/reka.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,12 +317,12 @@ export class Reka {
return this.state;
}

get getVariablesAtNode() {
return this.head.resolver.getVariablesAtNode.bind(this.head.resolver);
get getIdentifiablesAtNode() {
return this.head.resolver.getIdentifiablesAtNode.bind(this.head.resolver);
}

get getVariableFromIdentifier() {
return this.head.resolver.getVariableFromIdentifier.bind(
get getIdentifiableFromIdentifier() {
return this.head.resolver.getIdentifiableFromIdentifier.bind(
this.head.resolver
);
}
Expand Down
102 changes: 53 additions & 49 deletions packages/core/src/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Reka } from './reka';
import {
getKeyFromScopeDescription,
getMaybeScopeDescriptionByNodeOwner,
GetVariablesOpts,
GetIdentifiableOpts,
Scope,
} from './scope';

Expand All @@ -28,8 +28,8 @@ type CachedComponentResolver = {

export class Resolver {
scopeRegistry: Map<string, Scope> = new Map();
identifiersToVariableDistance: Map<string, number>;
identifiersToVariable: Map<t.Identifier, t.Variable>;
identifiersToIdentifiableDistance: Map<string, number>;
identifiersToIdentifiable: Map<t.Identifier, t.Identifiable>;
nodeToScope: Map<t.ASTNode, Scope>;

private scope: Scope;
Expand All @@ -44,8 +44,8 @@ export class Resolver {
constructor(readonly reka: Reka) {
this.scope = new Scope(this, reka.program);

this.identifiersToVariableDistance = new Map();
this.identifiersToVariable = new Map();
this.identifiersToIdentifiableDistance = new Map();
this.identifiersToIdentifiable = new Map();

this.cachedComponentResolver = new WeakMap();
this.cachedTemplateResolver = new WeakMap();
Expand All @@ -62,32 +62,32 @@ export class Resolver {
this.nodeToScope = new Map();

makeObservable(this, {
identifiersToVariableDistance: observable,
identifiersToIdentifiableDistance: observable,
nodeToScope: observable,
});
}

getDistance(identifier: t.Identifier) {
return this.identifiersToVariableDistance.get(identifier.id);
return this.identifiersToIdentifiableDistance.get(identifier.id);
}

getVariablesAtNode(node: t.ASTNode, opts?: GetVariablesOpts) {
getIdentifiablesAtNode(node: t.ASTNode, opts?: GetIdentifiableOpts) {
const scope = this.nodeToScope.get(node);

if (!scope) {
return [];
}

return scope.getVariables(opts);
return scope.getIdentifiables(opts);
}

getVariableFromIdentifier(identifier: t.Identifier) {
return this.identifiersToVariable.get(identifier) || null;
getIdentifiableFromIdentifier(identifier: t.Identifier) {
return this.identifiersToIdentifiable.get(identifier) || null;
}

removeDistance(identifier: t.Identifier) {
runInAction(() => {
this.identifiersToVariableDistance.delete(identifier.id);
this.identifiersToIdentifiableDistance.delete(identifier.id);
});
}

Expand All @@ -97,16 +97,16 @@ export class Resolver {
}

runInAction(() => {
this.identifiersToVariableDistance.set(identifier.id, distance);
this.identifiersToIdentifiableDistance.set(identifier.id, distance);
});
}

private bindIdentifierToVariable(
private bindIdentifierToIdentifiable(
identifier: t.Identifier,
variable: t.Variable
identifiable: t.Identifiable
) {
runInAction(() => {
this.identifiersToVariable.set(identifier, variable);
this.identifiersToIdentifiable.set(identifier, identifiable);
});
}

Expand All @@ -116,9 +116,9 @@ export class Resolver {
});
}

unbindIdentifierToVariable(identifier: t.Identifier) {
unbindIdentifierToIdentifiable(identifier: t.Identifier) {
runInAction(() => {
this.identifiersToVariable.delete(identifier);
this.identifiersToIdentifiable.delete(identifier);
});
}

Expand All @@ -133,25 +133,30 @@ export class Resolver {

if (expr instanceof t.Identifier) {
if (expr.external) {
const externalVariable = this.reka.externals.get(expr.name);
const externalIdentifiable = this.reka.externals.get(expr.name);

if (externalVariable) {
this.bindIdentifierToVariable(expr, externalVariable);
if (externalIdentifiable) {
this.bindIdentifierToIdentifiable(expr, externalIdentifiable);
}

return;
}

const variableWithDistance = scope.getVariableWithDistance(expr.name);
const identifiableWithDistance = scope.getIdentifiableWithDistance(
expr.name
);

if (!variableWithDistance) {
if (!identifiableWithDistance) {
this.setDistance(expr, -1);
this.unbindIdentifierToVariable(expr);
this.unbindIdentifierToIdentifiable(expr);
return;
}

this.setDistance(expr, variableWithDistance.distance);
this.bindIdentifierToVariable(expr, variableWithDistance.variable);
this.setDistance(expr, identifiableWithDistance.distance);
this.bindIdentifierToIdentifiable(
expr,
identifiableWithDistance.identifiable
);
}

// TODO: assignment should be handled as binary expr
Expand Down Expand Up @@ -225,16 +230,11 @@ export class Resolver {
this.bindNodeToScope(component, componentScope);

component.props.forEach((prop) => {
componentScope.defineVariable(prop);
this.bindNodeToScope(prop, componentScope);

if (prop.init) {
this.resolveExpr(prop.init, scope);
}
this.resolveVariable(prop, componentScope);
});

component.state.forEach((state) => {
this.resolveVal(state, componentScope);
this.resolveVariable(state, componentScope);
});

this.resolveTemplate(component.template, componentScope);
Expand All @@ -245,7 +245,7 @@ export class Resolver {
}

cache.computed.get();
scope.defineVariable(component);
scope.defineIdentifiable(component);
}
}

Expand Down Expand Up @@ -273,23 +273,23 @@ export class Resolver {

if (template.each.alias) {
if (eachAliasName && eachAliasName !== template.each.alias.name) {
templateScope.removeVariableByName(eachAliasName);
templateScope.removeIdentifiableByName(eachAliasName);
}

templateScope.defineVariable(template.each.alias);
templateScope.defineIdentifiable(template.each.alias);
eachAliasName = template.each.alias.name;
}

if (template.each.index) {
if (eachIndex && eachIndex !== template.each.index.name) {
templateScope.removeVariableByName(eachIndex);
templateScope.removeIdentifiableByName(eachIndex);
}

eachIndex = template.each.index.name;
templateScope.defineVariable(template.each.index);
templateScope.defineIdentifiable(template.each.index);
} else {
if (eachIndex) {
templateScope.removeVariableByName(eachIndex);
templateScope.removeIdentifiableByName(eachIndex);
eachIndex = null;
}
}
Expand Down Expand Up @@ -321,10 +321,14 @@ export class Resolver {
cache.computed.get();
}

private resolveVal(val: t.Val, scope: Scope) {
this.bindNodeToScope(val, scope);
this.resolveExpr(val.init, scope);
scope.defineVariable(val);
private resolveVariable(variable: t.Variable, scope: Scope) {
this.bindNodeToScope(variable, scope);

if (variable.init) {
this.resolveExpr(variable.init, scope);
}

scope.defineIdentifiable(variable);
}

private resolveProgram() {
Expand All @@ -335,23 +339,23 @@ export class Resolver {
this.bindNodeToScope(program, this.scope);

program.globals.forEach((global) => {
this.resolveVal(global, this.scope);
this.resolveVariable(global, this.scope);
});

program.components.forEach((component) => {
this.scope.defineVariable(component);
this.scope.defineIdentifiable(component);
});

const globalNames = [...program.globals, ...program.components].map(
(globalOrComponent) => globalOrComponent.name
);

this.scope.forEach((variable) => {
if (globalNames.includes(variable.name)) {
this.scope.forEach((identifiable) => {
if (globalNames.includes(identifiable.name)) {
return;
}

this.scope.removeVariableByName(variable.name);
this.scope.removeIdentifiableByName(identifiable.name);
});

program.components.forEach((component) => {
Expand All @@ -370,7 +374,7 @@ export class Resolver {
cleanupDisposedNode(node: t.ASTNode) {
if (node instanceof t.Identifier) {
this.removeDistance(node);
this.unbindIdentifierToVariable(node);
this.unbindIdentifierToIdentifiable(node);
}

this.unbindNodeToScope(node);
Expand Down
Loading

1 comment on commit ceca2c7

@vercel
Copy link

@vercel vercel bot commented on ceca2c7 Oct 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

reka – ./

reka-prevwong.vercel.app
rekajs.vercel.app
reka-git-main-prevwong.vercel.app
reka.js.org

Please sign in to comment.