Update
This commit is contained in:
parent
30f3c67e32
commit
99c9440a39
8 changed files with 57 additions and 40 deletions
|
@ -4,7 +4,7 @@
|
||||||
<component name="FrameworkDetectionExcludesConfiguration">
|
<component name="FrameworkDetectionExcludesConfiguration">
|
||||||
<file type="web" url="file://$PROJECT_DIR$" />
|
<file type="web" url="file://$PROJECT_DIR$" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" project-jdk-name="openjdk-22" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_22" default="true" project-jdk-name="openjdk-22" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -14,5 +14,7 @@ short munis(int a,int b){
|
||||||
int l = a;
|
int l = a;
|
||||||
int f = b;
|
int f = b;
|
||||||
int k = l - f;
|
int k = l - f;
|
||||||
return k;
|
int h = add(l,f);
|
||||||
|
int p = k / h;
|
||||||
|
return p;
|
||||||
}
|
}
|
|
@ -167,7 +167,7 @@ fun App() {
|
||||||
getInvokeTraceTreeString("main",sf,relations)
|
getInvokeTraceTreeString("main",sf,relations)
|
||||||
|
|
||||||
ttGraph = generateGraph(relations)
|
ttGraph = generateGraph(relations)
|
||||||
ivGraph = sf.functions.getInvokeGraph("main")
|
ivGraph = sf.functions.getInvokeGraph()
|
||||||
|
|
||||||
showResult.value = true
|
showResult.value = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ fun List<CFunction>.find(name: String): CFunction? {
|
||||||
* List<CFunction>.getInvokeTree
|
* List<CFunction>.getInvokeTree
|
||||||
* @param List<CFunction>: 要求包含所有函数以查找
|
* @param List<CFunction>: 要求包含所有函数以查找
|
||||||
* @param name: 从哪个函数开始查找
|
* @param name: 从哪个函数开始查找
|
||||||
* @return 特制的 TraceTree
|
* @return 特制的 TraceTree funcName -> tracetree[], 包含的是调用者的参数
|
||||||
*/
|
*/
|
||||||
fun List<CFunction>.getInvokeTree(name: String): Map<String, List<TraceTree>> {
|
fun List<CFunction>.getInvokeTree(name: String): Map<String, List<TraceTree>> {
|
||||||
// 先找到开始的函数
|
// 先找到开始的函数
|
||||||
|
@ -154,10 +154,13 @@ fun List<CFunction>.getInvokeTree(name: String): Map<String, List<TraceTree>> {
|
||||||
if (function != null) {
|
if (function != null) {
|
||||||
val info = InvokeInfo(name, args)
|
val info = InvokeInfo(name, args)
|
||||||
val tt = function.getTraceTree(info)
|
val tt = function.getTraceTree(info)
|
||||||
invokeTrees.addAll(tt)
|
// 过滤 trace tree
|
||||||
|
invokeTrees.addAll(tt.filter { it.name.startsWith(name) })
|
||||||
}
|
}
|
||||||
if (funcName != "") {
|
if (funcName != "") {
|
||||||
resultMap[funcName] = invokeTrees
|
val newTree = invokeTrees.toList()
|
||||||
|
resultMap[funcName] = newTree // 因为之后要清空
|
||||||
|
invokeTrees.clear()
|
||||||
args.clear()
|
args.clear()
|
||||||
funcName = ""
|
funcName = ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,15 +7,15 @@ fun generateGraph(relations: Map<String, List<Relation>>, crossLabelPaths: List<
|
||||||
sb.append("digraph G {\n")
|
sb.append("digraph G {\n")
|
||||||
|
|
||||||
for ((label, edges) in relations) {
|
for ((label, edges) in relations) {
|
||||||
sb.append(" subgraph cluster_$label {\n")
|
sb.append("subgraph cluster_$label {")
|
||||||
sb.append(" label = \"$label\";\n")
|
sb.append("label = \"$label\";")
|
||||||
|
|
||||||
val uniquePaths = mutableSetOf<String>()
|
val uniquePaths = mutableSetOf<String>()
|
||||||
|
|
||||||
for (relation in edges) {
|
for (relation in edges) {
|
||||||
uniquePaths.add("${relation.from} -> ${relation.to}")
|
uniquePaths.add("${relation.from} -> ${relation.to}")
|
||||||
sb.append("${relation.from}$label[label=${relation.from}];\n${relation.to}$label[label=${relation.to}];\n")
|
sb.append("${relation.from}$label[label=${relation.from}];${relation.to}$label[label=${relation.to}];")
|
||||||
sb.append("${relation.from}$label -> ${relation.to}$label;\n")
|
sb.append("${relation.from}$label -> ${relation.to}$label;")
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append("}\n")
|
sb.append("}\n")
|
||||||
|
@ -23,6 +23,7 @@ fun generateGraph(relations: Map<String, List<Relation>>, crossLabelPaths: List<
|
||||||
|
|
||||||
if (crossLabelPaths != null) {
|
if (crossLabelPaths != null) {
|
||||||
// 处理跨函数
|
// 处理跨函数
|
||||||
|
val hashes = mutableListOf<Int>() // 去重, 重复是因为一个参数可以有多个影响其他变量的路线,但一起显示太奇怪了
|
||||||
for (path in crossLabelPaths) {
|
for (path in crossLabelPaths) {
|
||||||
val parts = path.split(":")
|
val parts = path.split(":")
|
||||||
if (parts.size == 3) {
|
if (parts.size == 3) {
|
||||||
|
@ -31,13 +32,18 @@ fun generateGraph(relations: Map<String, List<Relation>>, crossLabelPaths: List<
|
||||||
val fromNode = subPath[0] // 这里就是z
|
val fromNode = subPath[0] // 这里就是z
|
||||||
val toNode = subPath[1] // 下一个就是
|
val toNode = subPath[1] // 下一个就是
|
||||||
// from 到 to 用虚线
|
// from 到 to 用虚线
|
||||||
sb.append(" $fromNode${parts[1]} -> $toNode${parts[0]} [style=dashed];\n")
|
val str = "$fromNode${parts[1]} -> $toNode${parts[0]} [style=dashed];"
|
||||||
|
val hash = str.hashCode()
|
||||||
|
if (hash !in hashes){ // 不重复
|
||||||
|
sb.append(str)
|
||||||
|
hashes.add(hash)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append("}\n")
|
sb.append("\n}")
|
||||||
return sb.toString()
|
return sb.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,14 +69,13 @@ fun parseRelation(funcName: String, parse: String): Map<String, List<Relation>>{
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun List<CFunction>.getInvokeGraph(funcName: String): String {
|
fun List<CFunction>.getInvokeGraph(): String {
|
||||||
val relations = mutableMapOf<String, List<Relation>>()
|
val relations = mutableMapOf<String, List<Relation>>()
|
||||||
val func = this.find(funcName) ?: return ""
|
val crossLabelPaths = StringBuilder()
|
||||||
|
|
||||||
this.forEach {
|
this.forEach {
|
||||||
relations.putAll(parseRelation(it.name,it.getTraceTree().getStringRepr()))
|
relations.putAll(parseRelation(it.name,it.getTraceTree().getStringRepr()))
|
||||||
|
crossLabelPaths.append(this.getInvokeTree(it.name).getFuncRepr(it.name))
|
||||||
|
crossLabelPaths.append('\n')
|
||||||
}
|
}
|
||||||
|
return generateGraph(relations,crossLabelPaths.split('\n').filter { it.isNotEmpty() })
|
||||||
val crossLabelPaths = this.getInvokeTree(func.name).getFuncRepr(func.name)
|
|
||||||
return generateGraph(relations,crossLabelPaths.split('\n')) + "\n"
|
|
||||||
}
|
}
|
|
@ -6,8 +6,6 @@ import java.io.File
|
||||||
import core.CLanguage.Companion.OPERATION.*
|
import core.CLanguage.Companion.OPERATION.*
|
||||||
import core.CLanguage.Companion.declarationRegex
|
import core.CLanguage.Companion.declarationRegex
|
||||||
import core.CLanguage.Companion.types
|
import core.CLanguage.Companion.types
|
||||||
import utils.getDefineList
|
|
||||||
import utils.getUseList
|
|
||||||
|
|
||||||
class SourceFile {
|
class SourceFile {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -156,18 +154,12 @@ fun main() {
|
||||||
val funcs = sourceFile.parseFunction()
|
val funcs = sourceFile.parseFunction()
|
||||||
val relations = mutableMapOf<String, List<Relation>>()
|
val relations = mutableMapOf<String, List<Relation>>()
|
||||||
funcs.forEach {
|
funcs.forEach {
|
||||||
println("${it.name}(${it.params}) -> ${it.returnType} {\n${it.content}\n} ")
|
|
||||||
it.cParser.sentenceList.forEach{ s->
|
|
||||||
println("${s.left},${s.right},${s.type}")
|
|
||||||
}
|
|
||||||
println(it.getTraceTree().getStringRepr())
|
|
||||||
relations.putAll(parseRelation(it.name,it.getTraceTree().getStringRepr()))
|
relations.putAll(parseRelation(it.name,it.getTraceTree().getStringRepr()))
|
||||||
}
|
}
|
||||||
println(funcs.getInvokeTree("main").getFuncRepr("main"))
|
for (function in funcs) {
|
||||||
|
println(funcs.getInvokeTree(function.name).getFuncRepr(function.name))
|
||||||
|
}
|
||||||
|
|
||||||
println(generateGraph(relations))
|
println(generateGraph(relations))
|
||||||
println(funcs.getInvokeGraph("main"))
|
println(funcs.getInvokeGraph())
|
||||||
|
|
||||||
println(getDefineList(sourceFile.getDef()))
|
|
||||||
println(getUseList(sourceFile.getUse()))
|
|
||||||
}
|
}
|
|
@ -49,15 +49,13 @@ fun List<TraceTree>.getStringRepr(): String {
|
||||||
|
|
||||||
fun Map<String, List<TraceTree>>.getFuncRepr(func: String): String {
|
fun Map<String, List<TraceTree>>.getFuncRepr(func: String): String {
|
||||||
val result = StringBuilder()
|
val result = StringBuilder()
|
||||||
var fName = ""
|
|
||||||
this.forEach { (name, list) ->
|
this.forEach { (name, list) ->
|
||||||
fName = name
|
|
||||||
val listRepr = list.getStringRepr()
|
val listRepr = list.getStringRepr()
|
||||||
result.append(listRepr.split('\n').filter { it.startsWith(func) }.joinToString("\n"))
|
for (line in listRepr.lines()) {
|
||||||
|
if (line.startsWith(func)){ // main:x-> 这样的
|
||||||
|
result.append("$name:$line\n")
|
||||||
}
|
}
|
||||||
val fixedResult = StringBuilder()
|
|
||||||
result.lines().forEach { line ->
|
|
||||||
fixedResult.append("$fName:$line\n")
|
|
||||||
}
|
}
|
||||||
return fixedResult.toString()
|
}
|
||||||
|
return result.toString().trim()
|
||||||
}
|
}
|
|
@ -1,6 +1,10 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import java.awt.Desktop
|
import java.awt.Desktop
|
||||||
|
import java.awt.Toolkit
|
||||||
|
import java.awt.datatransfer.StringSelection
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -10,7 +14,20 @@ fun openBrowser(uri: URI) {
|
||||||
when {
|
when {
|
||||||
Desktop.isDesktopSupported() && desktop.isSupported(Desktop.Action.BROWSE) -> desktop.browse(uri)
|
Desktop.isDesktopSupported() && desktop.isSupported(Desktop.Action.BROWSE) -> desktop.browse(uri)
|
||||||
"mac" in osName -> Runtime.getRuntime().exec("open $uri")
|
"mac" in osName -> Runtime.getRuntime().exec("open $uri")
|
||||||
"nix" in osName || "nux" in osName -> Runtime.getRuntime().exec("xdg-open $uri")
|
"nix" in osName || "nux" in osName -> {
|
||||||
|
try {
|
||||||
|
Runtime.getRuntime().exec("xdg-open $uri")
|
||||||
|
}catch (_: IOException){
|
||||||
|
// xdg-open 不存在
|
||||||
|
if (File("/run/current-system/sw/bin/xdg-open").exists()){ // nixos
|
||||||
|
Runtime.getRuntime().exec("/run/current-system/sw/bin/xdg-open $uri")
|
||||||
|
}else{
|
||||||
|
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
|
||||||
|
val content = StringSelection(uri.toString())
|
||||||
|
clipboard.setContents(content, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> desktop.browse(uri)
|
else -> desktop.browse(uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue