Exemplo n.º 1
0
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
	}
}
Exemplo n.º 2
0
// 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
}
Exemplo n.º 3
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
}