feat: actually print file from ast
parent
ec9ec20189
commit
30f79e9322
|
@ -1,10 +1,12 @@
|
||||||
package imports
|
package imports
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
|
"go/printer"
|
||||||
"go/token"
|
"go/token"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
@ -132,14 +134,7 @@ func (ft *Formatter) formatFile(path string) error {
|
||||||
}
|
}
|
||||||
ft.log("formatFile: moduleName: %+v\n", moduleName)
|
ft.log("formatFile: moduleName: %+v\n", moduleName)
|
||||||
|
|
||||||
// Parse ast
|
if err := ft.formatImports(path, pathBytes, moduleName); err != nil {
|
||||||
pathASTFile, err := ft.parseAST(path, pathBytes)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ft.log("formatFile: pathASTFile: %+v\n", pathASTFile)
|
|
||||||
|
|
||||||
if err := ft.formatASTFile(pathASTFile, moduleName); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,36 +145,36 @@ func (ft *Formatter) formatFile(path string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ft *Formatter) parseAST(path string, pathBytes []byte) (*ast.File, error) {
|
// Copy from goimports-reviser
|
||||||
|
func (ft *Formatter) formatImports(
|
||||||
|
path string,
|
||||||
|
pathBytes []byte,
|
||||||
|
moduleName string,
|
||||||
|
) error {
|
||||||
|
// Parse ast
|
||||||
fset := token.NewFileSet()
|
fset := token.NewFileSet()
|
||||||
|
|
||||||
parserMode := parser.Mode(0)
|
parserMode := parser.Mode(0)
|
||||||
parserMode |= parser.ParseComments
|
parserMode |= parser.ParseComments
|
||||||
|
|
||||||
pathASTFile, err := parser.ParseFile(fset, path, pathBytes, parserMode)
|
astFile, err := parser.ParseFile(fset, path, pathBytes, parserMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parser: failed to parse file [%s]: %w", path, err)
|
return fmt.Errorf("parser: failed to parse file [%s]: %w", path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore generated file
|
// Ignore generated file
|
||||||
if isGoGenerated(pathASTFile) {
|
if isGoGenerated(astFile) {
|
||||||
return nil, ErrGoGeneratedFile
|
return ErrGoGeneratedFile
|
||||||
}
|
}
|
||||||
|
|
||||||
return pathASTFile, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy from goimports-reviser
|
|
||||||
// If exist multi import, combine them into one
|
|
||||||
// This func will edit pathASTFile directly to combine
|
|
||||||
func (ft *Formatter) formatASTFile(
|
|
||||||
pathASTFile *ast.File,
|
|
||||||
moduleName string,
|
|
||||||
) error {
|
|
||||||
// Extract imports
|
// Extract imports
|
||||||
importSpecs := make([]ast.Spec, 0, len(pathASTFile.Imports))
|
importSpecs := make([]ast.Spec, 0, len(astFile.Imports))
|
||||||
for _, importSpec := range pathASTFile.Imports {
|
for _, importSpec := range astFile.Imports {
|
||||||
ft.log("parseImportsAndCombine: importSpec: %+v %+v\n", importSpec.Name.String(), importSpec.Path.Value)
|
if importSpec.Path.Value == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ft.log("formatImports: importSpec: %+v %+v\n", importSpec.Name.String(), importSpec.Path.Value)
|
||||||
importSpecs = append(importSpecs, importSpec)
|
importSpecs = append(importSpecs, importSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,12 +190,13 @@ func (ft *Formatter) formatASTFile(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
ft.mustLogImportSpecs("formatImports: formattedImportSpecs: ", formattedImportSpecs)
|
||||||
|
|
||||||
// Combine multi import decl
|
// Combine multi import decl into one
|
||||||
isMultiImportDecl := false
|
isMultiImportDecl := false
|
||||||
isExistFirstImportDecl := false
|
isExistFirstImportDecl := false
|
||||||
decls := make([]ast.Decl, 0, len(pathASTFile.Decls))
|
decls := make([]ast.Decl, 0, len(astFile.Decls))
|
||||||
for _, decl := range pathASTFile.Decls {
|
for _, decl := range astFile.Decls {
|
||||||
genDecl, ok := decl.(*ast.GenDecl)
|
genDecl, ok := decl.(*ast.GenDecl)
|
||||||
if !ok {
|
if !ok {
|
||||||
decls = append(decls, decl)
|
decls = append(decls, decl)
|
||||||
|
@ -215,8 +211,8 @@ func (ft *Formatter) formatASTFile(
|
||||||
if isExistFirstImportDecl {
|
if isExistFirstImportDecl {
|
||||||
isMultiImportDecl = true
|
isMultiImportDecl = true
|
||||||
// TODO: explain this
|
// TODO: explain this
|
||||||
storedGenDecl := decls[len(decls)-1].(*ast.GenDecl)
|
storedGenDecl, ok := decls[len(decls)-1].(*ast.GenDecl)
|
||||||
if storedGenDecl.Tok == token.IMPORT {
|
if ok && storedGenDecl.Tok == token.IMPORT {
|
||||||
storedGenDecl.Rparen = genDecl.End()
|
storedGenDecl.Rparen = genDecl.End()
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
@ -227,12 +223,20 @@ func (ft *Formatter) formatASTFile(
|
||||||
genDecl.Specs = formattedImportSpecs
|
genDecl.Specs = formattedImportSpecs
|
||||||
decls = append(decls, genDecl)
|
decls = append(decls, genDecl)
|
||||||
}
|
}
|
||||||
ft.log("parseImportsAndCombine: decls: %+v\n", decls)
|
|
||||||
|
|
||||||
if isMultiImportDecl {
|
if isMultiImportDecl {
|
||||||
pathASTFile.Decls = decls
|
astFile.Decls = decls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Print formatted bytes from formatted ast
|
||||||
|
var formattedBytes []byte
|
||||||
|
formattedBuffer := bytes.NewBuffer(formattedBytes)
|
||||||
|
if err := printer.Fprint(formattedBuffer, fset, astFile); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(formattedBuffer.String())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,16 +282,17 @@ func (ft *Formatter) groupImportSpecs(
|
||||||
result[thirdPartyImport] = append(result[thirdPartyImport], importSpec)
|
result[thirdPartyImport] = append(result[thirdPartyImport], importSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
ft.log("groupImports: std: %+v\n", result[stdImport])
|
ft.logImportSpecs("stdImport", result[stdImport])
|
||||||
ft.log("groupImports: third-party: %+v\n", result[thirdPartyImport])
|
ft.logImportSpecs("thirdPartyImport", result[thirdPartyImport])
|
||||||
if ft.companyPrefix != "" {
|
if ft.companyPrefix != "" {
|
||||||
ft.log("groupImports: company: %+v\n", result[companyImport])
|
ft.logImportSpecs("companyImport", result[companyImport])
|
||||||
}
|
}
|
||||||
ft.log("groupImports: local: %+v\n", result[localImport])
|
ft.logImportSpecs("localImport", result[localImport])
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy from goimports-reviser
|
||||||
func (ft *Formatter) formatImportSpecs(
|
func (ft *Formatter) formatImportSpecs(
|
||||||
importSpecs []ast.Spec,
|
importSpecs []ast.Spec,
|
||||||
groupedImportSpecs map[string][]*ast.ImportSpec,
|
groupedImportSpecs map[string][]*ast.ImportSpec,
|
||||||
|
@ -350,6 +355,7 @@ func (ft *Formatter) formatImportSpecs(
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy from goimports-reviser
|
||||||
func (ft *Formatter) moduleName(path string) (string, error) {
|
func (ft *Formatter) moduleName(path string) (string, error) {
|
||||||
ft.muModuleNames.RLock()
|
ft.muModuleNames.RLock()
|
||||||
if pkgName, ok := ft.moduleNames[path]; ok {
|
if pkgName, ok := ft.moduleNames[path]; ok {
|
||||||
|
@ -413,3 +419,24 @@ func (ft *Formatter) log(format string, v ...any) {
|
||||||
log.Printf(format, v...)
|
log.Printf(format, v...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ft *Formatter) logImportSpecs(logPrefix string, importSpecs []*ast.ImportSpec) {
|
||||||
|
if ft.isVerbose {
|
||||||
|
for _, importSpec := range importSpecs {
|
||||||
|
log.Printf("%s: importSpec: %+v %+v\n", logPrefix, importSpec.Name.String(), importSpec.Path.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ft *Formatter) mustLogImportSpecs(logPrefix string, importSpecs []ast.Spec) {
|
||||||
|
if ft.isVerbose {
|
||||||
|
for _, importSpec := range importSpecs {
|
||||||
|
importSpec, ok := importSpec.(*ast.ImportSpec)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("%s: importSpec: %+v %+v\n", logPrefix, importSpec.Name.String(), importSpec.Path.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue