Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor of reconstruct.ts #484

Closed
wants to merge 111 commits into from
Closed
Changes from 3 commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
a08e74a
wip, doc: Comments for questions in reconstruct.ts
Ehcsan Nov 7, 2023
e367620
wip, refactor: Comments to group parts of reconstruct.ts
Ehcsan Nov 7, 2023
de9289d
Merge branch 'main' into main
Ehcsan Nov 7, 2023
19041f3
wip, refactor: refactor of 'reconstructToCode' into main.ts and seper…
Ehcsan Nov 13, 2023
e5d9a30
typo: corrected typo of reconstruct in reconstruct.ts
Ehcsan Nov 13, 2023
5c90575
wip, refactor: refactor of 'helper functions', as declared in earlier…
Ehcsan Nov 13, 2023
f546c5f
Merge branch 'Code-Inspect:main' into main
Ehcsan Nov 22, 2023
9971485
Merge branch 'Code-Inspect:main' into main
Ehcsan Nov 23, 2023
bda524a
wip, feat: Added parts to PrettyPrintLine
Ehcsan Nov 24, 2023
3006674
Merge branch 'Code-Inspect:main' into main
EagleoutIce Nov 24, 2023
86a2cd1
Merge branch 'main' of https://github.com/Ehcsan/flowr
Ehcsan Nov 24, 2023
5dce5a0
Merge branch 'Code-Inspect:main' into main
Ehcsan Nov 30, 2023
7c64c31
Merge branch 'main' of https://github.com/Ehcsan/flowr
Ehcsan Nov 30, 2023
5995277
feat(reconstruct): lineParts now work with locations
Ehcsan Nov 30, 2023
030edc9
fix(reconstruct): fixed problems the linter gave
Ehcsan Nov 30, 2023
03cbf9e
wip(reconstruct): cleaned up based on suggestions
Ehcsan Dec 1, 2023
329a0af
fix(reconstruct): fixed linter recommendations in helper.ts
Ehcsan Dec 1, 2023
428d7bf
feat: code update during the meeting
EagleoutIce Dec 1, 2023
f33ad56
Merge branch 'Code-Inspect:main' into main
Ehcsan Dec 7, 2023
82552b7
fix(reconstruct): pretty-print-to-string use the result :)
EagleoutIce Dec 8, 2023
f1adaa5
refactor(doc): fix typo (theis->this)
EagleoutIce Dec 8, 2023
36a1df4
feat(delims): limit subtype
EagleoutIce Dec 8, 2023
0446887
refactor(delimiter): improve RDelimiter node type
EagleoutIce Dec 8, 2023
bc156d9
Merge branch 'Code-Inspect:main' into main
Ehcsan Dec 13, 2023
508d152
Merge branch 'Code-Inspect:main' into main
Ehcsan Dec 13, 2023
998a6d3
feat(test): added first tests for plain and merge of reconstruct
Ehcsan Dec 13, 2023
2e2472e
feat-fix(reconstruct): changes that got lost
Ehcsan Dec 13, 2023
0cd9ab2
feat(test): added more cases to merge
Ehcsan Dec 13, 2023
7b9cb5b
refactor(reconstruct, test): minor meeting improvements
EagleoutIce Dec 15, 2023
b70c91d
Merge branch 'main' into main
EagleoutIce Dec 21, 2023
698febf
feat-fix(reconstruct): fixed error with columns
Ehcsan Dec 22, 2023
b9cc3dd
Merge branch 'main' into main
EagleoutIce Dec 22, 2023
624acf2
refactor(merge): fix dirty merge
EagleoutIce Dec 22, 2023
7c0c3c3
feat(reconstruct): work on more sensible reconstructions in for, repe…
EagleoutIce Dec 22, 2023
2897b9b
test-fix(test): fixed for-loop reconstruction
Ehcsan Jan 19, 2024
19ae981
wip: first stage of adding `(`, `in`, and `)` to the output
EagleoutIce Jan 19, 2024
089eb6a
test-fix(reconstruct): while Loop Reconstruction
Ehcsan Jan 24, 2024
2701d40
Merge branch 'main' of https://github.com/Ehcsan/flowr
Ehcsan Jan 24, 2024
a172d2b
lint: linter fixes
Ehcsan Jan 24, 2024
ef2d55b
feat-fix: fixed linting recomendations
Ehcsan Jan 25, 2024
6c7c02e
Merge branch 'Code-Inspect:main' into main
Ehcsan Jan 26, 2024
037d4ef
wip(reconstruct): attemt to implement (, in, )
Ehcsan Jan 26, 2024
d482745
add a handler for `ForIn` as part of normalize delimiter
EagleoutIce Jan 26, 2024
d2d3d87
feat(wip): might have broken reconstruction!!!
Ehcsan Jan 28, 2024
858a726
feat-fix(reconstruct): for-loop finished
Ehcsan Jan 30, 2024
744e160
feat-fix(reconstruct): while-loop exept empty body
Ehcsan Jan 30, 2024
08141bd
feat-fix(reconstruct): fixed while-loop
Ehcsan Jan 31, 2024
22911ad
feat-fix(reconstruct): cleaned up comments
Ehcsan Jan 31, 2024
1030310
test-fix(reconstruct): fixed nested assignments
Ehcsan Jan 31, 2024
47a7d93
feat-fix(reconstruct): started fixing function def
Ehcsan Feb 9, 2024
659574c
test(reconstruct): testing function definition
Ehcsan Feb 9, 2024
2bdd813
test-fix(reconstruct): debugging for function def
Ehcsan Feb 9, 2024
010db50
test(slicing): mermaid link shown again
Ehcsan Feb 23, 2024
5345f19
minor patches to get the tests running
EagleoutIce Feb 23, 2024
20ec3a8
removing only marker
EagleoutIce Feb 23, 2024
6ffcf9e
tests-fix(reconstruct): adjusted linePart tests
Ehcsan Feb 23, 2024
a8229ba
test-fix(reconstruct): removed .only from test
Ehcsan Feb 23, 2024
e245679
Merge branch 'main' of https://github.com/Ehcsan/flowr
Ehcsan Feb 23, 2024
5425223
test(reconstruct): removed unneccessary comment
Ehcsan Feb 23, 2024
227348b
feat-fix(reconstruct): removed unused import
Ehcsan Feb 23, 2024
23b0ab0
Merge branch 'main' into 484-refactor-reconstruct
EagleoutIce Feb 23, 2024
5ae5b74
lint-fix, refactor(reconstruct): some love?
EagleoutIce Feb 23, 2024
df6e39f
refactor: remove console logging and stuff
EagleoutIce Feb 23, 2024
5c68caf
Merge remote-tracking branch 'upstream/main'
Ehcsan Feb 27, 2024
2ef8892
feat-fix: fixed linting problems
Ehcsan Feb 27, 2024
677d8b8
test-fix(reconstructed): function definition reconstruct
Ehcsan Feb 27, 2024
f2ae684
wip: maintaining function body after reconstruct
EagleoutIce Mar 1, 2024
fd8e413
wip: handle parameters in fun-def reconstruct
EagleoutIce Mar 1, 2024
6d59c2e
feat: reconstruct calls correctly
EagleoutIce Mar 1, 2024
0ff9142
Merge branch 'Code-Inspect:main' into main
Ehcsan Mar 7, 2024
c9f01b1
tests-fix(reconstruct): fixed layout-preserving
Ehcsan Mar 7, 2024
9c4f04d
Merge branch 'main' of https://github.com/Ehcsan/flowr
Ehcsan Mar 7, 2024
97ce67d
further reconstruct
EagleoutIce Mar 8, 2024
73e3d46
test(reconstruct): started work on if testing
Ehcsan Mar 8, 2024
94d0e4b
feat(reconstruct): lint fixes
Ehcsan Mar 8, 2024
4c4abcf
feat(reconstruct): changed if-reconstruct; WIP
Ehcsan Mar 15, 2024
4795997
Merge branch 'main' into 484-refactor-reconstruct
EagleoutIce Mar 15, 2024
08fcb2e
Merge branch 'main' into 484-refactor-reconstruct
EagleoutIce Mar 15, 2024
fe57bd2
fix: imp for result reconstruction
EagleoutIce Mar 15, 2024
600abc9
doc: remove question comment
EagleoutIce Mar 15, 2024
870a9f2
feat(reconstruct): if-body works, else-body doesnt
Ehcsan Mar 15, 2024
576d17e
feat(reconstruct): if reconstruct good but broken
Ehcsan Mar 19, 2024
9f1bcc9
Merge branch 'main' into 484-refactor-reconstruct
EagleoutIce Mar 22, 2024
8a403e0
working on tests
EagleoutIce Mar 22, 2024
812b291
test-fix(reconstruct): tried finding correct index
Ehcsan Apr 5, 2024
0231dd6
if fixes
EagleoutIce Apr 5, 2024
bbfa26d
tests-fix(reconstruction): added layout preserving
Ehcsan Apr 25, 2024
3c0e2c2
tests-fix(reconstruct): more test fixes
Ehcsan Apr 25, 2024
7bf2750
tests(reconstruct): made changes to isolate failed tests
Ehcsan Apr 25, 2024
63be95e
test(reconstruct): added test to better understand assignments
Ehcsan Apr 25, 2024
0e5bf7c
fix: local patches
EagleoutIce Apr 26, 2024
d8004b6
test-fix(reconstruct): some fixes and minor change to merge
Ehcsan Apr 29, 2024
eef7854
lint-fix(reconstruct): linter fixes
Ehcsan Apr 29, 2024
2ca0554
feat-fix(reconstruct): implemented merge in function call
Ehcsan Apr 29, 2024
183dac0
feat(reconstruct): started work on semicolon adding
Ehcsan May 3, 2024
71a79c7
feat(reconstruction): semicolon problem solving
Ehcsan May 6, 2024
04f9b02
feat(reconstruct): finished semicolon reconstruction
Ehcsan May 7, 2024
2ea0759
Merge remote-tracking branch 'upstream/main' into 484-refactor-recons…
Ehcsan May 23, 2024
b26c780
feat(reconstruct): started cleaning up merge
Ehcsan May 23, 2024
7f5afec
feat-fix: handle some of the problems introduced by the merge
EagleoutIce May 24, 2024
ec43a73
feat(reconstruct): somehow there are no errors but its broken
Ehcsan May 30, 2024
57349a6
lint-fix(reconstruct): now the linter doesnt scream
Ehcsan May 30, 2024
c4cac54
feat-fix(reconstruct): fixed access to undefined
Ehcsan May 31, 2024
3132580
feat(reconstruct): some minor quality improvements
Ehcsan Jun 13, 2024
36565d0
tests-fix(reconstruct): started fixing test
Ehcsan Jun 21, 2024
d25e464
feat(reconstruct): changed reconstruction to work with new {}
Ehcsan Jun 27, 2024
eb5b11e
test(reconstruct): test for plainSplit
Ehcsan Jul 11, 2024
66888f5
feat-fix(reconstruct): fixed grouping
Ehcsan Jul 11, 2024
9261280
feat-fix(reconstruct): fixed indent and for
Ehcsan Jul 18, 2024
5b3ede2
tests-fix(reconstruct): dataflow v2 changes
Ehcsan Aug 9, 2024
d036b65
tests-fix: started fising calls-tests.ts
Ehcsan Aug 13, 2024
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
112 changes: 104 additions & 8 deletions src/reconstruct/reconstruct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* @module
*/

