Support compounding types with imported types.

Sets, Lists, Refs and Maps of imported types work now.

This PR also factors some of codegen.go into a separate package, to slim down
that file a bit.

Towards issue #294
This commit is contained in:
Chris Masone
2015-10-12 15:24:19 -07:00
parent d1ae467c5e
commit 56cd548328
9 changed files with 636 additions and 355 deletions
+12 -1
View File
@@ -88,7 +88,8 @@ func (suite *ImportTestSuite) TestDetectFreeVariable() {
},
types.Choices{})
suite.Panics(func() {
resolveNamespaces(map[string]types.TypeRef{"Local": ls}, map[string]ref.Ref{}, map[ref.Ref]types.Package{})
inter := intermediate{NamedTypes: map[string]types.TypeRef{"Local": ls}}
resolveNamespaces(&inter, map[string]ref.Ref{}, map[ref.Ref]types.Package{})
})
}
@@ -119,6 +120,9 @@ func (suite *ImportTestSuite) TestImports() {
r := strings.NewReader(fmt.Sprintf(`
alias Other = import "%s"
using List(Other.ForeignEnum)
using List(Local1)
struct Local1 {
a: Other.ForeignStruct
b: Int16
@@ -167,4 +171,11 @@ func (suite *ImportTestSuite) TestImports() {
suite.EqualValues(ref.Ref{}, field.T.PackageRef())
field = findChoice("t", namedUnion)
suite.EqualValues(suite.importRef, field.T.PackageRef())
usings := p.UsingDeclarations
suite.Len(usings, 2)
suite.EqualValues(types.ListKind, usings[0].Kind())
suite.EqualValues(suite.importRef, usings[0].Desc.(types.CompoundDesc).ElemTypes[0].PackageRef())
suite.EqualValues(types.ListKind, usings[1].Kind())
suite.EqualValues("Local1", usings[1].Desc.(types.CompoundDesc).ElemTypes[0].Name())
}
+30 -13
View File
@@ -18,7 +18,7 @@ func ParseNomDL(packageName string, r io.Reader, cs chunks.ChunkSource) Parsed {
for _, target := range aliases {
depRefs[target] = true
}
resolveNamespaces(i.NamedTypes, aliases, GetDeps(depRefs, cs))
resolveNamespaces(&i, aliases, GetDeps(depRefs, cs))
return Parsed{
types.PackageDef{Dependencies: depRefs, NamedTypes: i.NamedTypes},
i.Name,
@@ -71,15 +71,12 @@ func resolveImports(pkg intermediate) map[string]ref.Ref {
return aliases
}
func resolveNamespaces(namedTypes map[string]types.TypeRef, aliases map[string]ref.Ref, deps map[ref.Ref]types.Package) {
func resolveNamespaces(p *intermediate, aliases map[string]ref.Ref, deps map[ref.Ref]types.Package) {
var rec func(t types.TypeRef) types.TypeRef
resolveFields := func(fields []types.Field) {
for idx, f := range fields {
if f.T.IsUnresolved() {
if f.T.Namespace() == "" {
d.Chk.Equal(ref.Ref{}, f.T.PackageRef())
_, ok := namedTypes[f.T.Name()]
d.Exp.True(ok, "Could not find type %s in current package.", f.T.Name())
if checkLocal(f.T, p.NamedTypes) {
continue
}
f.T = resolveNamespace(f.T, aliases, deps)
@@ -90,21 +87,41 @@ func resolveNamespaces(namedTypes map[string]types.TypeRef, aliases map[string]r
}
}
rec = func(t types.TypeRef) types.TypeRef {
if t.Kind() == types.StructKind {
if t.IsUnresolved() {
if checkLocal(t, p.NamedTypes) {
return t
}
t = resolveNamespace(t, aliases, deps)
}
switch t.Kind() {
case types.ListKind, types.SetKind, types.RefKind:
return types.MakeCompoundTypeRef(t.Name(), t.Kind(), rec(t.Desc.(types.CompoundDesc).ElemTypes[0]))
case types.MapKind:
elemTypes := t.Desc.(types.CompoundDesc).ElemTypes
return types.MakeCompoundTypeRef(t.Name(), t.Kind(), rec(elemTypes[0]), rec(elemTypes[1]))
case types.StructKind:
resolveFields(t.Desc.(types.StructDesc).Fields)
resolveFields(t.Desc.(types.StructDesc).Union)
}
return t
}
for n, t := range namedTypes {
if t.IsUnresolved() {
namedTypes[n] = resolveNamespace(t, aliases, deps)
continue
}
namedTypes[n] = rec(t)
for n, t := range p.NamedTypes {
p.NamedTypes[n] = rec(t)
}
for i, t := range p.UsingDeclarations {
p.UsingDeclarations[i] = rec(t)
}
}
func checkLocal(t types.TypeRef, namedTypes map[string]types.TypeRef) bool {
if t.Namespace() == "" {
d.Chk.Equal(ref.Ref{}, t.PackageRef())
_, ok := namedTypes[t.Name()]
d.Exp.True(ok, "Could not find type %s in current package.", t.Name())
return true
}
return false
}
func resolveNamespace(t types.TypeRef, aliases map[string]ref.Ref, deps map[ref.Ref]types.Package) types.TypeRef {