22# frozen_string_literal: true
33require 'json'
44require 'bigdecimal'
5+ require 'set'
56
67module JSON ::LD
78 class Context
@@ -112,7 +113,7 @@ def initialize(term,
112113 def container_mapping = ( mapping )
113114 mapping = Array ( mapping )
114115 if @as_set = mapping . include? ( '@set' )
115- mapping -= %w( @set )
116+ mapping . delete ( ' @set' )
116117 end
117118 @container_mapping = mapping . first
118119 end
@@ -554,7 +555,7 @@ def create_term_definition(local_context, term, defined)
554555 end
555556
556557 # Since keywords cannot be overridden, term must not be a keyword. Otherwise, an invalid value has been detected, which is an error.
557- if KEYWORDS . include? ( term ) && ! %w( @vocab @language @version ) . include? ( term )
558+ if KEYWORDS . include? ( term ) && ( term != ' @vocab' && term != ' @language' && term != ' @version' )
558559 raise JsonLdError ::KeywordRedefinition , "term must not be a keyword: #{ term . inspect } " if
559560 @options [ :validate ]
560561 elsif !term_valid? ( term ) && @options [ :validate ]
@@ -606,7 +607,7 @@ def create_term_definition(local_context, term, defined)
606607 else
607608 :error
608609 end
609- unless %w( @id @vocab ) . include? ( type ) || type . is_a? ( RDF ::URI ) && type . absolute?
610+ unless ( type == ' @id' || type == ' @vocab' ) || type . is_a? ( RDF ::URI ) && type . absolute?
610611 raise JsonLdError ::InvalidTypeMapping , "unknown mapping for '@type': #{ type . inspect } on term #{ term . inspect } "
611612 end
612613 #log_debug("") {"type_mapping: #{type.inspect}"}
@@ -615,7 +616,7 @@ def create_term_definition(local_context, term, defined)
615616
616617 if value . has_key? ( '@reverse' )
617618 raise JsonLdError ::InvalidReverseProperty , "unexpected key in #{ value . inspect } on term #{ term . inspect } " if
618- value . keys . any? { | k | %w( @id @ nest) . include? ( k ) }
619+ value . key? ( '@id' ) || value . key? ( '@ nest' )
619620 raise JsonLdError ::InvalidIRIMapping , "expected value of @reverse to be a string: #{ value [ '@reverse' ] . inspect } on term #{ term . inspect } " unless
620621 value [ '@reverse' ] . is_a? ( String )
621622
@@ -633,7 +634,7 @@ def create_term_definition(local_context, term, defined)
633634 container = value [ '@container' ]
634635 raise JsonLdError ::InvalidReverseProperty ,
635636 "unknown mapping for '@container' to #{ container . inspect } on term #{ term . inspect } " unless
636- container . is_a? ( String ) && [ '@set' , '@index' ] . include? ( container )
637+ container . is_a? ( String ) && ( container == '@set' || container == '@index' )
637638 definition . container_mapping = check_container ( container , local_context , defined , term )
638639 end
639640 definition . reverse_property = true
@@ -654,7 +655,7 @@ def create_term_definition(local_context, term, defined)
654655 ( simple_term || ( ( processingMode || 'json-ld-1.0' ) == 'json-ld-1.0' ) )
655656 elsif term . include? ( ':' )
656657 # If term is a compact IRI with a prefix that is a key in local context then a dependency has been found. Use this algorithm recursively passing active context, local context, the prefix as term, and defined.
657- prefix , suffix = term . split ( ':' )
658+ prefix , suffix = term . split ( ':' , 2 )
658659 create_term_definition ( local_context , prefix , defined ) if local_context . has_key? ( prefix )
659660
660661 definition . id = if td = term_definitions [ prefix ]
@@ -791,15 +792,15 @@ def from_vocabulary(graph)
791792 ( statements [ statement . subject ] ||= [ ] ) << statement
792793
793794 # Keep track of predicate ranges
794- if [ RDF ::RDFS . range , RDF ::SCHEMA . rangeIncludes ] . include? ( statement . predicate )
795+ if [ RDF ::RDFS . range , RDF ::SCHEMA . rangeIncludes ] . include? ( statement . predicate )
795796 ( ranges [ statement . subject ] ||= [ ] ) << statement . object
796797 end
797798 end
798799
799800 # Add term definitions for each class and property not in vocab, and
800801 # for those properties having an object range
801802 statements . each do |subject , values |
802- types = values . select { | v | v . predicate == RDF . type } . map ( & :object )
803+ types = values . each_with_object ( [ ] ) { | v , memo | memo << v . object if v . predicate == RDF . type }
803804 is_property = types . any? { |t | t . to_s . include? ( "Property" ) }
804805
805806 term = subject . to_s . split ( /[\/ \# ]/ ) . last
@@ -886,7 +887,7 @@ def container(term)
886887 # @param [Term, #to_s] term in unexpanded form
887888 # @return [Boolean]
888889 def as_array? ( term )
889- return true if %w( @graph @list ) . include? ( term )
890+ return true if term == ' @graph' || term == ' @list'
890891 term = find_definition ( term )
891892 term && ( term . as_set || term . container_mapping == '@list' )
892893 end
@@ -979,12 +980,14 @@ def reverse_term(term)
979980 # IRI or String, if it's a keyword
980981 # @raise [JSON::LD::JsonLdError::InvalidIRIMapping] if the value cannot be expanded
981982 # @see http://json-ld.org/spec/latest/json-ld-api/#iri-expansion
982- def expand_iri ( value , documentRelative : false , vocab : false , local_context : nil , defined : { } , quiet : false , **options )
983+ def expand_iri ( value , documentRelative : false , vocab : false , local_context : nil , defined : nil , quiet : false , **options )
983984 return value unless value . is_a? ( String )
984985
985986 return value if KEYWORDS . include? ( value )
986987 #log_debug("expand_iri") {"value: #{value.inspect}"} unless quiet
987988
989+ defined = defined || { } # if we initialized in the keyword arg we would allocate {} at each invokation, even in the 2 (common) early returns above.
990+
988991 # If local context is not null, it contains a key that equals value, and the value associated with the key that equals value in defined is not true, then invoke the Create Term Definition subalgorithm, passing active context, local context, value as term, and defined. This will ensure that a term definition is created for value in active context during Context Processing.
989992 if local_context && local_context . has_key? ( value ) && !defined [ value ]
990993 create_term_definition ( local_context , value , defined )
@@ -1003,7 +1006,7 @@ def expand_iri(value, documentRelative: false, vocab: false, local_context: nil,
10031006
10041007 # If prefix is underscore (_) or suffix begins with double-forward-slash (//), return value as it is already an absolute IRI or a blank node identifier.
10051008 return RDF ::Node . new ( namer . get_sym ( suffix ) ) if prefix == '_'
1006- return RDF ::URI ( value ) if suffix [ 0 , 2 ] == '//'
1009+ return RDF ::URI ( value ) if suffix . start_with? ( '//' )
10071010
10081011 # If local context is not null, it contains a key that equals prefix, and the value associated with the key that equals prefix in defined is not true, invoke the Create Term Definition algorithm, passing active context, local context, prefix as term, and defined. This will ensure that a term definition is created for prefix in active context during Context Processing.
10091012 if local_context && local_context . has_key? ( prefix ) && !defined [ prefix ]
@@ -1138,7 +1141,7 @@ def compact_iri(iri, value: nil, vocab: nil, reverse: false, quiet: false, **opt
11381141 tl_value ||= '@null'
11391142 preferred_values = [ ]
11401143 preferred_values << '@reverse' if tl_value == '@reverse'
1141- if %w( @id @reverse ) . include? ( tl_value ) && value . is_a? ( Hash ) && value . has_key? ( '@id' )
1144+ if ( tl_value == ' @id' || tl_value == ' @reverse' ) && value . is_a? ( Hash ) && value . has_key? ( '@id' )
11421145 t_iri = compact_iri ( value [ '@id' ] , vocab : true , document_relative : true )
11431146 if ( r_td = term_definitions [ t_iri ] ) && r_td . id == value [ '@id' ]
11441147 preferred_values . concat ( %w( @vocab @id @none ) )
@@ -1204,6 +1207,8 @@ def compact_iri(iri, value: nil, vocab: nil, reverse: false, quiet: false, **opt
12041207 end
12051208 end
12061209
1210+ RDF_LITERAL_NATIVE_TYPES = Set . new ( [ RDF ::XSD . boolean , RDF ::XSD . integer , RDF ::XSD . double ] ) . freeze
1211+
12071212 ##
12081213 # If active property has a type mapping in the active context set to @id or @vocab, a JSON object with a single member @id whose value is the result of using the IRI Expansion algorithm on value is returned.
12091214 #
@@ -1246,7 +1251,7 @@ def expand_value(property, value, useNativeTypes: false, **options)
12461251 when RDF ::Literal
12471252 #log_debug("Literal") {"datatype: #{value.datatype.inspect}"}
12481253 res = { }
1249- if useNativeTypes && [ RDF :: XSD . boolean , RDF :: XSD . integer , RDF :: XSD . double ] . include? ( value . datatype )
1254+ if useNativeTypes && RDF_LITERAL_NATIVE_TYPES . include? ( value . datatype )
12501255 res [ '@value' ] = value . object
12511256 res [ '@type' ] = uri ( coerce ( property ) ) if coerce ( property )
12521257 else
@@ -1297,7 +1302,7 @@ def expand_value(property, value, useNativeTypes: false, **options)
12971302 def compact_value ( property , value , options = { } )
12981303 #log_debug("compact_value") {"property: #{property.inspect}, value: #{value.inspect}"}
12991304
1300- num_members = value . keys . length
1305+ num_members = value . length
13011306
13021307 num_members -= 1 if index? ( value ) && container ( property ) == '@index'
13031308 if num_members > 2
@@ -1407,7 +1412,7 @@ def dup
14071412 def coerce ( property )
14081413 # Map property, if it's not an RDF::Value
14091414 # @type is always is an IRI
1410- return '@id' if [ RDF . type , '@type' ] . include? ( property )
1415+ return '@id' if property == RDF . type || property == '@type'
14111416 term_definitions [ property ] && term_definitions [ property ] . type_mapping
14121417 end
14131418
@@ -1573,9 +1578,10 @@ def remove_base(iri)
15731578 #
15741579 # @return [Array<RDF::URI>]
15751580 def mappings
1576- term_definitions . inject ( { } ) do |memo , ( t , td ) |
1577- memo [ t ] = td ? td . id : nil
1578- memo
1581+ { } . tap do |memo |
1582+ term_definitions . each_pair do |t , td |
1583+ memo [ t ] = td ? td . id : nil
1584+ end
15791585 end
15801586 end
15811587
@@ -1595,9 +1601,10 @@ def mapping(term)
15951601 # @return [Array<String>]
15961602 # @deprecated
15971603 def languages
1598- term_definitions . inject ( { } ) do |memo , ( t , td ) |
1599- memo [ t ] = td . language_mapping
1600- memo
1604+ { } . tap do |memo |
1605+ term_definitions . each_pair do |t , td |
1606+ memo [ t ] = td . language_mapping
1607+ end
16011608 end
16021609 end
16031610
@@ -1610,7 +1617,7 @@ def check_container(container, local_context, defined, term)
16101617 end
16111618
16121619 val = Array ( container )
1613- val -= %w( @set ) if has_set = val . include? ( '@set' )
1620+ val . delete ( ' @set' ) if has_set = val . include? ( '@set' )
16141621
16151622 raise JsonLdError ::InvalidContainerMapping ,
16161623 "'@container' has more than one value other than @set" if val . length > 1
0 commit comments