Beispiel #1
0
// NewIRG returns a new IRG for populating the graph with parsed source.
func NewIRG(graph *compilergraph.SerulianGraph) *WebIRG {
	irg := &WebIRG{
		graph: graph,
		layer: graph.NewGraphLayer("webirg", parser.NodeTypeTagged),
	}

	modifier := irg.layer.NewModifier()
	irg.rootModuleNode = modifier.CreateNode(parser.NodeTypeGlobalModule).AsNode()
	modifier.Apply()
	return irg
}
Beispiel #2
0
// newTestTypeGraphConstructor returns a type graph constructor which adds all the given test types
// to a fake module with the given name.
func newTestTypeGraphConstructor(graph *compilergraph.SerulianGraph, moduleName string, testTypes []testType) *testTypeGraphConstructor {
	return &testTypeGraphConstructor{
		moduleName: moduleName,
		testTypes:  testTypes,
		layer:      graph.NewGraphLayer(moduleName, fakeNodeTypeTagged),

		typeMap:    map[string]compilergraph.GraphNode{},
		memberMap:  map[string]compilergraph.GraphNode{},
		genericMap: map[string]compilergraph.GraphNode{},
	}
}
Beispiel #3
0
// NewSRG returns a new SRG for populating the graph with parsed source.
func NewSRG(graph *compilergraph.SerulianGraph) *SRG {
	g := &SRG{
		Graph: graph,
		layer: graph.NewGraphLayer("srg", parser.NodeTypeTagged),

		aliasMap:      map[string]SRGType{},
		modulePathMap: nil,
	}

	return g
}
Beispiel #4
0
func NewBasicTypesConstructor(graph *compilergraph.SerulianGraph) TypeGraphConstructor {
	fsg := graph.NewGraphLayer("test", fakeNodeTypeTagged)
	return &testBasicTypesConstructor{emptyTypeConstructor{}, fsg, nil}
}
Beispiel #5
0
// newTestTypeGraph creates a new type graph for testing.
func newTestTypeGraph(graph *compilergraph.SerulianGraph, constructors ...TypeGraphConstructor) *TypeGraph {
	fsg := graph.NewGraphLayer("test", fakeNodeTypeTagged)

	constructors = append(constructors, &testBasicTypesConstructor{emptyTypeConstructor{}, fsg, nil})
	return BuildTypeGraph(graph, constructors...).Graph
}
Beispiel #6
0
// BuildTypeGraph returns a new TypeGraph that is populated from the given constructors.
func BuildTypeGraph(graph *compilergraph.SerulianGraph, constructors ...TypeGraphConstructor) *Result {
	// Create the type graph.
	typeGraph := &TypeGraph{
		graph:        graph,
		layer:        graph.NewGraphLayer("tdg", NodeTypeTagged),
		operators:    map[string]operatorDefinition{},
		aliasedTypes: map[string]TGTypeDecl{},
	}

	// Create a struct to hold the results of the construction.
	result := &Result{
		Status:   true,
		Warnings: make([]compilercommon.SourceWarning, 0),
		Errors:   make([]compilercommon.SourceError, 0),
		Graph:    typeGraph,
	}

	// Build all modules.
	for _, constructor := range constructors {
		modifier := typeGraph.layer.NewModifier()
		constructor.DefineModules(func() *moduleBuilder {
			return &moduleBuilder{
				tdg:      typeGraph,
				modifier: modifier,
			}
		})
		modifier.Apply()
	}

	// Build all types.
	for _, constructor := range constructors {
		modifier := typeGraph.layer.NewModifier()
		constructor.DefineTypes(func(moduleSourceNode compilergraph.GraphNode) *typeBuilder {
			moduleNode := typeGraph.getMatchingTypeGraphNode(moduleSourceNode)
			return &typeBuilder{
				module:   TGModule{moduleNode, typeGraph},
				modifier: modifier,
			}
		})
		modifier.Apply()
	}

	// Built the aliased types map.
	ait := typeGraph.layer.
		StartQuery().
		In(NodePredicateTypeAlias).
		BuildNodeIterator()

	for ait.Next() {
		typeDecl := TGTypeDecl{ait.Node(), typeGraph}
		alias, _ := typeDecl.Alias()
		typeGraph.aliasedTypes[alias] = typeDecl
	}

	// Annotate all dependencies.
	for _, constructor := range constructors {
		modifier := typeGraph.layer.NewModifier()
		annotator := Annotator{
			issueReporterImpl{typeGraph, modifier},
		}

		constructor.DefineDependencies(annotator, typeGraph)
		modifier.Apply()
	}

	// Load the operators map. Requires the types loaded as it performs lookups of certain types (int, etc).
	typeGraph.buildOperatorDefinitions()

	// Build all initial definitions for members.
	for _, constructor := range constructors {
		modifier := typeGraph.layer.NewModifier()
		constructor.DefineMembers(func(moduleOrTypeSourceNode compilergraph.GraphNode, isOperator bool) *MemberBuilder {
			typegraphNode := typeGraph.getMatchingTypeGraphNode(moduleOrTypeSourceNode)

			var parent TGTypeOrModule = nil
			if typegraphNode.Kind() == NodeTypeModule {
				parent = TGModule{typegraphNode, typeGraph}
			} else {
				parent = TGTypeDecl{typegraphNode, typeGraph}
			}

			return &MemberBuilder{
				modifier:   modifier,
				parent:     parent,
				tdg:        typeGraph,
				isOperator: isOperator,
			}
		}, issueReporterImpl{typeGraph, modifier}, typeGraph)
		modifier.Apply()
	}

	// Decorate all the members.
	for _, constructor := range constructors {
		modifier := typeGraph.layer.NewModifier()
		constructor.DecorateMembers(func(memberSourceNode compilergraph.GraphNode) *MemberDecorator {
			typegraphNode := typeGraph.getMatchingTypeGraphNode(memberSourceNode)

			return &MemberDecorator{
				modifier:           modifier,
				sourceNode:         memberSourceNode,
				member:             TGMember{typegraphNode, typeGraph},
				tdg:                typeGraph,
				genericConstraints: map[compilergraph.GraphNode]TypeReference{},
				tags:               map[string]string{},
			}
		}, issueReporterImpl{typeGraph, modifier}, typeGraph)
		modifier.Apply()
	}

	// Check for duplicate types, members and generics.
	typeGraph.checkForDuplicateNames()

	// Perform global validation, including checking fields in structs.
	typeGraph.globallyValidate()

	// Handle inheritance checking and member cloning.
	inheritsModifier := typeGraph.layer.NewModifier()
	typeGraph.defineFullInheritance(inheritsModifier)
	inheritsModifier.Apply()

	// Define implicit members.
	typeGraph.defineAllImplicitMembers()

	// If there are no errors yet, validate everything.
	if _, hasError := typeGraph.layer.StartQuery().In(NodePredicateError).TryGetNode(); !hasError {
		modifier := typeGraph.layer.NewModifier()
		for _, constructor := range constructors {
			reporter := issueReporterImpl{typeGraph, modifier}
			constructor.Validate(reporter, typeGraph)
		}
		modifier.Apply()
	}

	// Collect any errors generated during construction.
	it := typeGraph.layer.StartQuery().
		With(NodePredicateError).
		BuildNodeIterator(NodePredicateSource)

	for it.Next() {
		node := it.Node()
		result.Status = false

		sourceNodeId := it.GetPredicate(NodePredicateSource).NodeId()

		// Lookup the location of the source node.
		var location = compilercommon.SourceAndLocation{}
		for _, constructor := range constructors {
			constructorLocation, found := constructor.GetLocation(sourceNodeId)
			if found {
				location = constructorLocation
			}
		}

		// Add the error.
		errNode := node.GetNode(NodePredicateError)
		msg := errNode.Get(NodePredicateErrorMessage)
		result.Errors = append(result.Errors, compilercommon.NewSourceError(location, msg))
	}

	return result
}