Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion arch/certificate_model/MockCertificateModel.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ MockCertificateModel:

# XXX - Remove version information since specifying priv/unpriv ISA manual should imply this.
extensions:
$mref:
$inherits:
- "../profile_release/MockProfileRelease.yaml#/MockProfileRelease/profiles/MP-U-64/extensions"
- "../profile_release/MockProfileRelease.yaml#/MockProfileRelease/profiles/MP-S-64/extensions"
I:
Expand Down
2 changes: 1 addition & 1 deletion arch/inst/I/addi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ addi:
match: -----------------000-----0010011
variables:
- name: imm
$mref: ../../common/inst_variable_types.yaml#/itype_imm
$inherits: ../../common/inst_variable_types.yaml#/itype_imm
- name: rs1
location: 19-15
- name: rd
Expand Down
2 changes: 1 addition & 1 deletion arch/profile_release/MockProfileRelease.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ MockProfileRelease:
email: [email protected]
company: Disney
extensions:
$mref: "#/MockProfileRelease/profiles/MP-U-64/extensions"
$inherits: "#/MockProfileRelease/profiles/MP-U-64/extensions"
A:
presence: mandatory
S:
Expand Down
2 changes: 1 addition & 1 deletion arch/profile_release/RVA20.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ RVA20:
most important profile within application processors in
terms of the amount of software that targets this profile.
extensions:
$mref: "RVI20.yaml#/RVI20/profiles/RVI20U64/extensions"
$inherits: "RVI20.yaml#/RVI20/profiles/RVI20U64/extensions"
$remove: Zifencei # Not allowed as an option for Unpriv ISA (only available in Priv ISA).
A:
presence: mandatory
Expand Down
4 changes: 2 additions & 2 deletions arch/profile_release/RVA22.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ RVA22:
most important profile within application processors in
terms of the amount of software that targets this profile.
extensions:
$mref: "RVA20.yaml#/RVA20/profiles/RVA20U64/extensions"
$inherits: "RVA20.yaml#/RVA20/profiles/RVA20U64/extensions"
Zihpm:
presence: mandatory
version: "= 2.0"
Expand Down Expand Up @@ -167,7 +167,7 @@ RVA22:
processors. RVA22S64 is based on privileged architecture version
1.12.
extensions:
$mref: "RVA20.yaml#/RVA20/profiles/RVA20S64/extensions"
$inherits: "RVA20.yaml#/RVA20/profiles/RVA20S64/extensions"
S:
presence: mandatory
version: "= 1.12"
Expand Down
2 changes: 1 addition & 1 deletion arch/profile_release/RVI20.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,6 @@ RVI20:
Implementations are strongly recommended to raise illegal-instruction
exceptions on attempts to execute unimplemented opcodes.
RVI20U64:
$mref: "#/RVI20/profiles/RVI20U32"
$inherits: "#/RVI20/profiles/RVI20U32"
base: 64
marketing_name: RVI20U64
58 changes: 29 additions & 29 deletions lib/test/test_yaml_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_remove
key2: value2

child:
$mref: "#/base"
$inherits: "#/base"
$remove: key2
key3: value3
YAML
Expand All @@ -36,7 +36,7 @@ def test_multiple_remove
key3: value3

child:
$mref: "#/base"
$inherits: "#/base"
$remove:
- key2
- key3
Expand All @@ -51,20 +51,20 @@ def test_multiple_remove
assert_equal({ "key1" => "value1", "key4" => "value4" }, doc["child"])
end

def test_that_mref_with_nested_replace_works
def test_that_inherits_with_nested_replace_works
yaml = <<~YAML
base:
key1:
sub_key1: value1
key2: value2

middle:
$mref: "#/base"
$inherits: "#/base"
key3: value3
key4: value4

bottom:
$mref:
$inherits:
- "#/base"
- "#/middle"
key1:
Expand All @@ -82,19 +82,19 @@ def test_that_mref_with_nested_replace_works
assert_equal({ "key1" => {"sub_key1" => "value1", "sub_key6" => "value6"}, "key2" => "value2_new", "key3" => "value3", "key4" => "value4_new", "key5" => "value5" }, doc["bottom"])
end

def test_that_spurious_recursive_mref_works
def test_that_spurious_recursive_inherits_works
yaml = <<~YAML
base:
key1: value1
key2: value2

middle:
$mref: "#/base"
$inherits: "#/base"
key3: value3
key4: value4

