Skip to content

Commit 6992ea0

Browse files
committed
Exclude attr_* methods from duplicate checks.
1 parent e389107 commit 6992ea0

File tree

6 files changed

+86
-36
lines changed

6 files changed

+86
-36
lines changed

lib/rbs/definition.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ class Variable
66
attr_reader :parent_variable
77
attr_reader :type
88
attr_reader :declared_in
9+
attr_reader :source
910

10-
def initialize(parent_variable:, type:, declared_in:)
11+
def initialize(parent_variable:, type:, declared_in:, source:)
1112
@parent_variable = parent_variable
1213
@type = type
1314
@declared_in = declared_in
15+
@source = source
1416
end
1517

1618
def sub(s)
@@ -19,7 +21,8 @@ def sub(s)
1921
self.class.new(
2022
parent_variable: parent_variable,
2123
type: type.sub(s),
22-
declared_in: declared_in
24+
declared_in: declared_in,
25+
source: source
2326
)
2427
end
2528
end

lib/rbs/definition_builder.rb

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,23 +145,23 @@ def define_instance(definition, type_name, subst)
145145
type_name,
146146
definition.instance_variables,
147147
name: ivar_name,
148-
type: member.type.sub(subst_)
148+
type: member.type.sub(subst_),
149+
source: member
149150
)
150151
end
151152
end
152153

153154
when AST::Members::InstanceVariable
154-
InstanceVariableDuplicationError.check!(variables: definition.instance_variables, member: member, type_name: type_name)
155155
insert_variable(
156156
type_name,
157157
definition.instance_variables,
158158
name: member.name,
159-
type: member.type.sub(subst_)
159+
type: member.type.sub(subst_),
160+
source: member
160161
)
161162

162163
when AST::Members::ClassVariable
163-
ClassVariableDuplicationError.check!(variables: definition.class_variables, member: member, type_name: type_name)
164-
insert_variable(type_name, definition.class_variables, name: member.name, type: member.type)
164+
insert_variable(type_name, definition.class_variables, name: member.name, type: member.type, source: member)
165165
end
166166
end
167167
end
@@ -284,17 +284,15 @@ def build_singleton0(type_name)
284284
end
285285

286286
if ivar_name
287-
insert_variable(type_name, definition.instance_variables, name: ivar_name, type: member.type)
287+
insert_variable(type_name, definition.instance_variables, name: ivar_name, type: member.type, source: member)
288288
end
289289
end
290290

291291
when AST::Members::ClassInstanceVariable
292-
ClassInstanceVariableDuplicationError.check!(variables: definition.instance_variables, member: member, type_name: type_name)
293-
insert_variable(type_name, definition.instance_variables, name: member.name, type: member.type)
292+
insert_variable(type_name, definition.instance_variables, name: member.name, type: member.type, source: member)
294293

295294
when AST::Members::ClassVariable
296-
ClassVariableDuplicationError.check!(variables: definition.class_variables, member: member, type_name: type_name)
297-
insert_variable(type_name, definition.class_variables, name: member.name, type: member.type)
295+
insert_variable(type_name, definition.class_variables, name: member.name, type: member.type, source: member)
298296
end
299297
end
300298
end
@@ -539,12 +537,46 @@ def validate_type_params(definition, ancestors:, methods:)
539537
end
540538
end
541539

542-
def insert_variable(type_name, variables, name:, type:)
540+
def insert_variable(type_name, variables, name:, type:, source:)
543541
variables[name] = Definition::Variable.new(
544542
parent_variable: variables[name],
545543
type: type,
546-
declared_in: type_name
544+
declared_in: type_name,
545+
source: source
547546
)
547+
validate_variable(variables[name])
548+
end
549+
550+
def validate_variable(var)
551+
return unless var.parent_variable
552+
553+
# Ignore attrs
554+
variables = [] #: Array[Definition::Variable]
555+
tmp_var = var
556+
while tmp_var
557+
variables << tmp_var if tmp_var.source.is_a?(AST::Members::Var)
558+
tmp_var = tmp_var.parent_variable
559+
end
560+
561+
# Duplicates should be eliminated, so there can't be more than 3.
562+
return unless variables.length == 2
563+
564+
l, r = variables #: [Definition::Variable, Definition::Variable]
565+
566+
case l.source
567+
when AST::Members::InstanceVariable
568+
if r.source.instance_of?(AST::Members::InstanceVariable) && l.declared_in == r.declared_in
569+
raise InstanceVariableDuplicationError.new(member: l.source)
570+
end
571+
when AST::Members::ClassInstanceVariable
572+
if r.source.instance_of?(AST::Members::ClassInstanceVariable) && l.declared_in == r.declared_in
573+
raise ClassInstanceVariableDuplicationError.new(member: l.source)
574+
end
575+
when AST::Members::ClassVariable
576+
if r.source.instance_of?(AST::Members::ClassVariable)
577+
raise ClassVariableDuplicationError.new(member: l.source)
578+
end
579+
end
548580
end
549581

