import { binding_grammarVisitor } from '../antlr/binding_grammarVisitor' ; import { ParseTree } from 'antlr4ts/tree/ParseTree' ; import { RuleNode } from 'antlr4ts/tree/RuleNode' ; import { TerminalNode } from 'antlr4ts/tree/TerminalNode' ; import { ErrorNode } from 'antlr4ts/tree/ErrorNode' ; import { Override } from 'antlr4ts/Decorators' ; import { Policy , Statement , DisjunctionSet , ConjunctionSet } from './DataStructures' ; import { Binding_statementContext , NominatorContext , NomineeContext , Is_creatorContext , Binding_constrContext , Set_expresionContext , RoleContext , Endorsement_constrContext , Unbinding_statementContext } from '../antlr/binding_grammarParser' ; export class BindingVisitor implements binding_grammarVisitor < string > { _names : string [ ] = [ ] ; policy : Policy = new Policy ( ) ; protected defaultResult ( ) { return "" ; } updateRules ( names ) { this . _names = names ; } @ Override visitTerminal ( node ) { let res = node . toStringTree ( ) ; if ( res === 'and' ) return '&' ; else if ( res === 'or' ) return '|' ; else return res ; } @ Override visitErrorNode ( node ) { let res = node . toStringTree ( ) ; return res ; } visit ( tree ) { return tree . accept ( this ) ; } visitUnbinding_statement ( ctx ) { let statement = new Statement ( ) ; statement . nominator = ctx . nominator ( ) . accept ( this ) ; statement . nominee = ctx . nominee ( ) . accept ( this ) ; if ( ctx . binding_constr ( ) !== undefined ) statement . bindingConstraint = this . createDisjunctionSet ( ctx . binding_constr ( ) . accept ( this ) ) ; if ( ctx . endorsement_constr ( ) !== undefined ) statement . endorsementConstraint = this . createDisjunctionSet ( ctx . endorsement_constr ( ) . accept ( this ) ) ; this . policy . addReleaseStatement ( statement ) ; return '' ; } visitBinding_statement ( ctx ) { if ( ctx . is_creator ( ) !== undefined ) { let creator = ctx . is_creator ( ) . accept ( this ) ; this . policy . setCreator ( creator ) ; } else { let statement = new Statement ( ) ; statement . nominator = ctx . nominator ( ) . accept ( this ) ; statement . nominee = ctx . nominee ( ) . accept ( this ) ; if ( ctx . binding_constr ( ) !== undefined ) statement . bindingConstraint = this . createDisjunctionSet ( ctx . binding_constr ( ) . accept ( this ) ) ; if ( ctx . endorsement_constr ( ) !== undefined ) statement . endorsementConstraint = this . createDisjunctionSet ( ctx . endorsement_constr ( ) . accept ( this ) ) ; this . policy . addNominationStatement ( statement ) ; } return '' ; } visitIs_creator ( ctx ) { return ctx . role ( ) . text ; } visitNominator ( ctx ) { this . policy . addRole ( ctx . text ) ; return ctx . text ; } visitNominee ( ctx ) { this . policy . addRole ( ctx . text ) ; return ctx . text ; } visitRole ( ctx ) { this . policy . addRole ( ctx . text ) ; return ctx . text ; } visitBinding_constr ( ctx ) { let neg = ctx . NOT ( ) === undefined ? '+' : '-' ; return neg + ctx . set_expresion ( ) . accept ( this ) ; } visitEndorsement_constr ( ctx ) { return '+' + ctx . set_expresion ( ) . accept ( this ) ; } visitSet_expresion ( ctx ) { let exp = '' ; for ( let i = 0 ; i < ctx . childCount ; i ++ ) exp += ctx . getChild ( i ) . accept ( this ) ; return exp ; } visitChildren ( node ) { let nodeName = this . _names [ node . ruleContext . ruleIndex ] ; let res = '' ; for ( let i = 0 ; i < node . childCount ; i ++ ) res += node . getChild ( i ) . accept ( this ) ; return res ; } createDisjunctionSet ( setStr ) { let disjunctionSet = new DisjunctionSet ( ) ; disjunctionSet . isNegative = setStr [ 0 ] === '+' ? false : true ; let conjS = setStr . substr ( 1 ) . split ( '|' ) ; conjS . forEach ( value => { let conjuntionSet = new ConjunctionSet ( ) ; conjuntionSet . roles = value . split ( '&' ) ; disjunctionSet . conjunctionSets . push ( conjuntionSet ) ; } ) ; return disjunctionSet ; } }