// 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}
}
Beispiel #2
0
// 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)
}
Beispiel #3
0
// 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())
}
Beispiel #4
0
// 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
}