Analyzer checks uniqueness of types in union by comparing hashes
This commit is contained in:
parent
1ecd45e707
commit
aaefb9e6bf
@ -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
|
||||
}
|
||||
|
@ -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 }
|
||||
|
Loading…
Reference in New Issue
Block a user