Class: Udb::ExtensionVersion
- Inherits:
-
Object
- Object
- Udb::ExtensionVersion
- Extended by:
- T::Sig
- Includes:
- Comparable
- Defined in:
- lib/udb/obj/extension.rb,
lib/udb/condition.rb
Overview
A specific version of an extension
Defined Under Namespace
Classes: MemomizedState
Instance Attribute Summary collapse
- #arch ⇒ ConfiguredArchitecture readonly
-
#ext ⇒ Extension
readonly
Extension.
-
#name ⇒ String
readonly
Name of the extension.
- #version_spec ⇒ VersionSpec readonly
- #version_str ⇒ String readonly
Class Method Summary collapse
-
.create(yaml, cfg_arch) ⇒ ExtensionVersion
create an ExtensionVersion from YAML.
-
.to_ext_req(ext_vers) ⇒ ExtensionRequirement
given a set of extension versions from the same extension, return the minimal set of extension requirements that would cover then all.
Instance Method Summary collapse
-
#<=>(other) ⇒ Integer?
sorts extension by name, then by version.
- #all_csrs_that_must_be_implemented ⇒ Array<Csr>
-
#all_instructions_that_must_be_implemented ⇒ Array<Instruction>
list of all instructions that must be defined if this extension version is implemented includes both those instructions directly defined by the extension plus any instruction that must exist because of a dependence.
-
#breaking? ⇒ Boolean
Whether or not this is a breaking version (i.e., incompatible with all prior versions).
-
#canonical_version ⇒ String
Canonical version string.
- #changes ⇒ Array<String>?
-
#compatible?(other) ⇒ Boolean
Whether or not
otheris compatible with self. -
#compatible_versions ⇒ Array<ExtensionVersion>
the list is inclsive (this version is present).
- #condition_hash ⇒ Hash{String => T.untyped}, false
- #conditional_extension_requirements(expand:) ⇒ Array<ConditionalExtensionRequirement>
-
#contributors ⇒ Array<Person>
List of contributors to this extension version.
- #csrs ⇒ Array<Csr>
- #defining_extension_requirements ⇒ Array<ConditionalExtensionRequirement>
-
#directly_defined_instructions ⇒ Array<Instruction>
excluding instructions required by a dependence.
- #directly_defined_instructions_set ⇒ Set<Instruction> private
- #eql?(other) ⇒ Boolean
-
#exception_codes ⇒ Array<ExceptionCode>
the list of exception codes that require this extension version (or a compatible version) in order to be defined.
- #ext_conflicts(expand:) ⇒ Array<ConditionalExtensionRequirement>
-
#ext_requirements(expand:) ⇒ Array<ConditionalExtensionRequirement>
list of requirements that must be met to implement this ExtensionVersion If conditional, the requirement only applies when the condition is true.
- #hash ⇒ Integer
- #implied_csrs ⇒ Array<Csr>
- #implied_instructions ⇒ Array<Instruction>
- #implied_instructions_set ⇒ Set<Instruction>
- #in_scope_csrs(xlens) ⇒ Array<Csr>
- #in_scope_instructions(xlens) ⇒ Array<Instruction>
- #initialize(name, version_spec, arch, fail_if_version_does_not_exist: false) constructor
- #inspect ⇒ Object private
-
#interrupt_codes ⇒ Array<InterruptCode>
the list of interrupt codes that require this extension version (or a compatible version) in order to be defined.
-
#params ⇒ Array<Parameter, ParameterWithValue>
The list of parameters for this extension version.
- #ratification_date ⇒ String?
-
#requirements_condition ⇒ AbstractCondition
the combination of this extension version requirement along with the overall extension requirements.
-
#state ⇒ String
The state of the extension version (‘ratified’, ‘developemnt’, etc).
- #to_condition ⇒ AbstractCondition
- #to_ext_req ⇒ ExtensionRequirement
- #to_h ⇒ Hash{String => T.untyped}
-
#to_rvi_s ⇒ String
Formatted like the RVI manual.
-
#to_s ⇒ String
Ext@Version.
- #to_term ⇒ ExtensionTerm private
-
#unconditional_extension_conflicts(expand:) ⇒ Array<ExtensionRequirement>
return all ExtensionRequirements that this ExtensionVersion unconditionally conflicts with When expand is false, just return the list of ExtensionRequirements directly mentioned by the extension When expand is true, also include ExtensionRequirements that are required by those directly mentioned by the extension (i.e., collect the list from the transitive closure of requirements).
-
#unconditional_extension_requirements(expand:) ⇒ Array<ExtensionRequirement>
return all ExtensionRequirements that this ExtensionVersion unconditionally depends on When expand is false, just return the list of ExtensionRequirements directly mentioned by the extension When expand is true, also include ExtensionRequirements that are required by those directly mentioned by the extension (i.e., collect the list from the transitive closure of requirements).
-
#unconditional_extension_version_conflicts ⇒ Array<ExtensionVersion>
return the exhaustive, transitive list of all known extension versions that unconditionally conflict with self.
- #url ⇒ String?
-
#valid? ⇒ Boolean
true if the extension version is defined in the database, regardless of config false otherwise.
-
#version_specific_requirements_condition ⇒ AbstractCondition
Condition that must be met for this version to be allowed.
Constructor Details
#initialize(name, version_spec, arch, fail_if_version_does_not_exist: false)
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 |
# File 'lib/udb/obj/extension.rb', line 498 def initialize(name, version_spec, arch, fail_if_version_does_not_exist: false) @name = name.freeze @version_spec = version_spec.freeze @version_str = @version_spec.canonical.freeze @arch = arch @ext = @arch.extension(@name) if fail_if_version_does_not_exist && @ext.nil? raise "Extension #{name} not found in architecture" elsif @ext.nil? Udb.logger.warn "Extension #{name} not found in architecture" return # can't go futher end @data = @ext.data["versions"].find { |v| VersionSpec.new(v["version"]) == @version_spec } if fail_if_version_does_not_exist && @data.nil? raise ArgumentError, "Version #{version_str} of #{@name} extension is not defined" elsif @data.nil? Udb.logger.warn "Version #{version_str} of #{@name} extension is not defined" end @memo = MemomizedState.new end |
Instance Attribute Details
#arch ⇒ ConfiguredArchitecture (readonly)
447 448 449 |
# File 'lib/udb/obj/extension.rb', line 447 def arch @arch end |
#ext ⇒ Extension (readonly)
Returns Extension.
436 437 438 |
# File 'lib/udb/obj/extension.rb', line 436 def ext @ext end |
#name ⇒ String (readonly)
Returns Name of the extension.
432 433 434 |
# File 'lib/udb/obj/extension.rb', line 432 def name @name end |
#version_spec ⇒ VersionSpec (readonly)
440 441 442 |
# File 'lib/udb/obj/extension.rb', line 440 def version_spec @version_spec end |
#version_str ⇒ String (readonly)
444 445 446 |
# File 'lib/udb/obj/extension.rb', line 444 def version_str @version_str end |
Class Method Details
.create(yaml, cfg_arch) ⇒ ExtensionVersion
create an ExtensionVersion from YAML
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 |
# File 'lib/udb/obj/extension.rb', line 456 def self.create(yaml, cfg_arch) requirements = if yaml.key?("version") yaml.fetch("version") else raise "not an extension version" end if requirements.is_a?(Array) if requirements.size != 1 raise "not an extension version: #{requirements} (#{requirements.size})" end requirements = requirements.fetch(0) end begin cfg_arch.extension_version(yaml.fetch("name"), RequirementSpec.new(requirements).version_spec) rescue raise "not an extension version" end end |
.to_ext_req(ext_vers) ⇒ ExtensionRequirement
given a set of extension versions from the same extension, return the minimal set of extension requirements that would cover then all
542 543 544 545 546 547 548 549 550 551 552 |
# File 'lib/udb/obj/extension.rb', line 542 def self.to_ext_req(ext_vers) raise "ext_vers cannot be empty" if ext_vers.empty? raise "All ext_vers must be of the same extension" unless ext_vers.all? { |ev| ev.name == ext_vers.fetch(0).name } sorted = ext_vers.sort unless T.must(sorted.min).compatible?(T.must(sorted.max)) raise "Impossible to combine because the set contains incompatible versions" end ext_vers.fetch(0).arch.extension_requirement(ext_vers.fetch(0).name, "~> #{T.must(sorted.min).version_str}") end |
Instance Method Details
#<=>(other) ⇒ Integer?
sorts extension by name, then by version
1128 1129 1130 1131 1132 1133 1134 1135 1136 |
# File 'lib/udb/obj/extension.rb', line 1128 def <=>(other) return nil unless other.is_a?(ExtensionVersion) if other.name != @name @name <=> other.name else @version_spec <=> other.version_spec end end |
#all_csrs_that_must_be_implemented ⇒ Array<Csr>
733 734 735 |
# File 'lib/udb/obj/extension.rb', line 733 def all_csrs_that_must_be_implemented @all_csrs_that_must_be_implemented ||= csrs + implied_csrs end |
#all_instructions_that_must_be_implemented ⇒ Array<Instruction>
list of all instructions that must be defined if this extension version is implemented includes both those instructions directly defined by the extension plus any instruction that must exist because of a dependence
695 696 697 698 |
# File 'lib/udb/obj/extension.rb', line 695 def all_instructions_that_must_be_implemented @all_instructions_that_must_be_implemented ||= directly_defined_instructions + implied_instructions end |
#breaking? ⇒ Boolean
Returns Whether or not this is a breaking version (i.e., incompatible with all prior versions).
599 600 601 |
# File 'lib/udb/obj/extension.rb', line 599 def breaking? !@data["breaking"].nil? end |
#canonical_version ⇒ String
Returns Canonical version string.
605 |
# File 'lib/udb/obj/extension.rb', line 605 def canonical_version = @version_spec.canonical |
#changes ⇒ Array<String>?
629 |
# File 'lib/udb/obj/extension.rb', line 629 def changes = @data["changes"].nil? ? [] : T.cast(@data.fetch("changes"), T::Array[String]) |
#compatible?(other) ⇒ Boolean
Returns Whether or not other is compatible with self.
595 |
# File 'lib/udb/obj/extension.rb', line 595 def compatible?(other) = compatible_versions.include?(other) |
#compatible_versions ⇒ Array<ExtensionVersion>
the list is inclsive (this version is present)
579 580 581 582 583 584 585 586 587 588 589 590 |
# File 'lib/udb/obj/extension.rb', line 579 def compatible_versions return @memo.compatible_versions unless @memo.compatible_versions.nil? @memo.compatible_versions = [] @ext.versions.each do |v| @memo.compatible_versions << v if v.version_spec >= @version_spec break if @memo.compatible_versions.size.positive? && v.breaking? end raise "Didn't even find self?" if compatible_versions.empty? @memo.compatible_versions end |
#condition_hash ⇒ Hash{String => T.untyped}, false
567 568 569 570 571 572 573 574 |
# File 'lib/udb/obj/extension.rb', line 567 def condition_hash { "extension" => { "name" => name, "version" => "= #{version_str}" } } end |
#conditional_extension_requirements(expand:) ⇒ Array<ConditionalExtensionRequirement>
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 |
# File 'lib/udb/obj/extension.rb', line 927 def conditional_extension_requirements(expand:) if && !@memo..nil? @memo. elsif ! && !@memo..nil? @memo. else req = requirements_condition.to_logic_tree(expand:) cb = LogicNode.make_replace_cb do |node| next node unless node.type == LogicNodeType::Term rterm = node.children.fetch(0) next node unless rterm.is_a?(ExtensionTerm) # remove self next LogicNode::True if rterm.to_ext_req(@arch).satisfied_by?(self) # remove terms unconditionally true or false next LogicNode::True if unconditional_extension_requirements(expand: true).any? { |ext_req| ext_req.satisfied_by?(rterm.to_ext_req(@arch)) } next LogicNode::False if unconditional_extension_conflicts(expand: true).any? { |ext_req| ext_req.satisfied_by?(rterm.to_ext_req(@arch)) } node end remaining = req.replace_terms(cb).minimize(LogicNode::CanonicalizationType::ProductOfSums) list = T.let([], T::Array[ConditionalExtensionRequirement]) # for the remaining terms, find out which ones remaining.terms.each do |term| next unless term.is_a?(ExtensionTerm) # find unconditional reqs of self && term c = Condition.conjunction([term.to_condition(@arch), to_condition], @arch) ctree = c.to_logic_tree(expand: true) unconditional_terms = remaining.terms.select do |cterm| next if cterm.is_a?(ParameterTerm) || cterm.is_a?(XlenTerm) raise "?" if cterm.is_a?(FreeTerm) next if cterm.name == name next if cterm.name == term.name cb = LogicNode.make_replace_cb do |node| if node.type == LogicNodeType::Term && node.node_children.fetch(0).is_a?(ExtensionTerm) node_term = T.cast(node.node_children.fetch(0), ExtensionTerm) if node_term.name == name LogicNode::True elsif node_term.name == cterm.name LogicNode::False else node end else node end end !ctree.replace_terms(cb).satisfiable? end next if unconditional_terms.empty? if unconditional_terms.size == 1 cond = T.cast(unconditional_terms.fetch(0), ExtensionTerm).to_ext_req(@arch).to_condition contradiction = Condition.conjunction( [ cond, Condition.not(term.to_condition(@arch), @arch), to_condition ], @arch ) is_needed = !contradiction.satisfiable? if is_needed if Condition.conjunction([cond, Condition.not(term.to_condition(@arch), @arch)], @arch).satisfiable? # skip reqs that are implied list << ConditionalExtensionRequirement.new( ext_req: term.to_ext_req(@arch), cond: ) end end else conj = Condition.conjunction(unconditional_terms.map { |t| T.cast(t, ExtensionTerm).to_condition(@arch) }, @arch) conj_tree = conj.to_logic_tree(expand: false) formula = LogicNode.new( LogicNodeType::And, conj_tree.node_children.map do |node| covered = conj_tree.node_children.any? do |other_node| next false if node.equal?(other_node) if Condition.conjunction([to_condition, Condition.new(other_node.to_h, @arch)], @arch).always_implies?(Condition.new(node.to_h, @arch)) true else false end end if covered LogicNode::True else node end end ) # is this needed? if self can still be satisfied when condition is false but term is true, # this term isn't actually a requirement (it's most likely related to a conflict) contradiction = Condition.conjunction( [ conj, Condition.not(term.to_condition(@arch), @arch), to_condition ], @arch ) is_needed = !contradiction.satisfiable? cond = Condition.new(formula.reduce.to_h, @arch) if is_needed # && Condition.conjunction([cond, term.to_condition(@arch), to_condition], @arch).satisfiable? # make sure it's a requirement if Condition.conjunction([cond, Condition.not(term.to_condition(@arch), @arch)], @arch).satisfiable? list << ConditionalExtensionRequirement.new( ext_req: term.to_ext_req(@arch), cond: ) end end end end if list.each do |cond_ext_req| ext_ver = T.must(cond_ext_req.ext_req..max) ext_ver.ext_requirements(expand:).each do |nested_cond_ext_req| already_in_cond_list = list.any? { |c| c.ext_req.satisfied_by?(nested_cond_ext_req.ext_req) } \ || list.any? { |c| c.cond.to_logic_tree(expand: false).terms.any? { |t| T.cast(t, ExtensionTerm).to_ext_req(@arch).satisfied_by?(nested_cond_ext_req.ext_req) } } already_in_uncond_list = unconditional_extension_requirements(expand:).any? { |ext_req| nested_cond_ext_req.ext_req.satisfied_by?(ext_req) } next if already_in_uncond_list if already_in_cond_list # keep the one with the more expansive condition else if nested_cond_ext_req.cond.empty? list << ConditionalExtensionRequirement.new( ext_req: nested_cond_ext_req.ext_req, cond: cond_ext_req.cond ) else list << ConditionalExtensionRequirement.new( ext_req: nested_cond_ext_req.ext_req, cond: Condition.conjunction([cond_ext_req.cond, nested_cond_ext_req.cond], @arch) ) end end end end end if @memo. = list @memo..freeze else @memo. = list @memo..freeze end end end |
#contributors ⇒ Array<Person>
Returns List of contributors to this extension version.
636 637 638 639 640 641 642 643 644 |
# File 'lib/udb/obj/extension.rb', line 636 def contributors return @contributors unless @contributors.nil? @contributors = [] @data["contributors"]&.each do |c| @contributors << Person.new(c) end @contributors end |
#csrs ⇒ Array<Csr>
706 707 708 709 710 711 |
# File 'lib/udb/obj/extension.rb', line 706 def csrs @csrs ||= ext.csrs.select do |csr| (csr.defined_by_condition & to_condition).satisfiable? end end |
#defining_extension_requirements ⇒ Array<ConditionalExtensionRequirement>
788 789 790 791 |
# File 'lib/udb/obj/extension.rb', line 788 def defining_extension_requirements [] # combined_requirements_condition.implied_extension_requirements end |
#directly_defined_instructions ⇒ Array<Instruction>
excluding instructions required by a dependence
658 659 660 661 662 663 |
# File 'lib/udb/obj/extension.rb', line 658 def directly_defined_instructions @instructions ||= ext.instructions.select do |inst| (inst.defined_by_condition & to_condition).satisfiable? end end |
#directly_defined_instructions_set ⇒ Set<Instruction>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
667 668 669 |
# File 'lib/udb/obj/extension.rb', line 667 def directly_defined_instructions_set @instructions_set ||= Set.new(directly_defined_instructions) end |
#eql?(other) ⇒ Boolean
608 609 610 611 612 613 614 |
# File 'lib/udb/obj/extension.rb', line 608 def eql?(other) if other.is_a?(ExtensionVersion) self.==(other) else false end end |
#exception_codes ⇒ Array<ExceptionCode>
the list of exception codes that require this extension version (or a compatible version) in order to be defined
1141 1142 1143 1144 1145 1146 1147 1148 1149 |
# File 'lib/udb/obj/extension.rb', line 1141 def exception_codes @exception_codes ||= @arch.exception_codes.select do |ecode| # define every extension version except this one (and compatible), # and test if the condition can be satisfied ecode.defined_by_condition.satisfied_by_ext_req?(@arch.extension_requirement(@name, "~> #{@version_spec}"), include_requirements: false) || ecode.defined_by_condition.satisfiability_depends_on_ext_req?(@arch.extension_requirement(@name, "~> #{@version_spec}")) end end |
#ext_conflicts(expand:) ⇒ Array<ConditionalExtensionRequirement>
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 |
# File 'lib/udb/obj/extension.rb', line 1115 def ext_conflicts(expand:) # make a condition for the version, expand it, and then report what comes out, minus self if @memo. ||= unconditional_extension_conflicts(expand:).map { |ext_req| ConditionalExtensionRequirement.new(ext_req:, cond: AlwaysTrueCondition.new(@arch)) } else @memo. ||= unconditional_extension_conflicts(expand:).map { |ext_req| ConditionalExtensionRequirement.new(ext_req:, cond: AlwaysTrueCondition.new(@arch)) } end end |
#ext_requirements(expand:) ⇒ Array<ConditionalExtensionRequirement>
list of requirements that must be met to implement this ExtensionVersion If conditional, the requirement only applies when the condition is true
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 |
# File 'lib/udb/obj/extension.rb', line 1101 def ext_requirements(expand:) # make a condition for the version, expand it, and then report what comes out, minus self if @memo. ||= unconditional_extension_requirements(expand:).map { |ext_req| ConditionalExtensionRequirement.new(ext_req:, cond: AlwaysTrueCondition.new(@arch)) } \ + conditional_extension_requirements(expand:) else @memo. ||= unconditional_extension_requirements(expand:).map { |ext_req| ConditionalExtensionRequirement.new(ext_req:, cond: AlwaysTrueCondition.new(@arch)) } \ + conditional_extension_requirements(expand:) end end |
#hash ⇒ Integer
617 618 619 |
# File 'lib/udb/obj/extension.rb', line 617 def hash @memo.key ||= [@name, @version_spec].hash end |
#implied_csrs ⇒ Array<Csr>
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 |
# File 'lib/udb/obj/extension.rb', line 714 def implied_csrs @implied_csrs ||= begin pb = Udb.( "Finding implied csrs for #{self} [:bar] :current/:total", total: @arch.csrs.size, clear: true ) @arch.csrs.select do |csr| pb.advance if csr.defined_by_condition.mentions?(self, expand: true) (-csr.defined_by_condition & requirements_condition).unsatisfiable? end end end end |
#implied_instructions ⇒ Array<Instruction>
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 |
# File 'lib/udb/obj/extension.rb', line 672 def implied_instructions @implied_instructions ||= begin pb = Udb.( "Finding implied instructions for #{self} [:bar] :current/:total", total: @arch.instructions.size, clear: true ) @arch.instructions.select do |i| pb.advance next if directly_defined_instructions_set.include?(i) (-i.defined_by_condition & to_condition).unsatisfiable? end end end |
#implied_instructions_set ⇒ Set<Instruction>
701 702 703 |
# File 'lib/udb/obj/extension.rb', line 701 def implied_instructions_set @implied_instructions_set ||= Set.new(implied_instructions) end |
#in_scope_csrs(xlens) ⇒ Array<Csr>
1163 1164 1165 1166 1167 |
# File 'lib/udb/obj/extension.rb', line 1163 def in_scope_csrs(xlens) csrs.select do |csr| csr.base.nil? || xlens.include?(csr.base) end end |
#in_scope_instructions(xlens) ⇒ Array<Instruction>
1170 1171 1172 1173 1174 |
# File 'lib/udb/obj/extension.rb', line 1170 def in_scope_instructions(xlens) directly_defined_instructions.select do |inst| inst.base.nil? || xlens.include?(inst.base) end end |
#inspect ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
530 531 532 |
# File 'lib/udb/obj/extension.rb', line 530 def inspect to_s end |
#interrupt_codes ⇒ Array<InterruptCode>
the list of interrupt codes that require this extension version (or a compatible version) in order to be defined
1154 1155 1156 1157 1158 1159 1160 |
# File 'lib/udb/obj/extension.rb', line 1154 def interrupt_codes @interrupt_codes ||= @arch.interrupt_codes.select do |icode| icode.defined_by_condition.satisfied_by_ext_req?(@arch.extension_requirement(@name, "~> #{@version_spec}"), include_requirements: false) || icode.defined_by_condition.satisfiability_depends_on_ext_req?(@arch.extension_requirement(@name, "~> #{@version_spec}")) end end |
#params ⇒ Array<Parameter, ParameterWithValue>
Returns The list of parameters for this extension version.
648 649 650 651 652 653 |
# File 'lib/udb/obj/extension.rb', line 648 def params @params ||= ext.params.select do |param| (param.defined_by_condition & to_condition).satisfiable? end end |
#ratification_date ⇒ String?
626 |
# File 'lib/udb/obj/extension.rb', line 626 def ratification_date = @data["ratification_date"] |
#requirements_condition ⇒ AbstractCondition
the combination of this extension version requirement along with the overall extension requirements
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 |
# File 'lib/udb/obj/extension.rb', line 768 def requirements_condition @requirements_condition ||= if @data.key?("requirements") && ext.data.key?("requirements") Condition.new( { "allOf" => [ @data.fetch("requirements"), ext.data.fetch("requirements") ] }, @arch ) elsif !@data.key?("requirements") ext.general_extension_requirements_condition else version_specific_requirements_condition end end |
#state ⇒ String
Returns The state of the extension version (‘ratified’, ‘developemnt’, etc).
623 |
# File 'lib/udb/obj/extension.rb', line 623 def state = T.cast(@data.fetch("state"), String) |
#to_condition ⇒ AbstractCondition
561 562 563 564 |
# File 'lib/udb/obj/extension.rb', line 561 def to_condition @memo.condition ||= Condition.new(condition_hash, @arch) end |
#to_ext_req ⇒ ExtensionRequirement
1177 1178 1179 |
# File 'lib/udb/obj/extension.rb', line 1177 def to_ext_req @ext_req ||= @arch.extension_requirement(name, "= #{version_str}") end |
#to_h ⇒ Hash{String => T.untyped}
1182 1183 1184 1185 1186 1187 1188 |
# File 'lib/udb/obj/extension.rb', line 1182 def to_h @h ||= { "name" => @name, "version" => "= #{version_str}" } end |
#to_rvi_s ⇒ String
Returns formatted like the RVI manual.
742 743 744 |
# File 'lib/udb/obj/extension.rb', line 742 def to_rvi_s "#{name}#{@version_spec.to_rvi_s}" end |
#to_s ⇒ String
Returns Ext@Version.
748 749 750 |
# File 'lib/udb/obj/extension.rb', line 748 def to_s "#{name}@#{@version_spec.canonical}" end |
#to_term ⇒ ExtensionTerm
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
556 557 558 |
# File 'lib/udb/obj/extension.rb', line 556 def to_term @memo.term ||= ExtensionTerm.new(@name, "=", @version_str) end |
#unconditional_extension_conflicts(expand:) ⇒ Array<ExtensionRequirement>
return all ExtensionRequirements that this ExtensionVersion unconditionally conflicts with When expand is false, just return the list of ExtensionRequirements directly mentioned by the extension When expand is true, also include ExtensionRequirements that are required by those directly mentioned by the extension
(i.e., collect the list from the transitive closure of requirements)
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 |
# File 'lib/udb/obj/extension.rb', line 871 def unconditional_extension_conflicts(expand:) if && !@memo..nil? @memo. elsif ! && !@memo..nil? @memo. else list = begin requirements_condition.ext_req_terms(expand:).select do |ext_req| (requirements_condition & ext_req.to_condition).unsatisfiable? end # req = requirements_condition.to_logic_tree(expand:) # expand_req = requirements_condition.to_logic_tree(expand: true) # # find all unconditional reqs -- that is, # # reqs that must always be satisfied for requirements to be met # unconditional_terms = # req.terms.select do |term| # next if term.is_a?(ParameterTerm) || term.is_a?(XlenTerm) # raise "?" if term.is_a?(FreeTerm) # next if term.name == name # # see if req is unsatisfiable when term is present # cb = LogicNode.make_replace_cb do |node| # if node.type == LogicNodeType::Term && node.node_children.fetch(0).is_a?(ExtensionTerm) # node_term = T.cast(node.node_children.fetch(0), ExtensionTerm) # if node_term.name == name # LogicNode::True # elsif node_term.name == term.name # LogicNode::True # else # node # end # else # node # end # end # !expand_req.replace_terms(cb).satisfiable? # end # T.cast(unconditional_terms, T::Array[ExtensionTerm]).map { |t| t.to_ext_req(@arch) } end if @memo. = list @memo..freeze else @memo. = list @memo..freeze end end end |
#unconditional_extension_requirements(expand:) ⇒ Array<ExtensionRequirement>
return all ExtensionRequirements that this ExtensionVersion unconditionally depends on When expand is false, just return the list of ExtensionRequirements directly mentioned by the extension When expand is true, also include ExtensionRequirements that are required by those directly mentioned by the extension
(i.e., collect the list from the transitive closure of requirements)
798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 |
# File 'lib/udb/obj/extension.rb', line 798 def unconditional_extension_requirements(expand:) if && !@memo..nil? @memo. elsif ! && !@memo..nil? @memo. else list = begin requirements_condition.ext_req_terms(expand:).select do |ext_req| # is requirements_condition satisfiable when ext_req is not met? (requirements_condition & -ext_req.to_condition).unsatisfiable? end # req = requirements_condition.to_logic_tree(expand:) # expand_req = requirements_condition.to_logic_tree(expand: true) # # find all unconditional reqs -- that is, # # reqs that must always be satisfied for requirements to be met # unconditional_terms = # req.terms.select do |term| # next if term.is_a?(ParameterTerm) || term.is_a?(XlenTerm) # raise "?" if term.is_a?(FreeTerm) # next if term.name == name # # see if req is satisfiable when term is absent # cb = LogicNode.make_replace_cb do |node| # if node.type == LogicNodeType::Term && node.node_children.fetch(0).is_a?(ExtensionTerm) # node_term = T.cast(node.node_children.fetch(0), ExtensionTerm) # if node_term.name == name # LogicNode::True # elsif node_term.name == term.name # LogicNode::False # else # node # end # else # node # end # end # !expand_req.replace_terms(cb).satisfiable? # end # T.cast(unconditional_terms, T::Array[ExtensionTerm]).map { |t| t.to_ext_req(@arch) } end if @memo. = list @memo..freeze else @memo. = list @memo..freeze end end end |
#unconditional_extension_version_conflicts ⇒ Array<ExtensionVersion>
return the exhaustive, transitive list of all known extension versions that unconditionally conflict with self
856 857 858 859 860 861 862 863 864 |
# File 'lib/udb/obj/extension.rb', line 856 def unconditional_extension_version_conflicts @unconditional_extension_version_conflicts ||= @arch.extension_versions.select do |ext_ver| next if ext_ver.name == name (to_condition & ext_ver.to_condition).unsatisfiable? # !Condition.conjunction([to_condition, ext_ver.to_condition], @arch).satisfiable? end end |
#url ⇒ String?
632 |
# File 'lib/udb/obj/extension.rb', line 632 def url = @data["url"] |
#valid? ⇒ Boolean
true if the extension version is defined in the database, regardless of config false otherwise
527 |
# File 'lib/udb/obj/extension.rb', line 527 def valid? = !@ext.nil? |
#version_specific_requirements_condition ⇒ AbstractCondition
Returns Condition that must be met for this version to be allowed.
754 755 756 757 758 759 760 761 762 763 764 |
# File 'lib/udb/obj/extension.rb', line 754 def version_specific_requirements_condition @requirements_condition ||= @data.key?("requirements") \ ? Condition.new( @data.fetch("requirements"), @arch, input_file: Pathname.new(ext.__source), input_line: ext.source_line(["versions", ext.data.fetch("versions").index { |v| VersionSpec.new(v["version"]) == version_spec }]) ) : AlwaysTrueCondition.new(@arch) end |