package analyzer import "os" import "sort" import "path/filepath" import "git.tebibyte.media/arf/arf/types" // locator uniquely identifies a section in the section table. type locator struct { modulePath string name string } func (where locator) ToString () (output string) { cwd, _ := os.Getwd() modulePath, err := filepath.Rel(cwd, where.modulePath) if err != nil { panic("cant get relative path: " + err.Error()) } output += modulePath + "." + where.name return } // SectionTable stores a list of semantically analized sections from one module, // and all sections that it requires from other modules. type SectionTable map[locator] Section // ToString returns the data stored in the table as a string. func (table SectionTable) ToString (indent int) (output string) { sortedKeys := make(locatorArray, len(table)) index := 0 for key, _ := range table { sortedKeys[index] = key index ++ } sort.Sort(sortedKeys) for _, name := range sortedKeys { section := table[name] output += section.ToString(indent) } return } // locatorArray holds a sortable array of locators type locatorArray []locator // Len returns the length of the locator array func (array locatorArray) Len () (length int) { length = len(array) return } // Less returns whether item at index left is less than item at index right. func (array locatorArray) Less (left, right int) (less bool) { leftLocator := array[left] rightLocator := array[right] less = leftLocator.modulePath + leftLocator.name < rightLocator.modulePath + rightLocator.name return } // Swap swaps the elments at indices left and right. func (array locatorArray) Swap (left, right int) { temp := array[left] array[left] = array[right] array[right] = temp } // Section is a semantically analyzed section. type Section interface { // Provided by sectionBase Name () (name string) Complete () (complete bool) ModulePath () (path string) ModuleName () (path string) Permission () (permission types.Permission) locator () (where locator) // Must be implemented by each individual section ToString (indent int) (output string) } // sectionBase is a struct that all sections must embed. type sectionBase struct { where locator complete bool permission types.Permission } // Name returns the name of the section. func (section sectionBase) Name () (name string) { name = section.where.name return } // ModulePath returns the full path of the module the section came from. func (section sectionBase) ModulePath () (path string) { path = section.where.modulePath return } // ModuleName returns the name of the module where the section came from. func (section sectionBase) ModuleName () (name string) { name = filepath.Base(section.where.modulePath) return } // Complete returns wether the section has been completed. func (section sectionBase) Complete () (complete bool) { complete = section.complete return } // Permission returns the permission of the section. func (section sectionBase) Permission () (permission types.Permission) { permission = section.permission return } // locator returns the module path and name of the section. func (section sectionBase) locator () (where locator) { where = section.where return }