Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { BackendTypeRole } from "visualiser-debugger/Types/annotationType";
import { LinkedListNodeAnnotation } from "./LinkedListAnnotation";
import { assertUnreachable } from "visualiser-debugger/Component/Visualizer/Util/util";
import { TypeAnnotationProp } from "../TypeAnnotation";
import { TreeNodeAnnotation } from "./BinaryTreeAnnotation";
export function AnnotationFactory (backendRole: BackendTypeRole, {
typeDeclaration,
}: TypeAnnotationProp) : JSX.Element | null {
switch(backendRole){
case BackendTypeRole.LinkedList:
return <LinkedListNodeAnnotation backendType={typeDeclaration} />
case BackendTypeRole.BinaryTree:
return <TreeNodeAnnotation backendType={typeDeclaration} />
case BackendTypeRole.Empty:
return null;
default:
assertUnreachable(backendRole);
}
return null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import { BackendTypeDeclaration, isNativeTypeName, isPointerType, isStructTypeName } from 'visualiser-debugger/Types/backendType';
import styles from 'styles/Configuration.module.css';
import * as RadioGroup from '@radix-ui/react-radio-group';
import { BinaryTreeAnnotation, DataStructureType, PossibleBinaryTreeAnnotation } from '../../../Types/annotationType';
import { AnnotationComponent, AnnotationProp } from './AnnotationComponentBase';
import { useEffect, useState } from 'react';
import { useGlobalStore } from 'visualiser-debugger/Store/globalStateStore';
import ConfigurationSelect from '../ConfigurationSelect';

export const createPossibleTreeTypeDecl = (
typeDecl: BackendTypeDeclaration
) : PossibleBinaryTreeAnnotation | null => {
if (!('fields' in typeDecl)) {
return null;
}

if (!isStructTypeName(typeDecl.typeName)) {
return null;
}

const possibleTypeDecl: PossibleBinaryTreeAnnotation = {
typeName: typeDecl.typeName,
possibleValues: [],
possibleLefts: [],
possibleRights: [],
};
if (typeDecl.fields === undefined) {
return null;
}
typeDecl.fields.forEach((field) => {
if (isNativeTypeName(field.typeName)) {
possibleTypeDecl.possibleValues.push({
name: field.name,
typeName: field.typeName,
});
}
if (
isPointerType(field.typeName) &&
isStructTypeName(field.typeName.slice(0, -1)) &&
field.name.includes('left')
) {
possibleTypeDecl.possibleLefts.push({
name: field.name,
typeName: field.typeName,
});
}
if (
isPointerType(field.typeName) &&
isStructTypeName(field.typeName.slice(0, -1)) &&
field.name.includes('right')
) {
possibleTypeDecl.possibleRights.push({
name: field.name,
typeName: field.typeName,
});
}
});

if (
possibleTypeDecl.possibleValues.length >= 1 &&
possibleTypeDecl.possibleLefts.length >= 1 &&
possibleTypeDecl.possibleRights.length >= 1
) {
return possibleTypeDecl;
}
return null;
}

export const TreeNodeAnnotation: AnnotationComponent = ({ backendType }: AnnotationProp) => {
const [possibleTypeDeclForTree, setPossibleTypeDeclForTree] =
useState<PossibleBinaryTreeAnnotation | null>(createPossibleTreeTypeDecl(backendType));
const { updateUserAnnotation, visualizer } = useGlobalStore();
const [nodeAnnotation, setNodeAnnotation] = useState<BinaryTreeAnnotation | null>(null);
const handleUpdateNodeAnnotation = (newAnnotation: BinaryTreeAnnotation) => {
updateUserAnnotation({
stackAnnotation: visualizer.userAnnotation.stackAnnotation,
typeAnnotation: {
...visualizer.userAnnotation.typeAnnotation,
[backendType.typeName]: newAnnotation,
},
});
}
const handleTreeNodeAnnotation = (possibleTypeAnnotation: PossibleBinaryTreeAnnotation | null) => {
if (possibleTypeAnnotation === null) return;
setPossibleTypeDeclForTree(possibleTypeAnnotation);
const newAnnotation: BinaryTreeAnnotation = {
typeName: backendType.typeName as `struct ${string}`,
type: DataStructureType.BinaryTree,
value: {
name: possibleTypeAnnotation.possibleValues[0].name,
typeName: possibleTypeAnnotation.possibleValues[0].typeName,
},
left: {
name: possibleTypeAnnotation.possibleLefts[0].name,
typeName: possibleTypeAnnotation.possibleLefts[0].typeName,
},
right: {
name: possibleTypeAnnotation.possibleRights[0].name,
typeName: possibleTypeAnnotation.possibleRights[0].typeName,
},

}
setNodeAnnotation(newAnnotation);
handleUpdateNodeAnnotation(newAnnotation);
}

useEffect(() => {
handleTreeNodeAnnotation(possibleTypeDeclForTree);
} , [possibleTypeDeclForTree]);

useEffect(() => {
const possibleTypeDecls = createPossibleTreeTypeDecl(backendType);
setPossibleTypeDeclForTree(possibleTypeDecls);
}, [backendType]);

const handleUpdateNodeData = (newNodeData: string, newNodeDataType: string) => {
if (isNativeTypeName(newNodeDataType)) {
const newAnnotation: BinaryTreeAnnotation = {
...nodeAnnotation,
value: {
name: newNodeData,
typeName: newNodeDataType,
},
} as BinaryTreeAnnotation;
setNodeAnnotation(newAnnotation);
handleUpdateNodeAnnotation(newAnnotation);
}
};

const handleUpdateLeftData = (newLeftData: string, newLeftDataType: string) => {
if (isPointerType(newLeftDataType) && isStructTypeName(newLeftDataType.slice(0, -1))) {
const newAnnotation: BinaryTreeAnnotation = {
...nodeAnnotation,
left: {
name: newLeftData,
typeName: newLeftDataType,
},
} as BinaryTreeAnnotation;
setNodeAnnotation(newAnnotation);
handleUpdateNodeAnnotation(newAnnotation);
}
}

const handleUpdateRightData = (newRightData: string, newRightDataType: string) => {
if (isPointerType(newRightDataType) && isStructTypeName(newRightDataType.slice(0, -1))) {
const newAnnotation: BinaryTreeAnnotation = {
...nodeAnnotation,
right: {
name: newRightData,
typeName: newRightDataType,
},
} as BinaryTreeAnnotation;
setNodeAnnotation(newAnnotation);
handleUpdateNodeAnnotation(newAnnotation);
}
}

if (!possibleTypeDeclForTree) {
return (
<div className={styles.configuratorField}>
<span>
<span className={styles.highlightError}>Error:</span> No possible{' '}
{/* where is the styles.highlightLinkedList */}
<span className={styles.highlightLinkedList}>binary tree</span> annotation can be made.
</span>
</div>
);
}
return (
<div style={{ paddingTop: '10px', fontSize: '0.8rem' }}>
<RadioGroup.Root className={styles.RadioGroupRoot} value="Stub">
<div className={styles.configuratorField}>
<span>Node Data</span>
<ConfigurationSelect
fields={possibleTypeDeclForTree.possibleValues}
handleUpdateAnnotation={handleUpdateNodeData}
/>
</div>

<div className={styles.configuratorField}>
<span>Left Child</span>
<ConfigurationSelect
fields={possibleTypeDeclForTree.possibleLefts}
handleUpdateAnnotation={handleUpdateLeftData}
/>
</div>
<div className={styles.configuratorField}>
<span>Right Child</span>
<ConfigurationSelect
fields={possibleTypeDeclForTree.possibleRights}
handleUpdateAnnotation={handleUpdateRightData}
/>
</div>
</RadioGroup.Root>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const StackVarAnnotation: React.FC<StackVariableAnnotationProp> = ({

// Annotate by default if the variable contains a pointer
useEffect(() => {
if (selectedRole === StackVariableRole.LinkedListPointer) {
if (selectedRole === StackVariableRole.LinkedListPointer || selectedRole === StackVariableRole.BinaryTreePointer) {
const newStackAnnotation = {
[name]: memoryValue.typeName,
};
Expand Down Expand Up @@ -84,7 +84,7 @@ export const StackVarAnnotation: React.FC<StackVariableAnnotationProp> = ({
type="button"
onClick={() => {
setSelectedRole(role[1]);
if (role[1] === StackVariableRole.LinkedListPointer) {
if (role[1] === StackVariableRole.LinkedListPointer || role[1] === StackVariableRole.BinaryTreePointer) {
updateStackAnnotation({ [name]: memoryValue.typeName });
} else {
updateStackAnnotation({ [name]: null });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import { MotionCollapse } from './MotionCollapse';
import './typeAnnotation.css';
import { BackendTypeRole } from '../../Types/annotationType';
import {
LinkedListNodeAnnotation,
createPossibleLinkedListTypeDecl,
} from './RoleAnnotation/LinkedListAnnotation';
import { BackendTypeDeclaration } from '../../Types/backendType';
import { AnnotationFactory } from './RoleAnnotation/AnnotationFactory';
import { createPossibleTreeTypeDecl } from './RoleAnnotation/BinaryTreeAnnotation';


export type TypeAnnotationProp = {
typeDeclaration: BackendTypeDeclaration;
Expand All @@ -26,8 +28,11 @@ export const TypeAnnotation: React.FC<TypeAnnotationProp> = ({
if (createPossibleLinkedListTypeDecl(typeDeclaration) !== null) {
setSelectedRole(BackendTypeRole.LinkedList);
}
if (createPossibleTreeTypeDecl(typeDeclaration) !== null) {
setSelectedRole(BackendTypeRole.BinaryTree);
}
}, []);

const annotation = AnnotationFactory(selectedRole, {typeDeclaration});
return (
<div style={{ paddingBottom: '8px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
Expand Down Expand Up @@ -95,9 +100,9 @@ export const TypeAnnotation: React.FC<TypeAnnotationProp> = ({
</MotionCollapse>
</div>
</div>

<MotionCollapse isOpen={selectedRole === BackendTypeRole.LinkedList}>
<LinkedListNodeAnnotation backendType={typeDeclaration} />
{/* should this be true??? */}
<MotionCollapse isOpen={true}>
{annotation}
</MotionCollapse>
</div>
);
Expand Down
18 changes: 18 additions & 0 deletions client/src/visualiser-debugger/Types/annotationType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,13 @@ export type PossibleStructAnnotation = {

export enum BackendTypeRole {
LinkedList = 'Linked List Node',
BinaryTree = 'Binary Tree Node',
Empty = 'Not Visualized',
}

export enum StackVariableRole {
LinkedListPointer = 'Linked List Node',
BinaryTreePointer = 'Binary Tree Node',
Empty = 'Not Visualized',
}

Expand All @@ -155,3 +157,19 @@ export type PossibleLinkedListAnnotation = {
typeName: PointerType['typeName'];
}[];
};

export type PossibleBinaryTreeAnnotation = {
typeName: StructType['typeName'];
possibleValues: {
name: Name;
typeName: NativeTypeName;
}[];
possibleLefts: {
name: Name;
typeName: PointerType['typeName'];
}[];
possibleRights: {
name: Name;
typeName: PointerType['typeName'];
}[];
};
Loading