Skip to content

Commit 9b5b094

Browse files
committed
修复 import 索引问题:处理通配符导入、静态导入和命名冲突
- 将 importsByClassName 改为 Map<String, MutableList<CodeImport>> 以处理冲突 - 跳过通配符导入的索引(无法有效索引) - 修正静态导入:使用声明类名而不是成员名 - 在 containsType 中为通配符导入添加回退搜索 - 在查找时处理多个匹配的 import 解决了 PR review comments 中的 5 个问题。
1 parent 96b295f commit 9b5b094

File tree

2 files changed

+34
-16
lines changed

2 files changed

+34
-16
lines changed

chapi-ast-java/src/main/kotlin/chapi/ast/javaast/JavaBasicIdentListener.kt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ open class JavaBasicIdentListener(fileName: String) : JavaAstListener() {
1515
private var classNodes: MutableList<CodeDataStruct> = mutableListOf()
1616
private var imports: MutableList<CodeImport> = mutableListOf()
1717
// Index for fast import lookup by class name
18-
private var importsByClassName: MutableMap<String, CodeImport> = mutableMapOf()
18+
// Using MutableList to handle import collisions
19+
private var importsByClassName: MutableMap<String, MutableList<CodeImport>> = mutableMapOf()
1920

2021
private var currentNode = CodeDataStruct()
2122
private var currentFunction = CodeFunction(IsConstructor = false)
@@ -63,9 +64,11 @@ open class JavaBasicIdentListener(fileName: String) : JavaAstListener() {
6364
imports.add(codeImport)
6465
codeContainer.Imports += codeImport
6566

66-
// Build import index
67-
val className = fullSource.substringAfterLast('.')
68-
importsByClassName[className] = codeImport
67+
// Build import index for non-wildcard imports only
68+
if (!isWildcard) {
69+
val className = fullSource.substringAfterLast('.')
70+
importsByClassName.getOrPut(className) { mutableListOf() }.add(codeImport)
71+
}
6972
}
7073

7174
override fun enterPackageDeclaration(ctx: JavaParser.PackageDeclarationContext?) {
@@ -110,8 +113,12 @@ open class JavaBasicIdentListener(fileName: String) : JavaAstListener() {
110113
private fun containsType(typeName: String?): Boolean {
111114
if (typeName == null) return false
112115
// Fast lookup using index
113-
return importsByClassName.containsKey(typeName) ||
114-
imports.any { imp -> imp.Source.endsWith(".$typeName") }
116+
val importsByName = importsByClassName[typeName]
117+
if (importsByName != null && importsByName.isNotEmpty()) {
118+
return true
119+
}
120+
// Fallback to linear search for wildcard imports
121+
return imports.any { imp -> imp.Source.endsWith(".$typeName") }
115122
}
116123

117124
open fun buildImplements(ctx: JavaParser.EnumDeclarationContext): List<String> {

chapi-ast-java/src/main/kotlin/chapi/ast/javaast/JavaFullIdentListener.kt

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ open class JavaFullIdentListener(fileName: String, val classes: List<String>) :
3636

3737
private var imports: MutableList<CodeImport> = mutableListOf()
3838
// Index for fast import lookup by class name (O(1) instead of O(n))
39-
private var importsByClassName: MutableMap<String, CodeImport> = mutableMapOf()
39+
// Using MutableList to handle import collisions (same class name from different packages)
40+
private var importsByClassName: MutableMap<String, MutableList<CodeImport>> = mutableMapOf()
4041
private var importsByFullSource: MutableMap<String, CodeImport> = mutableMapOf()
4142

4243
private var lastNode = CodeDataStruct()
@@ -101,12 +102,20 @@ open class JavaFullIdentListener(fileName: String, val classes: List<String>) :
101102
codeContainer.Imports += codeImport
102103

103104
// Build import indexes for fast lookup
104-
val className = fullSource.substringAfterLast('.')
105-
importsByClassName[className] = codeImport
106105
importsByFullSource[fullSource] = codeImport
107-
// Also index by source for static imports
106+
108107
if (isStatic) {
108+
// For static imports, index by the declaring class name (from Source),
109+
// not by the static member name
110+
val sourceClassName = codeImport.Source.substringAfterLast('.')
111+
importsByClassName.getOrPut(sourceClassName) { mutableListOf() }.add(codeImport)
112+
// Also index by source for static imports (fully-qualified class name)
109113
importsByFullSource[codeImport.Source] = codeImport
114+
} else if (!isWildcard) {
115+
// For non-static, non-wildcard imports, index by the imported class name
116+
// Skip wildcard imports as they cannot be efficiently indexed
117+
val className = fullSource.substringAfterLast('.')
118+
importsByClassName.getOrPut(className) { mutableListOf() }.add(codeImport)
110119
}
111120
}
112121

@@ -535,9 +544,11 @@ open class JavaFullIdentListener(fileName: String, val classes: List<String>) :
535544
// second, parse from import using index (O(1) lookup)
536545
val pureTargetType = buildPureTargetType(targetType)
537546
if (pureTargetType.isNotEmpty()) {
538-
// Fast lookup using index
539-
val importByClassName = importsByClassName[pureTargetType]
540-
if (importByClassName != null) {
547+
// Fast lookup using index - check if there are any imports for this class name
548+
val importsByName = importsByClassName[pureTargetType]
549+
if (importsByName != null && importsByName.isNotEmpty()) {
550+
// Use the first matching import (consistent with original behavior)
551+
val importByClassName = importsByName[0]
541552
val isStatic = importByClassName.UsageName.isNotEmpty() && importByClassName.UsageName.contains(pureTargetType)
542553
return JavaTargetType(
543554
targetType = importByClassName.Source,
@@ -558,10 +569,10 @@ open class JavaFullIdentListener(fileName: String, val classes: List<String>) :
558569

559570
// others, may be from parent
560571
if (pureTargetType == "super" || pureTargetType == "this") {
561-
val importByExtend = importsByClassName[currentClzExtend]
562-
if (importByExtend != null) {
572+
val importsByExtend = importsByClassName[currentClzExtend]
573+
if (importsByExtend != null && importsByExtend.isNotEmpty()) {
563574
return JavaTargetType(
564-
targetType = importByExtend.Source,
575+
targetType = importsByExtend[0].Source,
565576
callType = CallType.SUPER
566577
)
567578
}

0 commit comments

Comments
 (0)