func (sh *srgSourceHandler) Verify(errorReporter packageloader.ErrorReporter, warningReporter packageloader.WarningReporter) { g := sh.srg // Collect any parse errors found and add them to the result. eit := g.findAllNodes(parser.NodeTypeError).BuildNodeIterator( parser.NodePredicateErrorMessage, parser.NodePredicateSource, parser.NodePredicateStartRune) for eit.Next() { sal := salForIterator(eit) errorReporter(compilercommon.NewSourceError(sal, eit.GetPredicate(parser.NodePredicateErrorMessage).String())) } // Verify all 'from ... import ...' are valid. fit := g.findAllNodes(parser.NodeTypeImportPackage). Has(parser.NodeImportPredicateSubsource). BuildNodeIterator(parser.NodeImportPredicateSubsource, parser.NodePredicateSource, parser.NodePredicateStartRune) for fit.Next() { // Load the package information. packageInfo := g.getPackageForImport(fit.Node()) if !packageInfo.IsSRGPackage() { continue } // Search for the subsource. subsource := fit.GetPredicate(parser.NodeImportPredicateSubsource).String() _, found := packageInfo.FindTypeOrMemberByName(subsource) if !found { source := fit.Node().GetIncomingNode(parser.NodeImportPredicatePackageRef).Get(parser.NodeImportPredicateSource) sal := salForIterator(fit) errorReporter(compilercommon.SourceErrorf(sal, "Import '%s' not found under package '%s'", subsource, source)) } } // Build the map for globally aliased types. ait := g.findAllNodes(parser.NodeTypeDecorator). Has(parser.NodeDecoratorPredicateInternal, aliasInternalDecoratorName). BuildNodeIterator() for ait.Next() { // Find the name of the alias. decorator := ait.Node() parameter, ok := decorator.TryGetNode(parser.NodeDecoratorPredicateParameter) if !ok || parameter.Kind() != parser.NodeStringLiteralExpression { sal := salForNode(decorator) errorReporter(compilercommon.SourceErrorf(sal, "Alias decorator requires a single string literal parameter")) continue } var aliasName = parameter.Get(parser.NodeStringLiteralExpressionValue) aliasName = aliasName[1 : len(aliasName)-1] // Remove the quotes. aliasedType := SRGType{decorator.GetIncomingNode(parser.NodeTypeDefinitionDecorator), g} g.aliasMap[aliasName] = aliasedType } }
// GetErrors returns the errors created during the build pass. func (sb *scopeBuilder) GetErrors() []compilercommon.SourceError { var errors = make([]compilercommon.SourceError, 0) it := sb.sg.layer.StartQuery(). IsKind(NodeTypeError). BuildNodeIterator() for it.Next() { errNode := it.Node() // Lookup the location of the SRG source node. errorSource := sb.sg.srg.GetNode(errNode.GetValue(NodePredicateNoticeSource).NodeId()) location := sb.sg.srg.NodeLocation(errorSource) // Add the error. msg := errNode.Get(NodePredicateNoticeMessage) errors = append(errors, compilercommon.NewSourceError(location, msg)) } return errors }
// 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 }