dawn_node: Allow Include and Mixins to come out of order in idlgen

Bug: dawn:1123
Change-Id: I120e6234e194f46954e3c7e75a3a8cc667df9611
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/75900
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_node/tools/src/cmd/idlgen/main.go b/src/dawn_node/tools/src/cmd/idlgen/main.go
index 5ea5499..55488e3 100644
--- a/src/dawn_node/tools/src/cmd/idlgen/main.go
+++ b/src/dawn_node/tools/src/cmd/idlgen/main.go
@@ -193,6 +193,7 @@
 	{
 		interfaces := map[string]*ast.Interface{}
 		mixins := map[string]*ast.Mixin{}
+		includes := []*ast.Includes{}
 		for _, d := range in.Declarations {
 			switch d := d.(type) {
 			case *ast.Interface:
@@ -209,27 +210,31 @@
 				mixins[d.Name] = d
 				s.declarations[d.Name] = d
 			case *ast.Includes:
-				// Merge mixin into interface
-				i, ok := interfaces[d.Name]
-				if !ok {
-					panic(fmt.Errorf("%v includes %v, but %v is not an interface", d.Name, d.Source, d.Name))
-				}
-				m, ok := mixins[d.Source]
-				if !ok {
-					panic(fmt.Errorf("%v includes %v, but %v is not an mixin", d.Name, d.Source, d.Source))
-				}
-				// Merge mixin into the interface
-				for _, member := range m.Members {
-					if member, ok := member.(*ast.Member); ok {
-						i.Members = append(i.Members, member)
-					}
-				}
+				includes = append(includes, d)
 			default:
 				if name := nameOf(d); name != "" {
 					s.declarations[nameOf(d)] = d
 				}
 			}
 		}
+
+		// Merge mixin into interface
+		for _, include := range includes {
+			i, ok := interfaces[include.Name]
+			if !ok {
+				panic(fmt.Errorf("%v includes %v, but %v is not an interface", include.Name, include.Source, include.Name))
+			}
+			m, ok := mixins[include.Source]
+			if !ok {
+				panic(fmt.Errorf("%v includes %v, but %v is not an mixin", include.Name, include.Source, include.Source))
+			}
+			// Merge mixin into the interface
+			for _, member := range m.Members {
+				if member, ok := member.(*ast.Member); ok {
+					i.Members = append(i.Members, member)
+				}
+			}
+		}
 	}
 
 	// Now traverse the declarations in to produce the dependency-ordered