checkProperty()

in lib/semantic.js [2006:2078]


  checkProperty(ast, env) {
    if (ast.id.lexeme === '__module') {
      const [key] = ast.propertyPath;
      const target = this.consts.get(key.lexeme);
      if (!target) {
        this.error(`the const ${key.lexeme} is undefined`, key);
      }
      replace(ast, target);
      return;
    }
    
    this.checkId(ast.id, env);
   
    // check property
    const type = this.getVariableType(ast.id, env);
    ast.id.inferred = type;
    
    if (type.type === 'model' || type.type === 'map') {
      // { type: 'map', keyTypeName: 'string', valueTypeName: 'any' }
      const currentPath = [ast.id.lexeme];
      let current = type;
      ast.propertyPathTypes = new Array(ast.propertyPath.length);
      for (let i = 0; i < ast.propertyPath.length; i++) {
        
        let prop = ast.propertyPath[i];

        let find = this.getPropertyType(current, prop.lexeme);
        if (!find) {
          this.error(`The property ${prop.lexeme} is undefined ` +
            `in model ${currentPath.join('.')}(${current.name})`, prop);
        }
        ast.propertyPathTypes[i] = find;
        currentPath.push(prop.lexeme);
        current = find;
      }

      return;
    }

    if (this.models.has(ast.id.lexeme)) {
      // submodel M.N
      let current = this.models.get(ast.id.lexeme);
      
      const currentPath = [ast.id.lexeme];
      for (let i = 0; i < ast.propertyPath.length; i++) {
        let prop = ast.propertyPath[i];
        currentPath.push(prop.lexeme);
        let find = this.findProperty(current, prop.lexeme, current.isException);
        if (!find) {
          this.error(`The model ${currentPath.join('.')} is undefined`, prop);
        }
        current = find.modelField;
      }
      ast.realType = {
        type: 'class',
        name: currentPath.join('.')
      };
      return;
    }

    if (this.dependencies.has(ast.id.lexeme)) {
      // Alias.M.N
      return;
    }

    if (this.enums.has(ast.id.lexeme)) {
      // E.K
      return;
    }

    const name = ast.id.lexeme;
    this.error(`The type of '${name}' must be model, object or map`, ast.id);
  }