Analyzer checks uniqueness of types in union by comparing hashes

This commit is contained in:
Sasha Koshka 2024-03-02 12:06:35 -05:00
parent 1ecd45e707
commit aaefb9e6bf
2 changed files with 31 additions and 18 deletions

View File

@ -156,11 +156,11 @@ func (this *Tree) analyzeTypeInternal (
ty.Acc = access
ty, err = this.assembleStructMap(ty)
updateIncompleteInfo()
if err != nil { return ty, err }
if err != nil { return nil, err }
for name, member := range ty.MemberMap {
ty.MemberMap[name].Ty,
err = this.analyzeType(member.Ty, false)
if err != nil { return ty, err }
if err != nil { return nil, err }
}
return ty, nil
@ -170,19 +170,30 @@ func (this *Tree) analyzeTypeInternal (
ty.Acc = access
ty, err = this.assembleInterfaceMap(ty)
updatePseudoCompleteInfo()
if err != nil { return ty, err }
if err != nil { return nil, err }
for name, behavior := range ty.BehaviorMap {
ty.BehaviorMap[name], err = this.analyzeBehavior(behavior)
if err != nil { return ty, err }
if err != nil { return nil, err }
}
return ty, nil
// union type
case *entity.TypeUnion:
// TODO this is a model for how all of the composite analysis
// processes should work. it is deterministic and covers
// everything. Change struct, interface, sig, etc to match
ty.Unt = this.unit
ty.Acc = access
ty, err = this.assembleUnionMap(ty)
updateIncompleteInfo()
return this.analyzeTypeUnion(ty)
if err != nil { return nil, err }
for index, allowed := range ty.Allowed {
allowed, err = this.analyzeType(allowed, false)
if err != nil { return nil, err }
ty.Allowed[index] = allowed
ty.AllowedMap[ty.AllowedOrder[index]] = allowed
}
return ty, nil
// integer type
case *entity.TypeInt:
@ -272,19 +283,19 @@ func (this *Tree) assembleInterfaceMap (ty *entity.TypeInterface) (*entity.TypeI
return ty, nil
}
func (this *Tree) analyzeTypeUnion (ty *entity.TypeUnion) (*entity.TypeUnion, error) {
func (this *Tree) assembleUnionMap (ty *entity.TypeUnion) (*entity.TypeUnion, error) {
ty.AllowedMap = make(map[entity.Hash] entity.Type)
ty.AllowedOrder = make([]entity.Hash, len(ty.Allowed))
for index, allowed := range ty.Allowed {
allowed, err := this.analyzeType(allowed, true)
if err != nil { return nil, err }
ty.Allowed[index] = allowed
for _, check := range ty.Allowed[:index] {
if entity.TypesEqual(check, allowed) {
return ty, errors.Errorf (
allowed.Position(), "%v already listed in union at %v",
allowed, check.Position())
}
hash := allowed.Hash()
if previous, exists := ty.AllowedMap[hash]; exists {
return ty, errors.Errorf (
allowed.Position(), "%v already listed in union at %v",
allowed, previous.Position())
}
ty.AllowedMap [hash] = allowed
ty.AllowedOrder[index] = hash
ty.Allowed [index] = allowed
}
return ty, nil
}

View File

@ -252,8 +252,10 @@ type TypeUnion struct {
Allowed []Type
// Semantics
Acc Access
Unt uuid.UUID
Acc Access
Unt uuid.UUID
AllowedOrder []Hash
AllowedMap map[Hash] Type
}
func (*TypeUnion) ty(){}
func (this *TypeUnion) Position () errors.Position { return this.Pos }