// 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) }
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), }) } }
// 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 }
// 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()) }
// 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()) }
// 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()) }
// 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 }