18 from Map.map
import fuzzymatch
19 from Tool.tool
import getParameter,removeParameter,getFileName,resolvePythonExecutable
85 s+=f
"posChange:{self.pos}, "
87 s+=f
"typeChange:{self.type}, "
89 s+=f
"delete:{self.dele}, "
91 s+=f
"add:{self.add}, "
103 with open(errorLog,
'a', encoding=
'utf-8')
as fw:
119 ansDict[
'current']=sharedDict[k][
'current']
120 ansDict[
'target']=sharedDict[k][
'target']
135 if key
not in sharedDict:
137 innerDict=sharedDict[key]
138 innerDict[
'current']=currentDict
139 innerDict[
'target']=targetDict
140 sharedDict[key]=innerDict
142 innerDict=sharedDict[key]
143 if sharedDict[key][
'current'][
'matchMethod']==
'static' and currentDict[
'matchMethod']==
'dynamic':
144 innerDict[
'current']=currentDict
145 if sharedDict[key][
'target'][
'matchMethod']==
'static' and targetDict[
'matchMethod']==
'dynamic':
146 innerDict[
'target']=targetDict
147 sharedDict[key]=innerDict
168 if oldType==
"" or newType==
"":
176 if oldType[0]==
"'" and oldType[-1]==
"'":
177 oldType=oldType[1:-1]
179 if newType[0]==
"'" and newType[-1]==
"'":
180 newType=newType[1:-1]
182 if 'Union' in oldType:
183 pattern=
r'.*?Union\[(.*)\].*?'
184 result=re.findall(pattern,oldType)
186 elif 'Optional' in oldType:
187 pattern=
r'.*?Optional\[(.*)\].*?'
188 result=re.findall(pattern,oldType)
191 oldLst=oldType.split(
'|')
196 oldTypeSet.add(it.replace(
' ',
''))
200 if 'Union' in newType:
201 pattern=
r'.*?Union\[(.*)\].*?'
202 result=re.findall(pattern,newType)
204 elif 'Optional' in newType:
205 pattern=
r'.*?Optional\[(.*)\].*?'
206 result=re.findall(pattern,newType)
209 newLst=newType.split(
'|')
214 newTypeSet.add(it.replace(
' ',
''))
217 if len(oldTypeSet)>0
and oldTypeSet.issubset(newTypeSet):
230 paraStr=paraStr.replace(
' ',
'')
233 paraStr=paraStr.split(
'->')[0]
234 if '(' in paraStr[0]:
235 paraStr=paraStr[1:-1]
241 lst=[para
for para
in lst
if para !=
'/']
245 elif 'cls' in lst[0]:
248 parameter=Parameter()
249 parameter.position=lst.index(para)
250 parameter.fullItem=para
256 if flagMaohao
and "'" not in para[0:pos]
and '"' not in para[0:pos]
and '<' not in para[0:pos]:
262 parameter.value=ll[1]
271 paraObjLst.append(parameter)
276 for para
in paraObjLst:
277 if '**' in para.name:
278 pos2Star=para.position
279 elif '*' in para.name:
280 posStar=para.position
287 posParameters=paraObjLst[0:pos]
289 for para
in paraObjLst[pos+1:]:
290 if '**' not in para.name:
291 keyParameters.append(para)
293 return posParameters,keyParameters
306 oldPosParaNum=len(oldPos)
310 for oldPara
in copy.deepcopy(oldPos):
312 for newPara
in newPos:
313 if oldPara.name==newPara.name:
315 if oldPara.position!=newPara.position:
316 up.pos=newPara.position
321 oldPos.remove(oldPara)
322 newPos.remove(newPara)
325 dic[(oldPara.name,oldPara.position)]=up
328 for oldPara
in copy.deepcopy(oldKey):
330 for newPara
in newKey:
331 if oldPara.name==newPara.name:
337 oldKey.remove(oldPara)
338 newKey.remove(newPara)
341 dic[(oldPara.name,oldPara.position)]=up
346 for oldPara
in copy.deepcopy(oldPos):
348 for newPara
in newKey:
349 if oldPara.name==newPara.name:
351 up.pos2key=oldPara.name
356 oldPos.remove(oldPara)
357 newKey.remove(newPara)
360 dic[(oldPara.name,oldPara.position)]=up
364 for oldPara
in copy.deepcopy(oldKey):
366 for newPara
in copy.deepcopy(newPos):
367 if oldPara.name==newPara.name:
368 print(f
"key2pos-->{oldPara.name}")
370 up.key2pos=oldPara.name
375 oldKey.remove(oldPara)
376 newPos.remove(newPara)
379 dic[(oldPara.name,oldPara.position)]=up
385 for oldPara
in copy.deepcopy(oldPos):
387 for newPara
in newPos:
388 if oldPara.position==newPara.position
and not isDifferType(oldPara.type,newPara.type):
390 if oldPara.name!=newPara.name:
391 up.rename=newPara.name
396 oldPos.remove(oldPara)
397 newPos.remove(newPara)
400 dic[(oldPara.name,oldPara.position)]=up
402 oldPos.remove(oldPara)
405 dic[(oldPara.name,oldPara.position)]=up
408 for oldPara
in copy.deepcopy(oldKey):
410 for newPara
in newKey:
411 if oldPara.type==newPara.type:
414 up.rename=newPara.name
415 oldKey.remove(oldPara)
416 newKey.remove(newPara)
419 dic[(oldPara.name,oldPara.position)]=up
421 oldKey.remove(oldPara)
424 dic[(oldPara.name,oldPara.position)]=up
432 if para.position>=0
and para.position<oldPosParaNum:
434 if key[1]==para.position:
440 dic[(para.name,para.position)]=up
449 dic[(para.name,para.position)]=up
454 for key,value
in dic.items():
455 if key
not in updateDict:
458 updateDict[key][
'delete']=value.dele
460 updateDict[key][
'typeChange']=value.type
462 updateDict[key][
'rename']=value.rename
464 updateDict[key][
'posChange']=value.pos
466 updateDict[key][
'replace']=value.rep
468 updateDict[key][
'pos2key']=value.pos2key
470 updateDict[key][
'addPos']=value.addPos
472 updateDict[key][
'addKey']=value.addKey
475 updateDict[key][
'key2pos']=value.key2pos
478 ansDict=dict(sorted(updateDict.items(), key=
lambda it: it[0][1]))
499 for oldPara
in oldPos:
501 for newPara
in newPos:
502 if oldPara.name==newPara.name
and oldPara.position==newPara.position
and not isDifferType(oldPara.type,newPara.type):
509 for newPara
in newPos:
510 if newPara.position>=len(oldPos):
511 if newPara.value==
'':
515 for oldPara
in oldKey:
517 for newPara
in newKey:
518 if oldPara.name==newPara.name
and not isDifferType(oldPara.type,newPara.type):
524 for newPara
in newPos:
525 if oldPara.name==newPara.name
and not isDifferType(oldPara.type,newPara.type):
527 print(f
"key2pos-->{oldPara.name}")
535 for newPara
in newKey:
537 for oldPara
in oldKey:
538 if newPara.name==oldPara.name:
542 if newPara.value==
'':
558 if len(current[
'match'])==0
or len(target[
'match'])==0:
563 if isinstance(current[
'match'],str):
564 currentDict={current[
'internalPath']:[current[
'match']]}
566 currentDict=current[
'match']
568 if isinstance(target[
'match'],str):
569 targetDict={target[
'internalPath']:[target[
'match']]}
571 targetDict=target[
'match']
576 for currentSameAPI,currentOvLst
in currentDict.items():
577 for targetSameAPI,targetOvLst
in targetDict.items():
578 if currentSameAPI==targetSameAPI
or (currentSameAPI+
'.' in targetSameAPI)
or (targetSameAPI+
'.' in currentSameAPI)
or len(currentDict)==1
and len(targetDict)==1:
583 for currentOvPara
in copy.deepcopy(currentOvLst):
584 for targetOvPara
in copy.deepcopy(targetOvLst):
585 if currentOvPara.split(
'->')[0]==targetOvPara.split(
'->')[0]:
586 currentOvLst.remove(currentOvPara)
587 targetOvLst.remove(targetOvPara)
592 for currentOvPara
in currentOvLst:
594 for targetOvPara
in targetOvLst:
599 if compatibleFlag==0:
600 for targetOvPara
in targetOvLst:
601 repairDict=
findDiffer(currentOvPara,targetOvPara)
602 tempLst1.append((repairDict,targetOvPara))
605 for currentOvPara
in currentOvLst:
607 for targetOvPara
in targetOvLst:
612 if compatibleFlag==0:
613 for targetOvPara
in targetOvLst:
614 repairDict=
findDiffer(currentOvPara,targetOvPara)
615 tempLst2.append((repairDict,targetOvPara))
635 currentMethod=current.get(
'matchMethod')
636 targetMethod=target.get(
'matchMethod')
637 if {currentMethod,targetMethod}=={
'dynamic',
'static'}:
638 if currentMethod==
'dynamic':
639 dynamicMatchInfo=current
640 staticMatchInfo=target
641 dynamicVersion=currentVersion
642 dynamicIsCurrent=
True
644 dynamicMatchInfo=target
645 staticMatchInfo=current
646 dynamicVersion=targetVersion
647 dynamicIsCurrent=
False
649 staticCandidates=staticMatchInfo.get(
'match',{})
651 if isinstance(staticCandidates,dict)
and len(staticCandidates)==1
and formatAPI
in staticCandidates:
654 dynamicStaticMatch=
fuzzymatch(formatAPI,libName,dynamicVersion,0)
655 qualifiedName=dynamicMatchInfo.get(
'qualifiedName')
656 if isinstance(qualifiedName,str)
and isinstance(dynamicStaticMatch,dict)
and isinstance(staticCandidates,dict) \
657 and qualifiedName
in dynamicStaticMatch
and qualifiedName
in staticCandidates:
658 dynamicStaticCompare={
'match':{qualifiedName:list(dynamicStaticMatch[qualifiedName])}}
659 staticCompare={
'match':{qualifiedName:list(staticCandidates[qualifiedName])}}
682 def addValueForAPI(callAPI,projName,runPath,runCommand,currentEnv,targetEnv,errLst,callKey,*,runtimePaths):
683 copyRoot=runtimePaths[
'copy_root']
684 dynamicRoot=runtimePaths[
'dynamic_root']
690 (
'new_'+pklName[:-4]+
'__object.pkl',1),
691 (
'new_'+pklName[:-4]+
'__expr.pkl',1),
693 (pklName[:-4]+
'__object.pkl',0),
694 (pklName[:-4]+
'__expr.pkl',0),
698 for candidateName,candidateFlag
in pklCandidates:
699 candidatePath=os.path.join(copyRoot,
'pkl',candidateName)
700 if os.path.exists(candidatePath):
702 pklPath=candidatePath
715 if runPath
and runPath
not in runCommand:
716 cwd = os.path.join(dynamicRoot, projName, runPath)
717 script =
'addValueForAPI.py'
719 cwd = os.path.join(dynamicRoot, projName)
720 script = os.path.join(runPath,
'addValueForAPI.py')
722 cwd = os.path.join(dynamicRoot, projName)
723 script =
'addValueForAPI.py'
724 matchResult = subprocess.run([pythonPath, script, pklPath, callAPI, pklKey],cwd=cwd, capture_output=
True, text=
True, encoding=
'utf-8')
725 if matchResult.returncode!=0:
726 errLst.append(f
"{callAPI}, addValueError: {matchResult.stderr}\n")
729 output=matchResult.stdout
731 obj=re.compile(pattern,re.DOTALL)
732 lst=obj.findall(output)
Update class for parameter change analysis 参数变更分析类
pos2key
Conversion of positional parameter to keyword parameter 位置参数变更为关键字参数
rename
New name of the parameter 参数重命名
dele
Flag (1) of parameter deletion 参数删除标记 (1)
addPos
New positional parameter 新增位置参数
key2pos
Conversion of keyword parameter to positional parameter 关键字参数变更为位置参数
addKey
New keyword parameter 新增关键字参数
type
New type of the parameter 参数新类型
def __repr__(self)
Return the string representation of the parameter update 返回参数变更的字符串表示形式
rep
Replacement of the parameter 参数替换
pos
New position of the parameter 参数新位置
def __init__(self)
The constructor 构造函数
value
New default value of the parameter 参数新默认值
def analyzeCompatibility(oldPara, newPara)
Analyze the compatibility of two APIs 判断两个重载API是否兼容
def analyzeMatchCompatibility(current, target, *formatAPI, libName, currentVersion, targetVersion)
Analyze compatibility after selecting comparable matching results 选择可比较的匹配结果,再分析版本间兼容性
def isCompatible(current, target)
Determine the compatibility of APIs from current and target versions 判断起始版本和目标版本API的兼容性
def updateErrorLst(errorLog, errorLst)
Save error messages 保存错误信息
def para2Obj(paraStr)
Convert parameter string to positional and keyword parameter objects 将参数字符串转换为位置和关键字参数对象
def isDifferType(oldType, newType)
Determine parameter type change: compatible type means no type change 判断两个参数的类型是否发生了变更: 只要兼容,就认为相同
def updateSharedDict(callAPI, currentDict, targetDict, sharedDict)
Update API mapping dictionary: add and revise 更新API映射字典: 添加和修改
def findDiffer(oldPara, newPara)
Determine difference of two parameters 输入两个api参数部分,判断参数部分有何不同
def querySharedDict(callAPI, sharedDict)
Query API mapping dictionary 查询API映射字典
def addValueForAPI(callAPI, projName, runPath, runCommand, currentEnv, targetEnv, errLst, callKey, *runtimePaths)
Add values stored by pkl file for API parameters 为API参数添加保存至pkl文件中的值
def fuzzymatch(formatAPI, libName, version, builtinFlag)
Static mapping of API signatures API签名静态匹配