bottom:
$mref:
$inherits:
- "#/base"
- "#/middle"
key2: value2_new
Expand All @@ -111,19 +111,19 @@ def test_that_spurious_recursive_mref_works
assert_equal({ "key1" => "value1", "key2" => "value2_new", "key3" => "value3", "key4" => "value4_new", "key5" => "value5" }, doc["bottom"])
end

def test_that_recursive_mref_works
def test_that_recursive_inherits_works
yaml = <<~YAML
base:
key1: value1
key2: value2

middle:
$mref: "#/base"
$inherits: "#/base"
key3: value3
key4: value4

bottom:
$mref: "#/middle"
$inherits: "#/middle"
key2: value2_new
key4: value4_new
key5: value5
Expand All @@ -138,7 +138,7 @@ def test_that_recursive_mref_works
assert_equal({ "key1" => "value1", "key2" => "value2_new", "key3" => "value3", "key4" => "value4_new", "key5" => "value5" }, doc["bottom"])
end

def test_that_nested_mref_works
def test_that_nested_inherits_works
yaml = <<~YAML
top:
base:
Expand All @@ -148,7 +148,7 @@ def test_that_nested_mref_works

bottom:
child:
$mref: "#/top/base"
$inherits: "#/top/base"
key3: value3_new
YAML

Expand All @@ -160,15 +160,15 @@ def test_that_nested_mref_works
assert_equal({ "key1" => "value1", "key2" => "value2", "key3" => "value3_new" }, doc["bottom"]["child"])
end

def test_that_mref_doesnt_delete_keys
def test_that_inherits_doesnt_delete_keys
yaml = <<~YAML
base:
key1: value1
key2: value2
key3: value3

child:
$mref: "#/base"
$inherits: "#/base"
key3: value3_new
YAML

Expand All @@ -180,7 +180,7 @@ def test_that_mref_doesnt_delete_keys
assert_equal({ "key1" => "value1", "key2" => "value2", "key3" => "value3_new" }, doc["child"])
end

def test_that_double_mref_doesnt_delete_keys
def test_that_double_inherits_doesnt_delete_keys
yaml = <<~YAML
base1:
key1: value1
Expand All @@ -193,7 +193,7 @@ def test_that_double_mref_doesnt_delete_keys
key6: value6

child:
$mref:
$inherits:
- "#/base1"
- "#/base2"
key3: value3_new
Expand Down Expand Up @@ -274,23 +274,23 @@ def test_refs_in_the_different_document
assert_equal({ "a" => "hash" }, doc["obj3"])
end

def test_mrefs_in_the_same_document
def test_inheritss_in_the_same_document
yaml = <<~YAML
$defs:
target1: A string
target2:
a: hash

obj1:
$mref: "#/$defs/target2"
$inherits: "#/$defs/target2"

obj2:
$mref: "#/$defs/target2"
$inherits: "#/$defs/target2"
a: Should take precedence

obj3:
a: Should take precedence
$mref: "#/$defs/target2"
$inherits: "#/$defs/target2"

YAML

Expand All @@ -304,7 +304,7 @@ def test_mrefs_in_the_same_document
assert_equal({ "a" => "Should take precedence" }, doc["obj3"])
end

def test_mrefs_in_the_different_document
def test_inheritss_in_the_different_document
yaml1 = <<~YAML
$defs:
target1: A string
Expand All @@ -319,15 +319,15 @@ def test_mrefs_in_the_different_document

yaml2 = <<~YAML
obj1:
$mref: "#{f1_path.basename}#/$defs/target2"
$inherits: "#{f1_path.basename}#/$defs/target2"

obj2:
$mref: "#{f1_path.basename}#/$defs/target2"
$inherits: "#{f1_path.basename}#/$defs/target2"
a: Should take precedence

obj3:
a: Should take precedence
$mref: "#{f1_path.basename}#/$defs/target2"
$inherits: "#{f1_path.basename}#/$defs/target2"
YAML

f2 = Tempfile.new("yml")
Expand All @@ -340,7 +340,7 @@ def test_mrefs_in_the_different_document
assert_equal({ "a" => "Should take precedence" }, doc["obj3"])
end

def test_multi_mrefs_in_the_same_document
def test_multi_inheritss_in_the_same_document
yaml = <<~YAML
$defs:
target1:
Expand All @@ -349,7 +349,7 @@ def test_multi_mrefs_in_the_same_document
a: hash

obj1:
$mref:
$inherits:
- "#/$defs/target1"
- "#/$defs/target2"

Expand All @@ -363,7 +363,7 @@ def test_multi_mrefs_in_the_same_document
assert_equal({ "a" => "hash", "b" => "nice" }, doc["obj1"])
end

