All files / src/cds cds_determine_types.ts

85.32% Statements 93/109
84.78% Branches 39/46
100% Functions 2/2
85.32% Lines 93/109

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 102 103 104 105 106 107 108 1091x 1x 1x 1x 1x 1x 1x 1x 33x 33x 33x 1x 33x 32x 32x 32x 84x 28x 28x 28x 17x 17x 28x 28x 28x 1x 1x 1x 1x 1x 1x 28x 5x 5x 5x 5x 5x 5x 5x             22x 28x 28x 28x 22x 5x 5x 4x 4x 4x 4x 5x 1x 1x 1x 1x 1x 22x 17x 17x 17x 17x 17x 17x 28x                     84x 56x 56x 56x 56x 56x 84x 32x 32x 33x 1x 1x 1x 56x 5x 5x 56x 46x 46x 11x 11x 9x 9x 11x 46x 42x 42x 1x 1x
import {AbstractType, IRegistry} from "..";
import {IStructureComponent, StructureType, UnknownType, VoidType} from "../abap/types/basic";
import {DDIC} from "../ddic";
import {ParsedDataDefinition} from "../objects";
 
export class CDSDetermineTypes {
 
  public parseType(reg: IRegistry, parsedData: ParsedDataDefinition, ddlsName: string): AbstractType {
    const ddic = new DDIC(reg);
 
    if (parsedData?.fields.length === 0) {
      return VoidType.get("DDLS:todo");
    } else {
      const components: IStructureComponent[] = [];
 
      for (const f of parsedData?.fields || []) {
        if (f.prefix !== "") {
          const prefixUpper = f.prefix.toUpperCase();
          let source = parsedData.sources.find((s) => s.as?.toUpperCase() === prefixUpper);
          if (source?.name === undefined) {
            source = parsedData.sources.find((s) => s.name.toUpperCase() === prefixUpper);
          }
          if (source?.name === undefined
              && (parsedData.associations.find((s) => s.name.toUpperCase() === prefixUpper)
              || parsedData.associations.find((s) => s.as?.toUpperCase() === prefixUpper))) {
            components.push({
              name: f.name,
              type: VoidType.get("DDLS:association"),
            });
            continue;
          }
          if (source?.name === undefined) {
            if (prefixUpper.startsWith("_")) {
              components.push({
                name: f.name,
                type: VoidType.get("DDLS:association"),
              });
              continue;
            }
            components.push({
              name: f.name,
              type: new UnknownType("CDS parser error, unknown source, " + f.name + ", " + ddlsName),
            });
            continue;
          }
 
          const nameInSource = f.nameInSource ?? f.name;
          const lookup = ddic.lookupTableOrView(source.name);
          if (lookup.type) {
            if (lookup.type instanceof StructureType) {
              const type = lookup.type.getComponentByName(nameInSource);
              if (type) {
                components.push({
                  name: f.name,
                  type: type,
                });
              } else {
                components.push({
                  name: f.name,
                  type: new UnknownType(nameInSource + " not found in " + source.name + ", CDSDetermineTypes"),
                });
              }
            } else {
              // its void or unknown
              components.push({
                name: f.name,
                type: lookup.type,
              });
            }
          } else if (reg.inErrorNamespace(source.name)) {
            components.push({
              name: f.name,
              type: new UnknownType(source.name + " not found, CDSDetermineTypes"),
            });
          } else {
            components.push({
              name: f.name,
              type: VoidType.get(source.name),
            });
          }
        } else {
          components.push({
            name: f.name,
            type: this.findInSources(ddic, parsedData, f.nameInSource) ?? VoidType.get("DDLS:fieldname:" + ddlsName),
          });
        }
      }
      return new StructureType(components, parsedData.definitionName, parsedData.definitionName, parsedData.description);
    }
  }
 
  /** unprefixed field, take the type from the first source containing it, void or unknown sources are skipped */
  private findInSources(ddic: DDIC, parsedData: ParsedDataDefinition, nameInSource: string | undefined): AbstractType | undefined {
    if (nameInSource === undefined) {
      return undefined;
    }
    for (const source of parsedData.sources) {
      const lookup = ddic.lookupTableOrView(source.name);
      if (lookup.type instanceof StructureType) {
        const type = lookup.type.getComponentByName(nameInSource);
        if (type) {
          return type;
        }
      }
    }
    return undefined;
  }
 
}