From e544339880c78dae032731927536babbfbf3c66e Mon Sep 17 00:00:00 2001 From: itchyny Date: Mon, 10 Jun 2024 03:24:41 +0900 Subject: [PATCH] Remove dependency on gen to generate sets (#746) --- .golangci.yml | 2 - Makefile | 6 - README.md | 11 -- ast/BUILD.bazel | 3 +- ast/ast.go | 9 +- ast/identifier.go | 99 +++++++++++++ ast/identifier_set.go | 174 ----------------------- ast/{util_test.go => identifier_test.go} | 0 ast/util.go | 46 ------ internal/parser/BUILD.bazel | 1 - internal/parser/literalfield_set.go | 172 ---------------------- internal/parser/parser.go | 21 ++- 12 files changed, 116 insertions(+), 428 deletions(-) create mode 100644 ast/identifier.go delete mode 100644 ast/identifier_set.go rename ast/{util_test.go => identifier_test.go} (100%) delete mode 100644 ast/util.go delete mode 100644 internal/parser/literalfield_set.go diff --git a/.golangci.yml b/.golangci.yml index 99f9de434..485299994 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,5 +1,3 @@ -run: - skip-files: ast/identifier_set.go linters: enable: - stylecheck diff --git a/Makefile b/Makefile index 0b119106f..cc20aa32b 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,9 @@ all: install.dependencies generate generate.stdlib build.bazel test tidy .PHONY: all -# https://github.com/golang/go/issues/30515 -# We temporarily set GO111MODULE=off here to avoid adding these binaries to the go.mod|sum files -# As they are not needed during runtime -install.dependencies : export GO111MODULE=off install.dependencies: git submodule init git submodule update - go get github.com/clipperhouse/gen - go get github.com/clipperhouse/set .PHONY: install.dependencies build.bazel: diff --git a/README.md b/README.md index 21a1cdd8c..628e9bd65 100644 --- a/README.md +++ b/README.md @@ -188,17 +188,6 @@ _replace the FILTER with the name of the test you are working on_ FILTER=Builtin_manifestJsonEx make benchmark ``` -## Implementation Notes - -We are generating some helper classes on types by using http://clipperhouse.github.io/gen/. Do the following to regenerate these if necessary: - -```bash -go get github.com/clipperhouse/gen -go get github.com/clipperhouse/set -export PATH=$PATH:$GOPATH/bin # If you haven't already -go generate -``` - ## Update cpp-jsonnet sub-repo This repo depends on [the original Jsonnet repo](https://github.com/google/jsonnet). Shared parts include the standard library, headers files for C API and some tests. diff --git a/ast/BUILD.bazel b/ast/BUILD.bazel index be8a578ae..833c2a7b0 100644 --- a/ast/BUILD.bazel +++ b/ast/BUILD.bazel @@ -6,9 +6,8 @@ go_library( "ast.go", "clone.go", "fodder.go", - "identifier_set.go", + "identifier.go", "location.go", - "util.go", ], importpath = "github.com/google/go-jsonnet/ast", visibility = ["//visibility:public"], diff --git a/ast/ast.go b/ast/ast.go index 90e970f9b..8de21ca55 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -21,13 +21,6 @@ import ( "fmt" ) -// Identifier represents a variable / parameter / field name. -// +gen set -type Identifier string - -// Identifiers represents an Identifier slice. -type Identifiers []Identifier - // TODO(jbeda) implement interning of identifiers if necessary. The C++ // version does so. @@ -80,7 +73,7 @@ func NewNodeBase(loc LocationRange, fodder Fodder, freeVariables Identifiers) No // NewNodeBaseLoc creates a new NodeBase from an initial LocationRange. func NewNodeBaseLoc(loc LocationRange, fodder Fodder) NodeBase { - return NewNodeBase(loc, fodder, []Identifier{}) + return NewNodeBase(loc, fodder, Identifiers{}) } // Loc returns a NodeBase's loc. diff --git a/ast/identifier.go b/ast/identifier.go new file mode 100644 index 000000000..81c9e5a62 --- /dev/null +++ b/ast/identifier.go @@ -0,0 +1,99 @@ +/* +Copyright 2016 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package ast + +import ( + "sort" +) + +// Identifier represents a variable / parameter / field name. +type Identifier string + +// Identifiers represents an Identifier slice. +type Identifiers []Identifier + +// IdentifierSet represents an Identifier set. +type IdentifierSet map[Identifier]struct{} + +// NewIdentifierSet creates a new IdentifierSet. +func NewIdentifierSet(idents ...Identifier) IdentifierSet { + set := make(IdentifierSet) + for _, ident := range idents { + set[ident] = struct{}{} + } + return set +} + +// Add adds an Identifier to the set. +func (set IdentifierSet) Add(ident Identifier) bool { + if _, ok := set[ident]; ok { + return false + } + set[ident] = struct{}{} + return true +} + +// AddIdentifiers adds a slice of identifiers to the set. +func (set IdentifierSet) AddIdentifiers(idents Identifiers) { + for _, ident := range idents { + set.Add(ident) + } +} + +// Contains returns true if an Identifier is in the set. +func (set IdentifierSet) Contains(ident Identifier) bool { + _, ok := set[ident] + return ok +} + +// Remove removes an Identifier from the set. +func (set IdentifierSet) Remove(ident Identifier) { + delete(set, ident) +} + +// ToSlice returns an Identifiers slice from the set. +func (set IdentifierSet) ToSlice() Identifiers { + idents := make(Identifiers, len(set)) + i := 0 + for ident := range set { + idents[i] = ident + i++ + } + return idents +} + +// ToOrderedSlice returns the elements of the current set as an ordered slice. +func (set IdentifierSet) ToOrderedSlice() []Identifier { + idents := set.ToSlice() + sort.Sort(identifierSorter(idents)) + return idents +} + +type identifierSorter []Identifier + +func (s identifierSorter) Len() int { return len(s) } +func (s identifierSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s identifierSorter) Less(i, j int) bool { return s[i] < s[j] } + +// Clone returns a clone of the set. +func (set IdentifierSet) Clone() IdentifierSet { + newSet := make(IdentifierSet, len(set)) + for k, v := range set { + newSet[k] = v + } + return newSet +} diff --git a/ast/identifier_set.go b/ast/identifier_set.go deleted file mode 100644 index bc2efff51..000000000 --- a/ast/identifier_set.go +++ /dev/null @@ -1,174 +0,0 @@ -// Generated by: main -// TypeWriter: set -// Directive: +gen on identifier - -package ast - -// Set is a modification of https://github.com/deckarep/golang-set -// The MIT License (MIT) -// Copyright (c) 2013 Ralph Caraveo (deckarep@gmail.com) - -// IdentifierSet is the primary type that represents a set -type IdentifierSet map[Identifier]struct{} - -// NewIdentifierSet creates and returns a reference to an empty set. -func NewIdentifierSet(a ...Identifier) IdentifierSet { - s := make(IdentifierSet, len(a)) - for _, i := range a { - s.Add(i) - } - return s -} - -// ToSlice returns the elements of the current set as a slice -func (set IdentifierSet) ToSlice() []Identifier { - s := make([]Identifier, len(set), len(set)) - j := 0 - for v := range set { - s[j] = v - j++ - } - return s -} - -// Add adds an item to the current set if it doesn't already exist in the set. -func (set IdentifierSet) Add(i Identifier) bool { - _, found := set[i] - set[i] = struct{}{} - return !found //False if it existed already -} - -// Contains determines if a given item is already in the set. -func (set IdentifierSet) Contains(i Identifier) bool { - _, found := set[i] - return found -} - -// ContainsAll determines if the given items are all in the set -func (set IdentifierSet) ContainsAll(i ...Identifier) bool { - for _, v := range i { - if !set.Contains(v) { - return false - } - } - return true -} - -// IsSubset determines if every item in the other set is in this set. -func (set IdentifierSet) IsSubset(other IdentifierSet) bool { - for elem := range set { - if !other.Contains(elem) { - return false - } - } - return true -} - -// IsSuperset determines if every item of this set is in the other set. -func (set IdentifierSet) IsSuperset(other IdentifierSet) bool { - return other.IsSubset(set) -} - -// Union returns a new set with all items in both sets. -func (set IdentifierSet) Union(other IdentifierSet) IdentifierSet { - unionedSet := NewIdentifierSet() - - for elem := range set { - unionedSet.Add(elem) - } - for elem := range other { - unionedSet.Add(elem) - } - return unionedSet -} - -// Intersect returns a new set with items that exist only in both sets. -func (set IdentifierSet) Intersect(other IdentifierSet) IdentifierSet { - intersection := NewIdentifierSet() - // loop over smaller set - if set.Cardinality() < other.Cardinality() { - for elem := range set { - if other.Contains(elem) { - intersection.Add(elem) - } - } - } else { - for elem := range other { - if set.Contains(elem) { - intersection.Add(elem) - } - } - } - return intersection -} - -// Difference returns a new set with items in the current set but not in the other set -func (set IdentifierSet) Difference(other IdentifierSet) IdentifierSet { - differencedSet := NewIdentifierSet() - for elem := range set { - if !other.Contains(elem) { - differencedSet.Add(elem) - } - } - return differencedSet -} - -// SymmetricDifference returns a new set with items in the current set or the other set but not in both. -func (set IdentifierSet) SymmetricDifference(other IdentifierSet) IdentifierSet { - aDiff := set.Difference(other) - bDiff := other.Difference(set) - return aDiff.Union(bDiff) -} - -// Clear clears the entire set to be the empty set. -func (set *IdentifierSet) Clear() { - *set = make(IdentifierSet) -} - -// Remove allows the removal of a single item in the set. -func (set IdentifierSet) Remove(i Identifier) { - delete(set, i) -} - -// Cardinality returns how many items are currently in the set. -func (set IdentifierSet) Cardinality() int { - return len(set) -} - -// Iter returns a channel of type identifier that you can range over. -func (set IdentifierSet) Iter() <-chan Identifier { - ch := make(chan Identifier) - go func() { - for elem := range set { - ch <- elem - } - close(ch) - }() - - return ch -} - -// Equal determines if two sets are equal to each other. -// If they both are the same size and have the same items they are considered equal. -// Order of items is not relevent for sets to be equal. -func (set IdentifierSet) Equal(other IdentifierSet) bool { - if set.Cardinality() != other.Cardinality() { - return false - } - for elem := range set { - if !other.Contains(elem) { - return false - } - } - return true -} - -// Clone returns a clone of the set. -// Does NOT clone the underlying elements. -func (set IdentifierSet) Clone() IdentifierSet { - clonedSet := NewIdentifierSet() - for elem := range set { - clonedSet.Add(elem) - } - return clonedSet -} diff --git a/ast/util_test.go b/ast/identifier_test.go similarity index 100% rename from ast/util_test.go rename to ast/identifier_test.go diff --git a/ast/util.go b/ast/util.go deleted file mode 100644 index 45e99451f..000000000 --- a/ast/util.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2016 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package ast - -import ( - "sort" -) - -// AddIdentifiers adds a slice of identifiers to an identifier set. -func (i IdentifierSet) AddIdentifiers(idents Identifiers) { - for _, ident := range idents { - i.Add(ident) - } -} - -// ToOrderedSlice returns the elements of the current set as an ordered slice. -func (i IdentifierSet) ToOrderedSlice() []Identifier { - s := make([]Identifier, len(i)) - j := 0 - for v := range i { - s[j] = v - j++ - } - sort.Sort(identifierSorter(s)) - return s -} - -type identifierSorter []Identifier - -func (s identifierSorter) Len() int { return len(s) } -func (s identifierSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s identifierSorter) Less(i, j int) bool { return s[i] < s[j] } diff --git a/internal/parser/BUILD.bazel b/internal/parser/BUILD.bazel index 97e2d5d8c..bdaf56048 100644 --- a/internal/parser/BUILD.bazel +++ b/internal/parser/BUILD.bazel @@ -5,7 +5,6 @@ go_library( srcs = [ "context.go", "lexer.go", - "literalfield_set.go", "parser.go", "string_util.go", ], diff --git a/internal/parser/literalfield_set.go b/internal/parser/literalfield_set.go deleted file mode 100644 index e39b4cd5b..000000000 --- a/internal/parser/literalfield_set.go +++ /dev/null @@ -1,172 +0,0 @@ -// Generated by: main -// TypeWriter: set -// Directive: +gen on LiteralField - -package parser - -// Set is a modification of https://github.com/deckarep/golang-set -// The MIT License (MIT) -// Copyright (c) 2013 Ralph Caraveo (deckarep@gmail.com) - -// LiteralFieldSet is the primary type that represents a set -type LiteralFieldSet map[LiteralField]struct{} - -// NewLiteralFieldSet creates and returns a reference to an empty set. -func NewLiteralFieldSet(a ...LiteralField) LiteralFieldSet { - s := make(LiteralFieldSet) - for _, i := range a { - s.Add(i) - } - return s -} - -// ToSlice returns the elements of the current set as a slice -func (set LiteralFieldSet) ToSlice() []LiteralField { - var s []LiteralField - for v := range set { - s = append(s, v) - } - return s -} - -// Add adds an item to the current set if it doesn't already exist in the set. -func (set LiteralFieldSet) Add(i LiteralField) bool { - _, found := set[i] - set[i] = struct{}{} - return !found //False if it existed already -} - -// Contains determines if a given item is already in the set. -func (set LiteralFieldSet) Contains(i LiteralField) bool { - _, found := set[i] - return found -} - -// ContainsAll determines if the given items are all in the set -func (set LiteralFieldSet) ContainsAll(i ...LiteralField) bool { - for _, v := range i { - if !set.Contains(v) { - return false - } - } - return true -} - -// IsSubset determines if every item in the other set is in this set. -func (set LiteralFieldSet) IsSubset(other LiteralFieldSet) bool { - for elem := range set { - if !other.Contains(elem) { - return false - } - } - return true -} - -// IsSuperset determines if every item of this set is in the other set. -func (set LiteralFieldSet) IsSuperset(other LiteralFieldSet) bool { - return other.IsSubset(set) -} - -// Union returns a new set with all items in both sets. -func (set LiteralFieldSet) Union(other LiteralFieldSet) LiteralFieldSet { - unionedSet := NewLiteralFieldSet() - - for elem := range set { - unionedSet.Add(elem) - } - for elem := range other { - unionedSet.Add(elem) - } - return unionedSet -} - -// Intersect returns a new set with items that exist only in both sets. -func (set LiteralFieldSet) Intersect(other LiteralFieldSet) LiteralFieldSet { - intersection := NewLiteralFieldSet() - // loop over smaller set - if set.Cardinality() < other.Cardinality() { - for elem := range set { - if other.Contains(elem) { - intersection.Add(elem) - } - } - } else { - for elem := range other { - if set.Contains(elem) { - intersection.Add(elem) - } - } - } - return intersection -} - -// Difference returns a new set with items in the current set but not in the other set -func (set LiteralFieldSet) Difference(other LiteralFieldSet) LiteralFieldSet { - differencedSet := NewLiteralFieldSet() - for elem := range set { - if !other.Contains(elem) { - differencedSet.Add(elem) - } - } - return differencedSet -} - -// SymmetricDifference returns a new set with items in the current set or the other set but not in both. -func (set LiteralFieldSet) SymmetricDifference(other LiteralFieldSet) LiteralFieldSet { - aDiff := set.Difference(other) - bDiff := other.Difference(set) - return aDiff.Union(bDiff) -} - -// Clear clears the entire set to be the empty set. -func (set *LiteralFieldSet) Clear() { - *set = make(LiteralFieldSet) -} - -// Remove allows the removal of a single item in the set. -func (set LiteralFieldSet) Remove(i LiteralField) { - delete(set, i) -} - -// Cardinality returns how many items are currently in the set. -func (set LiteralFieldSet) Cardinality() int { - return len(set) -} - -// Iter returns a channel of type LiteralField that you can range over. -func (set LiteralFieldSet) Iter() <-chan LiteralField { - ch := make(chan LiteralField) - go func() { - for elem := range set { - ch <- elem - } - close(ch) - }() - - return ch -} - -// Equal determines if two sets are equal to each other. -// If they both are the same size and have the same items they are considered equal. -// Order of items is not relevent for sets to be equal. -func (set LiteralFieldSet) Equal(other LiteralFieldSet) bool { - if set.Cardinality() != other.Cardinality() { - return false - } - for elem := range set { - if !other.Contains(elem) { - return false - } - } - return true -} - -// Clone returns a clone of the set. -// Does NOT clone the underlying elements. -func (set LiteralFieldSet) Clone() LiteralFieldSet { - clonedSet := NewLiteralFieldSet() - for elem := range set { - clonedSet.Add(elem) - } - return clonedSet -} diff --git a/internal/parser/parser.go b/internal/parser/parser.go index 08ec6721b..e01b19452 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -369,9 +369,18 @@ func (p *parser) parseObjectAssignmentOp() (opFodder ast.Fodder, plusSugar bool, return } -// A LiteralField is a field of an object or object comprehension. -// +gen set -type LiteralField string +// A literalField is a field of an object or object comprehension. +type literalField string + +type literalFieldSet map[literalField]struct{} + +func (set literalFieldSet) add(f literalField) bool { + if _, ok := set[f]; ok { + return false + } + set[f] = struct{}{} + return true +} func (p *parser) parseObjectRemainderComp(fields ast.ObjectFields, gotComma bool, tok *token, next *token) (ast.Node, *token, errors.StaticError) { numFields := 0 @@ -414,7 +423,7 @@ func (p *parser) parseObjectRemainderComp(fields ast.ObjectFields, gotComma bool }, last, nil } -func (p *parser) parseObjectRemainderField(literalFields *LiteralFieldSet, tok *token, next *token) (*ast.ObjectField, errors.StaticError) { +func (p *parser) parseObjectRemainderField(literalFields *literalFieldSet, tok *token, next *token) (*ast.ObjectField, errors.StaticError) { var kind ast.ObjectFieldKind var fodder1 ast.Fodder var expr1 ast.Node @@ -475,7 +484,7 @@ func (p *parser) parseObjectRemainderField(literalFields *LiteralFieldSet, tok * } if kind != ast.ObjectFieldExpr { - if !literalFields.Add(LiteralField(next.data)) { + if !literalFields.add(literalField(next.data)) { return nil, errors.MakeStaticError( fmt.Sprintf("Duplicate field: %v", next.data), next.loc) } @@ -627,7 +636,7 @@ func (p *parser) parseObjectRemainderAssert(tok *token, next *token) (*ast.Objec // Parse object or object comprehension without leading brace func (p *parser) parseObjectRemainder(tok *token) (ast.Node, *token, errors.StaticError) { var fields ast.ObjectFields - literalFields := make(LiteralFieldSet) + literalFields := make(literalFieldSet) binds := make(ast.IdentifierSet) gotComma := false