Skip to content
This repository has been archived by the owner on Jun 15, 2021. It is now read-only.

Commit

Permalink
chore: bound values carry closer syntax (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
OmarTawfik committed Mar 12, 2019
1 parent 73ba6aa commit 1e82159
Show file tree
Hide file tree
Showing 10 changed files with 298 additions and 222 deletions.
128 changes: 67 additions & 61 deletions src/binding/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import {
VersionSyntax,
BlockSyntax,
SyntaxKind,
BaseValueSyntax,
StringValueSyntax,
StringArrayValueSyntax,
ObjectValueSyntax,
BasePropertySyntax,
StringPropertySyntax,
ArrayPropertySyntax,
ObjectPropertySyntax,
} from "../parsing/syntax-nodes";
import {
BoundDocument,
Expand All @@ -26,6 +26,8 @@ import {
BoundEnv,
BoundSecrets,
BoundUses,
BoundStringValue,
BoundObjectMember,
} from "./bound-nodes";
import { TokenKind } from "../scanning/tokens";
import { MAXIMUM_SUPPORTED_VERSION } from "../util/constants";
Expand Down Expand Up @@ -92,15 +94,15 @@ export function bindDocument(root: DocumentSyntax, bag: DiagnosticBag): BoundDoc
if (on) {
bag.propertyAlreadyDefined(property.key);
} else {
on = new BoundOn(bindString(property.value), property);
on = new BoundOn(bindString(property), property);
}
break;
}
case TokenKind.ResolvesKeyword: {
if (resolves) {
bag.propertyAlreadyDefined(property.key);
} else {
resolves = new BoundResolves(bindStringOrArray(property.value), property);
resolves = new BoundResolves(bindStringOrArray(property), property);
}
break;
}
Expand Down Expand Up @@ -131,42 +133,42 @@ export function bindDocument(root: DocumentSyntax, bag: DiagnosticBag): BoundDoc
if (uses) {
bag.propertyAlreadyDefined(property.key);
} else {
uses = new BoundUses(bindString(property.value), property);
uses = new BoundUses(bindString(property), property);
}
break;
}
case TokenKind.NeedsKeyword: {
if (needs) {
bag.propertyAlreadyDefined(property.key);
} else {
needs = new BoundNeeds(bindStringOrArray(property.value), property);
needs = new BoundNeeds(bindStringOrArray(property), property);
}
break;
}
case TokenKind.RunsKeyword: {
if (runs) {
bag.propertyAlreadyDefined(property.key);
} else {
runs = new BoundRuns(bindStringOrArray(property.value), property);
runs = new BoundRuns(bindStringOrArray(property), property);
}
break;
}
case TokenKind.ArgsKeyword: {
if (args) {
bag.propertyAlreadyDefined(property.key);
} else {
args = new BoundArgs(bindStringOrArray(property.value), property);
args = new BoundArgs(bindStringOrArray(property), property);
}
break;
}
case TokenKind.EnvKeyword: {
if (env) {
bag.propertyAlreadyDefined(property.key);
} else {
env = new BoundEnv(bindObject(property.value), property);
for (const variable of env.variables.keys()) {
if (variable.startsWith("GITHUB_")) {
bag.reservedEnvironmentVariable(property.key.range);
env = new BoundEnv(bindObject(property), property);
for (const variable of env.variables) {
if (variable.name.startsWith("GITHUB_")) {
bag.reservedEnvironmentVariable(variable.syntax.name.range);
}
}
}
Expand All @@ -176,7 +178,7 @@ export function bindDocument(root: DocumentSyntax, bag: DiagnosticBag): BoundDoc
if (secrets) {
bag.propertyAlreadyDefined(property.key);
} else {
secrets = new BoundSecrets(bindStringOrArray(property.value), property);
secrets = new BoundSecrets(bindStringOrArray(property), property);
}
break;
}
Expand All @@ -193,43 +195,55 @@ export function bindDocument(root: DocumentSyntax, bag: DiagnosticBag): BoundDoc
actions.push(new BoundAction(removeDoubleQuotes(syntax.name.text), uses, needs, runs, args, env, secrets, syntax));
}

function bindString(syntax: BaseValueSyntax | undefined): string {
function bindString(syntax: BasePropertySyntax | undefined): BoundStringValue | undefined {
if (!syntax) {
return "";
return undefined;
}

switch (syntax.kind) {
case SyntaxKind.StringValue: {
return removeDoubleQuotes((syntax as StringValueSyntax).value.text);
case SyntaxKind.StringProperty: {
const property = syntax as StringPropertySyntax;
if (property.value) {
const value = removeDoubleQuotes(property.value.text);
return new BoundStringValue(value, property.value);
}
return undefined;
}
case SyntaxKind.StringArrayValue: {
bag.valueIsNotString((syntax as StringArrayValueSyntax).openBracket.range);
return "";
case SyntaxKind.ArrayProperty: {
bag.valueIsNotString(syntax.key.range);
return undefined;
}
case SyntaxKind.ObjectValue: {
bag.valueIsNotString((syntax as ObjectValueSyntax).openBracket.range);
return "";
case SyntaxKind.ObjectProperty: {
bag.valueIsNotString(syntax.key.range);
return undefined;
}
default: {
throw new Error(`Unexpected Syntax kind '${syntax.kind}'`);
}
}
}

function bindStringOrArray(syntax: BaseValueSyntax | undefined): ReadonlyArray<string> {
function bindStringOrArray(syntax: BasePropertySyntax | undefined): ReadonlyArray<BoundStringValue> {
if (!syntax) {
return [];
}

switch (syntax.kind) {
case SyntaxKind.StringValue: {
return [removeDoubleQuotes((syntax as StringValueSyntax).value.text)];
case SyntaxKind.StringProperty: {
const property = syntax as StringPropertySyntax;
if (property.value) {
const value = removeDoubleQuotes(property.value.text);
return [new BoundStringValue(value, property.value)];
}
return [];
}
case SyntaxKind.StringArrayValue: {
return (syntax as StringArrayValueSyntax).values.map(v => removeDoubleQuotes(v.value.text));
case SyntaxKind.ArrayProperty: {
return (syntax as ArrayPropertySyntax).items.map(
item => new BoundStringValue(removeDoubleQuotes(item.value.text), item.value),
);
}
case SyntaxKind.ObjectValue: {
bag.valueIsNotStringOrArray((syntax as ObjectValueSyntax).openBracket.range);
case SyntaxKind.ObjectProperty: {
bag.valueIsNotStringOrArray(syntax.key.range);
return [];
}
default: {
Expand All @@ -238,37 +252,29 @@ export function bindDocument(root: DocumentSyntax, bag: DiagnosticBag): BoundDoc
}
}

function bindObject(syntax: BaseValueSyntax | undefined): ReadonlyMap<string, string> {
const map = new Map<string, string>();
if (syntax) {
switch (syntax.kind) {
case SyntaxKind.StringValue: {
bag.valueIsNotAnObject((syntax as StringValueSyntax).value.range);
break;
}
case SyntaxKind.StringArrayValue: {
bag.valueIsNotAnObject((syntax as StringArrayValueSyntax).openBracket.range);
break;
}
case SyntaxKind.ObjectValue: {
(syntax as ObjectValueSyntax).members.forEach(variable => {
const key = variable.name.text;
if (map.has(key)) {
bag.duplicateKey(key, variable.name.range);
} else {
const value = removeDoubleQuotes(variable.value.text);
map.set(key, value);
}
});
break;
}
default: {
throw new Error(`Unexpected Syntax kind '${syntax.kind}'`);
}
}
function bindObject(syntax: BasePropertySyntax | undefined): ReadonlyArray<BoundObjectMember> {
if (!syntax) {
return [];
}

return map;
switch (syntax.kind) {
case SyntaxKind.StringProperty: {
bag.valueIsNotAnObject(syntax.key.range);
return [];
}
case SyntaxKind.ArrayProperty: {
bag.valueIsNotAnObject(syntax.key.range);
return [];
}
case SyntaxKind.ObjectProperty: {
return (syntax as ObjectPropertySyntax).members.map(
member => new BoundObjectMember(member.name.text, removeDoubleQuotes(member.value.text), member),
);
}
default: {
throw new Error(`Unexpected Syntax kind '${syntax.kind}'`);
}
}
}

function removeDoubleQuotes(value: string): string {
Expand Down
21 changes: 18 additions & 3 deletions src/binding/bound-node-visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ import {
BoundArgs,
BoundEnv,
BoundSecrets,
BoundStringValue,
BoundObjectMember,
} from "./bound-nodes";
import { BaseSyntaxNode } from "../parsing/syntax-nodes";

export abstract class BoundNodeVisitor {
protected visit(node: BaseBoundNode<BaseSyntaxNode>): void {
protected visit(node: BaseBoundNode): void {
switch (node.kind) {
case BoundKind.Document: {
return this.visitDocument(node as BoundDocument);
Expand Down Expand Up @@ -59,6 +60,12 @@ export abstract class BoundNodeVisitor {
case BoundKind.Secrets: {
return this.visitSecrets(node as BoundSecrets);
}
case BoundKind.StringValue: {
return this.visitStringValue(node as BoundStringValue);
}
case BoundKind.ObjectMember: {
return this.visitObjectMember(node as BoundObjectMember);
}
default: {
throw new Error(`Unexpected bound kind: '${node.kind}'`);
}
Expand Down Expand Up @@ -113,7 +120,15 @@ export abstract class BoundNodeVisitor {
return this.visitDefault(node);
}

private visitDefault(node: BaseBoundNode<BaseSyntaxNode>): void {
protected visitStringValue(node: BoundStringValue): void {
return this.visitDefault(node);
}

protected visitObjectMember(node: BoundObjectMember): void {
return this.visitDefault(node);
}

private visitDefault(node: BaseBoundNode): void {
node.children.forEach(child => {
this.visit(child);
});
Expand Down
Loading

0 comments on commit 1e82159

Please sign in to comment.