Skip to content

Commit

Permalink
update to LuaHelper 0.2.17
Browse files Browse the repository at this point in the history
  • Loading branch information
lalawue committed Jul 19, 2022
1 parent 371ad82 commit f403145
Show file tree
Hide file tree
Showing 16 changed files with 278 additions and 62 deletions.
20 changes: 16 additions & 4 deletions luahelper-lsp/langserver/check/analysis/analysis_search.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,29 @@ func (a *Analysis) getFuncCallReferFunc(node *ast.FuncCallStat) (referFunc *comm
strName := strTabName[1:]

// 2.1) 查找局部变量的引用
var referInfo *common.ReferInfo
var findVar *common.VarInfo

// 需要先判断该变量是否直接含义key的函数
loc = common.GetTablePrefixLoc(taExp)
if locVar, ok := scope.FindLocVar(strName, loc); ok {
referInfo = locVar.ReferInfo
findVar = locVar
} else {
// 2.2) 局部变量没有找到,查找全局变量
if ok, oneVar := fileResult.FindGlobalVarInfo(strName, false, ""); ok {
referInfo = oneVar.ReferInfo
findVar = oneVar
}
}

if findVar == nil {
return nil, strName
}

subVar := common.GetVarSubGlobalVar(findVar, strKeyName)
if subVar != nil {
return subVar.ReferFunc, strKeyName
}

referInfo := findVar.ReferInfo
if referInfo == nil {
return nil, strName
}
Expand Down Expand Up @@ -1313,7 +1325,7 @@ func (a *Analysis) GetImportReferByCallExp(funcExp *ast.FuncCallExp) *common.Ref
}

// 先查找该引用是否有效
fileResult.CheckReferFile(oneRefer, a.Projects.GetAllFilesMap())
fileResult.CheckReferFile(oneRefer, a.Projects.GetAllFilesMap(), a.Projects.GetFileIndexInfo())

