Example #1
0
// salForValues returns a SourceAndLocation for the given string predicate values.
func salForValues(sourceStr string, bytePositionStr string) compilercommon.SourceAndLocation {
	source := compilercommon.InputSource(sourceStr)
	bytePosition, err := strconv.Atoi(bytePositionStr)
	if err != nil {
		panic(fmt.Sprintf("Expected int value for byte position, found: %v", bytePositionStr))
	}

	return compilercommon.NewSourceAndLocation(source, bytePosition)
}
Example #2
0
func (tt *testTracker) Parse(source compilercommon.InputSource, input string, importHandler ImportHandler) {
	tt.pathsImported[string(source)] = true

	file := testFile{}
	json.Unmarshal([]byte(input), &file)

	for _, importPath := range file.Imports {
		importHandler(PackageImport{
			Kind:           "",
			Path:           importPath,
			ImportType:     ImportTypeLocal,
			SourceLocation: compilercommon.NewSourceAndLocation(source, 0),
		})
	}
}
Example #3
0
// reportImport reports an import of the given token value as a path.
func (p *sourceParser) reportImport(value string, kind string) (string, error) {
	if p.importReporter == nil {
		return "", nil
	}

	sal := compilercommon.NewSourceAndLocation(p.source, int(p.currentToken.position))

	importPath, importType, err := ParseImportValue(value)
	if err != nil {
		return "", err
	}

	var packageImportType = packageloader.ImportTypeLocal
	if importType == ParsedImportTypeVCS {
		packageImportType = packageloader.ImportTypeVCS
	}

	return p.importReporter(packageloader.PackageImport{kind, importPath, packageImportType, sal}), nil
}
Example #4
0
// parseAndFormatSourceFile parses the source file at the given path (with associated file info),
// formats it and, if changed, writes it back to that path.
func parseAndFormatSourceFile(sourceFilePath string, info os.FileInfo, importHandling importHandlingInfo) error {
	// Load the source from the file.
	source, err := ioutil.ReadFile(sourceFilePath)
	if err != nil {
		return err
	}

	// Conduct the parsing.
	parseTree := newParseTree(source)
	inputSource := compilercommon.InputSource(sourceFilePath)
	rootNode := parser.Parse(parseTree.createAstNode, nil, inputSource, string(source))

	// Report any errors found.
	if len(parseTree.errors) > 0 {
		for _, err := range parseTree.errors {
			startRune, _ := strconv.Atoi(err.properties[parser.NodePredicateStartRune])
			sal := compilercommon.NewSourceAndLocation(inputSource, startRune)
			location := sal.Location()

			fmt.Printf("%v: line %v, column %v: %s\n",
				sourceFilePath,
				location.LineNumber()+1,
				location.ColumnPosition()+1,
				err.properties[parser.NodePredicateErrorMessage])
		}

		return fmt.Errorf("Parsing errors found in file %s", sourceFilePath)
	}

	// Create the formatted source.
	formattedSource := buildFormattedSource(parseTree, rootNode.(formatterNode), importHandling)
	if string(formattedSource) == string(source) {
		// Nothing changed.
		return nil
	}

	// Overwrite the file with the formatted source.
	return ioutil.WriteFile(sourceFilePath, formattedSource, info.Mode())
}
Example #5
0
// salForNode returns a SourceAndLocation for the given graph node.
func salForNode(node compilergraph.GraphNode) compilercommon.SourceAndLocation {
	return compilercommon.NewSourceAndLocation(
		compilercommon.InputSource(node.Get(parser.NodePredicateSource)),
		node.GetValue(parser.NodePredicateStartRune).Int())
}
Example #6
0
// salForIterator returns a SourceAndLocation for the given iterator. Note that
// the iterator *must* contain the NodePredicateSource and NodePredicateStartRune predicates.
func salForIterator(iterator compilergraph.NodeIterator) compilercommon.SourceAndLocation {
	return compilercommon.NewSourceAndLocation(
		compilercommon.InputSource(iterator.GetPredicate(parser.NodePredicateSource).String()),
		iterator.GetPredicate(parser.NodePredicateStartRune).Int())
}
Example #7
0
// Load performs the loading of a Serulian package found at the directory path.
// Any libraries specified will be loaded as well.
func (p *PackageLoader) Load(libraries ...Library) LoadResult {
	// Start the loading goroutine.
	go p.loadAndParse()

	// Start the error/warning collection goroutine.
	result := &LoadResult{
		Status:   true,
		Errors:   make([]compilercommon.SourceError, 0),
		Warnings: make([]compilercommon.SourceWarning, 0),
	}

	go p.collectIssues(result)

	// Add the root source file as the first package to be parsed.
	sal := compilercommon.NewSourceAndLocation(compilercommon.InputSource(p.rootSourceFile), 0)

	var added = false
	for _, handler := range p.handlers {
		if strings.HasSuffix(p.rootSourceFile, handler.PackageFileExtension()) {
			p.pushPath(pathSourceFile, handler.Kind(), p.rootSourceFile, sal)
			added = true
			break
		}
	}

	if !added {
		log.Fatalf("Could not find handler for root source file: %v", p.rootSourceFile)
	}

	// Add the libraries to be parsed.
	for _, library := range libraries {
		if library.IsSCM {
			sal := compilercommon.NewSourceAndLocation(compilercommon.InputSource(library.PathOrURL), 0)
			p.pushPath(pathVCSPackage, library.Kind, library.PathOrURL, sal)
		} else {
			sal := compilercommon.NewSourceAndLocation(compilercommon.InputSource(library.PathOrURL), 0)
			p.pushPath(pathLocalPackage, library.Kind, library.PathOrURL, sal)
		}
	}

	// Wait for all packages and source files to be completed.
	p.workTracker.Wait()

	// Tell the goroutines to quit.
	p.finished <- true
	p.finished <- true

	// Save the package map.
	result.PackageMap = p.packageMap.Build()

	// Apply all handler changes.
	for _, handler := range p.handlers {
		handler.Apply(result.PackageMap)
	}

	// Perform verification in all handlers.
	if len(result.Errors) == 0 {
		errorReporter := func(err compilercommon.SourceError) {
			result.Errors = append(result.Errors, err)
			result.Status = false
		}

		warningReporter := func(warning compilercommon.SourceWarning) {
			result.Warnings = append(result.Warnings, warning)
		}

		for _, handler := range p.handlers {
			handler.Verify(errorReporter, warningReporter)
		}
	}

	return *result
}