@@ -694,7 +694,7 @@ func (a *RBadDeclaration) Equal(rule R, check *CrossFileEqualityCheck) bool {
694694}
695695
696696func (r * RBadDeclaration ) Hash () (uint32 , bool ) {
697- hash := uint32 (11 )
697+ hash := uint32 (7 )
698698 hash = HashTokens (hash , r .Tokens )
699699 return hash , true
700700}
@@ -709,7 +709,7 @@ func (a *RComment) Equal(rule R, check *CrossFileEqualityCheck) bool {
709709}
710710
711711func (r * RComment ) Hash () (uint32 , bool ) {
712- hash := uint32 (12 )
712+ hash := uint32 (8 )
713713 hash = helpers .HashCombineString (hash , r .Text )
714714 return hash , true
715715}
@@ -741,7 +741,7 @@ func (a *RAtLayer) Equal(rule R, check *CrossFileEqualityCheck) bool {
741741}
742742
743743func (r * RAtLayer ) Hash () (uint32 , bool ) {
744- hash := uint32 (13 )
744+ hash := uint32 (9 )
745745 hash = helpers .HashCombine (hash , uint32 (len (r .Names )))
746746 for _ , parts := range r .Names {
747747 hash = helpers .HashCombine (hash , uint32 (len (parts )))
@@ -753,6 +753,226 @@ func (r *RAtLayer) Hash() (uint32, bool) {
753753 return hash , true
754754}
755755
756+ type RAtMedia struct {
757+ AtToken string
758+ Queries []MediaQuery
759+ Rules []Rule
760+ CloseBraceLoc logger.Loc
761+ }
762+
763+ func (a * RAtMedia ) Equal (rule R , check * CrossFileEqualityCheck ) bool {
764+ b , ok := rule .(* RAtMedia )
765+ return ok && MediaQueriesEqual (a .Queries , b .Queries , check ) && RulesEqual (a .Rules , b .Rules , check )
766+ }
767+
768+ func (r * RAtMedia ) Hash () (uint32 , bool ) {
769+ hash := uint32 (10 )
770+ hash = HashMediaQueries (hash , r .Queries )
771+ hash = HashRules (hash , r .Rules )
772+ return hash , true
773+ }
774+
775+ type MediaQuery struct {
776+ Loc logger.Loc
777+ Data MQ
778+ }
779+
780+ type MQ interface {
781+ Equal (query MQ , check * CrossFileEqualityCheck ) bool
782+ Hash () uint32
783+ }
784+
785+ func MediaQueriesEqual (a []MediaQuery , b []MediaQuery , check * CrossFileEqualityCheck ) bool {
786+ if len (a ) != len (b ) {
787+ return false
788+ }
789+ for i , ai := range a {
790+ if ! ai .Data .Equal (b [i ].Data , check ) {
791+ return false
792+ }
793+ }
794+ return true
795+ }
796+
797+ func HashMediaQueries (hash uint32 , queries []MediaQuery ) uint32 {
798+ hash = helpers .HashCombine (hash , uint32 (len (queries )))
799+ for _ , q := range queries {
800+ hash = helpers .HashCombine (hash , q .Data .Hash ())
801+ }
802+ return hash
803+ }
804+
805+ type MQTypeOp uint8
806+
807+ const (
808+ MQTypeOpNone MQTypeOp = iota
809+ MQTypeOpNot
810+ MQTypeOpOnly
811+ )
812+
813+ type MQType struct {
814+ Op MQTypeOp
815+ Type string
816+ AndOrNull MediaQuery
817+ }
818+
819+ func (q * MQType ) Equal (query MQ , check * CrossFileEqualityCheck ) bool {
820+ p , ok := query .(* MQType )
821+ return ok && q .Op == p .Op && q .Type == p .Type
822+ }
823+
824+ func (q * MQType ) Hash () uint32 {
825+ hash := uint32 (0 )
826+ hash = helpers .HashCombine (hash , uint32 (q .Op ))
827+ hash = helpers .HashCombineString (hash , q .Type )
828+ return hash
829+ }
830+
831+ type MQNot struct {
832+ Inner MediaQuery
833+ }
834+
835+ func (q * MQNot ) Equal (query MQ , check * CrossFileEqualityCheck ) bool {
836+ p , ok := query .(* MQNot )
837+ return ok && q .Inner .Data .Equal (p .Inner .Data , check )
838+ }
839+
840+ func (q * MQNot ) Hash () uint32 {
841+ hash := uint32 (1 )
842+ hash = helpers .HashCombine (hash , q .Inner .Data .Hash ())
843+ return hash
844+ }
845+
846+ type MQBinaryOp uint8
847+
848+ const (
849+ MQBinaryOpAnd MQBinaryOp = iota
850+ MQBinaryOpOr
851+ )
852+
853+ type MQBinary struct {
854+ Op MQBinaryOp
855+ Terms []MediaQuery
856+ }
857+
858+ func (q * MQBinary ) Equal (query MQ , check * CrossFileEqualityCheck ) bool {
859+ p , ok := query .(* MQBinary )
860+ return ok && q .Op == p .Op && MediaQueriesEqual (q .Terms , p .Terms , check )
861+ }
862+
863+ func (q * MQBinary ) Hash () uint32 {
864+ hash := uint32 (2 )
865+ hash = helpers .HashCombine (hash , uint32 (q .Op ))
866+ hash = HashMediaQueries (hash , q .Terms )
867+ return hash
868+ }
869+
870+ type MQGeneralEnclosed struct {
871+ Tokens []Token
872+ }
873+
874+ func (q * MQGeneralEnclosed ) Equal (query MQ , check * CrossFileEqualityCheck ) bool {
875+ p , ok := query .(* MQGeneralEnclosed )
876+ return ok && TokensEqual (q .Tokens , p .Tokens , check )
877+ }
878+
879+ func (q * MQGeneralEnclosed ) Hash () uint32 {
880+ hash := uint32 (3 )
881+ hash = HashTokens (hash , q .Tokens )
882+ return hash
883+ }
884+
885+ type MQPlainOrBoolean struct {
886+ Name string
887+ ValueOrNil []Token
888+ }
889+
890+ func (q * MQPlainOrBoolean ) Equal (query MQ , check * CrossFileEqualityCheck ) bool {
891+ p , ok := query .(* MQPlainOrBoolean )
892+ return ok && q .Name == p .Name && TokensEqual (q .ValueOrNil , p .ValueOrNil , check )
893+ }
894+
895+ func (q * MQPlainOrBoolean ) Hash () uint32 {
896+ hash := uint32 (4 )
897+ hash = helpers .HashCombineString (hash , q .Name )
898+ hash = HashTokens (hash , q .ValueOrNil )
899+ return hash
900+ }
901+
902+ type MQRange struct {
903+ Before []Token
904+ Name string
905+ After []Token
906+ NameLoc logger.Loc
907+ BeforeCmp MQCmp
908+ AfterCmp MQCmp
909+ }
910+
911+ func (q * MQRange ) Equal (query MQ , check * CrossFileEqualityCheck ) bool {
912+ p , ok := query .(* MQRange )
913+ return ok && q .BeforeCmp == p .BeforeCmp && q .AfterCmp == p .AfterCmp && q .Name == p .Name &&
914+ TokensEqual (q .Before , p .Before , check ) && TokensEqual (q .After , p .After , check )
915+ }
916+
917+ func (q * MQRange ) Hash () uint32 {
918+ hash := uint32 (5 )
919+ hash = HashTokens (hash , q .Before )
920+ hash = helpers .HashCombine (hash , uint32 (q .BeforeCmp ))
921+ hash = helpers .HashCombineString (hash , q .Name )
922+ hash = helpers .HashCombine (hash , uint32 (q .AfterCmp ))
923+ hash = HashTokens (hash , q .After )
924+ return hash
925+ }
926+
927+ type MQCmp uint8
928+
929+ const (
930+ MQCmpNone MQCmp = iota
931+ MQCmpEq
932+ MQCmpLt
933+ MQCmpLe
934+ MQCmpGt
935+ MQCmpGe
936+ )
937+
938+ func (cmp MQCmp ) String () string {
939+ switch cmp {
940+ case MQCmpLt :
941+ return "<"
942+ case MQCmpLe :
943+ return "<="
944+ case MQCmpGt :
945+ return ">"
946+ case MQCmpGe :
947+ return ">="
948+ }
949+ return "="
950+ }
951+
952+ func (cmp MQCmp ) Dir () int {
953+ switch cmp {
954+ case MQCmpLt , MQCmpLe :
955+ return - 1
956+ case MQCmpGt , MQCmpGe :
957+ return 1
958+ }
959+ return 0
960+ }
961+
962+ func (cmp MQCmp ) Flip () MQCmp {
963+ switch cmp {
964+ case MQCmpLt :
965+ return MQCmpGe
966+ case MQCmpLe :
967+ return MQCmpGt
968+ case MQCmpGt :
969+ return MQCmpLe
970+ case MQCmpGe :
971+ return MQCmpLt
972+ }
973+ return cmp
974+ }
975+
756976type ComplexSelector struct {
757977 Selectors []CompoundSelector
758978}
0 commit comments