Skip to content

Commit

Permalink
June Fixes (#224)
Browse files Browse the repository at this point in the history
Co-authored-by: Tal Ben-Nun <[email protected]>
  • Loading branch information
phschaad and tbennun authored Jul 5, 2023
1 parent 0449497 commit bfaca06
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 75 deletions.
17 changes: 11 additions & 6 deletions src/components/dace_interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,17 +301,21 @@ implements vscode.WebviewViewProvider {
// We were unable to start and connect to a daemon, show a
// message hinting at a potentially missing DaCe instance.
vscode.window.showErrorMessage(
'Unable to start and connect to DaCe. Do you have it ' +
'installed?',
'Unable to start and connect to DaCe. Do you want to ' +
'retry or open the troubleshooting guide?',
'Retry',
'Install DaCe'
'Troubleshooting'
).then(opt => {
switch (opt) {
case 'Retry':
this.startDaemonInTerminal();
break;
case 'Install DaCe':
vscode.commands.executeCommand('dace.installDace');
case 'Troubleshooting':
vscode.env.openExternal(vscode.Uri.parse(
'https://spcldace.readthedocs.io/en/latest' +
'/setup/installation.html#common-issues-with' +
'-the-visual-studio-code-extension'
));
break;
}
});
Expand Down Expand Up @@ -883,7 +887,8 @@ implements vscode.WebviewViewProvider {
});
}

