20 from Extract.getCall
import getCallFunction, modifyWithName
22 from Tool.tool
import getAst,getParameter,getLastAPIParameter,departAPI,departAPI2,ConditionalReturnTransformer, getFileName, getRunFile
23 from Tool.workspace
import getRuntimePaths
59 return minL,minR,midL,midR,huaL,huaR
70 with open(filePath,
'w',encoding=
'UTF-8')
as fw:
71 newCode=ast.unparse(root)
73 fw.write(f
"{newCode}\n")
74 except Exception
as e:
75 print(f
"oneLine --> {filePath} parse to ast failed: {e}")
85 transformer = ConditionalReturnTransformer()
86 new_root = transformer.visit(root)
88 with open(filePath,
'w',encoding=
'UTF-8')
as fw:
89 newCode=ast.unparse(root)
90 fw.write(f
"{newCode}\n")
91 except Exception
as e:
92 print(f
"expandConditionalReturn --> {filePath} parse to ast failed: {e}")
106 for node
in ast.iter_child_nodes(root):
107 if isinstance(node,ast.ListComp):
108 s=ast.unparse(node.generators).lstrip(
' ')
109 pattern=
"for (.*?) in"
110 lst=re.findall(pattern,s)
117 s1=f
"{var}=[{temp} {s}][0]"
133 for node
in ast.iter_child_nodes(root):
134 if isinstance(node,ast.DictComp):
135 s=ast.unparse(node.generators).lstrip(
' ')
136 pattern=
"for (.*?) in"
137 lst=re.findall(pattern,s)
144 s1=f
"{var}=[{temp} {s}][0]"
157 with open(filePath,
'r',encoding=
'UTF-8')
as fr:
158 codeLst=fr.readlines()
160 for i
in range(len(codeLst)):
161 s=codeLst[i].lstrip(
' ').rstrip(
' ')
163 root=ast.parse(s,filename=
'<unknown>',mode=
'exec')
164 except Exception
as e:
170 for node
in ast.walk(root):
171 if isinstance(node,ast.ListComp):
173 if isinstance(node,ast.DictComp):
176 if not listComp
and not dictComp:
182 callLst=[record[
'call_text']
for record
in callDict.values()]
184 for node
in ast.walk(root):
185 if isinstance(node, ast.Call):
186 callState=ast.unparse(node)
187 callState=callState.replace(
' ',
'').replace(
'"',
'').replace(
"'",
'')
189 if callState==it.replace(
' ',
'').replace(
'"',
'').replace(
"'",
''):
205 exceptStr=
"except:\n"
208 tryStr=
' '*spaceNum*1+tryStr
209 it=
' '*spaceNum*1+
' '*4+it+
'\n'
210 exceptStr=
' '*spaceNum*1+exceptStr
211 passStr=
' '*spaceNum*1+
' '*4+passStr
214 it=
' '*spaceNum*1+it+
'\n'
215 passStr=
' '*spaceNum*1+passStr
218 s=tryStr+it+exceptStr+passStr
229 exceptStr=
"except:\n"
232 tryStr=
' '*spaceNum*1+tryStr
233 it=
' '*spaceNum*1+
' '*4+it+
'\n'
234 exceptStr=
' '*spaceNum*1+exceptStr
235 passStr=
' '*spaceNum*1+
' '*4+passStr
238 it=
' '*spaceNum*1+it+
'\n'
239 passStr=
' '*spaceNum*1+passStr
242 s=tryStr+it+exceptStr+passStr
248 with open(filePath,
'w',encoding=
'UTF-8')
as fw:
261 for node
in ast.walk(root):
262 if isinstance(node,ast.Assign)
and isinstance(node.value,ast.Call):
263 target=ast.unparse(node.targets)
264 assignLst.append(target)
277 aliasName=receiverName.split(
'.')[0]
278 receiverSuffix=receiverName[len(aliasName):]
283 scopeBodies=[root.body]
284 for node
in ast.walk(root):
285 if isinstance(node,(ast.FunctionDef,ast.AsyncFunctionDef,ast.ClassDef)):
287 end=getattr(node,
'end_lineno',start)
288 if start<lineno<=end:
289 scopeBodies.append(node.body)
291 for body
in scopeBodies:
293 if not hasattr(stmt,
'lineno')
or stmt.lineno>=lineno:
295 if isinstance(stmt,(ast.If,ast.For,ast.AsyncFor,ast.While,ast.Try,ast.With,ast.AsyncWith)):
299 if isinstance(stmt,ast.Assign):
302 elif isinstance(stmt,ast.AnnAssign):
304 targets=[stmt.target]
307 for target
in targets:
308 if isinstance(target,ast.Name)
and target.id==aliasName
and stmt.lineno>bestLine:
309 sourceExpr=ast.get_source_segment(source,value)
311 expr=sourceExpr.strip()
319 for body
in scopeBodies:
321 if not hasattr(stmt,
'lineno')
or stmt.lineno>=lineno:
324 if isinstance(stmt,ast.Assign):
326 elif isinstance(stmt,(ast.AnnAssign,ast.AugAssign)):
327 targets=[stmt.target]
328 for target
in targets:
329 for node
in ast.walk(target):
330 if isinstance(node,ast.Name):
331 localNames.add(node.id)
333 for node
in ast.walk(root):
334 if isinstance(node,(ast.FunctionDef,ast.AsyncFunctionDef)):
336 end=getattr(node,
'end_lineno',start)
337 if start<lineno<=end:
338 for arg
in node.args.posonlyargs+node.args.args+node.args.kwonlyargs:
339 localNames.add(arg.arg)
341 localNames.add(node.args.vararg.arg)
343 localNames.add(node.args.kwarg.arg)
345 loadedNames={node.id
for node
in ast.walk(exprNode)
if isinstance(node,ast.Name)
and isinstance(node.ctx,ast.Load)}
346 if loadedNames & localNames:
350 return f
'({expr}){receiverSuffix}'
362 for node
in ast.walk(root):
363 if not isinstance(node,ast.ClassDef):
366 end=getattr(node,
'end_lineno',start)
367 if not (start<lineno<=end)
or len(node.bases)==0:
370 for item
in ast.iter_child_nodes(node):
371 if isinstance(item,(ast.FunctionDef,ast.AsyncFunctionDef)):
372 defNames.add(item.name)
373 if methodName
in defNames:
375 return ast.unparse(node.bases[0])
407 for i
in range(len(codeLst)):
408 if 'import' in codeLst[i]
and '__future__' in codeLst[i]:
413 if index==-1
and '"""' in codeLst[0]:
414 for i
in range(0,len(codeLst)):
415 if '"""' in codeLst[i]:
434 for n
in ast.walk(root):
435 if isinstance(n, (ast.FunctionDef, ast.ClassDef))
and n.decorator_list:
436 for decorator
in n.decorator_list:
437 if isinstance(decorator, ast.Call):
438 decoratorLst.append(ast.unparse(decorator.func))
455 if not codeLst[index].lstrip().startswith(
'@'):
461 if codeLst[j].lstrip().startswith(
'@')
and countSpace(codeLst[j])==spaceNum:
478 with open(filePath,
'r',encoding=
'UTF-8')
as fr:
479 codeLst=fr.readlines()
480 source=
''.join(codeLst)
483 importDict=
'from recordValue import paraValueDict\nfrom recordValue import callsiteInfoDict\n'
484 codeLst.insert(lineno,importDict)
492 withitem_visitor = WithVisitor()
493 withitem_visitor.visit(root)
494 withitem_call_names = withitem_visitor.get_withitem_call()
496 for i
in range(len(codeLst)):
497 if callAPI.replace(
' ',
'')
in codeLst[i].replace(
' ',
'')
and 'def ' not in codeLst[i]
and 'paraValueDict' not in codeLst[i]
and 'callsiteInfoDict' not in codeLst[i]:
506 firstPart=firstPart.rstrip(
'.')
509 'call_text': callAPI,
510 'format_api': callAPI,
512 displayCall=callAPI.replace(
'\n',
' ')
513 dicStringComment=f
'# PCART callsite: {displayCall}\n'
514 dicStringKey=f
'__pcart_runtime_callsite_key__={repr(callKey)}\n'
515 dicString0=f
'callsiteInfoDict[__pcart_runtime_callsite_key__]={repr(callsiteInfo)}\n'
516 if firstPart
and (firstPart.split(
'.')[0]
in targetLst
or firstPart.split(
'.')[0]==
'self')
and len(l)==1:
519 if firstPart.split(
'.')[0]
in targetLst:
521 elif firstPart.split(
'.')[0]==
'self':
522 methodName=callAPI.split(
'(')[0].split(
'.')[-1]
525 receiverExpr=receiverExpr.replace(
'\\',
'\\\\').replace(
'"',
'\\"')
526 dicString1=f
'paraValueDict[\"@\"+__pcart_runtime_callsite_key__]={{}}; paraValueDict[\"@\"+__pcart_runtime_callsite_key__][\"object\"]={firstPart}; paraValueDict[\"@\"+__pcart_runtime_callsite_key__][\"expr\"]=\"{receiverExpr}\"\n'
528 dicString1=f
'paraValueDict[\"@\"+__pcart_runtime_callsite_key__]={firstPart}\n'
530 dicString1=f
'paraValueDict[\"@\"+__pcart_runtime_callsite_key__]={l[-2]}\n'
533 if firstPart
and firstPart.split(
'.')[0]
in withitem_call_names:
535 initialCallName =
modifyWithName(firstPart, withitem_call_names, lineNo).rstrip(
'.')
537 initialCallName=initialCallName.replace(
'\\',
'\\\\').replace(
'"',
'\\"')
538 dicString1=f
'paraValueDict[\"@\"+__pcart_runtime_callsite_key__]={{}}; paraValueDict[\"@\"+__pcart_runtime_callsite_key__][\"object\"]={firstPart}; paraValueDict[\"@\"+__pcart_runtime_callsite_key__][\"expr\"]=\"{initialCallName}\"\n'
541 dicString2=
'paraValueDict[__pcart_runtime_callsite_key__]=['
542 for para
in parameterLst:
543 if '=' in para
and "'='" not in para
and '"="' not in para:
545 if '(' not in para[0:pos]
and "'" not in para[0:pos]
and '"' not in para[0:pos]
and para[pos+1]!=
'=':
548 para=para.lstrip(
'*')
549 dicString2=dicString2+para+
','
550 dicString2=dicString2.rstrip(
',')+
']\n'
553 dicStringComment=
' '+dicStringComment
554 dicStringKey=
' '+dicStringKey
555 dicString0=
' '+dicString0
557 dicString1=
' '+dicString1
558 dicString2=
' '+dicString2
562 if 'elif' not in codeLst[i]:
564 codeLst.insert(insertIndex,dicString2)
566 codeLst.insert(insertIndex,dicString1)
567 codeLst.insert(insertIndex,dicString0)
568 codeLst.insert(insertIndex,dicStringKey)
569 codeLst.insert(insertIndex,dicStringComment)
572 dicString1=dicString1.lstrip(
' ')
573 dicStringComment=dicStringComment.lstrip(
' ')
574 dicStringKey=dicStringKey.lstrip(
' ')
575 dicString0=dicString0.lstrip(
' ')
576 dicString2=dicString2.lstrip(
' ')
577 for j
in range(i+1,len(codeLst)):
578 if codeLst[j]!=
'\n' and '#' not in codeLst[j]:
581 dicStringComment=
' '+dicStringComment
582 dicStringKey=
' '+dicStringKey
583 dicString0=
' '+dicString0
585 dicString1=
' '+dicString1
586 dicString2=
' '+dicString2
589 codeLst.insert(j,dicString2)
591 codeLst.insert(j,dicString1)
592 codeLst.insert(j,dicString0)
593 codeLst.insert(j,dicStringKey)
594 codeLst.insert(j,dicStringComment)
600 if codeLst[0]==
'pass\n':
602 with open(filePath,
'w',encoding=
'UTF-8')
as fw:
620 def addDictAll(projPath,projName,filePath,copyRoot,runFileLst,libName,runPath,runCommand,pcresolveLookup=None):
621 with open(filePath,
'r',encoding=
'UTF-8')
as fr:
624 codeLst=fr.readlines()
626 root=ast.parse(code,filename=
'<unknown>',mode=
'exec')
627 except Exception
as e:
628 print(f
"addDictAll --> ast.parse failed, {filePath}: {e}")
632 fileName = os.path.basename(filePath)[0:-3]
633 fileRelativePath=os.path.relpath(filePath,os.path.join(copyRoot,projName))
634 fileAbsolutePath=os.path.join(projPath,fileRelativePath)
637 importDict=
'from recordValue import paraValueDict\nfrom recordValue import apiCoveredSet\nfrom recordValue import callsiteInfoDict\n'
638 codeLst.insert(lineno,importDict)
639 if pcresolveLookup
is None:
642 _,callDict=
getCallFunction(fileAbsolutePath,libName,projPath,pcresolveLookup=pcresolveLookup)
648 withitem_root =
getAst(fileAbsolutePath)
651 withitem_visitor = WithVisitor()
652 withitem_visitor.visit(withitem_root)
653 withitem_call_names = withitem_visitor.get_withitem_call()
658 for artifactId,record
in callDict.items():
660 lineno=int(record[
'lineno'])
661 callState=record[
'call_text']
662 paraStr=record[
'parameters']
663 callAPI=callState.replace(
' ',
'')
664 if callAPI==preInsertAPI:
666 if preInsertAPICount<=0:
670 while i<len(codeLst):
672 if callAPI
in codeLst[i].replace(
' ',
'')
and 'def ' not in codeLst[i]
and 'paraValueDict' not in codeLst[i]
and 'apiCoveredSet' not in codeLst[i]
and 'callsiteInfoDict' not in codeLst[i]:
673 if callAPI!=preInsertAPI:
674 preInsertAPICount=codeLst[i].replace(
' ',
'').count(callAPI)
678 callSiteKey=artifactId
680 'artifact_hash': record.get(
'artifact_hash',
''),
681 'rel_path': record.get(
'rel_path',
''),
682 'lineno': record.get(
'lineno'),
683 'col_offset': record.get(
'col_offset'),
684 'end_lineno': record.get(
'end_lineno'),
685 'end_col_offset': record.get(
'end_col_offset'),
686 'call_text': record.get(
'call_text',
''),
687 'format_api': record.get(
'format_api',
''),
689 displayPath=record.get(
'rel_path',
'')
690 displayLine=record.get(
'lineno')
691 displayColumn=record.get(
'col_offset')
692 displayCall=str(record.get(
'call_text',
'')).replace(
'\n',
' ')
693 displayPrefix=f
'{displayPath}:{displayLine}:{displayColumn} ' if displayPath
else ''
694 dicStringComment=f
'# PCART callsite: {displayPrefix}{displayCall}\n'
695 dicStringKey=f
'__pcart_runtime_callsite_key__={repr(callSiteKey)}\n'
696 dicString0=f
'callsiteInfoDict[__pcart_runtime_callsite_key__]={repr(callsiteInfo)}\n'
703 firstPart=firstPart.rstrip(
'.')
711 if firstPart
and (firstPart.split(
'.')[0]
in targetLst
or firstPart.split(
'.')[0]==
'self')
and len(l)==1:
713 if firstPart.split(
'.')[0]
in targetLst:
715 elif firstPart.split(
'.')[0]==
'self':
716 methodName=callState.split(
'(')[0].split(
'.')[-1]
719 receiverExpr=receiverExpr.replace(
'\\',
'\\\\').replace(
'"',
'\\"')
720 dicString1=f
'paraValueDict[\"@\"+__pcart_runtime_callsite_key__]={{}}; paraValueDict[\"@\"+__pcart_runtime_callsite_key__][\"object\"]={firstPart}; paraValueDict[\"@\"+__pcart_runtime_callsite_key__][\"expr\"]=\"{receiverExpr}\"\n'
722 dicString1=f
'paraValueDict[\"@\"+__pcart_runtime_callsite_key__]={firstPart}\n'
724 dicString1=f
'paraValueDict[\"@\"+__pcart_runtime_callsite_key__]={l[-2]}\n'
727 if firstPart
and firstPart.split(
'.')[0]
in withitem_call_names:
728 initialCallName =
modifyWithName(firstPart, withitem_call_names, lineno).rstrip(
'.')
729 initialCallName = initialCallName.rstrip(
'.')
731 initialCallName=initialCallName.replace(
'\\',
'\\\\').replace(
'"',
'\\"')
732 dicString1=f
'paraValueDict[\"@\"+__pcart_runtime_callsite_key__]={{}}; paraValueDict[\"@\"+__pcart_runtime_callsite_key__][\"object\"]={firstPart}; paraValueDict[\"@\"+__pcart_runtime_callsite_key__][\"expr\"]=\"{initialCallName}\"\n'
734 dicString2=
'paraValueDict[__pcart_runtime_callsite_key__]=['
737 if '=' in para
and "'='" not in para
and '"="' not in para:
739 if '(' not in para[0:pos]
and "'" not in para[0:pos]
and '"' not in para[0:pos]
and para[pos+1]!=
'=':
742 para=para.lstrip(
'*')
743 dicString2=dicString2+para+
','
744 dicString2=dicString2.rstrip(
',')+
']\n'
746 dicString3=
'apiCoveredSet.add(__pcart_runtime_callsite_key__)\n'
748 dicStringComment=
' '+dicStringComment
749 dicStringKey=
' '+dicStringKey
750 dicString0=
' '+dicString0
752 dicString1=
' '+dicString1
753 dicString2=
' '+dicString2
754 dicString3=
' '+dicString3
759 if 'elif' not in codeLst[i]:
761 codeLst.insert(insertIndex,dicString3)
762 codeLst.insert(insertIndex,dicString2)
764 codeLst.insert(insertIndex,dicString1)
765 codeLst.insert(insertIndex,dicString0)
766 codeLst.insert(insertIndex,dicStringKey)
767 codeLst.insert(insertIndex,dicStringComment)
770 insertStartLine=insertIndex+6
772 insertStartLine=insertIndex+5
775 dicString1=dicString1.lstrip(
' ')
776 dicStringComment=dicStringComment.lstrip(
' ')
777 dicStringKey=dicStringKey.lstrip(
' ')
778 dicString0=dicString0.lstrip(
' ')
779 dicString2=dicString2.lstrip(
' ')
780 dicString3=dicString3.lstrip(
' ')
781 for j
in range(i+1,len(codeLst)):
782 if codeLst[j]!=
'\n' and '#' not in codeLst[j]:
785 dicStringComment=
' '+dicStringComment
786 dicStringKey=
' '+dicStringKey
787 dicString0=
' '+dicString0
789 dicString1=
' '+dicString1
790 dicString2=
' '+dicString2
791 dicString3=
' '+dicString3
793 codeLst.insert(j,dicString3)
794 codeLst.insert(j,dicString2)
796 codeLst.insert(j,dicString1)
797 codeLst.insert(j,dicString0)
798 codeLst.insert(j,dicStringKey)
799 codeLst.insert(j,dicStringComment)
814 print(f
"{fileName}#{lineno}-->{callState}\n")
816 if codeLst[0]==
'pass\n':
818 with open(filePath,
'w',encoding=
'UTF-8')
as fw:
837 with open(file,
'r',encoding=
'UTF-8')
as fr:
838 codeLst=fr.readlines()
840 codeLst.insert(lineno,f
"from recordValue import paraValueDict\n")
842 if codeLst[0]==
'pass\n':
844 with open(file,
'w',encoding=
'UTF-8')
as fw:
853 with open(sourcePath,
'r',encoding=
'UTF-8')
as fr:
856 root=ast.parse(code,filename=
'<unknown>',mode=
'exec')
860 fw=open(
'Copy/defFile.py',
'a',encoding=
'UTF-8')
861 for node
in ast.iter_child_nodes(root):
862 if isinstance(node,ast.ClassDef)
or isinstance(node,ast.FunctionDef):
875 with open(filePath,
'r', encoding=
'UTF-8')
as fr:
876 codeLst=fr.readlines()
878 s=
'\n'.join(importStatement)+
'\n'
881 with open(filePath,
'w', encoding=
'UTF-8')
as fw:
910 for n
in ast.walk(astNode):
911 if isinstance(n,ast.Assign):
913 valueAstContent = ast.dump(n.value)
914 targetAstContent = ast.dump(n.targets[0])
915 if isinstance(n.targets[0], ast.Name):
916 varName = n.targets[0].id
918 if any(varName
in decorator.split(
'.')
for decorator
in decoratorLst):
921 if isinstance(value, ast.Constant):
922 if varName
in nonConstantVar:
929 if isinstance(target, ast.Name):
930 constantVar.append(target.id)
933 pattern =
r"id='([^']*)'"
934 valueMatches = re.findall(pattern, valueAstContent)
935 targetMatches = re.findall(pattern, targetAstContent)
936 if not len(valueMatches):
937 if targetMatches[0]
in nonConstantVar:
941 for match
in valueMatches:
942 if match
not in constantVar:
943 nonConstantVar.append(targetMatches[0])
952 astBody.append(astNode)
964 pathObj.getPath(projPath)
965 filePath=[it
for it
in pathObj.path
if it.endswith(
'py')]
966 for file
in filePath:
968 callLst=[record[
'call_text']
for record
in callDict.values()]
970 with open(file,
'r', encoding=
'UTF-8')
as fr:
973 root=ast.parse(code,filename=
'<unknown>',mode=
'exec')
974 except Exception
as e:
975 print(f
"saveStructure --> ast parse failed in {file}: {e}")
982 for node
in root.body:
984 if isinstance(node,ast.Import)
or isinstance(node,ast.ImportFrom)
or isinstance(node,ast.ClassDef)
or isinstance(node,ast.FunctionDef)
or isinstance(node,ast.AsyncFunctionDef):
998 if isinstance(node,ast.Assign):
1006 for node
in ast.walk(root):
1007 if isinstance(node,ast.Assign):
1013 if ast.dump(item)
not in [ast.dump(i)
for i
in newBody]:
1014 newBody.append(item)
1017 newFile=ast.unparse(root)
1018 with open(file,
'w',encoding=
'utf-8')
as fw:
1019 fw.write(f
"{newFile}\n")
1030 return [f
for f
in files
if os.path.islink(os.path.join(directory, f))]
1043 pathObj.getPath(projPath)
1044 filePath=[file
for file
in pathObj.path
if file.endswith(
'.py')]
1045 pattern=rf
"(from {libName}|import {libName})"
1046 for file
in filePath:
1048 with open(file,
'r', encoding=
'UTF-8')
as fr:
1051 root=ast.parse(code,filename=
'<unknown>',mode=
'exec')
1052 for node
in ast.walk(root):
1053 if isinstance(node,ast.Import)
or isinstance(node,ast.ImportFrom):
1055 if bool(re.search(pattern,s)):
1057 except Exception
as e:
1058 print(f
"getLibImportLst: ast parse failed, {file}, {e}")
1061 ansLst=list(set(lst))
1062 ansLst.sort(key=lst.index)
1072 for root, dirs, files
in os.walk(directory):
1074 if file.endswith(
'.py'):
1075 file_path = os.path.join(root, file)
1077 with open(file_path,
'r', encoding=
'utf-8')
as f:
1080 content = content.expandtabs(4)
1081 with open(file_path,
'w', encoding=
'utf-8')
as f:
1083 except Exception
as e:
1084 print(f
"Error converting file {file_path}: {e}")
1095 scriptPath=os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
'Script',
'recordValue.py')
1096 with open(scriptPath,
'r',encoding=
'UTF-8')
as fr:
1098 content=content.replace(
"'__PCART_PKL_REL_PATH__'",repr(pklRelPath))
1099 content=content.replace(
'__PCART_USE_CALLSITE_NAME__',str(bool(useCallsiteName)))
1100 with open(filePath,
'w',encoding=
'UTF-8')
as fw:
1110 return os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
'Script',scriptName)
1121 os.makedirs(tempDir,exist_ok=
True)
1122 tempProjPath=os.path.join(tempDir,projName)
1123 if os.path.exists(tempProjPath):
1124 shutil.rmtree(tempProjPath)
1125 shutil.move(os.path.join(copyRoot, projName), tempProjPath)
1126 shutil.move(os.path.join(copyRoot, f
'bak_{projName}'), os.path.join(copyRoot, projName))
1127 shutil.move(tempProjPath, os.path.join(copyRoot, f
'bak_{projName}'))
1150 def codeProcess(projPath,runCommand,runPath,libName,workspace,pcresolveLookup=None):
1152 copyRoot=runtimePaths[
'copy_root']
1153 dynamicRoot=runtimePaths[
'dynamic_root']
1154 dataDir=runtimePaths[
'data_dir']
1160 if runFile
and (
'/' in runFile
or '\\' in runFile):
1162 prefix = os.path.dirname(runFile)
1164 runFile = os.path.basename(runFile)
1166 runFileLst.append(runFile)
1169 if runPath!=
'' and prefix!=runPath:
1172 projName = os.path.basename(projPath)
1173 copyProjPath=os.path.join(copyRoot,projName)
1175 for it
in runFileLst:
1178 importStatement+=f
"from {it} import *\n"
1183 libImportLst.append(importStatement)
1186 if os.path.isdir(copyRoot):
1187 shutil.rmtree(copyRoot)
1188 os.makedirs(os.path.dirname(copyRoot)
or '.',exist_ok=
True)
1189 shutil.copytree(projPath,os.path.join(copyRoot,projName),ignore=ignore_sym_links)
1190 os.mkdir(os.path.join(copyRoot,
'pkl'))
1191 if os.path.isdir(dynamicRoot):
1192 shutil.rmtree(dynamicRoot)
1193 os.makedirs(os.path.dirname(dynamicRoot)
or '.',exist_ok=
True)
1194 shutil.copytree(projPath,os.path.join(dynamicRoot,projName),ignore=ignore_sym_links)
1199 dynamicScriptDir=os.path.join(dynamicRoot,projName,prefix)
1200 shutil.copy2(
scriptPath(
'addValueForAPI.py'),dynamicScriptDir)
1201 shutil.copy2(
scriptPath(
'codeUtils.py'),dynamicScriptDir)
1202 shutil.copy2(
scriptPath(
'dynamicMatch.py'),dynamicScriptDir)
1203 shutil.copy2(
scriptPath(
'verifySingle.py'),dynamicScriptDir)
1206 modifyFromImport(os.path.join(dynamicScriptDir,
'addValueForAPI.py'),libImportLst)
1207 modifyFromImport(os.path.join(dynamicScriptDir,
'dynamicMatch.py'),libImportLst)
1208 modifyFromImport(os.path.join(dynamicScriptDir,
'verifySingle.py'),libImportLst)
1211 if os.path.isdir(dataDir):
1212 shutil.rmtree(dataDir)
1213 os.makedirs(dataDir)
1221 pathObj.getPath(copyProjPath)
1222 filePath=[file
for file
in pathObj.path
if file.endswith(
'.py')]
1223 for file
in filePath:
1227 for file
in filePath:
1231 for file
in filePath:
1235 shutil.copytree(os.path.join(copyRoot,projName),os.path.join(copyRoot,f
'bak_{projName}'))
1240 pklDepth+=len([s
for s
in prefix.replace(
'\\',
'/').strip(
'/').split(
'/')
if s])
1241 pklRelPath=
'/'.join([
'..']*pklDepth+[
'pkl'])
1242 writeRecordValue(os.path.join(copyRoot,f
'bak_{projName}',prefix,
'recordValue.py'),pklRelPath,0)
1245 for file
in filePath:
1246 if pcresolveLookup
is None:
1247 addDictAll(projPath,projName,file,copyRoot,runFileLst,libName,runPath,runCommand)
1249 addDictAll(projPath,projName,file,copyRoot,runFileLst,libName,runPath,runCommand,pcresolveLookup=pcresolveLookup)
1252 for file
in runFileLst:
1253 file=os.path.join(copyRoot,f
'bak_{projName}',prefix,file)
1256 shutil.copy2(
scriptPath(
'codeUtils.py'),os.path.join(copyRoot,f
'bak_{projName}',prefix))
1259 writeRecordValue(os.path.join(copyRoot,projName,prefix,
'recordValue.py'),pklRelPath,1)
1261 shutil.copy2(
scriptPath(
'codeUtils.py'),os.path.join(copyRoot,projName,runPath))
1263 shutil.copy2(
scriptPath(
'codeUtils.py'),os.path.join(copyRoot,projName,prefix))
def getCallFunction(filePath, libName, projPath=None, pcresolveLookup=None)
Extract all API calls from a given .py file 每次传进来一个.py文件,抽取所有的调用API.
def modifyWithName(callName, withitemCallName, lineno=None)
Restore the conventional API call path in the withitem (including AsyncWith) call form 还原withitemAPI调...
def convertLocalVar(filePath, libName)
Convert the ListComp and DictComp statements to variable assignment statements 将列表推导式listComp和字典推导式Di...
def codeProcess(projPath, runCommand, runPath, libName, workspace, pcresolveLookup=None)
Code processing 代码预处理
def convertTabsToSpaces(directory)
Convert tabs to spaces in all Python files within a directory 将目录下所有Python文件中的制表符转换为空格
def getDictVar(root, ansLst)
Get the local variable in the dictionary comprehension 获取字典推导式中的局部变量
def oneLine(filePath)
Convert the multi-line parameter calls in the code into a single line to facilitate insertion into di...
def expandConditionalReturn(filePath)
Expand the single-line conditional return statement into a multi-line if-else structure 展开单行条件retur...
def obtainDef(sourcePath)
Extract class and function definitions from a source file 从源文件中提取类和函数定义
def addDictSingle(callAPI, filePath, callKey)
Code instrumentation for a single API call within a source file 源文件单个API调用代码插桩
def getImportLine(codeLst)
Determine the instrumentation line for import statements 确定import语句插桩行
def writeRecordValue(filePath, pklRelPath, useCallsiteName)
Write recordValue.py used by instrumented project files 写入插桩文件共享的recordValue.py.
def getLibImportLst(projPath, libName)
Get all lib-related import statements 获取所有第三方库相关的import语句
def restoreProjectCopy(projName, copyRoot, tempDir)
Restore the project copy prepared for single-API instrumentation 恢复用于单个API插桩的项目副本
def getListVar(root, ansLst)
Get the local variable in the list comprehension 获取列表推导式中的局部变量
def countBracket(s)
Count the number of different types of brackets ((), [], {}) in a string 计算字符串中各类括号((),...
def getSelfReceiverExpr(root, lineno, methodName)
Resolve the visible base-class expression for an inherited self receiver 还原继承场景中self调用者可见的基类表达式
def scriptPath(scriptName)
Get source script path from PCART repository 获取PCART仓库中的辅助脚本路径
def countSpace(s)
Count the number of spaces at the beginning of a string 计算字符串的前面有多少个空格
def saveConstantAssign(astNode, constantVar, nonConstantVar, decoratorLst)
Save assignment statement with constant values 保存常量赋值语句
def addDictAll(projPath, projName, filePath, copyRoot, runFileLst, libName, runPath, runCommand, pcresolveLookup=None)
Code instrumentation for all API calls within a project source file 项目源文件所有API调用代码插桩
def modifyFromImport(filePath, importStatement)
Save import statement to source file 将import语句保存到源码中
def getAssignReceiverExpr(root, source, receiverName, lineno)
Resolve the source expression assigned to a receiver alias 还原调用者别名在当前作用域内的赋值来源表达式
def ignore_sym_links(directory, files)
Determine the soft link files in a directory 确定文件夹中的软链接文件
def handleRunFile(file, runPath, runCommand)
Code instrumentation for project run file 项目运行文件代码插桩
def findAssignCall(root)
Find assignment call statements 获取赋值调用语句
def extractDecorator(root)
Extract decorator API calls 抽取项目中第三方库装饰器调用
def saveStructure(projPath, libName)
Save structure information of the project 保存项目的结构信息
def getDecoratorInsertIndex(codeLst, index)
Get decorator block start index 获取装饰器块起始行号
def getRuntimePaths(workspace)
Return runtime artifact paths for the current execution 返回当前执行使用的运行产物路径