maestro-roku-bsc-plugin
Version:
Visual studio plugin for maestro brightscript development
205 lines • 9.39 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const brighterscript_1 = require("brighterscript");
const Diagnostics_1 = require("../utils/Diagnostics");
const BindingProperties_1 = require("./BindingProperties");
const BindingType_1 = require("./BindingType");
let callArgsMap = new Map([
[BindingType_1.BindingSendMode.none, 0],
[BindingType_1.BindingSendMode.node, 1],
[BindingType_1.BindingSendMode.value, 1],
[BindingType_1.BindingSendMode.both, 2]
]);
class Binding {
constructor(file) {
this.file = file;
this.isValid = false;
this.isTopBinding = false;
this.isUsingGetterAndSetter = false;
this.properties = new BindingProperties_1.BindingProperties();
}
validate() {
this.isValid = this.validateImpl();
return this.isValid;
}
validateAgainstClass() {
if (this.properties.type === BindingType_1.BindingType.code) {
return true;
}
if (!this.file.bindingClass) {
return false;
}
if (this.properties.sendMode === BindingType_1.BindingSendMode.badlyFormed) {
return false;
}
if (this.properties.sendMode > BindingType_1.BindingSendMode.field) {
let method = this.file.getMethod(this.observerField, brighterscript_1.TokenKind.Public);
if (!(0, brighterscript_1.isClassMethodStatement)(method)) {
(0, Diagnostics_1.addXmlBindingVMFunctionNotFound)(this.file, this);
this.isValid = false;
}
else {
let expectedArgs = callArgsMap.get(this.properties.sendMode);
let maxArgs = method.func.parameters.length;
let minArgs = method.func.parameters.filter((p) => !p.defaultValue).length;
if (expectedArgs < minArgs || expectedArgs > maxArgs) {
(0, Diagnostics_1.addXmlBindingVMFunctionWrongArgCount)(this.file, this, minArgs, maxArgs, expectedArgs);
this.isValid = false;
}
}
}
else if (!this.isUsingGetterAndSetter) {
if (!this.file.getField(this.observerField, brighterscript_1.TokenKind.Public)) {
(0, Diagnostics_1.addXmlBindingVMFieldNotFound)(this.file, this);
this.isValid = false;
}
if (this.file.getMethod(this.observerField)) {
(0, Diagnostics_1.addXmlBindingUsingFunctionAsField)(this.file, this);
}
if (this.isValid && this.properties.type === BindingType_1.BindingType.oneWaySource && !(0, brighterscript_1.isClassFieldStatement)(this.file.getField(this.observerField))) {
(0, Diagnostics_1.addXmlBindingVMFieldRequired)(this.file, this);
this.isValid = false;
}
}
return this.isValid && (this.getBinding ? this.getBinding.validateAgainstClass() : true) && (this.setBinding ? this.setBinding.validateAgainstClass() : true);
}
validateImpl() {
if (this.isUsingGetterAndSetter) {
return this.getBinding.validate() && this.setBinding.validate();
}
else {
if (!this.nodeId) {
this.errorMessage = 'node Id is not defined';
return false;
}
if (!this.nodeField) {
this.errorMessage = 'node field is not defined';
return false;
}
if (!this.observerField && this.properties.type !== BindingType_1.BindingType.code) {
this.errorMessage = 'observer.field is not defined';
return false;
}
if (this.properties.type === BindingType_1.BindingType.static || this.properties.type === BindingType_1.BindingType.code) {
}
if (this.properties.transformFunction && this.properties.type !== BindingType_1.BindingType.oneWaySource) {
this.errorMessage = 'Illegal transform function: You can ony use transform function for vm values that are set on a node.';
return false;
}
if (this.properties.type === BindingType_1.BindingType.code) {
let { diagnostics } = brighterscript_1.Parser.parse(`a=${this.rawValueText}`);
if (diagnostics.length > 0) {
this.errorMessage = `Could not parse inline brightscript code: '${diagnostics[0].message}'`;
return false;
}
}
}
return true;
}
getInitText() {
switch (this.properties.type) {
case BindingType_1.BindingType.oneWaySource:
return this.getOneWaySourceText();
case BindingType_1.BindingType.oneWayTarget:
return this.getOneWayTargetText();
case BindingType_1.BindingType.twoWay:
if (this.isUsingGetterAndSetter) {
return this.getBinding.getOneWaySourceText() + '\n' + this.setBinding.getOneWayTargetText();
}
else {
return this.getOneWaySourceText() + '\n' + this.getOneWayTargetText();
}
case BindingType_1.BindingType.static:
case BindingType_1.BindingType.code:
case BindingType_1.BindingType.invalid:
//not part of init
break;
}
return undefined;
}
getOneWaySourceText() {
return `vm.bindField("${this.observerField}", m.${this.nodeId}, "${this.nodeField}", ${this.properties.fireOnSetText}, ${this.properties.transformFunction || 'invalid'}, ${this.properties.isFiringOnce ? 'true' : 'false'})`;
}
getOneWayTargetText() {
let funcText = this.properties.sendMode === BindingType_1.BindingSendMode.field ? `"${this.observerField}"` : `vm.${this.observerField}`;
return `vm.observeNodeField(m.${this.nodeId}, "${this.nodeField}", ${funcText}, "${this.properties.getModeText()}", ${this.properties.isFiringOnce ? 'true' : 'false'})`;
}
getStaticText() {
let text = '';
if (this.properties.type === BindingType_1.BindingType.code) {
if (this.nodeField === 'fields') {
text += `m.${this.nodeId}.setFields(${this.rawValueText})`;
}
else {
text += `m.${this.nodeId}.${this.nodeField} = ${this.rawValueText}`;
}
}
else if (this.properties.type === BindingType_1.BindingType.static) {
const valueText = this.fullFieldPath.split('.').length > 1
? `mc_getPath(vm,"${this.fullFieldPath}")` : `vm.${this.observerField}`;
if (this.nodeField === 'fields') {
if (this.properties.transformFunction) {
text += `m.${this.nodeId}.setFields(${this.properties.transformFunction}(${valueText}))`;
}
else {
text += `m.${this.nodeId}.setFields(${valueText})`;
}
}
else {
if (this.properties.transformFunction) {
text += `m.${this.nodeId}.${this.nodeField} = ${this.properties.transformFunction}(${valueText})`;
}
else {
text += `m.${this.nodeId}.${this.nodeField} = ${valueText}`;
}
}
}
return text;
}
createBinding(isGet) {
let binding = new Binding(this.file);
binding.isTopBinding = this.isTopBinding;
binding.nodeId = this.nodeId;
binding.nodeField = this.nodeField;
binding.properties.type = isGet ? BindingType_1.BindingType.oneWaySource : BindingType_1.BindingType.oneWayTarget;
binding.range = this.range;
if (isGet) {
this.getBinding = binding;
}
else {
this.setBinding = binding;
}
this.isUsingGetterAndSetter = true;
}
parseObserveField(partText) {
let regex = /([a-z0-8_]*)(\( *(value *,* *node| *value *| *node *)*\))*/gi;
let parts = regex.exec(partText);
this.observerField = parts[1];
this.fullFieldPath = partText;
if (parts.length > 2) {
let callArgs = parts[2] ? parts[2].replace(/ /g, '') : '';
// if (callArgs === '()' || (partText.includes('(') && !partText.endsWith(')'))) {
if (callArgs === '()') {
this.properties.sendMode = BindingType_1.BindingSendMode.none;
}
else if (callArgs === '(value)') {
this.properties.sendMode = BindingType_1.BindingSendMode.value;
}
else if (callArgs === '(node)') {
this.properties.sendMode = BindingType_1.BindingSendMode.node;
}
else if (callArgs === '(value,node)') {
this.properties.sendMode = BindingType_1.BindingSendMode.both;
}
else if (partText.includes('(')) {
//must be corrupt
this.properties.sendMode = BindingType_1.BindingSendMode.badlyFormed;
}
else {
this.properties.sendMode = BindingType_1.BindingSendMode.field;
}
}
}
}
exports.default = Binding;
//# sourceMappingURL=Binding.js.map