// GenerateES5 produces ES5 code from the given scope graph. func GenerateES5(sg *scopegraph.ScopeGraph, generatedFilePath string, sourceRoot string) (string, *sourcemap.SourceMap, error) { generated := generateModules(sg) // Order the modules by their paths. pather := shared.NewPather(sg.SourceGraph().Graph) modulePathMap := map[string]esbuilder.SourceBuilder{} var modulePathList = make([]string, 0) for module, _ := range generated { path := pather.GetModulePath(module) modulePathList = append(modulePathList, path) modulePathMap[path] = generated[module] } sort.Strings(modulePathList) // Collect the generated modules into their final source. ordered := ordered_map.NewOrderedMap() for _, modulePath := range modulePathList { ordered.Set(modulePath, modulePathMap[modulePath]) } // Generate the unformatted code and source map. template := esbuilder.Template("es5", runtimeTemplate, ordered) sm := sourcemap.NewSourceMap(generatedFilePath, sourceRoot) unformatted := esbuilder.BuildSourceAndMap(template, sm) // Format the code. return escommon.FormatMappedECMASource(unformatted.String(), sm) }
// GenerateExpression generates the full ES5 expression for the given CodeDOM expression representation. func GenerateExpression(expression codedom.Expression, asyncOption AsyncOption, scopegraph *scopegraph.ScopeGraph, positionMapper *compilercommon.PositionMapper, machineBuilder StateMachineBuilder) ExpressionResult { generator := &expressionGenerator{ scopegraph: scopegraph, machineBuilder: machineBuilder, positionmapper: positionMapper, pather: shared.NewPather(scopegraph.SourceGraph().Graph), wrappers: make([]*expressionWrapper, 0), variables: make([]string, 0), } // Determine whether the expression is a promise. var isPromise = false if promising, ok := expression.(codedom.Promising); ok { isPromise = promising.IsPromise() } // Generate the expression into code. generated := generator.generateExpression(expression, generationContext{}) // Check to see if async is required. If so and the expression is not async, // wrap it in a new promise. if asyncOption == EnsureAsync && len(generator.wrappers) == 0 { generated = generator.wrapSynchronousExpression(generated) } return ExpressionResult{generated, generator.wrappers, generator.variables, isPromise} }
// generateModules generates all the modules found in the given scope graph into source. func generateModules(sg *scopegraph.ScopeGraph) map[typegraph.TGModule]esbuilder.SourceBuilder { generator := es5generator{ graph: sg.SourceGraph().Graph, scopegraph: sg, positionMapper: compilercommon.NewPositionMapper(), templater: shared.NewTemplater(), pather: shared.NewPather(sg.SourceGraph().Graph), } // Generate the builder for each of the modules. return generator.generateModules(sg.TypeGraph().Modules()) }
// buildGenerator builds a new state machine generator. func buildGenerator(scopegraph *scopegraph.ScopeGraph, positionMapper *compilercommon.PositionMapper, templater *shared.Templater, isGeneratorFunction bool) *stateGenerator { generator := &stateGenerator{ pather: shared.NewPather(scopegraph.SourceGraph().Graph), templater: templater, positionMapper: positionMapper, scopegraph: scopegraph, states: make([]*state, 0), stateStartMap: map[codedom.Statement]*state{}, variables: map[string]bool{}, resources: &ResourceStack{}, managesResources: false, isGeneratorFunction: isGeneratorFunction, } return generator }