def test_that_invalid_mrefs_raise
def test_that_invalid_inheritss_raise
yaml = <<~YAML
$defs:
target1:
Expand All @@ -372,7 +372,7 @@ def test_that_invalid_mrefs_raise
a: hash

obj1:
$mref: "#/path/to/nowwhere"
$inherits: "#/path/to/nowwhere"

YAML

Expand Down
34 changes: 17 additions & 17 deletions lib/yaml_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "pathname"
require "yaml"

# loads a YAML file and expands any $ref/$mref references
# loads a YAML file and expands any $ref/$inherits references
class YamlLoader
@cache = {}

Expand Down Expand Up @@ -46,42 +46,42 @@ def self.expand(filename, obj, yaml_opts = {})

ref
end
elsif obj.keys.include?("$mref")
# we handle the mref key first so that any override will take priority
mref = obj["$mref"]
raise ArgumentError, "Missing reference after $mref (did you forget to put a relative reference in quotes?)" if mref.nil?
mref_targets = mref.is_a?(String) ? [mref] : mref
elsif obj.keys.include?("$inherits")
# we handle the inherits key first so that any override will take priority
inherits = obj["$inherits"]
raise ArgumentError, "Missing reference after $inherits (did you forget to put a relative reference in quotes?)" if inherits.nil?
inherits_targets = inherits.is_a?(String) ? [inherits] : inherits

new_obj = {}

mref_targets.each do |mref_target|
relative_path = mref_target.split("#")[0]
inherits_targets.each do |inherits_target|
relative_path = inherits_target.split("#")[0]
target_obj =
if relative_path.empty?
YAML.load_file(filename, **yaml_opts)
else
target_filename = File.realpath(File.join(filename.dirname, relative_path))

unless File.exist?(target_filename)
raise DereferenceError, "While locating $mref in #{filename}, #{target_filename} does not exist"
raise DereferenceError, "While locating $inherits in #{filename}, #{target_filename} does not exist"
end

YamlLoader.load(target_filename, yaml_opts)
end

mref_target_suffix = mref_target.split("#/")[1]
mref_target_path = mref_target_suffix.split("/")
inherits_target_suffix = inherits_target.split("#/")[1]
inherits_target_path = inherits_target_suffix.split("/")
begin
target_obj = target_obj.dig(*mref_target_path)
target_obj = target_obj.dig(*inherits_target_path)
rescue TypeError => e
if e.message == "no implicit conversion of String into Integer"
warn "$mref: \"#{mref_target}\" found in file #{filename} references an Array but needs to reference a Hash"
warn "$inherits: \"#{inherits_target}\" found in file #{filename} references an Array but needs to reference a Hash"
end
raise e
end

raise DereferenceError, "JSON Path #{mref_target_suffix} in file #{filename} does not exist in #{relative_path}" if target_obj.nil?
raise ArgumentError, "$mref: \"#{mref_target}\" in file #{filename} references a #{target_obj.class} but needs to reference a Hash" unless target_obj.is_a?(Hash)
raise DereferenceError, "JSON Path #{inherits_target_suffix} in file #{filename} does not exist in #{relative_path}" if target_obj.nil?
raise ArgumentError, "$inherits: \"#{inherits_target}\" in file #{filename} references a #{target_obj.class} but needs to reference a Hash" unless target_obj.is_a?(Hash)

target_obj = expand(filename, target_obj, yaml_opts)
target_obj.each do |target_key, target_value|
Expand All @@ -94,7 +94,7 @@ def self.expand(filename, obj, yaml_opts = {})
end
end

obj.delete("$mref")
obj.delete("$inherits")
# now merge target_obj and obj
keys = (obj.keys + new_obj.keys).uniq
final_obj = {}
Expand Down Expand Up @@ -138,7 +138,7 @@ def self.expand(filename, obj, yaml_opts = {})
new_obj
end

# load a YAML file and expand any $ref/$mref references
# load a YAML file and expand any $ref/$inherits references
# @param filename [String,Pathname] path to the YAML file
# @param yaml_opts [Hash] options to pass to YAML.load_file
# @return [Object] the loaded YAML file
Expand Down
2 changes: 1 addition & 1 deletion schemas/inst_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"name": {
"type": "string"
},
"$mref": {
"$inherits": {
"type": "string",
"pattern": "^(\\.\\./)+common/inst_variable_types\\.yaml#/[a-zA-Z0-9_]+",
"description": "Reference to variable metadata"
Expand Down
Loading