mirror of
				https://gitea.invidious.io/iv-org/shard-ameba.git
				synced 2024-08-15 00:53:29 +00:00 
			
		
		
		
	New rule: hash duplicated key
This commit is contained in:
		
							parent
							
								
									a947dee851
								
							
						
					
					
						commit
						1839ef2ab5
					
				
					 4 changed files with 86 additions and 0 deletions
				
			
		| 
						 | 
					@ -18,6 +18,10 @@ EmptyExpression:
 | 
				
			||||||
  # Disallows empty expressions.
 | 
					  # Disallows empty expressions.
 | 
				
			||||||
  Enabled: true
 | 
					  Enabled: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HashDuplicatedKey:
 | 
				
			||||||
 | 
					  # Disallows duplicated keys in hash literals.
 | 
				
			||||||
 | 
					  Enabled: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LargeNumbers:
 | 
					LargeNumbers:
 | 
				
			||||||
  # A rule that disallows usage of large numbers without underscore.
 | 
					  # A rule that disallows usage of large numbers without underscore.
 | 
				
			||||||
  Enabled: true
 | 
					  Enabled: true
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										41
									
								
								spec/ameba/rule/hash_duplicated_key_spec.cr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								spec/ameba/rule/hash_duplicated_key_spec.cr
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					require "../../spec_helper"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module Ameba::Rule
 | 
				
			||||||
 | 
					  describe HashDuplicatedKey do
 | 
				
			||||||
 | 
					    subject = HashDuplicatedKey.new
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "passes if there is no duplicated keys in a hash literals" do
 | 
				
			||||||
 | 
					      s = Source.new %(
 | 
				
			||||||
 | 
					        h = {"a" => 1, :a => 2, "b" => 3}
 | 
				
			||||||
 | 
					        h = {"a" => 1, "b" => 2, "c" => {"a" => 3, "b" => 4}}
 | 
				
			||||||
 | 
					        h = {} of String => String
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      subject.catch(s).should be_valid
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "fails if there is a duplicated key in a hash literal" do
 | 
				
			||||||
 | 
					      s = Source.new %q(
 | 
				
			||||||
 | 
					        h = {"a" => 1, "b" => 2, "a" => 3}
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      subject.catch(s).should_not be_valid
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "fails if there is a duplicated key in the inner hash literal" do
 | 
				
			||||||
 | 
					      s = Source.new %q(
 | 
				
			||||||
 | 
					        h = {"a" => 1, "b" => {"a" => 3, "b" => 4, "a" => 5}}
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      subject.catch(s).should_not be_valid
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it "reports rule, location and message" do
 | 
				
			||||||
 | 
					      s = Source.new %q(
 | 
				
			||||||
 | 
					        h = {"a" => 1, "a" => 2}
 | 
				
			||||||
 | 
					      ), "source.cr"
 | 
				
			||||||
 | 
					      subject.catch(s).should_not be_valid
 | 
				
			||||||
 | 
					      error = s.errors.first
 | 
				
			||||||
 | 
					      error.rule.should_not be_nil
 | 
				
			||||||
 | 
					      error.location.to_s.should eq "source.cr:2:13"
 | 
				
			||||||
 | 
					      error.message.should eq "Duplicated keys in hash literal."
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ module Ameba::AST
 | 
				
			||||||
    EnumDef,
 | 
					    EnumDef,
 | 
				
			||||||
    ExceptionHandler,
 | 
					    ExceptionHandler,
 | 
				
			||||||
    Expressions,
 | 
					    Expressions,
 | 
				
			||||||
 | 
					    HashLiteral,
 | 
				
			||||||
    If,
 | 
					    If,
 | 
				
			||||||
    InstanceVar,
 | 
					    InstanceVar,
 | 
				
			||||||
    LibDef,
 | 
					    LibDef,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										40
									
								
								src/ameba/rule/hash_duplicated_key.cr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/ameba/rule/hash_duplicated_key.cr
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					module Ameba::Rule
 | 
				
			||||||
 | 
					  # A rule that disallows duplicated keys in hash literals.
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # This is considered invalid:
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # ```
 | 
				
			||||||
 | 
					  # h = {"foo" => 1, "bar" => 2, "foo" => 3}
 | 
				
			||||||
 | 
					  # ```
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # And it has to written as this instead:
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # ```
 | 
				
			||||||
 | 
					  # h = {"foo" => 1, "bar" => 2}
 | 
				
			||||||
 | 
					  # ```
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # YAML configuration example:
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # ```
 | 
				
			||||||
 | 
					  # HashDuplicatedKey:
 | 
				
			||||||
 | 
					  #   Enabled: true
 | 
				
			||||||
 | 
					  # ```
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  struct HashDuplicatedKey < Base
 | 
				
			||||||
 | 
					    def test(source)
 | 
				
			||||||
 | 
					      AST::Visitor.new self, source
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test(source, node : Crystal::HashLiteral)
 | 
				
			||||||
 | 
					      return unless duplicated_keys?(node.entries)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      source.error self, node.location, "Duplicated keys in hash literal."
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private def duplicated_keys?(entries)
 | 
				
			||||||
 | 
					      entries.map(&.key)
 | 
				
			||||||
 | 
					             .group_by(&.itself)
 | 
				
			||||||
 | 
					             .any? { |_, v| v.size > 1 }
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue