func (stc *srgTypeConstructor) DecorateMembers(decorater typegraph.GetMemberDecorator, reporter typegraph.IssueReporter, graph *typegraph.TypeGraph) { // Decorate all module members. for _, module := range stc.srg.GetModules() { for _, member := range module.GetMembers() { parent, _ := graph.GetTypeOrModuleForSourceNode(module.Node()) stc.decorateMember(member, parent, decorater(member.GraphNode), reporter, graph) } } // Decorate all type members. buildTypeMembers := func(key interface{}, value interface{}) bool { data := value.(typeMemberWork) for _, member := range data.srgType.GetMembers() { parent, _ := graph.GetTypeOrModuleForSourceNode(data.srgType.Node()) stc.decorateMember(member, parent, decorater(member.GraphNode), reporter, graph) } return true } workqueue := compilerutil.Queue() for _, srgType := range stc.srg.GetTypes() { workqueue.Enqueue(srgType.Node(), typeMemberWork{srgType}, buildTypeMembers) } workqueue.Run() }
func (stc *srgTypeConstructor) Validate(reporter typegraph.IssueReporter, graph *typegraph.TypeGraph) { validateTyperef := func(key interface{}, value interface{}) bool { srgTypeRef := value.(srg.SRGTypeRef) typeref, err := stc.BuildTypeRef(srgTypeRef, graph) if err != nil { reporter.ReportError(srgTypeRef.GraphNode, "%v", err) return false } verr := typeref.Verify() if verr != nil { reporter.ReportError(srgTypeRef.GraphNode, "%v", verr) return false } return true } workqueue := compilerutil.Queue() for _, srgTypeRef := range stc.srg.GetTypeReferences() { workqueue.Enqueue(srgTypeRef, srgTypeRef, validateTyperef) } workqueue.Run() }
// defineFullInheritance copies any inherited members over to types, as well as type checking // for inheritance cycles. func (g *TypeGraph) defineFullInheritance(modifier compilergraph.GraphLayerModifier) { buildInheritance := func(key interface{}, value interface{}) bool { typeDecl := value.(TGTypeDecl) g.buildInheritedMembership(typeDecl, NodePredicateMember, modifier) g.buildInheritedMembership(typeDecl, NodePredicateTypeOperator, modifier) return true } // Enqueue the full set of classes with dependencies on any parent types. workqueue := compilerutil.Queue() for _, typeDecl := range g.TypeDecls() { if typeDecl.TypeKind() != ClassType { continue } // Build a set of dependencies for this type. var dependencies = make([]interface{}, 0) for _, inheritsRef := range typeDecl.ParentTypes() { dependencies = append(dependencies, inheritsRef.ReferredType()) } workqueue.Enqueue(typeDecl, typeDecl, buildInheritance, dependencies...) } // Run the queue to construct the full inheritance. result := workqueue.Run() if result.HasCycle { // TODO(jschorr): If there are two cycles, this will conflate them. We should do actual // checking here. var types = make([]string, len(result.Cycle)) for index, key := range result.Cycle { decl := key.(TGTypeDecl) types[index] = decl.Name() } typeNode := result.Cycle[0].(TGTypeDecl).GraphNode g.decorateWithError(modifier.Modify(typeNode), "A cycle was detected in the inheritance of types: %v", types) } }
// generateModules generates all the given modules into ES5. func (gen *es5generator) generateModules(modules []typegraph.TGModule) map[typegraph.TGModule]esbuilder.SourceBuilder { // Queue all the modules to be generated. generatedSource := make([]esbuilder.SourceBuilder, len(modules)) queue := compilerutil.Queue() for index, module := range modules { fn := func(key interface{}, value interface{}) bool { generatedSource[key.(int)] = gen.generateModule(value.(typegraph.TGModule)) return true } queue.Enqueue(index, module, fn) } // Generate the full source tree for each module. queue.Run() // Build a map from module to source tree. moduleMap := map[typegraph.TGModule]esbuilder.SourceBuilder{} for index, module := range modules { moduleMap[module] = generatedSource[index] } return moduleMap }