All files / src/abap/types form_definition.ts

97.96% Statements 48/49
93.75% Branches 15/16
100% Functions 7/7
97.96% Lines 48/49

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 1021x 1x 1x 1x 1x   1x   1x   1x   1x             210x     210x 210x 210x 210x   210x 210x   210x 210x 210x       105x       108x       105x           210x   210x 210x 198x     12x 12x   2x   10x   10x   10x 10x 6x     10x 8x 2x       10x       12x       420x 420x 388x   32x       32x 32x 36x 36x   32x      
import * as Statements from "../2_statements/statements";
import * as Expressions from "../2_statements/expressions";
import * as Tokens from "../1_lexer/tokens";
import {Identifier} from "../4_file_information/_identifier";
import {StructureNode, StatementNode, ExpressionNode} from "../nodes";
import {Expression} from "../2_statements/combi";
import {TypedIdentifier, IdentifierMeta} from "./_typed_identifier";
import {CurrentScope} from "../5_syntax/_current_scope";
import {FormParam} from "../5_syntax/expressions/form_param";
import {IFormDefinition} from "./_form_definition";
import {TableType, UnknownType, VoidType} from "./basic";
 
export class FormDefinition extends Identifier implements IFormDefinition {
  private readonly node: StatementNode;
  private readonly tableParameters: TypedIdentifier[];
  private readonly usingParameters: TypedIdentifier[];
  private readonly changingParameters: TypedIdentifier[];
 
  public constructor(node: StructureNode | StatementNode, filename: string, scope: CurrentScope) {
    const st = node instanceof StructureNode ? node.findFirstStatement(Statements.Form)! : node;
 
    // FORMs can contain a dash in the name
    const formName = st.findFirstExpression(Expressions.FormName);
    const pos = formName!.getFirstToken().getStart();
    const name = formName!.concatTokens();
    const nameToken = new Tokens.Identifier(pos, name);
 
    super(nameToken, filename);
    this.node = st;
 
    this.tableParameters = this.findTables(scope, filename);
    this.usingParameters = this.findType(Expressions.FormUsing, scope);
    this.changingParameters = this.findType(Expressions.FormChanging, scope);
  }
 
  public getTablesParameters(): TypedIdentifier[] {
    return this.tableParameters;
  }
 
  public getUsingParameters(): TypedIdentifier[] {
    return this.usingParameters;
  }
 
  public getChangingParameters(): TypedIdentifier[] {
    return this.changingParameters;
  }
 
///////////////
 
  private findTables(scope: CurrentScope, filename: string): TypedIdentifier[] {
    const ret: TypedIdentifier[] = [];
 
    const tables = this.node.findFirstExpression(Expressions.FormTables);
    if (tables === undefined) {
      return [];
    }
 
    for (const param of tables.findAllExpressions(Expressions.FormParam)) {
      if (param.getChildren().length === 1) {
        // untyped TABLES parameter
        ret.push(new TypedIdentifier(param.getFirstToken(), filename, new VoidType("FORM:UNTYPED"), [IdentifierMeta.FormParameter]));
      } else {
        const p = new FormParam().runSyntax(param, scope, this.filename);
 
        let type = p.getType();
 
        const isStructure = param.findDirectTokenByText("STRUCTURE") !== undefined;
        if (isStructure) {
          type = new TableType(type, {withHeader: true});
        }
 
        if (type instanceof TableType) {
          type = new TableType(type.getRowType(), {withHeader: true});
        } else Iif (!(type instanceof UnknownType) && !(type instanceof VoidType)) {
          type = new UnknownType("FORM TABLES type must be table type");
        }
 
        ret.push(new TypedIdentifier(p.getToken(), filename, type, [IdentifierMeta.FormParameter]));
      }
    }
 
    return ret;
  }
 
  private findType(type: new () => Expression, scope: CurrentScope): TypedIdentifier[] {
    const found = this.node.findFirstExpression(type);
    if (found === undefined) {
      return [];
    }
    return this.findParams(found, scope);
  }
 
  private findParams(node: ExpressionNode | StatementNode, scope: CurrentScope) {
    const res: TypedIdentifier[] = [];
    for (const param of node.findAllExpressions(Expressions.FormParam)) {
      const p = new FormParam().runSyntax(param, scope, this.filename);
      res.push(p);
    }
    return res;
  }
 
}