Ejemplo n.º 1
0
// buildLoopExpression builds the CodeDOM for a loop expression.
func (db *domBuilder) buildLoopExpression(node compilergraph.GraphNode) codedom.Expression {
	member, found := db.scopegraph.TypeGraph().StreamType().ParentModule().FindMember("MapStream")
	if !found {
		panic("Missing MapStream function under Stream's module")
	}

	// Retrieve the item type for the members of the stream and the mapped values.
	mapExpr := node.GetNode(parser.NodeLoopExpressionMapExpression)
	namedValue := node.GetNode(parser.NodeLoopExpressionNamedValue)

	namedScope, _ := db.scopegraph.GetScope(namedValue)
	namedItemType := namedScope.AssignableTypeRef(db.scopegraph.TypeGraph())

	mapScope, _ := db.scopegraph.GetScope(mapExpr)
	mappedItemType := mapScope.ResolvedTypeRef(db.scopegraph.TypeGraph())

	// Build a reference to the Map function.
	mapFunctionReference := codedom.FunctionCall(
		codedom.StaticMemberReference(member, db.scopegraph.TypeGraph().StreamTypeReference(mappedItemType), node),
		[]codedom.Expression{
			codedom.TypeLiteral(namedItemType, node),
			codedom.TypeLiteral(mappedItemType, node),
		},
		node)

	// A loop expression is replaced with a call to the Map function, with the stream as the first parameter
	// and a mapper function which resolves the mapped value as the second.
	builtMapExpr := db.buildExpression(mapExpr)
	builtStreamExpr := db.getExpression(node, parser.NodeLoopExpressionStreamExpression)

	loopValueName := namedValue.Get(parser.NodeNamedValueName)
	mapperFunction := codedom.FunctionDefinition(
		[]string{},
		[]string{loopValueName},
		codedom.Resolution(builtMapExpr, builtMapExpr.BasisNode()),
		false,
		codedom.NormalFunction,
		builtMapExpr.BasisNode())

	return codedom.AwaitPromise(
		codedom.FunctionCall(mapFunctionReference,
			[]codedom.Expression{builtStreamExpr, mapperFunction},
			node),
		node)
}
Ejemplo n.º 2
0
// generateMachine generates state machine source for a CodeDOM statement or expression.
func (sg *stateGenerator) generateMachine(element codedom.StatementOrExpression, isGeneratorFunction bool) esbuilder.SourceBuilder {
	// Build a state generator for the new machine.
	generator := buildGenerator(sg.scopegraph, sg.positionMapper, sg.templater, isGeneratorFunction)

	// Generate the statement or expression that forms the definition of the state machine.
	if statement, ok := element.(codedom.Statement); ok {
		generator.generateStates(statement, generateNewState)
	} else if expression, ok := element.(codedom.Expression); ok {
		basisNode := expression.BasisNode()
		generator.generateStates(codedom.Resolution(expression, basisNode), generateNewState)
	} else {
		panic("Unknown element at root")
	}

	// Filter out any empty states.
	states := generator.filterStates()

	// Finally, generate the source of the machine.
	return generator.source(states)
}
Ejemplo n.º 3
0
// buildReturnStatement builds the CodeDOM for a return statement.
func (db *domBuilder) buildReturnStatement(node compilergraph.GraphNode) codedom.Statement {
	returnExpr, _ := db.tryGetExpression(node, parser.NodeReturnStatementValue)
	return codedom.Resolution(returnExpr, node)
}