550582
def import_methods(definition, module_name, module_methods, interfaces_methods, subst, self_type_methods)

lib/rbs/errors.rb

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -340,31 +340,12 @@ def location
340340
end
341341

342342
class InstanceVariableDuplicationError < VariableDuplicationError
343-
def self.check!(variables:, member:, type_name:)
344-
if old = variables[member.name]
345-
if old.declared_in == type_name
346-
raise new(member: member)
347-
end
348-
end
349-
end
350343
end
351344

352345
class ClassInstanceVariableDuplicationError < VariableDuplicationError
353-
def self.check!(variables:, member:, type_name:)
354-
if old = variables[member.name]
355-
if old.declared_in == type_name
356-
raise new(member: member)
357-
end
358-
end
359-
end
360346
end
361347

362348
class ClassVariableDuplicationError < VariableDuplicationError
363-
def self.check!(variables:, member:, type_name:)
364-
if old = variables[member.name]
365-
raise new(member: member)
366-
end
367-
end
368349
end
369350

370351
class UnknownMethodAliasError < DefinitionError

sig/definition.rbs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,15 @@ module RBS
66
attr_reader parent_variable: Variable?
77
attr_reader type: Types::t
88
attr_reader declared_in: TypeName
9-
10-
def initialize: (parent_variable: Variable?, type: Types::t, declared_in: TypeName) -> void
9+
type source = AST::Members::AttrAccessor
10+
| AST::Members::AttrReader
11+
| AST::Members::AttrWriter
12+
| AST::Members::InstanceVariable
13+
| AST::Members::ClassVariable
14+
| AST::Members::ClassInstanceVariable
15+
attr_reader source: source
16+
17+
def initialize: (parent_variable: Variable?, type: Types::t, declared_in: TypeName, source: source) -> void
1118

1219
def sub: (Substitution) -> Variable
1320
end

sig/definition_builder.rbs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ module RBS
105105

106106
def source_location: (Definition::Ancestor::Instance::source, AST::Declarations::t) -> Location[untyped, untyped]?
107107

108-
def insert_variable: (TypeName, Hash[Symbol, Definition::Variable], name: Symbol, type: Types::t) -> void
108+
def validate_variable: (Definition::Variable) -> void
109+
110+
def insert_variable: (TypeName, Hash[Symbol, Definition::Variable], name: Symbol, type: Types::t, source: Definition::Variable::source) -> void
109111

110112
# Add method definition to `methods`, which will be merged to `class_definition` after defining all methods at this *level* -- class, module, or interface
111113
#

test/rbs/definition_builder_test.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2714,6 +2714,22 @@ class InstanceVariable
27142714
@instance: Integer
27152715
end
27162716
2717+
class AttrInstanceVariable
2718+
attr_accessor instance: Integer
2719+
@instance: Integer
2720+
end
2721+
2722+
class InstanceVariableAttr
2723+
@instance: Integer
2724+
attr_accessor instance: Integer
2725+
end
2726+
2727+
class InstanceVariableAttrInstanceVariable
2728+
@instance: Integer
2729+
attr_accessor instance: Integer
2730+
@instance: Integer
2731+
end
2732+
27172733
class ClassInstanceVariable
27182734
self.@class_instance: Integer
27192735
self.@class_instance: Integer
@@ -2731,6 +2747,15 @@ class ClassVariable
27312747
assert_raises(RBS::InstanceVariableDuplicationError) do
27322748
builder.build_instance(type_name("::InstanceVariable"))
27332749
end
2750+
assert_nothing_raised do
2751+
builder.build_instance(type_name("::AttrInstanceVariable"))
2752+
end
2753+
assert_nothing_raised do
2754+
builder.build_instance(type_name("::InstanceVariableAttr"))
2755+
end
2756+
assert_raises(RBS::InstanceVariableDuplicationError) do
2757+
builder.build_instance(type_name("::InstanceVariableAttrInstanceVariable"))
2758+
end
27342759
assert_raises(RBS::ClassInstanceVariableDuplicationError) do
27352760
builder.build_singleton(type_name("::ClassInstanceVariable"))
27362761
end

0 commit comments

Comments
 (0)