module Measures::ElmDependencyFinder

Public Class Methods

find_dependencies(cql_library_files, main_cql_library_id) click to toggle source
# File lib/measure-loader/elm_dependency_finder.rb, line 5
def find_dependencies(cql_library_files, main_cql_library_id)
  elms = cql_library_files.map(&:elm)
  all_elms_dep_map = Hash[elms.map { |elm| [Helpers.elm_id(elm), make_statement_deps_for_elm(elm)] }]
  needed_deps_map = Hash[elms.map { |elm| [Helpers.elm_id(elm), {}] }]

  needed_deps_map[main_cql_library_id] = all_elms_dep_map[main_cql_library_id]
  needed_deps_map[main_cql_library_id].each_value do |stmnts|
    stmnts.each { |stmnt| deep_add_external_library_deps(stmnt, needed_deps_map, all_elms_dep_map) }
  end
  return needed_deps_map
end

Private Class Methods

deep_add_external_library_deps(statement, needed_deps_map, all_elms_dep_map) click to toggle source
# File lib/measure-loader/elm_dependency_finder.rb, line 52
def deep_add_external_library_deps(statement, needed_deps_map, all_elms_dep_map)
  statement_library = statement[:library_name]
  statement_name = statement[:statement_name]

  return unless needed_deps_map.dig(statement_library, statement_name).nil? # return if key already exists

  if all_elms_dep_map[statement_library].nil?
    raise MeasureLoadingInvalidPackageException.new("Elm library #{statement_library} referenced but not found.")
  end
  if all_elms_dep_map[statement_library][statement_name].nil?
    raise MeasureLoadingException.new("Elm statement '#{statement_name}' referenced but not found in library '#{statement_library}'.")
  end
  deps_to_add = all_elms_dep_map[statement_library][statement_name]
  needed_deps_map.deep_merge!(statement_library => { statement_name => deps_to_add })

  deps_to_add.each { |stmnt| deep_add_external_library_deps(stmnt, needed_deps_map, all_elms_dep_map) }
end
make_library_alias_to_path_hash(elm) click to toggle source
# File lib/measure-loader/elm_dependency_finder.rb, line 19
def make_library_alias_to_path_hash(elm)
  lib_alias_to_path = { nil => Helpers.elm_id(elm) } # nil value used for statements without libraryName
  (elm.dig('library','includes','def') || []).each do |library_hash|
    lib_alias_to_path[library_hash['localIdentifier']] = library_hash['path']
  end
  return lib_alias_to_path
end
make_statement_deps_for_elm(elm) click to toggle source
# File lib/measure-loader/elm_dependency_finder.rb, line 27
def make_statement_deps_for_elm(elm)
  deps = {}
  lib_alias_to_path = make_library_alias_to_path_hash(elm)
  make_statement_deps_for_elm_helper(elm, nil, deps, lib_alias_to_path)
  deps.each_value(&:uniq!)
  return deps
end
make_statement_deps_for_elm_helper(obj, parent_name, deps, lib_alias_to_path) click to toggle source
# File lib/measure-loader/elm_dependency_finder.rb, line 35
def make_statement_deps_for_elm_helper(obj, parent_name, deps, lib_alias_to_path)
  if obj.is_a? Array
    obj.each { |el| make_statement_deps_for_elm_helper(el, parent_name, deps, lib_alias_to_path) }
  elsif obj.is_a? Hash
    if obj['type'].in?(['ExpressionRef', 'FunctionRef']) && parent_name != 'Patient'
      dep = { library_name: lib_alias_to_path[obj['libraryName']], statement_name: obj['name'] }
      deps[parent_name] << dep
    elsif obj.key?('name') && obj.key?('expression')
      parent_name = obj['name']
      deps[parent_name] = [] unless deps.key?('parent_name')
    end
    obj.each_pair do |k,v|
      make_statement_deps_for_elm_helper(v, parent_name, deps, lib_alias_to_path) unless k == 'annotation'
    end
  end
end