From 2e7f043c1db4e02d7879f78583dae91725d64032 Mon Sep 17 00:00:00 2001 From: love2hina Date: Sun, 6 Mar 2022 19:31:33 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=B3=E3=83=B3=E3=82=B9=E3=83=88=E3=83=A9?= =?UTF-8?q?=E3=82=AF=E3=82=BF=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refs #19 --- .../kotlin/sharon/data/ConstructorInfo.kt | 75 ++++++++++++++++ .../kotlin/sharon/parser/FunctionVisitor.kt | 88 +++++++++++++++++++ .../love2hina/kotlin/sharon/parser/Parser.kt | 35 +------- .../kotlin/sharon/ParseTestClassTarget.java | 13 +++ 4 files changed, 179 insertions(+), 32 deletions(-) create mode 100644 src/main/kotlin/net/love2hina/kotlin/sharon/data/ConstructorInfo.kt diff --git a/src/main/kotlin/net/love2hina/kotlin/sharon/data/ConstructorInfo.kt b/src/main/kotlin/net/love2hina/kotlin/sharon/data/ConstructorInfo.kt new file mode 100644 index 0000000..b0381b5 --- /dev/null +++ b/src/main/kotlin/net/love2hina/kotlin/sharon/data/ConstructorInfo.kt @@ -0,0 +1,75 @@ +package net.love2hina.kotlin.sharon.data + +import kotlin.collections.LinkedHashMap + +internal data class ConstructorInfo( + + /** 説明 */ + override val description: StringBuilder = StringBuilder(), + + /** パラメーター型 */ + val typeParameters: HashMap = LinkedHashMap(), + + /** パラメーター */ + val parameters: HashMap = LinkedHashMap(), + + /** 例外 */ + val throws: HashMap = LinkedHashMap(), + + /* + * see + * @since + * @deprecated + * @serialData + */ + +): JavadocInfo { + + override fun parseTag(name: String?, value: String): Boolean + = when (name) { + "param" -> { + val r = Regex("^(?:(?\\w+)|<(?\\w+)>)(?:\\s+(?.*))?$") + val m = r.find(value) + + if (m != null) { + val groups = (m.groups as MatchNamedGroupCollection) + + val paramName = groups["name"]?.value + val paramType = groups["type"]?.value + val paramDesc = groups["desc"]?.value ?: "" + + if (paramName != null) { + val paramInfo = parameters.getOrPut(paramName) { ParameterInfo("", "", paramName) } + + paramInfo.description = paramDesc + } + else if (paramType != null) { + val typeParameterInfo = typeParameters.getOrPut(paramType) { TypeParameterInfo(paramType) } + + typeParameterInfo.description = paramDesc + } + } + + true + } + "throws", "exception" -> { + val r = Regex("^(?\\w+)(?:\\s+(?.*))?$") + val m = r.find(value) + + if (m != null) { + val groups = (m.groups as MatchNamedGroupCollection) + + val expType = groups["name"]!!.value + val expDesc = groups["desc"]?.value ?: "" + + val throwsInfo = throws.getOrPut(expType) { ThrowsInfo(expType) } + + throwsInfo.description = expDesc + } + + true + } + else -> false + } + +} diff --git a/src/main/kotlin/net/love2hina/kotlin/sharon/parser/FunctionVisitor.kt b/src/main/kotlin/net/love2hina/kotlin/sharon/parser/FunctionVisitor.kt index 0feb916..02e7e83 100644 --- a/src/main/kotlin/net/love2hina/kotlin/sharon/parser/FunctionVisitor.kt +++ b/src/main/kotlin/net/love2hina/kotlin/sharon/parser/FunctionVisitor.kt @@ -1,9 +1,96 @@ package net.love2hina.kotlin.sharon.parser +import com.github.javaparser.ast.body.ConstructorDeclaration import com.github.javaparser.ast.body.MethodDeclaration import net.love2hina.kotlin.sharon.data.* import net.love2hina.kotlin.sharon.* +/** + * コンストラクタ定義. + */ +internal fun Parser.Visitor.visitInConstructor(n: ConstructorDeclaration, arg: Void?) { + // コンストラクタ情報 + val ctorInfo = ConstructorInfo() + + // 実体解析 + // タイプパラメーター + n.typeParameters.forEach { + val name = it.name.asString() + ctorInfo.typeParameters[name] = TypeParameterInfo(name) + } + // 明示的なthisパラメーター + n.receiverParameter.ifPresent { + val name = it.name.asString() + ctorInfo.parameters[name] = ParameterInfo("", it.type.asString(), name) + } + // パラメーター + n.parameters.forEach { + val name = it.name.asString() + ctorInfo.parameters[name] = ParameterInfo( + getModifier(it.modifiers), + it.type.asString(), + name + ) + } + // 例外 + n.thrownExceptions.forEach { + val type = it.asString() + ctorInfo.throws[type] = ThrowsInfo(type) + } + + // コメントの解析 + n.comment.parseJavadoc(ctorInfo) + + // 出力開始 + writer.writeStartElement("method") + writer.writeAttribute("type", "constructor") + writer.writeAttribute("modifier", getModifier(n.modifiers)) + writer.writeAttribute("name", n.name.asString()) + + // 定義全体 + writer.writeStartElement("definitions") + writer.writeStrings(n.getDeclarationAsString(true, true, true)) + writer.writeEndElement() + + // 説明の出力 + writer.writeStartElement("description") + writer.writeStrings(ctorInfo.description.toString()) + writer.writeEndElement() + // タイプパラメーターの出力 + ctorInfo.typeParameters.forEach { + writer.writeStartElement("typeParameter") + writer.writeAttribute("type", it.value.type) + writer.writeStrings(it.value.description) + writer.writeEndElement() + } + // パラメーターの出力 + ctorInfo.parameters.forEach { + writer.writeStartElement("parameter") + writer.writeAttribute("modifier", it.value.modifier) + writer.writeAttribute("type", it.value.type) + writer.writeAttribute("name", it.value.name) + writer.writeStrings(it.value.description) + writer.writeEndElement() + } + // 例外の出力 + ctorInfo.throws.forEach { + writer.writeStartElement("throws") + writer.writeAttribute("type", it.value.type) + writer.writeStrings(it.value.description) + writer.writeEndElement() + } + + // アノテーション + n.annotations.forEach { it.accept(this, arg) } + + // ステートメント + writer.writeStartElement("code") + n.body.accept(this, arg) + writer.writeEndElement() + + writer.writeEndElement() +} + /** * 関数定義. */ @@ -46,6 +133,7 @@ internal fun Parser.Visitor.visitInFunction(n: MethodDeclaration, arg: Void?) { // 出力開始 writer.writeStartElement("method") + writer.writeAttribute("type", "normal") writer.writeAttribute("modifier", getModifier(n.modifiers)) writer.writeAttribute("name", n.name.asString()) diff --git a/src/main/kotlin/net/love2hina/kotlin/sharon/parser/Parser.kt b/src/main/kotlin/net/love2hina/kotlin/sharon/parser/Parser.kt index 839151e..e5b97f1 100644 --- a/src/main/kotlin/net/love2hina/kotlin/sharon/parser/Parser.kt +++ b/src/main/kotlin/net/love2hina/kotlin/sharon/parser/Parser.kt @@ -333,39 +333,10 @@ internal class Parser( } } - /** - * コンストラクタ定義. - */ - override fun visit(n: ConstructorDeclaration?, arg: Void?) { - // TODO - // n.getBody().accept(this, arg); - // n.getModifiers().forEach(p -> p.accept(this, arg)); - // n.getName().accept(this, arg); - // n.getParameters().forEach(p -> p.accept(this, arg)); - // n.getReceiverParameter().ifPresent(l -> l.accept(this, arg)); - // n.getThrownExceptions().forEach(p -> p.accept(this, arg)); - // n.getTypeParameters().forEach(p -> p.accept(this, arg)); - // n.getAnnotations().forEach(p -> p.accept(this, arg)); - // n.getComment().ifPresent(l -> l.accept(this, arg)); - } - + override fun visit(n: ConstructorDeclaration?, arg: Void?) = visitInConstructor(n!!, arg) override fun visit(n: MethodDeclaration?, arg: Void?) = visitInFunction(n!!, arg) - - /** - * 明示的なthisパラメータ. - */ - override fun visit(n: ReceiverParameter?, arg: Void?) { - // 使われない - throw IllegalAccessException() - } - - /** - * パラメータ. - */ - override fun visit(n: Parameter?, arg: Void?) { - // 使われない - throw IllegalAccessException() - } + override fun visit(n: ReceiverParameter?, arg: Void?) = error("使われない") + override fun visit(n: Parameter?, arg: Void?) = error("使われない") /** * ブロックステートメント. diff --git a/src/test/java/net/love2hina/kotlin/sharon/ParseTestClassTarget.java b/src/test/java/net/love2hina/kotlin/sharon/ParseTestClassTarget.java index d30886d..72c3f57 100644 --- a/src/test/java/net/love2hina/kotlin/sharon/ParseTestClassTarget.java +++ b/src/test/java/net/love2hina/kotlin/sharon/ParseTestClassTarget.java @@ -1,5 +1,6 @@ package net.love2hina.kotlin.sharon; +import java.io.IOException; import java.nio.file.Path; /** @@ -28,6 +29,18 @@ public enum MyEnum { } + /** + * コンストラクタ. + * + * @param parent 親 + * @exception IOException IO例外 + */ + public ParseTestClassTarget(final String parent) throws IOException + { + /// # 初期化 + /// 初期化処理を行う + } + /** * メソッド. *