introduce the concept of sections

This commit is contained in:
Dmitry Jemerov
2015-01-20 12:29:44 +01:00
parent f3763bc2b5
commit c3a496b9a2
29 changed files with 288 additions and 137 deletions
@@ -17,9 +17,11 @@
package org.jetbrains.kotlin.kdoc.parser;
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink;
import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection;
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag;
public class KDocElementTypes {
public static final KDocElementType KDOC_SECTION = new KDocElementType("KDOC_SECTION", KDocSection.class);
public static final KDocElementType KDOC_TAG = new KDocElementType("KDOC_TAG", KDocTag.class);
public static final KDocElementType KDOC_LINK = new KDocElementType("KDOC_LINK", KDocLink.class);
}
@@ -17,24 +17,32 @@
package org.jetbrains.kotlin.kdoc.parser;
public enum KDocKnownTag {
AUTHOR(false),
THROWS(true),
EXCEPTION(true),
PARAM(true),
RETURN(false),
SEE(false),
SINCE(false);
AUTHOR(false, false),
THROWS(true, false),
EXCEPTION(true, false),
PARAM(true, false),
RETURN(false, false),
SEE(false, false),
SINCE(false, false),
CONSTRUCTOR(false, true),
PROPERTY(true, true);
private final boolean takesReference;
private final boolean startsSection;
KDocKnownTag(boolean takesReference) {
KDocKnownTag(boolean takesReference, boolean startsSection) {
this.takesReference = takesReference;
this.startsSection = startsSection;
}
public boolean isReferenceRequired() {
return takesReference;
}
public boolean isSectionStart() {
return startsSection;
}
public static KDocKnownTag findByTagName(String tagName) {
if (tagName.startsWith("@")) {
try {
@@ -28,30 +28,48 @@ public class KDocParser implements PsiParser {
@NotNull
public ASTNode parse(IElementType root, PsiBuilder builder) {
PsiBuilder.Marker rootMarker = builder.mark();
if (builder.getTokenType() == KDocTokens.START) {
builder.advanceLexer();
}
PsiBuilder.Marker currentSectionMarker = builder.mark();
// todo: parse KDoc tags, markdown, etc...
while (!builder.eof()) {
if (builder.getTokenType() == KDocTokens.TAG_NAME) {
parseTag(builder);
currentSectionMarker = parseTag(builder, currentSectionMarker);
}
else if (builder.getTokenType() == KDocTokens.MARKDOWN_LINK) {
PsiBuilder.Marker linkStart = builder.mark();
builder.advanceLexer();
linkStart.done(KDocElementTypes.KDOC_LINK);
}
else if (builder.getTokenType() == KDocTokens.END) {
if (currentSectionMarker != null) {
currentSectionMarker.done(KDocElementTypes.KDOC_SECTION);
currentSectionMarker = null;
}
builder.advanceLexer();
}
else {
builder.advanceLexer();
}
}
if (currentSectionMarker != null) {
currentSectionMarker.done(KDocElementTypes.KDOC_SECTION);
}
rootMarker.done(root);
return builder.getTreeBuilt();
}
private static void parseTag(PsiBuilder builder) {
PsiBuilder.Marker tagStart = builder.mark();
private static PsiBuilder.Marker parseTag(PsiBuilder builder, PsiBuilder.Marker currentSectionMarker) {
String tagName = builder.getTokenText();
KDocKnownTag knownTag = KDocKnownTag.findByTagName(tagName);
if (knownTag != null && knownTag.isSectionStart()) {
currentSectionMarker.done(KDocElementTypes.KDOC_SECTION);
currentSectionMarker = builder.mark();
}
PsiBuilder.Marker tagStart = builder.mark();
builder.advanceLexer();
if (knownTag != null && knownTag.isReferenceRequired() && builder.getTokenType() == KDocTokens.TEXT_OR_LINK) {
@@ -71,6 +89,7 @@ public class KDocParser implements PsiParser {
}
}
tagStart.done(KDocElementTypes.KDOC_TAG);
return currentSectionMarker;
}
private static boolean isAtEndOfTag(PsiBuilder builder) {
@@ -0,0 +1,32 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.kdoc.psi.impl;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
/**
* The part of a doc comment which describes a single class, method or property
* produced by the element being documented. For example, the doc comment of a class
* can have sections for the class itself, its primary constructor and each of the
* properties defined in the primary constructor.
*/
public class KDocSection extends KDocElementImpl {
public KDocSection(@NotNull ASTNode node) {
super(node);
}
}