Skip to content

Commit 79a4d6f

Browse files
committed
修复了泛型类类型解析错误的问题
修复了泛型类不能重载的问题 修复了不能访问泛型类只读成员的问题
1 parent 2ec6a27 commit 79a4d6f

File tree

15 files changed

+130
-101
lines changed

15 files changed

+130
-101
lines changed

src/main/kotlin/top/mcfpp/Project.kt

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,16 @@ object Project {
7575
val macroFunction : LinkedHashMap<String, String> = LinkedHashMap()
7676

7777
var compileStage = 0
78-
val READ_PROJECT = 1
79-
val READ_LIB = 2
80-
val INIT = 3
81-
val INDEX_TYPE = 4
82-
val RESOVLE_FIELD = 5
83-
val COMPILE = 6
84-
val OPTIMIZATION = 7
85-
val GEN_INDEX = 8
86-
val GEN_DATAPACK = 9
78+
79+
const val READ_PROJECT = 1
80+
const val READ_LIB = 2
81+
const val INIT = 3
82+
const val INDEX_TYPE = 4
83+
const val RESOLVE_FIELD = 5
84+
const val COMPILE = 6
85+
const val OPTIMIZATION = 7
86+
const val GEN_INDEX = 8
87+
const val GEN_DATAPACK = 9
8788

8889
/**
8990
* 编译阶段处理器。每个阶段的处理器都会在对应的阶段被调用。
@@ -254,11 +255,12 @@ object Project {
254255
}
255256
GlobalField.importedLibNamespaces.clear()
256257
}
258+
//解析所有泛型类的泛型参数类型
257259
stageProcessor[compileStage].forEach { it() }
258260
}
259261

260262
/**
261-
* 编制函数索引
263+
* 编制函数索引,解析类/模板成员
262264
*/
263265
fun resolveField() {
264266
compileStage++

src/main/kotlin/top/mcfpp/antlr/MCFPPFieldVisitor.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,15 @@ open class MCFPPFieldVisitor : mcfppParserBaseVisitor<Any?>() {
158158
val id = ctx.classWithoutNamespace().text
159159
val namespace = GlobalField.localNamespaces[Project.currNamespace]!!
160160
if(ctx.readOnlyParams() != null){
161-
//如果是泛型类,暂时不编译
161+
//如果是泛型类,将类型实例化,但暂时不编译
162+
val types = ctx.readOnlyParams().parameterList().parameter().map { MCFPPType.parseFromContext(it.type(), namespace.field)?: run {
163+
LogProcessor.error(TextTranslator.INVALID_TYPE_ERROR.translate(it.text))
164+
MCFPPBaseType.Any
165+
} }
166+
val clazz = namespace.field.getClass(id, types)!!
167+
for (p in clazz.readOnlyParams) {
168+
p.type = MCFPPType.parseFromIdentifier(p.typeIdentifier, namespace.field)
169+
}
162170
return null
163171
}
164172
val clazz = if (namespace.field.hasClass(id)) {
@@ -277,7 +285,7 @@ open class MCFPPFieldVisitor : mcfppParserBaseVisitor<Any?>() {
277285
val p = m.second as Property?
278286
if(v == null || p == null) return null
279287
//访问修饰符
280-
v.accessModifier = AccessModifier.valueOf(ctx.accessModifier()?.text?:"public".uppercase(Locale.getDefault()))
288+
v.accessModifier = AccessModifier.valueOf((ctx.accessModifier()?.text?:"public").uppercase(Locale.getDefault()))
281289
p.accessModifier = v.accessModifier
282290
Class.currClass!!.addMember(v)
283291
Class.currClass!!.addMember(p)

src/main/kotlin/top/mcfpp/antlr/MCFPPTypeVisitor.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ class MCFPPTypeVisitor: mcfppParserBaseVisitor<Unit>() {
181181
Class(id, Project.currNamespace)
182182
}
183183
//如果没有声明过这个类
184-
if(nsp.field.hasDeclaredType(id)){
185-
LogProcessor.error("Type has been defined: $id in namespace ${Project.currNamespace}")
184+
if(nsp.field.hasDeclaredType(cls)){
185+
LogProcessor.error("Type has been defined: $cls in namespace ${Project.currNamespace}")
186186
return
187187
}
188188
cls.initialize()

src/main/kotlin/top/mcfpp/core/minecraft/PlayerVar.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ open class PlayerVar : Var<PlayerVar>, EntityBase {
131131
val data = CompoundData("PlayerEntity", "mcfpp")
132132

133133
init {
134-
Project.stageProcessor[Project.RESOVLE_FIELD].add {
134+
Project.stageProcessor[Project.RESOLVE_FIELD].add {
135135
data.getNativeFromClass(PlayerEntityData::class.java)
136136
}
137137
}

src/main/kotlin/top/mcfpp/io/MCFPPFile.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ import top.mcfpp.type.MCFPPBaseType
1010
import top.mcfpp.model.Class
1111
import top.mcfpp.model.field.FileField
1212
import top.mcfpp.model.field.GlobalField
13+
import top.mcfpp.model.field.NamespaceField
1314
import top.mcfpp.model.function.Function
15+
import top.mcfpp.model.generic.GenericClass
16+
import top.mcfpp.type.MCFPPType
1417
import top.mcfpp.util.LogProcessor
1518
import top.mcfpp.util.StringHelper
1619
import java.io.File
@@ -31,6 +34,11 @@ class MCFPPFile(path : String) : File(path) {
3134
//TODO 同名文件的顶级函数之间的命名冲突
3235
val topFunction = Function(StringHelper.toLegalIdentifier(this.name), context = null)
3336

37+
/**
38+
* 此文件引用了的命名空间
39+
*/
40+
val importedNamespace = ArrayList<NamespaceField>()
41+
3442
init {
3543
val n = Project.config.sourcePath.toAbsolutePath().relativize(this.toPath().toAbsolutePath().parent).toString()
3644
namespace = Project.config.rootNamespace + "." + StringHelper.toLegalIdentifier(n.replace("\\",".").replace("/","."))
@@ -56,7 +64,10 @@ class MCFPPFile(path : String) : File(path) {
5664
currFile = this
5765
Project.currNamespace = namespace
5866
MCFPPTypeVisitor().visit(tree())
59-
//类是否有空继承
67+
for (a in GlobalField.importedLibNamespaces.values){
68+
importedNamespace.add(a.field)
69+
}
70+
//类是否有空继承,以及实例化每个泛型类的类型
6071
GlobalField.localNamespaces.forEach { _, u ->
6172
u.field.forEachClass { c ->
6273
for (p in c.parent){
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
package top.mcfpp.model.field
22

3+
import top.mcfpp.type.MCFPPType
4+
35
class FileField : NamespaceField()

src/main/kotlin/top/mcfpp/model/field/NamespaceField.kt

Lines changed: 22 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ open class NamespaceField(
178178
*/
179179
override fun getClass(identifier: String, readOnlyParam: List<MCFPPType>): GenericClass? {
180180
for (`class` in classes[identifier]) {
181-
if (`class` is GenericClass && `class`.isSelf(identifier, readOnlyParam)) {
181+
if (`class` is GenericClass && `class`.isSelfByType(identifier, readOnlyParam)) {
182182
return `class`
183183
}
184184
}
@@ -195,7 +195,15 @@ open class NamespaceField(
195195
}
196196

197197
override fun hasClass(cls: Class): Boolean{
198-
return classes.containsValue(cls.identifier)
198+
return classes.containsValue(cls)
199+
}
200+
201+
fun hasNotGenericClass(cls: String): Boolean{
202+
return classes.values().any { it.identifier == cls && it !is GenericClass }
203+
}
204+
205+
fun hasNotGenericClass(cls: Class): Boolean{
206+
return classes.values().any { it == cls && it !is GenericClass }
199207
}
200208

201209

@@ -239,61 +247,7 @@ open class NamespaceField(
239247
}
240248
//endregion
241249

242-
/*
243-
//region Var
244-
/**
245-
* 向此缓存中添加一个新的变量键值对。如果已存在此对象,将不会进行覆盖。
246-
* @param key 变量的标识符
247-
* @param var 变量的对象
248-
* @return 如果缓存中已经存在此对象,则返回false,否则返回true。
249-
*/
250-
fun putVar(key: String, `var`: Var): Boolean {
251-
return if (vars.containsKey(key)) {
252-
false
253-
} else {
254-
vars[key] = `var`
255-
true
256-
}
257-
}
258-
259-
/**
260-
* 从缓存中取出一个变量。如果此缓存中没有,则从父缓存中寻找。
261-
* @param key 变量的标识符
262-
* @return 变量的对象。若不存在,则返回null。
263-
*/
264-
fun getVar(key: String): Var? {
265-
return vars.getOrDefault(key, null)
266-
}
267-
268-
val allVars: Collection<Var>
269-
/**
270-
* 获取此缓存中的全部变量。不会从父缓存搜索。
271-
* @return 一个包含了此缓存全部变量的集合。
272-
*/
273-
get() = vars.values
274-
275-
/**
276-
* 缓存中是否包含某个变量
277-
* @param id 变量名
278-
* @return 如果包含则返回true,否则返回false
279-
*/
280-
fun containVar(id: String): Boolean {
281-
return vars.containsKey(id)
282-
}
283-
284-
/**
285-
* 移除缓存中的某个变量
286-
*
287-
* @param id 变量名
288-
* @return 若变量存在,则返回被移除的变量,否则返回空
289-
*/
290-
fun removeVar(id : String): Var?{
291-
return vars.remove(id)
292-
}
293-
//endregion
294-
*/
295-
296-
//region struct
250+
//region template
297251
/**
298252
* 向域中添加一个模板
299253
*
@@ -362,6 +316,8 @@ open class NamespaceField(
362316
}
363317

364318
//endregion
319+
320+
//region interface
365321
/**
366322
* 向域中添加一个接口
367323
*
@@ -428,10 +384,18 @@ open class NamespaceField(
428384
override fun hasInterface(itf: Interface): Boolean {
429385
return interfaces.containsKey(itf.identifier)
430386
}
431-
387+
//endregion
432388

433389
fun hasDeclaredType(identifier: String): Boolean{
434390
return hasEnum(identifier) || hasTemplate(identifier) || hasInterface(identifier) || hasClass(identifier)
435391
}
436392

393+
fun hasDeclaredType(type: CompoundData): Boolean{
394+
if(type !is GenericClass){
395+
val identifier = type.identifier
396+
return hasEnum(identifier) || hasTemplate(identifier) || hasInterface(identifier) || hasNotGenericClass(identifier)
397+
}else{
398+
return hasClass(type)
399+
}
400+
}
437401
}

src/main/kotlin/top/mcfpp/model/function/Function.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import top.mcfpp.type.UnresolvedType
1515
import top.mcfpp.core.lang.MCFPPValue
1616
import top.mcfpp.model.*
1717
import top.mcfpp.model.field.FunctionField
18+
import top.mcfpp.model.generic.Generic
1819
import top.mcfpp.util.LogProcessor
1920
import top.mcfpp.util.StringHelper
2021
import top.mcfpp.util.TextTranslator
@@ -438,7 +439,7 @@ open class Function : Member, FieldContainer, Serializable {
438439
}
439440
}
440441

441-
protected fun parseParam(param: mcfppParser.ParameterContext) : Pair<FunctionParam,Var<*>>{
442+
protected open fun parseParam(param: mcfppParser.ParameterContext) : Pair<FunctionParam,Var<*>>{
442443
//参数构建
443444
val param1 = FunctionParam(
444445
MCFPPType.parseFromContext(param.type(), this.field)?: run {
@@ -448,7 +449,8 @@ open class Function : Member, FieldContainer, Serializable {
448449
param.Identifier().text,
449450
this,
450451
param.STATIC() != null,
451-
param.value() != null
452+
param.value() != null,
453+
this is Generic<*>
452454
)
453455
//检查缺省参数是否合法
454456
if(param.value() == null && hasDefaultValue){

src/main/kotlin/top/mcfpp/model/function/FunctionParam.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,24 @@ class FunctionParam(
3939
/**
4040
* 是否有缺省值
4141
*/
42-
var hasDefault: Boolean = false
42+
var hasDefault: Boolean = false,
43+
44+
/**
45+
*
46+
*/
47+
var isReadOnly: Boolean = false
4348
) {
4449

4550
var typeIdentifier: String = type.typeName
4651

4752
var defaultVar: Var<*>? = null
4853

4954
fun buildVar(): Var<*>{
50-
val qwq = type.buildUnConcrete(identifier, function)
55+
val qwq = if(isReadOnly){
56+
type.build(identifier, function)
57+
}else{
58+
type.buildUnConcrete(identifier, function)
59+
}
5160
if(qwq is DataTemplateObject){
5261
qwq.toFunctionParam()
5362
}

src/main/kotlin/top/mcfpp/model/generic/GenericClass.kt

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import top.mcfpp.type.MCFPPClassType
1010
import top.mcfpp.type.MCFPPType
1111
import top.mcfpp.model.Class
1212
import top.mcfpp.model.CompiledGenericClass
13+
import top.mcfpp.model.accessor.Property
1314
import top.mcfpp.model.field.GlobalField
1415

1516
/**
@@ -66,12 +67,13 @@ class GenericClass : Class {
6667

6768
//只读属性
6869
for (i in readOnlyParams.indices) {
69-
val r = readOnlyArgs[i].clone()
70+
val r = readOnlyArgs[i].implicitCast(readOnlyParams[i].type!!)
7071
r.isConst = true
7172
if(r is MCFPPTypeVar){
7273
cls.field.putType(readOnlyParams[i].identifier, r.value)
7374
}
7475
cls.field.putVar(readOnlyParams[i].identifier, r, false)
76+
cls.field.putProperty(readOnlyParams[i].identifier, Property.buildSimpleProperty(r))
7577
}
7678

7779
//注册
@@ -90,13 +92,34 @@ class GenericClass : Class {
9092
return cls
9193
}
9294

93-
fun isSelf(identifier: String, readOnlyParam: List<MCFPPType>): Boolean {
95+
fun isSelfByType(identifier: String, readOnlyParam: List<MCFPPType>): Boolean {
9496
if (this.identifier == identifier) {
9597
if (readOnlyParam.size != readOnlyParams.size) {
9698
return false
9799
}
98100
for (i in readOnlyParam.indices) {
99-
if (readOnlyParam[i].typeName != readOnlyParams[i].typeIdentifier) {
101+
if(readOnlyParams[i].type != null){
102+
if (!readOnlyParams[i].type!!.build("").canAssignedBy(readOnlyParam[i].build(""))) {
103+
return false
104+
}
105+
}else{
106+
if(readOnlyParam[i].typeName != readOnlyParam[i].typeName){
107+
return false
108+
}
109+
}
110+
}
111+
return true
112+
}
113+
return false
114+
}
115+
116+
fun isSelfByString(identifier: String, readOnlyParam: List<String>): Boolean{
117+
if (this.identifier == identifier) {
118+
if (readOnlyParam.size != readOnlyParams.size) {
119+
return false
120+
}
121+
for (i in readOnlyParam.indices) {
122+
if (readOnlyParam[i] != readOnlyParams[i].typeIdentifier) {
100123
return false
101124
}
102125
}
@@ -113,12 +136,17 @@ class GenericClass : Class {
113136
class ClassParam(
114137

115138
/**
116-
* 参数类型
139+
* 参数类型标识符
117140
*/
118141
var typeIdentifier: String,
119142

120143
/**
121144
* 参数的名字
122145
*/
123146
var identifier: String,
147+
148+
/**
149+
* 参数的类型。只有在[Project.INDEX_TYPE]阶段结束后才有值
150+
*/
151+
var type: MCFPPType? = null
124152
)

0 commit comments

Comments
 (0)