//imports {note: as of current, do not change}
import {
NormalizedAst,
NodeId,
Expand All @@ -29,6 +30,10 @@ import {
import { log, LogLevel } from '../util/log'
import { guard, isNotNull } from '../util/assert'
import { MergeableRecord } from '../util/objects'

/*
--helper function--
*/
type Selection = Set<NodeId>
interface PrettyPrintLine {
line: string
Expand All @@ -39,11 +44,20 @@ function plain(text: string): PrettyPrintLine[] {
}
type Code = PrettyPrintLine[]

export const reconstructLogger = log.getSubLogger({ name: 'reconstruct' })

/*
--logger--
*/
export const reconstructLogger = log.getSubLogger({ name: 'reconstruct' })

/*
--helper function--
*/
const getLexeme = (n: RNodeWithParent) => n.info.fullLexeme ?? n.lexeme ?? ''

/*
--reconstruct--
*/
const reconstructAsLeaf = (leaf: RNodeWithParent, configuration: ReconstructionConfiguration): Code => {
const selectionHasLeaf = configuration.selection.has(leaf.info.id) || configuration.autoSelectIf(leaf)
if(selectionHasLeaf) {
Expand All @@ -57,10 +71,17 @@ const reconstructAsLeaf = (leaf: RNodeWithParent, configuration: ReconstructionC

const foldToConst = (n: RNodeWithParent): Code => plain(getLexeme(n))

//look up exact function
/*
--helper function--
*/
function indentBy(lines: Code, indent: number): Code {
return lines.map(({ line, indent: i }) => ({ line, indent: i + indent }))
}

/*
--recunstruct--
*/
function reconstructExpressionList(exprList: RExpressionList<ParentInformation>, expressions: Code[], configuration: ReconstructionConfiguration): Code {
if(isSelected(configuration, exprList)) {
return plain(getLexeme(exprList))
Expand All @@ -80,10 +101,16 @@ function reconstructExpressionList(exprList: RExpressionList<ParentInformation>,
}
}

/*
--helper function--
*/
function isSelected(configuration: ReconstructionConfiguration, n: RNode<ParentInformation>) {
return configuration.selection.has(n.info.id) || configuration.autoSelectIf(n)
}

/*
--recunstruct--
*/
function reconstructRawBinaryOperator(lhs: PrettyPrintLine[], n: string, rhs: PrettyPrintLine[]) {
return [ // inline pretty print
...lhs.slice(0, lhs.length - 1),
Expand All @@ -92,7 +119,9 @@ function reconstructRawBinaryOperator(lhs: PrettyPrintLine[], n: string, rhs: Pr
]
}


/*
--recunstruct--
*/
function reconstructUnaryOp(leaf: RNodeWithParent, operand: Code, configuration: ReconstructionConfiguration) {
if(configuration.selection.has(leaf.info.id)) {
return foldToConst(leaf)
Expand All @@ -104,6 +133,9 @@ function reconstructUnaryOp(leaf: RNodeWithParent, operand: Code, configuration:
}
}

/*
--recunstruct--
*/
function reconstructBinaryOp(n: RBinaryOp<ParentInformation> | RPipe<ParentInformation>, lhs: Code, rhs: Code, configuration: ReconstructionConfiguration): Code {
if(isSelected(configuration, n)) {
return plain(getLexeme(n))
Expand All @@ -122,6 +154,9 @@ function reconstructBinaryOp(n: RBinaryOp<ParentInformation> | RPipe<ParentInfor
return reconstructRawBinaryOperator(lhs, n.type === RType.Pipe ? '|>' : n.operator, rhs)
}

/*
--recunstruct--
*/
function reconstructForLoop(loop: RForLoop<ParentInformation>, variable: Code, vector: Code, body: Code, configuration: ReconstructionConfiguration): Code {
if(isSelected(configuration, loop)) {
return plain(getLexeme(loop))
Expand Down Expand Up @@ -149,6 +184,9 @@ function reconstructForLoop(loop: RForLoop<ParentInformation>, variable: Code, v
}
}

/*
--recunstruct--
*/
function reconstructRepeatLoop(loop: RRepeatLoop<ParentInformation>, body: Code, configuration: ReconstructionConfiguration): Code {
if(isSelected(configuration, loop)) {
return plain(getLexeme(loop))
Expand All @@ -175,6 +213,9 @@ function reconstructRepeatLoop(loop: RRepeatLoop<ParentInformation>, body: Code,
}
}

/*
--helper function--
*/
function removeExpressionListWrap(code: Code) {
if(code.length > 0 && code[0].line === '{' && code[code.length - 1].line === '}') {
return indentBy(code.slice(1, code.length - 1), -1)
Expand All @@ -183,7 +224,9 @@ function removeExpressionListWrap(code: Code) {
}
}


/*
--recunstruct--
*/
function reconstructIfThenElse(ifThenElse: RIfThenElse<ParentInformation>, condition: Code, when: Code, otherwise: Code | undefined, configuration: ReconstructionConfiguration): Code {
if(isSelected(configuration, ifThenElse)) {
return plain(getLexeme(ifThenElse))
Expand Down Expand Up @@ -219,7 +262,9 @@ function reconstructIfThenElse(ifThenElse: RIfThenElse<ParentInformation>, condi
}
}


/*
--recunstruct--
*/
function reconstructWhileLoop(loop: RWhileLoop<ParentInformation>, condition: Code, body: Code, configuration: ReconstructionConfiguration): Code {
if(isSelected(configuration, loop)) {
return plain(getLexeme(loop))
Expand Down Expand Up @@ -247,6 +292,9 @@ function reconstructWhileLoop(loop: RWhileLoop<ParentInformation>, condition: Co
}
}

/*
--recunstruct--
*/
function reconstructParameters(parameters: RParameter<ParentInformation>[]): string[] {
// const baseParameters = parameters.flatMap(p => plain(getLexeme(p)))
return parameters.map(p => {
Expand All @@ -259,6 +307,10 @@ function reconstructParameters(parameters: RParameter<ParentInformation>[]): str
}


//foldAccess?? Arrayzugriffe
/*
--recunstruct--
*/
function reconstructFoldAccess(node: RAccess<ParentInformation>, accessed: Code, access: string | (Code | null)[], configuration: ReconstructionConfiguration): Code {
if(isSelected(configuration, node)) {
return plain(getLexeme(node))
Expand All @@ -275,6 +327,9 @@ function reconstructFoldAccess(node: RAccess<ParentInformation>, accessed: Code,
return plain(getLexeme(node))
}

/*
--recunstruct--
*/
function reconstructArgument(argument: RArgument<ParentInformation>, name: Code | undefined, value: Code | undefined, configuration: ReconstructionConfiguration): Code {
if(isSelected(configuration, argument)) {
return plain(getLexeme(argument))
Expand All @@ -287,7 +342,9 @@ function reconstructArgument(argument: RArgument<ParentInformation>, name: Code
}
}


/*
--recunstruct--
*/
function reconstructParameter(parameter: RParameter<ParentInformation>, name: Code, value: Code | undefined, configuration: ReconstructionConfiguration): Code {
if(isSelected(configuration, parameter)) {
return plain(getLexeme(parameter))
Expand All @@ -302,7 +359,9 @@ function reconstructParameter(parameter: RParameter<ParentInformation>, name: Co
}
}


/*
--recunstruct--
*/
function reconstructFunctionDefinition(definition: RFunctionDefinition<ParentInformation>, functionParameters: Code[], body: Code, configuration: ReconstructionConfiguration): Code {
// if a definition is not selected, we only use the body - slicing will always select the definition
if(!isSelected(configuration, definition) && functionParameters.every(p => p.length === 0)) {
Expand Down Expand Up @@ -332,6 +391,9 @@ function reconstructFunctionDefinition(definition: RFunctionDefinition<ParentInf

}

/*
--recunstruct--
*/
function reconstructSpecialInfixFunctionCall(args: (Code | undefined)[], call: RFunctionCall<ParentInformation>): Code {
guard(args.length === 2, () => `infix special call must have exactly two arguments, got: ${args.length} (${JSON.stringify(args)})`)
guard(call.flavor === 'named', `infix special call must be named, got: ${call.flavor}`)
Expand All @@ -355,6 +417,9 @@ function reconstructSpecialInfixFunctionCall(args: (Code | undefined)[], call: R
return plain(`${getLexeme(call.arguments[0] as RArgument<ParentInformation>)} ${call.functionName.content} ${getLexeme(call.arguments[1] as RArgument<ParentInformation>)}`)
}

/*
--recunstruct--
*/
function reconstructFunctionCall(call: RFunctionCall<ParentInformation>, functionName: Code, args: (Code | undefined)[], configuration: ReconstructionConfiguration): Code {
if(call.infixSpecial === true) {
return reconstructSpecialInfixFunctionCall(args, call)
Expand Down Expand Up @@ -383,22 +448,36 @@ function reconstructFunctionCall(call: RFunctionCall<ParentInformation>, functio
}
}

/*
--helper function--
*/
/** The structure of the predicate that should be used to determine if a given normalized node should be included in the reconstructed code independent of if it is selected by the slice or not */
export type AutoSelectPredicate = (node: RNode<ParentInformation>) => boolean


/*
--interface--
*/
interface ReconstructionConfiguration extends MergeableRecord {
selection: Selection
/** if true, this will force the ast part to be reconstructed, this can be used, for example, to force include `library` statements */
autoSelectIf: AutoSelectPredicate
}

/*
--helper function--
*/
export function doNotAutoSelect(_node: RNode<ParentInformation>): boolean {
return false
}

/*
--helper function--
*/
const libraryFunctionCall = /^(library|require|((require|load|attach)Namespace))$/

/*
--helper function--
*/
export function autoSelectLibrary(node: RNode<ParentInformation>): boolean {
if(node.type !== RType.FunctionCall || node.flavor !== 'named') {
return false
Expand All @@ -407,6 +486,9 @@ export function autoSelectLibrary(node: RNode<ParentInformation>): boolean {
}


/*
--reconstruct--
*/
/**
* The fold functions used to reconstruct the ast in {@link reconstructToCode}.
*/
Expand Down Expand Up @@ -454,21 +536,32 @@ const reconstructAstFolds: StatefulFoldFunctions<ParentInformation, Reconstructi
}



/*
--helper function--
*/
function getIndentString(indent: number): string {
return ' '.repeat(indent * 4)
}

/*
--helper function--
*/
function prettyPrintCodeToString(code: Code, lf ='\n'): string {
return code.map(({ line, indent }) => `${getIndentString(indent)}${line}`).join(lf)
}

/*
--interface--
*/
export interface ReconstructionResult {
code: string
/** number of nodes that triggered the `autoSelectIf` predicate {@link reconstructToCode} */
autoSelected: number
}

/*
--helper function--
*/
function removeOuterExpressionListIfApplicable(result: PrettyPrintLine[], autoSelected: number) {
if(result.length > 1 && result[0].line === '{' && result[result.length - 1].line === '}') {
// remove outer block
Expand All @@ -478,6 +571,9 @@ function removeOuterExpressionListIfApplicable(result: PrettyPrintLine[], autoSe
}
}

/*
--main function--
*/
/**
* Reconstructs parts of a normalized R ast into R code on an expression basis.
*
Expand Down