From d377e3650dc94a77df427418e72e2c96c7d8d50d Mon Sep 17 00:00:00 2001 From: Martin Vladic Date: Sat, 13 Jul 2024 11:42:07 +0200 Subject: [PATCH] #210 searchForObjectDependencies --- packages/project-editor/core/search.ts | 272 +++++++-------------- packages/project-editor/store/clipboard.ts | 2 +- resources/expression-grammar.pegjs | 4 +- 3 files changed, 89 insertions(+), 189 deletions(-) diff --git a/packages/project-editor/core/search.ts b/packages/project-editor/core/search.ts index cb037730..72ac812f 100644 --- a/packages/project-editor/core/search.ts +++ b/packages/project-editor/core/search.ts @@ -32,7 +32,7 @@ import { visitExpressionNodes } from "project-editor/flow/expression/helper"; import type { - IdentifierExpressionNode, + ExpressionNode, IdentifierType } from "project-editor/flow/expression/node"; @@ -261,11 +261,25 @@ export function* searchForPattern( } } -export function* searchForAllReferences2( +export function* searchForObjectDependencies( projectStore: ProjectStore, root: IEezObject, - withPause: boolean -) { + withPause: boolean, + lookInsideExpressions: boolean +): IterableIterator< + | { kind: "object-reference"; valueObject: EezValueObject } + | { kind: "configuration-reference"; valueObject: EezValueObject } + | { kind: "expression-start"; valueObject: EezValueObject } + | { + kind: "expression-node"; + valueObject: EezValueObject; + node: ExpressionNode; + expressionStartIndex: number; + } + | { kind: "expression-end"; valueObject: EezValueObject } + | { kind: "variable-type"; valueObject: EezValueObject } + | null +> { let v = (withPause ? visitWithPause : visitWithoutPause)(root); while (true) { @@ -307,7 +321,7 @@ export function* searchForAllReferences2( valueObject.propertyInfo.type === PropertyType.ThemedColor ) { yield { - kinde: "object-reference", + kind: "object-reference", valueObject }; } else if ( @@ -315,13 +329,18 @@ export function* searchForAllReferences2( PropertyType.ConfigurationReference ) { yield { - kinde: "configuration-reference", + kind: "configuration-reference", valueObject }; } else if ( valueObject.propertyInfo.expressionType != undefined || flowProperty == "scpi-template-literal" ) { + yield { + kind: "expression-start", + valueObject + }; + const component = getAncestorOfType( valueObject, ProjectEditor.ComponentClass.classInfo @@ -393,11 +412,19 @@ export function* searchForAllReferences2( yield { kind: "expression-node", valueObject, - node + node, + expressionStartIndex: expression.start }; } - } catch (err) {} + } catch (err) { + console.error(err); + } } + + yield { + kind: "expression-end", + valueObject + }; } else if (valueObject.propertyInfo == variableTypeProperty) { yield { kind: "variable-type", @@ -424,7 +451,6 @@ export function* searchForReference( let identifierType: IdentifierType | undefined; let structType: ValueType | undefined; let enumType: ValueType | undefined; - if (object instanceof ProjectEditor.VariableClass) { let flow = getAncestorOfType(object, ProjectEditor.FlowClass.classInfo); if (flow) { @@ -464,15 +490,10 @@ export function* searchForReference( identifierType = "imported-project"; } - let v = (withPause ? visitWithPause : visitWithoutPause)(root); - let objectName; let objectParentPath; - const classInfo = getClassInfo(object); - let importedProject; - if (classInfo.getImportedProject) { importedProject = classInfo.getImportedProject(object); if (!importedProject) { @@ -500,46 +521,25 @@ export function* searchForReference( } } + let v = searchForObjectDependencies( + project._store, + root, + withPause, + identifierType != undefined || structType != undefined + ); while (true) { let visitResult = v.next(); if (visitResult.done) { return; } - let valueObject = visitResult.value; - if (valueObject) { - if ( - !isPropertySearchable( - getParent(valueObject), - valueObject.propertyInfo - ) || - !valueObject.value - ) { - continue; - } - + let dependency = visitResult.value; + if (dependency) { let match = false; - let flowProperty; - if (valueObject.propertyInfo.flowProperty) { - if (typeof valueObject.propertyInfo.flowProperty == "string") { - flowProperty = valueObject.propertyInfo.flowProperty; - } else { - flowProperty = valueObject.propertyInfo.flowProperty( - getParent(valueObject) - ); - } - } + const valueObject = dependency.valueObject; - if ( - (valueObject.propertyInfo.type === - PropertyType.ObjectReference && - (!project.projectTypeTraits.hasFlowSupport || - valueObject.propertyInfo - .referencedObjectCollectionPath != - "variables/globalVariables")) || - valueObject.propertyInfo.type === PropertyType.ThemedColor - ) { + if (dependency.kind == "object-reference") { if (importedProject) { if ( valueObject.propertyInfo.referencedObjectCollectionPath @@ -577,10 +577,7 @@ export function* searchForReference( } } } - } else if ( - valueObject.propertyInfo.type === - PropertyType.ConfigurationReference - ) { + } else if (dependency.kind == "configuration-reference") { if ( valueObject.propertyInfo.referencedObjectCollectionPath == objectParentPath && @@ -593,148 +590,49 @@ export function* searchForReference( } } } - } else if ( - valueObject.propertyInfo.expressionType != undefined || - flowProperty == "scpi-template-literal" - ) { - if (identifierType || structType) { - const component = getAncestorOfType( - valueObject, - ProjectEditor.ComponentClass.classInfo - ); - let expressions; - - if (flowProperty && flowProperty == "template-literal") { - expressions = templateLiteralToExpressions( - valueObject.value - ).map(expression => ({ - start: expression.start + 1, - end: expression.end - 1 - })); - } else if ( - flowProperty && - flowProperty == "scpi-template-literal" - ) { - expressions = []; - - try { - const parts = parseScpi(valueObject.value); - for (const part of parts) { - const tag = part.tag; - const str = part.value!; + } else if (dependency.kind == "expression-start") { + valueObject.foundPositions = []; + } else if (dependency.kind == "expression-node") { + const node = dependency.node; - if (tag == SCPI_PART_EXPR) { - expressions.push({ - start: part.token.offset + 1, - end: part.token.offset + str.length - 1 - }); - } else if ( - tag == SCPI_PART_QUERY_WITH_ASSIGNMENT - ) { - if (str[0] == "{") { - expressions.push({ - start: part.token.offset + 1, - end: - part.token.offset + - str.length - - 1 - }); - } else { - expressions.push({ - start: part.token.offset, - end: part.token.offset + str.length - }); - } - } - } - } catch (err) { - expressions = []; - } - } else { - expressions = [ - { start: 0, end: valueObject.value.length } - ]; + if (node.type == "Identifier") { + if ( + node.identifierType === identifierType && + (identifierType != "enum-member" || + node.valueType == enumType) && + node.name == objectName + ) { + valueObject.foundPositions!.push({ + start: + node.location.start.offset + + dependency.expressionStartIndex, + end: + node.location.end.offset + + dependency.expressionStartIndex + }); } - - for (const expression of expressions) { - try { - const rootNode = expressionParser.parse( - valueObject.value.substring( - expression.start, - expression.end - ) - ); - - findValueTypeInExpressionNode( - project, - component, - rootNode, - flowProperty == "assignable" - ); - - const foundExpressionNodes: IdentifierExpressionNode[] = - []; - - for (const node of visitExpressionNodes(rootNode)) { - if (node.type == "Identifier") { - if ( - node.identifierType === - identifierType && - (identifierType != "enum-member" || - node.valueType == enumType) && - node.name == objectName - ) { - node.location.start.offset += - expression.start; - - node.location.end.offset += - expression.start; - - foundExpressionNodes.push(node); - } - } else if (node.type == "MemberExpression") { - if ( - node.object.type == "Identifier" && - node.object.valueType == structType && - node.property.type == "Identifier" && - node.property.name == objectName - ) { - node.property.location.start.offset += - expression.start; - - node.property.location.end.offset += - expression.start; - - foundExpressionNodes.push( - node.property - ); - } - } - } - - if (foundExpressionNodes.length > 0) { - match = true; - - const foundPositions = foundExpressionNodes.map( - node => ({ - start: node.location.start.offset, - end: node.location.end.offset - }) - ); - - if (!valueObject.foundPositions) { - valueObject.foundPositions = foundPositions; - } else { - valueObject.foundPositions = [ - ...valueObject.foundPositions, - ...foundPositions - ]; - } - } - } catch (err) {} + } else if (node.type == "MemberExpression") { + if ( + node.object.type == "Identifier" && + node.object.valueType == structType && + node.property.type == "Identifier" && + node.property.name == objectName + ) { + valueObject.foundPositions!.push({ + start: + node.property.location.start.offset + + dependency.expressionStartIndex, + end: + node.property.location.end.offset + + dependency.expressionStartIndex + }); } } - } else if (valueObject.propertyInfo == variableTypeProperty) { + } else if (dependency.kind == "expression-end") { + if (valueObject.foundPositions!.length > 0) { + match = true; + } + } else if (dependency.kind == "variable-type") { if (object instanceof ProjectEditor.StructureClass) { if (valueObject.value == `struct:${objectName}`) { valueObject.foundPositions = [ diff --git a/packages/project-editor/store/clipboard.ts b/packages/project-editor/store/clipboard.ts index 68e31d70..4304ba06 100644 --- a/packages/project-editor/store/clipboard.ts +++ b/packages/project-editor/store/clipboard.ts @@ -159,7 +159,7 @@ export function getProjectEditorDataFromClipboard( projectStore: ProjectStore ): SerializedData | undefined { let textBuffer = clipboard.readBuffer(CLIPOARD_DATA_ID); - if (textBuffer) { + if (textBuffer && textBuffer.length > 0) { const text = textBuffer.toString("utf-8"); let serializedData = clipboardDataToObject(projectStore, text); if (serializedData) { diff --git a/resources/expression-grammar.pegjs b/resources/expression-grammar.pegjs index d68669bd..dff938f9 100644 --- a/resources/expression-grammar.pegjs +++ b/resources/expression-grammar.pegjs @@ -53,7 +53,9 @@ } Start - = Expression + = __ expr:Expression __ { + return expr; + } // ----- A.1 Lexical Grammar -----