// 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 }
// 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{}, } }
// 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 }
func NewBasicTypesConstructor(graph *compilergraph.SerulianGraph) TypeGraphConstructor { fsg := graph.NewGraphLayer("test", fakeNodeTypeTagged) return &testBasicTypesConstructor{emptyTypeConstructor{}, fsg, nil} }
// 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 }
// 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 }