// 全局的引用文件里面增加一个引用对象
// if fileResult.ReferVec == nil {
Expand Down
14 changes: 5 additions & 9 deletions luahelper-lsp/langserver/check/analysis/analysis_stat.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,7 @@ func (a *Analysis) cgFuncCallParamCheck(node *ast.FuncCallStat) {
fileResult := a.curResult
nArgs := len(node.Args)

var referFunc *common.FuncInfo
var referStr string
referFunc, referStr = a.getFuncCallReferFunc(node)
referFunc, referStr := a.getFuncCallReferFunc(node)
if referFunc == nil {
return
}
Expand All @@ -100,15 +98,13 @@ func (a *Analysis) cgFuncCallParamCheck(node *ast.FuncCallStat) {
}

paramLen := len(referFunc.ParamList)

if nArgs > paramLen {
//调用处参数个数大于定义参数个数的,直接告警
errorStr := fmt.Sprintf("%s call func param num(%d) > func define param num(%d)", referStr, nArgs, paramLen)
fileResult.InsertError(common.CheckErrorCallParam, errorStr, node.Loc)
return
} else if nArgs < paramLen {
// 函数调用处参数个数小于定义参数个数的,支持注解辅助检查

// 如果未获取过
if !referFunc.ParamDefaultInit {
referFunc.ParamDefaultInit = true
Expand Down Expand Up @@ -219,7 +215,7 @@ func (a *Analysis) funcCallParamTypeCheck(node *ast.FuncCallStat, referFunc *com
}
}

//获取表达式类型字符串,如果是引用,则递归查找,(即支持类型传递)
//GetAnnTypeStrForRefer 获取表达式类型字符串,如果是引用,则递归查找,(即支持类型传递)
func (a *Analysis) GetAnnTypeStrForRefer(referExp ast.Exp, idx int) (retVec []string) {
retVec = []string{}
argType := common.GetAnnTypeFromExp(referExp)
Expand Down Expand Up @@ -277,10 +273,10 @@ func (a *Analysis) GetAnnTypeStrForRefer(referExp ast.Exp, idx int) (retVec []st
if argType == "LuaTypeRefer" {
//若仍是LuaTypeRefer 递归推导
return a.GetAnnTypeStrForRefer(varInfo.ReferExp, varIdx)
} else {
retVec = append(retVec, argType)
return retVec
}

retVec = append(retVec, argType)
return retVec
}

func (a *Analysis) cgBreakStat(node *ast.BreakStat) {
Expand Down
22 changes: 17 additions & 5 deletions luahelper-lsp/langserver/check/check_all.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ import (

// AllProject 所有工程包含的内容
type AllProject struct {
// 所有需要分析的文件map
allFilesMap map[string]struct{}
// 所有需要分析的文件map。key值为前缀,截取前面.部分的字符串, 例如 test.lua, 返回test。
allFilesMap map[string]string

// 文件名的缓存信息
fileIndexInfo *common.FileIndexInfo

// entryFile string
// 所有的工程入口分析文件
Expand Down Expand Up @@ -49,7 +52,7 @@ type AllProject struct {
func CreateAllProject(allFilesList []string, entryFileArr []string, clientExpPathList []string) *AllProject {
// 第一阶段(生成AST,第一次遍历AST),用多协程分析所有的扫描出来的文件
allProject := &AllProject{
allFilesMap: map[string]struct{}{},
allFilesMap: map[string]string{},
entryFilesList: entryFileArr,
clientExpFileMap: map[string]struct{}{},
fileStructMap: map[string]*results.FileStruct{},
Expand All @@ -59,11 +62,13 @@ func CreateAllProject(allFilesList []string, entryFileArr []string, clientExpPat
checkTerm: results.CheckTermFirst,
completeCache: common.CreateCompleteCache(),
fileLRUMap: common.NewLRUCache(20),
fileIndexInfo: common.CreateFileIndexInfo(),
}

// 传人的所有文件列表转换成map
for _, fileName := range allFilesList {
allProject.allFilesMap[fileName] = struct{}{}
allProject.allFilesMap[fileName] = common.CompleteFilePathToPreStr(fileName)
allProject.fileIndexInfo.InsertOneFile(fileName)
}

// 传人的插件客户端额外的文件列表转换成map
Expand Down Expand Up @@ -154,10 +159,15 @@ func (a *AllProject) rebuidCreateTypeMap() {
}

// GetAllFilesMap 获取分析的文件map列表
func (a *AllProject) GetAllFilesMap() (allFilesMap map[string]struct{}) {
func (a *AllProject) GetAllFilesMap() (allFilesMap map[string]string) {
return a.allFilesMap
}

// GetFileIndexInfo 获取文件的缓存结构
func (a *AllProject) GetFileIndexInfo() *common.FileIndexInfo {
return a.fileIndexInfo
}

// IsInAllFilesMap 指定的文件,是否在已经分析的map列表中
func (a *AllProject) IsInAllFilesMap(strFile string) bool {
_, flag := a.allFilesMap[strFile]
Expand All @@ -174,6 +184,8 @@ func (a *AllProject) RemoveFile(strFile string) {
// 1) 所有需要分析的文件,删除它
delete(a.allFilesMap, strFile)

a.fileIndexInfo.RemoveOneFile(strFile)

// 2)删除第一阶段的文件指针
_, beforeExitFlag := a.GetFirstFileStuct(strFile)
delete(a.fileStructMap, strFile)
Expand Down
2 changes: 1 addition & 1 deletion luahelper-lsp/langserver/check/check_find_var_refer.go
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ func (a *AllProject) getImportReferSymbol(luaInFile string, funcExp *ast.FuncCal
}

// 先查找该引用是否有效
fileStruct.FileResult.CheckReferFile(oneRefer, a.allFilesMap)
fileStruct.FileResult.CheckReferFile(oneRefer, a.allFilesMap, a.fileIndexInfo)
if !oneRefer.Valid {
return nil
}
Expand Down
34 changes: 34 additions & 0 deletions luahelper-lsp/langserver/check/check_first_hanlde.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,40 @@ func (a *AllProject) HandleFirstAllProject() {

// 重建
common.GConfig.RebuildSameFileNameVar(a.allFilesMap)
// time2 := time.Now()
// // 创建所有文件的目录结构
// for strFile := range a.allFilesMap {
// splitVec := strings.Split(strFile, "/")
// vecLen := len(splitVec)

// tmpFileDir := a.allFilesDirStruct
// for index := range splitVec {
// if index == vecLen - 1 {
// if tmpFileDir.FilesMap == nil {
// tmpFileDir.FilesMap = map[string]struct{}{}
// }
// tmpFileDir.FilesMap[strFile] = struct{}{}
// break
// }

// subStr := strings.Join(splitVec[0:index + 1], "/")
// if subFileDir, ok := tmpFileDir.SubDirList[subStr]; ok {
// tmpFileDir = subFileDir
// } else {
// oneFileDir := &common.FileDirSturct{}
// oneFileDir.CurDir = subStr
// if tmpFileDir.SubDirList == nil {
// tmpFileDir.SubDirList = map[string]*common.FileDirSturct{}
// }

// tmpFileDir.SubDirList[subStr] = oneFileDir
// tmpFileDir = oneFileDir
// }
// }
// }
// tc2 := time.Since(time2)
// ftime2 := tc2.Milliseconds()
// log.Debug("allFilesDirStruct cost time=%d(ms)", ftime2)

a.firstCreateAndTraverseAst(filesList, false)

Expand Down
2 changes: 1 addition & 1 deletion luahelper-lsp/langserver/check/check_lsp_define.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (a *AllProject) FindOpenFileDefine(strFile string, strOpenFile string) (def
}

// 1) 文件匹配的完整路径
strOpenFile = common.GConfig.GetDirManager().GetBestMatchReferFile(strFile, strOpenFile, a.allFilesMap)
strOpenFile = common.GConfig.GetDirManager().GetBestMatchReferFile(strFile, strOpenFile, a.allFilesMap, a.fileIndexInfo)

// 2) 判断是否为直接打开某一个文件
if strOpenFile == "" {
Expand Down
6 changes: 4 additions & 2 deletions luahelper-lsp/langserver/check/check_lsp_filechange.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ func (a *AllProject) HandleFileEventChanges(fileEventVec []FileEventStruct) (cha
for _, fileEvents := range fileEventVec {
strFile := fileEvents.StrFile
if fileEvents.Type == FileEventCreated {
a.allFilesMap[strFile] = struct{}{}
a.allFilesMap[strFile] = common.CompleteFilePathToPreStr(strFile)
a.fileIndexInfo.InsertOneFile(strFile)

needAgainFileVec = append(needAgainFileVec, strFile)
if dirManager.IsInDir(strFile) {
needReferFileMap[strFile] = struct{}{}
Expand Down Expand Up @@ -116,7 +118,7 @@ func (a *AllProject) HandleFileEventChanges(fileEventVec []FileEventStruct) (cha
continue
}

fileStruct.FileResult.ReanalyseReferInfo(needReferFileMap, a.allFilesMap)
fileStruct.FileResult.ReanalyseReferInfo(needReferFileMap, a.allFilesMap, a.fileIndexInfo)
}
// 引用关系变了,诊断信息也要跟着改变
changeDiagnostic = true
Expand Down
31 changes: 14 additions & 17 deletions luahelper-lsp/langserver/check/common/dir_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ func calcMatchStrScore(fileName string, referFileName string, condidateStr strin
// referFile 为引用的lua文件名
// allFilesMap 为项目中所有包含的lua文件
// 返回值为匹配最合适的文件
func (d *DirManager) GetBestMatchReferFile(curFile string, referFile string, allFilesMap map[string]struct{}) (findStr string) {
func (d *DirManager) GetBestMatchReferFile(curFile string, referFile string, allFilesMap map[string]string, fileIndexInfo *FileIndexInfo) (findStr string) {
// 首先判断传人的文件是否带有后缀的
suffixFlag := false
seperateIndex := strings.Index(referFile, ".")
Expand All @@ -646,30 +646,27 @@ func (d *DirManager) GetBestMatchReferFile(curFile string, referFile string, all
}

candidateVec := []string{}
lenReferFile := len(referFile)
for strFile := range allFilesMap {
referFileTmp := referFile
strVec := strings.Split(referFile, "/")
referfileName := strVec[len(strVec)-1]

if suffixFlag {
if len(strFile) > lenReferFile {
referFileTmp = "/" + referFile
}
var fileNameMap map[string]string
if suffixFlag {
fileNameMap = fileIndexInfo.GetFileNameMap(referfileName)
} else {
fileNameMap = fileIndexInfo.GetPreFileNameMap(referfileName)
}

// 如果是带了后缀,拿后缀的去匹配
referFileTmp := "/" + referFile
for strFile, pathToPreStr := range fileNameMap {
if suffixFlag {
if !strings.HasSuffix(strFile, referFileTmp) {
continue
}
}
} else {
// 如果不带后缀,map中的路径名先提取
preFile := completeFilePathToPreStr(strFile)
preFile := pathToPreStr
if preFile == "" {
continue
}

if len(preFile) > lenReferFile {
referFileTmp = "/" + referFile
}

if !strings.HasSuffix(preFile, referFileTmp) {
continue
}
Expand Down
93 changes: 93 additions & 0 deletions luahelper-lsp/langserver/check/common/file_index_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package common

import "strings"

// // FileDirSturct 文件的层级目录结构
// type FileDirSturct struct {
// CurDir string // 当前的目录,例如 g:/compangyproject
// FilesMap map[string]struct{} // 该目录下包含的具体的lua文件。全路径,例如为:g:/compangyproject/one.lua
// SubDirList map[string]*FileDirSturct // 当前目录下,包含的所有子文件夹,嵌套的结构
// }

// // GetFirstContentDir 递归向下获取第一个包含有用内容的子目录
// func (f *FileDirSturct) GetFirstContentDir() *FileDirSturct {
// if len(f.FilesMap) == 0 && len(f.SubDirList) == 1 {
// for _, subDir := range f.SubDirList {
// return subDir.GetFirstContentDir()
// }
// return nil
// }

// return f
// }

// FileIndexInfo 文件索引信息,文件名映射到全路径
type FileIndexInfo struct {
fileNameMap map[string](map[string]string) // 文件名(包括后缀名)映射到所有的完整路径
freFileNameMap map[string](map[string]string) // 文件名(不包括后缀名)映射到所有的完整路径
}

// CreateFileIndexInfo 创建文件索引对象
func CreateFileIndexInfo() *FileIndexInfo {
return &FileIndexInfo{
fileNameMap: map[string](map[string]string){},
freFileNameMap: map[string](map[string]string){},
}
}

// InsertOneFile 缓存中插入一个文件名
func (f *FileIndexInfo) InsertOneFile(strFile string) {
// CompleteFilePathToPreStr
strVec := strings.Split(strFile, "/")
fileName := strVec[len(strVec)-1]

completePathToPreStr := CompleteFilePathToPreStr(strFile)
if valeMap, ok := f.fileNameMap[fileName]; ok {
valeMap[strFile] = completePathToPreStr
} else {
f.fileNameMap[fileName] = map[string]string{}
f.fileNameMap[fileName][strFile] = completePathToPreStr
}

seperateIndex := strings.Index(fileName, ".")
if seperateIndex < 0 {
return
}

preStr := fileName[0:seperateIndex]
if valeMap, ok := f.freFileNameMap[preStr]; ok {
valeMap[strFile] = completePathToPreStr
} else {
f.freFileNameMap[preStr] = map[string]string{}
f.freFileNameMap[preStr][strFile] = completePathToPreStr
}
}

// RemoveOneFile 清除指定的文件
func (f *FileIndexInfo) RemoveOneFile(strFile string) {
strVec := strings.Split(strFile, "/")
fileName := strVec[len(strVec)-1]
if valeMap, ok := f.fileNameMap[fileName]; ok {
delete(valeMap, fileName)
}

seperateIndex := strings.Index(fileName, ".")
if seperateIndex < 0 {
return
}

preStr := fileName[0:seperateIndex]
if valeMap, ok := f.freFileNameMap[preStr]; ok {
delete(valeMap, preStr)
}
}

// GetFileNameMap 获取文件名(包括后缀名)映射的所有文件名称
func (f *FileIndexInfo) GetFileNameMap(strFile string) map[string]string {
return f.fileNameMap[strFile]
}

// GetPreFileNameMap 获取文件名(不包括后缀名)映射的所有文件名称
func (f *FileIndexInfo) GetPreFileNameMap(strFile string) map[string]string {
return f.freFileNameMap[strFile]
}
2 changes: 1 addition & 1 deletion luahelper-lsp/langserver/check/common/global_conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -1228,7 +1228,7 @@ func (g *GlobalConfig) IsIgnoreRequireModuleError(strName string) bool {

// RebuildSameFileNameVar 重构应该忽略的同文件名的变量
// allFilesMap为最新的加载的所有文件名,包含了前缀
func (g *GlobalConfig) RebuildSameFileNameVar(allFilesMap map[string]struct{}) {
func (g *GlobalConfig) RebuildSameFileNameVar(allFilesMap map[string]string) {
if !g.IgnoreFileNameVarFlag {
return
}
Expand Down
Loading

0 comments on commit f403145

Please sign in to comment.