public async querySdfgMetadata(): Promise<any> {
@ICPCRequest()
public async querySdfgMetadata(): Promise<Record<string, any>> {
return new Promise<any>((resolve, reject) => {
if (this.daemonRunning)
this.sendGetRequest(
Expand Down
57 changes: 34 additions & 23 deletions src/webclients/components/sdfv/properties/properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ export abstract class Property {
return this.target;
}

public setKey(nKey: string): void {
this.key = nKey;
}

}

export class KeyProperty {
Expand All @@ -103,6 +107,7 @@ export class KeyProperty {
*/

private _deleted: boolean = false;
private _connectedProps: Set<Property> = new Set();

constructor(
protected element: any | undefined,
Expand Down Expand Up @@ -143,6 +148,8 @@ export class KeyProperty {
);
delete this.target[this.key];
this.key = res.value;
for (const connectedProp of this.connectedProperties)
connectedProp.setKey(this.key);
}
return res.valueChanged;
}
Expand All @@ -155,6 +162,10 @@ export class KeyProperty {
return this.key;
}

public get connectedProperties(): Set<Property> {
return this._connectedProps;
}

}

export class ValueProperty extends Property {
Expand Down Expand Up @@ -553,29 +564,29 @@ export class DictProperty extends Property {
let valueChanged = false;
this.properties.forEach(prop => {
if ((prop.keyProp || prop.key) && prop.valProp) {
if (prop.keyProp && !prop.keyProp.deleted) {
const keyRes = prop.keyProp.getValue();
let keyVal = keyRes?.value;
if (!keyVal || keyVal === '')
keyVal = prop.key;
if (keyVal !== undefined && keyVal !== '') {
prop.valProp.forEach(vp => {
const valRes = vp.getValue();
const valSubkey = vp.getSubkey();
if (vp.getDatatype() === 'CodeBlock' &&
valSubkey !== undefined) {
// For code properties, we need to write back
// the entire code property structure, including
// language info.
let codeVal = vp.getTarget()[vp.getKey()];
codeVal[valSubkey] = valRes.value;
newDict[keyVal] = codeVal;
} else {
newDict[keyVal] = valRes.value;
}
});
valueChanged = true;
}
let keyRes = undefined;
if (prop.keyProp && !prop.keyProp.deleted)
keyRes = prop.keyProp.getValue();
let keyVal = keyRes?.value;
if (!keyVal || keyVal === '')
keyVal = prop.key;
if (keyVal !== undefined && keyVal !== '') {
prop.valProp.forEach(vp => {
const valRes = vp.getValue();
const valSubkey = vp.getSubkey();
if (vp.getDatatype() === 'CodeBlock' &&
valSubkey !== undefined) {
// For code properties, we need to write back
// the entire code property structure, including
// language info.
let codeVal = vp.getTarget()[vp.getKey()];
codeVal[valSubkey] = valRes.value;
newDict[keyVal] = codeVal;
} else {
newDict[keyVal] = valRes.value;
}
});
valueChanged = true;
}
}
});
Expand Down
134 changes: 96 additions & 38 deletions src/webclients/components/sdfv/utils/attributes_table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
LogicalGroup,
SDFGElement,
sdfg_property_to_string,
State
State,
SDFG
} from '@spcl/sdfv/src';
import { editor as monaco_editor } from 'monaco-editor';
import { Range } from '../../../../types';
Expand Down Expand Up @@ -38,7 +39,16 @@ import {
} from './helpers';
import { ComponentTarget } from '../../../../components/components';

declare const vscode: any;
function updateAttrTable(): void {
// TODO(later): this is an ugly workaround to how the system of filling the
// info bar currently works. It should instead update the information
// _without_ re-rendering everything, but at the moment it is difficult to
// upate all related property keys while making sure none are left over or
// forgotten. Re-rendering the panel takes care of this for now.
const sdfg = VSCodeRenderer.getInstance()?.get_sdfg();
if (sdfg)
VSCodeSDFV.getInstance().fillInfo(new SDFG(sdfg));
}

function getMonacoThemeName() {
switch ($('body').attr('data-vscode-theme-kind')) {
Expand Down Expand Up @@ -246,8 +256,10 @@ export function attrTablePutData(
if (modal.confirmBtn)
modal.confirmBtn.on('click', () => {
const sdfg = VSCodeRenderer.getInstance()?.get_sdfg();
if (prop.update() && !xform && sdfg)
if (prop.update() && !xform && sdfg) {
updateAttrTable();
vscodeWriteGraph(sdfg);
}
modal.modal.modal('hide');
});

Expand Down Expand Up @@ -485,8 +497,10 @@ export function attrTablePutDict(
if (modal.confirmBtn)
modal.confirmBtn.on('click', () => {
const sdfg = VSCodeRenderer.getInstance()?.get_sdfg();
if (prop.update() && !xform && sdfg)
if (prop.update() && !xform && sdfg) {
updateAttrTable();
vscodeWriteGraph(sdfg);
}
modal.modal.modal('hide');
});

Expand Down Expand Up @@ -611,8 +625,10 @@ export function attrTablePutList(
if (modal.confirmBtn)
modal.confirmBtn.on('click', () => {
const sdfg = VSCodeRenderer.getInstance()?.get_sdfg();
if (prop.update() && !xform && sdfg)
if (prop.update() && !xform && sdfg) {
updateAttrTable();
vscodeWriteGraph(sdfg);
}
modal.modal.modal('hide');
});

Expand Down Expand Up @@ -821,8 +837,10 @@ export function attrTablePutRange(
if (modal.confirmBtn)
modal.confirmBtn.on('click', () => {
const sdfg = VSCodeRenderer.getInstance()?.get_sdfg();
if (prop.update() && !xform && sdfg)
if (prop.update() && !xform && sdfg) {
updateAttrTable();
vscodeWriteGraph(sdfg);
}
modal.modal.modal('hide');
});

Expand Down Expand Up @@ -1115,6 +1133,8 @@ export async function attributeTablePutEntry(
}

if (updateOnChange && keyProp && keyProp.getInput() !== undefined) {
for (const vProp of valProp ?? [])
keyProp.connectedProperties.add(vProp);
keyProp.getInput().on('change', () => {
if (keyProp)
keyPropUpdateHandler(keyProp);
Expand Down Expand Up @@ -1502,6 +1522,73 @@ export function appendDataDescriptorTable(
});

VSCodeSDFV.getInstance().getMetaDict().then(metaDict => {
const updateNameListener = (prop: KeyProperty) => {
// When a data container name is changed, update the data container
// and label for all access nodes referencing this data container.
const nVal = prop.getValue();
if (nVal.valueChanged) {
const oldDescriptor = prop.getKey();
const newDescriptor = nVal.value;

doForAllNodeTypes(
sdfg, 'AccessNode', (accessNode: JsonSDFGNode) => {
if (accessNode.attributes?.data ===
oldDescriptor) {
accessNode.attributes.data = newDescriptor;
accessNode.label = newDescriptor;
}
}, false
);

prop.update();

// Write back the change - this is necessary since we're
// overwriting the default handler which writes changes back
// when update-on-value-change is enabled.
const wholeSdfg =
VSCodeRenderer.getInstance()?.get_sdfg();
if (wholeSdfg)
vscodeWriteGraph(wholeSdfg);
}
};

const updateContainerListener = (prop: Property) => {
// If this is the data container type property, ensure that the data
// container attributes are updated accordingly (i.e., remove
// obsolete ones, add default values for new ones).
const sdfg = VSCodeRenderer.getInstance()?.get_sdfg();
if (!sdfg)
return;

if (prop.getSubkey() === 'type') {
const attrs = descriptors[prop.getKey()]['attributes'];
const nType = prop.getValue().value;
const nMeta = metaDict[nType];
const nMetaKeys = Object.keys(nMeta);
const oldKeys = Object.keys(attrs);

// Remove obsolete ones.
for (const existing of oldKeys) {
if (!nMetaKeys.includes(existing))
delete attrs[existing];
}

// Add the default values for any new ones.
for (const newKey of nMetaKeys) {
if (newKey === 'debuginfo' || newKey === 'metatype')
continue;
if (!oldKeys.includes(newKey))
attrs[newKey] = nMeta[newKey].default;
}

if (prop.getValue().valueChanged)
updateAttrTable();
}

if (prop.update())
vscodeWriteGraph(sdfg);
};

for (const descriptor in descriptors) {
const val = descriptors[descriptor];

Expand All @@ -1516,37 +1603,8 @@ export function appendDataDescriptorTable(
}).appendTo(attrTable);
attributeTablePutEntry(
descriptor, val, attrMeta, descriptors, undefined,
undefined, row, true, true, true,
(prop: KeyProperty) => {
// When a data container name is changed, update the data
// container and label for all access nodes referencing this
// data container.
const nVal = prop.getValue();
if (nVal.valueChanged) {
const oldDescriptor = prop.getKey();
const newDescriptor = nVal.value;

doForAllNodeTypes(
sdfg, 'AccessNode', (accessNode: JsonSDFGNode) => {
if (accessNode.attributes?.data ===
oldDescriptor) {
accessNode.attributes.data = newDescriptor;
accessNode.label = newDescriptor;
}
}, false
);

prop.update();

// Write back the change - this is necessary since we're
// overwriting the default handler which writes changes
// back when update-on-value-change is enabled.
const wholeSdfg =
VSCodeRenderer.getInstance()?.get_sdfg();
if (wholeSdfg)
vscodeWriteGraph(wholeSdfg);
}
}, undefined, true
undefined, row, true, true, true, updateNameListener,
updateContainerListener, true
).then(res => {
if (res.deleteBtn)
res.deleteBtn.on('click', () => {
Expand Down Expand Up @@ -1612,7 +1670,7 @@ export function appendDataDescriptorTable(
attributeTablePutEntry(
nameVal, defaultValues, newMetaType, descriptors,
undefined, undefined, row, true, true, true,
undefined, undefined, true
updateNameListener, updateContainerListener, true
).then(newProp => {
if (newProp) {
if (newProp.deleteBtn)
Expand Down
26 changes: 18 additions & 8 deletions src/webclients/components/sdfv/vscode_sdfv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export class VSCodeSDFV extends SDFV {
private monaco: any | null = null;
private origSDFG: JsonSDFG | null = null;
private sdfgMetaDict: { [key: string]: any } | null = null;
private queryMetaDictFunc: Promise<{ [key: string]: any }> | null= null;
private queryMetaDictFunc: Promise<Record<string, any>> | null= null;
private viewingHistoryState: boolean = false;
private viewingHistoryIndex: number | undefined = undefined;
private viewingCompressed: boolean = false;
Expand Down Expand Up @@ -946,17 +946,27 @@ export class VSCodeSDFV extends SDFV {
return this.monaco;
}

public async getMetaDict(): Promise<{ [key: string]: any }> {
public async getMetaDict(): Promise<Record<string, any>> {
if (!this.sdfgMetaDict) {
// If SDFG property metadata isn't available, use the static one and
// query an up-to-date one from the dace github page. If that
// doesn't work, query the daemon (waking it up if it isn't up).
if (!this.queryMetaDictFunc)
this.queryMetaDictFunc = fetch(
'https://spcl.github.io/dace/metadata/sdfg_meta_dict.json'
).then(
(response) => response.json()
);
if (!this.queryMetaDictFunc) {
this.queryMetaDictFunc = new Promise((resolve) => {
SDFVComponent.getInstance().invoke(
'querySdfgMetadata', undefined, ComponentTarget.DaCe
).then((metaDict: Record<string, any>) => {
resolve(metaDict);
}).catch(() => {
fetch(
'https://spcl.github.io/dace/metadata/' +
'sdfg_meta_dict.json'
).then((response) => {
resolve(response.json());
});
});
});
}

return this.queryMetaDictFunc.then((data) => {
this.sdfgMetaDict = data;
Expand Down

0 comments on commit bfaca06

Please sign in to comment.