lib/rbs/parser.y in rbs-0.5.0 vs lib/rbs/parser.y in rbs-0.6.0

- old
+ new

@@ -104,45 +104,83 @@ result = Declarations::Class::Super.new(name: val[1].value, args: val[3]) } module_decl: - annotations kMODULE start_new_scope class_name module_type_params module_self_type class_members kEND { + annotations kMODULE start_new_scope class_name module_type_params colon_module_self_types class_members kEND { reset_variable_scope location = val[1].location + val[7].location result = Declarations::Module.new( name: val[3].value, type_params: val[4]&.value || Declarations::ModuleTypeParams.empty, - self_type: val[5], + self_types: val[5], members: val[6], annotations: val[0], location: location, comment: leading_comment(val[0].first&.location || location) ) } - | annotations kMODULE start_new_scope tUKEYWORD type class_members kEND { + | annotations kMODULE start_new_scope tUKEYWORD module_self_types class_members kEND { reset_variable_scope location = val[1].location + val[6].location result = Declarations::Module.new( name: val[3].value, type_params: Declarations::ModuleTypeParams.empty, - self_type: val[4], + self_types: val[4], members: val[5], annotations: val[0], location: location, comment: leading_comment(val[0].first&.location || location) ) } - module_self_type: - { result = nil } - | kCOLON type { + colon_module_self_types: + { result = [] } + | kCOLON module_self_types { result = val[1] } + module_self_types: + module_self_type { + result = [val[0]] + } + | module_self_types kCOMMA module_self_type { + result = val[0].push(val[2]) + } + + module_self_type: + qualified_name kLBRACKET type_list kRBRACKET { + name = val[0].value + args = val[2] + location = val[0].location + val[3].location + + case + when name.class? + result = Declarations::Module::Self.new(name: name, args: args, location: location) + when name.interface? + result = Declarations::Module::Self.new(name: name, args: args, location: location) + else + raise SemanticsError.new("Module self type should be instance or interface", subject: val[0], location: val[0].location) + end + } + | qualified_name { + name = val[0].value + args = [] + location = val[0].location + + case + when name.class? + result = Declarations::Module::Self.new(name: name, args: args, location: location) + when name.interface? + result = Declarations::Module::Self.new(name: name, args: args, location: location) + else + raise SemanticsError.new("Module self type should be instance or interface", subject: val[0], location: val[0].location) + end + } + class_members: { result = [] } | class_members class_member { result = val[0].push(val[1]) } @@ -1028,10 +1066,11 @@ @input = StringScanner.new(buffer.content) @eof_re = eof_re @eof = false @bound_variables_stack = [] @comments = {} + @ascii_only = buffer.content.ascii_only? end def start_merged_variables_scope set = @bound_variables_stack.last&.dup || Set.new @bound_variables_stack.push set @@ -1121,20 +1160,29 @@ @comments[new_comment.location.end_line] = new_comment end def new_token(type, value = input.matched) - start_index = input.charpos - input.matched.size - end_index = input.charpos + charpos = charpos(input) + start_index = charpos - input.matched.size + end_index = charpos location = RBS::Location.new(buffer: buffer, start_pos: start_index, end_pos: end_index) [type, LocatedValue.new(location: location, value: value)] end +def charpos(scanner) + if @ascii_only + scanner.pos + else + scanner.charpos + end +end + def empty_params_result [ [], [], nil, @@ -1248,11 +1296,12 @@ case when input.scan(/\s+/) # skip when input.scan(/#(( *)|( ?(?<string>.*)))\n/) - start_index = input.charpos - input.matched.size - end_index = input.charpos-1 + charpos = charpos(input) + start_index = charpos - input.matched.size + end_index = charpos-1 location = RBS::Location.new(buffer: buffer, start_pos: start_index, end_pos: end_index)