You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Field.IsInterface() function doesn't work for named interfaces. This occurs because — while parsing — named field's are deepcopied, then have their definition's replaced. Such that a string comparison of that definition (i.e NamedInterface[9:] == "interface") would return false. This function used to be resolved by checking a .Collection field (of models.Field), but that field was removed due to being unnecessary... until now.
Solution
Collection
The previous .Collection field specifies which type of collection (f.IsPointer() || (f.IsArray() || f.IsSlice() || f.IsMap() || f.IsChan()) || f.IsFunc() || f.IsInterface()) the field is. This field was removed in a previous version because it was being used to account for the actual type definition of the field (i.e *Account where Definition == "Account" and Collection == *). Not only did this contribute to confusion, but it also made generating type-to-type code harder.
Adding back the Collection field would not cause confusion anymore because it would not be used for any other portion of the code. However, expanding the purpose of this field to represent an Underlying type of the field may be more useful. Currently, there is no way to determine the underlying type of a field. As an example, a field id Number will have a Name=="id" and Definition=="Number"; Number is an alias to a string. However, there is currently no way to find more information about the underlying field string that Number represents.
Underlying
An Underlying field of a models.Field would represent the actual underlying type (in a models.Field object) if it exists. There is a distinction between the go/types Underlying() method and models.Field Underlying() method. In go/types, the underlying function represents a unique instance of a go/type, and can represent go/types that have underlying go/types (such that a "Named' type is nothing more than a go/types.Named type). In contrast, the models.Field underlying field represents a default type (in colloquial terms), which likely shares an instance with other default underlying types.
To be specific, models.Field objects typically represent the copygen definition of a field: These objects are created in a context which always gives them a Name (either in the Copygen Interface function parameters func(to string) from string or as a field of other models.Field structs, etc). In contrast, the model.Field present in the Field.Underlyingfield would represent actual default types (basic types, map, struct, interface, category.go) which a user (developer) can use to determine more information about a field's Go Type.
The objects contained in a .Underlying models.Field field should represent the same object when it represents the same Go type. As an example, id Number and word Wordmodels.Field objects represent two different models.Field. However, since the underlying type of each models.Field.Definition is an alias (Number, Word) to a string, the Field.Underlying of each models.Field should point to the same object (which is a models.Field representation of a string).
Thus, it would be expected for users who — for whatever reason — modify the Underlying field of a models.Field to also modify the .Underlying field of every other models.Field that references it. Otherwise, the user can always use field.Deepcopy() prior to modifying that field, if that is ever necessary.
The text was updated successfully, but these errors were encountered:
copygen is essentially becoming an abstraction of go/types which is centered around fields rather than types. It is also easier to get started since the UI is a visual interface, everything is parsed for you, and the generator doesn't have to be compiled for usage. The one thing that go/types has that Copygen does not is a way to find the type you are looking for without information. Well, in actuality it requires you to parse the AST, but then you can use a map to find your object from there. One way we could provide this functionality is by implementing a global map that maps the Function.Name + FullVariableName() of a field to it's models.Field representation.
Problem
The
Field.IsInterface()
function doesn't work for named interfaces. This occurs because — while parsing — named field's are deepcopied, then have their definition's replaced. Such that a string comparison of that definition (i.eNamedInterface[9:] == "interface"
) would return false. This function used to be resolved by checking a.Collection
field (ofmodels.Field
), but that field was removed due to being unnecessary... until now.Solution
Collection
The previous
.Collection
field specifies which type of collection (f.IsPointer() || (f.IsArray() || f.IsSlice() || f.IsMap() || f.IsChan()) || f.IsFunc() || f.IsInterface()
) the field is. This field was removed in a previous version because it was being used to account for the actual type definition of the field (i.e*Account
whereDefinition == "Account"
andCollection == *
). Not only did this contribute to confusion, but it also made generating type-to-type code harder.Adding back the
Collection
field would not cause confusion anymore because it would not be used for any other portion of the code. However, expanding the purpose of this field to represent anUnderlying
type of the field may be more useful. Currently, there is no way to determine the underlying type of a field. As an example, a fieldid Number
will have aName=="id"
andDefinition=="Number"
; Number is an alias to astring
. However, there is currently no way to find more information about the underlying fieldstring
that Number represents.Underlying
An
Underlying
field of amodels.Field
would represent the actual underlying type (in amodels.Field
object) if it exists. There is a distinction between thego/types Underlying()
method andmodels.Field Underlying()
method. Ingo/types
, the underlying function represents a unique instance of ago/type
, and can representgo/types
that have underlyinggo/types
(such that a "Named' type is nothing more than ago/types.Named
type). In contrast, themodels.Field
underlying field represents a default type (in colloquial terms), which likely shares an instance with other default underlying types.To be specific,
models.Field
objects typically represent thecopygen
definition of a field: These objects are created in a context which always gives them aName
(either in theCopygen Interface
function parametersfunc(to string) from string
or as a field of othermodels.Field
structs, etc). In contrast, themodel.Field
present in theField.Underlying
field would represent actual default types (basic types,map
,struct
,interface
,category.go
) which a user (developer) can use to determine more information about a field's Go Type.The objects contained in a
.Underlying models.Field
field should represent the same object when it represents the same Go type. As an example,id Number
andword Word
models.Field
objects represent two differentmodels.Field
. However, since the underlying type of eachmodels.Field.Definition
is an alias (Number
,Word
) to astring
, theField.Underlying
of eachmodels.Field
should point to the same object (which is amodels.Field
representation of astring
).Thus, it would be expected for users who — for whatever reason — modify the
Underlying
field of amodels.Field
to also modify the.Underlying
field of every othermodels.Field
that references it. Otherwise, the user can always usefield.Deepcopy()
prior to modifying that field, if that is ever necessary.The text was updated successfully, but these errors were encountered: