Conversation
d1158c6 to
065dc23
Compare
| fn validate_constant_references(&mut self) { | ||
| let mut diagnostics = Vec::new(); | ||
|
|
||
| for reference in self.graph.constant_references().values() { |
There was a problem hiding this comment.
Instead of looping through the entire list, I think we can just add diagnostics directly to anything that's still in the unit_queue, no?
Whatever is left is what we failed to resolve.
| diagnostics | ||
| } | ||
|
|
||
| fn validate_mixins(&self, declaration: &Declaration) -> Vec<Diagnostic> { |
There was a problem hiding this comment.
For both of the mixin diagnostics, are we not able to add them during linearization to avoid looping afterwards?
| for definition in declaration.definitions().iter().skip(1) { | ||
| let definition = self.graph.definitions().get(definition).unwrap(); | ||
| let definition_declaration_kind = DeclarationKind::from_definition_kind(definition.kind()); | ||
| if definition_declaration_kind != first_definition_declaration_kind { |
There was a problem hiding this comment.
I don't think we can just compare that they're not the same. For example, this is valid code:
Foo = Struct.new
class Foo
include Bar
endI was looking into this specific case as part of the struct work and I believe we need these checks (or maybe some of them) in Graph#add_declaration, so that we can auto-promote certain declaration cases like the one in this example.
Another valid case is having a method declaration that has two definitions: one method and one attribute.
There was a problem hiding this comment.
The trick is in from_definition_kind where we map the output definition kind to declaration kind:
pub fn from_definition_kind(definition_kind: DefinitionKind) -> Self {
match definition_kind {
DefinitionKind::Class => DeclarationKind::Class,
DefinitionKind::SingletonClass => DeclarationKind::SingletonClass,
DefinitionKind::Module => DeclarationKind::Module,
DefinitionKind::Constant => DeclarationKind::Constant,
DefinitionKind::ConstantAlias => DeclarationKind::ConstantAlias,
DefinitionKind::Method
| DefinitionKind::MethodAlias
| DefinitionKind::AttrAccessor
| DefinitionKind::AttrReader
| DefinitionKind::AttrWriter => DeclarationKind::Method,
DefinitionKind::InstanceVariable => DeclarationKind::InstanceVariable,
DefinitionKind::ClassVariable => DeclarationKind::ClassVariable,
DefinitionKind::GlobalVariable | DefinitionKind::GlobalVariableAlias => DeclarationKind::GlobalVariable,So both an attr accessor and a method definition map to a method declaration so this is correct:
def foo; end
attr_reader :fooFor Struct, this would be the same:
match definition_kind {
DefinitionKind::Class | DefinitionKind::Struct => DeclarationKind::Class,Signed-off-by: Alexandre Terrasa <alexandre.terrasa@shopify.com>
Signed-off-by: Alexandre Terrasa <alexandre.terrasa@shopify.com>
Signed-off-by: Alexandre Terrasa <alexandre.terrasa@shopify.com>
Signed-off-by: Alexandre Terrasa <alexandre.terrasa@shopify.com>
Signed-off-by: Alexandre Terrasa <alexandre.terrasa@shopify.com>
Signed-off-by: Alexandre Terrasa <alexandre.terrasa@shopify.com>
Signed-off-by: Alexandre Terrasa <alexandre.terrasa@shopify.com>
065dc23 to
1e92a1c
Compare
Signed-off-by: Alexandre Terrasa <alexandre.terrasa@shopify.com>
Signed-off-by: Alexandre Terrasa <alexandre.terrasa@shopify.com>
1e92a1c to
3851796
Compare
|
@vinistock I pushed another PR #502 to show what it would look like to compute the diagnostics during the resolution rather than after. TL;DR: it's not faster but more invasive and complex. |
Please review #472 and #473 first.
Closes #435.
Introduce 6 new diagnostics: