All files / src/abap/5_syntax/statements class_implementation.ts

100% Statements 56/56
100% Branches 12/12
100% Functions 1/1
100% Lines 56/56

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 561x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 778x 778x 778x 778x 778x 778x 778x 778x 3x 3x 3x 3x 775x 775x 778x 774x 127x 127x 774x 775x 775x 778x 150x 778x 625x 625x 625x 775x 775x 775x 775x 775x 778x 774x 774x 774x 80x 80x 774x 775x 775x 775x 1x
import {StatementNode} from "../../nodes";
import {ObjectOriented} from "../_object_oriented";
import {ObjectReferenceType, VoidType} from "../../types/basic";
import {Identifier} from "../../1_lexer/tokens";
import {TypedIdentifier} from "../../types/_typed_identifier";
import {Position} from "../../../position";
import {BuiltIn} from "../_builtin";
import {ScopeType} from "../_scope_type";
import {StatementSyntax} from "../_statement_syntax";
import {SyntaxInput, syntaxIssue} from "../_syntax_input";
 
export class ClassImplementation implements StatementSyntax {
  public runSyntax(node: StatementNode, input: SyntaxInput): void {
    const helper = new ObjectOriented(input.scope);
 
    const className = helper.findClassName(node);
 
    input.scope.push(ScopeType.ClassImplementation, className, node.getFirstToken().getStart(), input.filename);
 
    const classDefinition = input.scope.findClassDefinition(className);
    if (classDefinition === undefined) {
      const message = "Class definition for \"" + className + "\" not found";
      input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
      return;
    }
 
    const types = classDefinition.getTypeDefinitions();
    if (types !== undefined) {
      for (const t of types.getAll()) {
        input.scope.addType(t.type);
      }
    }
 
    const sup = input.scope.findClassDefinition(classDefinition.getSuperClass());
    if (sup) {
      input.scope.addIdentifier(new TypedIdentifier(new Identifier(new Position(1, 1), "super"), BuiltIn.filename, new ObjectReferenceType(sup)));
    } else {
      // todo: instead of the void type, do proper typing, ie. only empty constructor method
      input.scope.addIdentifier(new TypedIdentifier(new Identifier(new Position(1, 1), "super"), BuiltIn.filename, VoidType.get("noSuper")));
    }
    input.scope.addIdentifier(new TypedIdentifier(new Identifier(new Position(1, 1), "me"), BuiltIn.filename, new ObjectReferenceType(classDefinition)));
    helper.addAliasedAttributes(classDefinition); // todo, this is not correct, take care of instance vs static
    helper.addAliasedTypes(classDefinition);
 
    const classAttributes = classDefinition.getAttributes();
    if (classAttributes !== undefined) {
      input.scope.addList(classAttributes.getConstants());
      input.scope.addList(classAttributes.getStatic());
      for (const i of classAttributes.getInstance()) {
        input.scope.addExtraLikeType(i);
      }
    }
 
    helper.fromSuperClassesAndInterfaces(classDefinition);
  }
}