diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex
index a7e0e5fedda..0b289c916d7 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex
+++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex
@@ -53,7 +53,7 @@ ALPHA=[:jletter:]
TAG_NAME={ALPHA}({ALPHA}|{DIGIT})*
IDENTIFIER={ALPHA}({ALPHA}|{DIGIT}|".")*
CODE_LINK_START={ALPHA}
-CODE_LINK_CHAR={ALPHA}|{DIGIT}|[()\-\.<>]
+CODE_LINK_CHAR={ALPHA}|{DIGIT}|[\.]
CODE_LINK=\[{CODE_LINK_START}{CODE_LINK_CHAR}*\]
%%
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDocTokens.java b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDocTokens.java
index 250cd27a5f7..df450cd06f7 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDocTokens.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDocTokens.java
@@ -26,8 +26,10 @@ import com.intellij.psi.tree.ILazyParseableElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.idea.JetLanguage;
+import org.jetbrains.kotlin.kdoc.parser.KDocLinkParser;
import org.jetbrains.kotlin.kdoc.parser.KDocParser;
import org.jetbrains.kotlin.kdoc.psi.impl.KDocImpl;
+import org.jetbrains.kotlin.lexer.JetLexer;
public interface KDocTokens {
ILazyParseableElementType KDOC = new ILazyParseableElementType("KDoc", JetLanguage.INSTANCE) {
@@ -62,7 +64,18 @@ public interface KDocTokens {
*/
KDocToken TEXT_OR_LINK = new KDocToken("KDOC_TEXT_OR_LINK");
KDocToken TAG_NAME = new KDocToken("KDOC_TAG_NAME");
- KDocToken MARKDOWN_LINK = new KDocToken("KDOC_MARKDOWN_LINK");
+ ILazyParseableElementType MARKDOWN_LINK = new ILazyParseableElementType("KDOC_MARKDOWN_LINK", JetLanguage.INSTANCE) {
+ @Override
+ public ASTNode parseContents(ASTNode chameleon) {
+ PsiElement parentElement = chameleon.getTreeParent().getPsi();
+ Project project = parentElement.getProject();
+ PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, new JetLexer(), getLanguage(),
+ chameleon.getText());
+ PsiParser parser = new KDocLinkParser();
+
+ return parser.parse(this, builder).getFirstChildNode();
+ }
+ };
KDocToken MARKDOWN_ESCAPED_CHAR = new KDocToken("KDOC_MARKDOWN_ESCAPED_CHAR");
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java
index 4c9eaba2c23..cb3240248d6 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java
@@ -1,4 +1,20 @@
-/* The following code was generated by JFlex 1.4.3 on 2/2/15 2:35 PM */
+/*
+ * 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.
+ */
+
+/* The following code was generated by JFlex 1.4.3 on 2/3/15 2:37 PM */
package org.jetbrains.kotlin.kdoc.lexer;
@@ -12,7 +28,7 @@ import java.lang.Character;
/**
* This class is a scanner generated by
* JFlex 1.4.3
- * on 2/2/15 2:35 PM from the specification file
+ * on 2/3/15 2:37 PM from the specification file
* /Users/yole/jetbrains/kotlin/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex
*/
class _KDocLexer implements FlexLexer {
@@ -40,67 +56,67 @@ class _KDocLexer implements FlexLexer {
* Translates characters to character classes
*/
private static final String ZZ_CMAP_PACKED =
- "\11\0\1\1\1\13\1\0\2\1\22\0\1\1\3\0\1\3\3\0"+
- "\2\5\1\11\2\0\1\5\1\4\1\10\12\2\2\0\1\5\1\0"+
- "\1\5\1\0\1\12\32\3\1\6\1\14\1\7\1\0\1\3\1\0"+
- "\32\3\47\0\4\3\4\0\1\3\12\0\1\3\4\0\1\3\5\0"+
- "\27\3\1\0\37\3\1\0\u013f\3\31\0\162\3\4\0\14\3\16\0"+
- "\5\3\11\0\1\3\213\0\1\3\13\0\1\3\1\0\3\3\1\0"+
- "\1\3\1\0\24\3\1\0\54\3\1\0\46\3\1\0\5\3\4\0"+
- "\202\3\10\0\105\3\1\0\46\3\2\0\2\3\6\0\20\3\41\0"+
- "\46\3\2\0\1\3\7\0\47\3\110\0\33\3\5\0\3\3\56\0"+
- "\32\3\5\0\13\3\43\0\2\3\1\0\143\3\1\0\1\3\17\0"+
- "\2\3\7\0\2\3\12\0\3\3\2\0\1\3\20\0\1\3\1\0"+
- "\36\3\35\0\3\3\60\0\46\3\13\0\1\3\u0152\0\66\3\3\0"+
- "\1\3\22\0\1\3\7\0\12\3\43\0\10\3\2\0\2\3\2\0"+
- "\26\3\1\0\7\3\1\0\1\3\3\0\4\3\3\0\1\3\36\0"+
- "\2\3\1\0\3\3\16\0\4\3\21\0\6\3\4\0\2\3\2\0"+
- "\26\3\1\0\7\3\1\0\2\3\1\0\2\3\1\0\2\3\37\0"+
- "\4\3\1\0\1\3\23\0\3\3\20\0\11\3\1\0\3\3\1\0"+
- "\26\3\1\0\7\3\1\0\2\3\1\0\5\3\3\0\1\3\22\0"+
- "\1\3\17\0\2\3\17\0\1\3\23\0\10\3\2\0\2\3\2\0"+
- "\26\3\1\0\7\3\1\0\2\3\1\0\5\3\3\0\1\3\36\0"+
- "\2\3\1\0\3\3\17\0\1\3\21\0\1\3\1\0\6\3\3\0"+
- "\3\3\1\0\4\3\3\0\2\3\1\0\1\3\1\0\2\3\3\0"+
- "\2\3\3\0\3\3\3\0\10\3\1\0\3\3\77\0\1\3\13\0"+
- "\10\3\1\0\3\3\1\0\27\3\1\0\12\3\1\0\5\3\46\0"+
- "\2\3\43\0\10\3\1\0\3\3\1\0\27\3\1\0\12\3\1\0"+
- "\5\3\3\0\1\3\40\0\1\3\1\0\2\3\43\0\10\3\1\0"+
- "\3\3\1\0\27\3\1\0\20\3\46\0\2\3\43\0\22\3\3\0"+
- "\30\3\1\0\11\3\1\0\1\3\2\0\7\3\72\0\60\3\1\0"+
- "\2\3\13\0\10\3\72\0\2\3\1\0\1\3\2\0\2\3\1\0"+
- "\1\3\2\0\1\3\6\0\4\3\1\0\7\3\1\0\3\3\1\0"+
- "\1\3\1\0\1\3\2\0\2\3\1\0\4\3\1\0\2\3\11\0"+
- "\1\3\2\0\5\3\1\0\1\3\25\0\2\3\42\0\1\3\77\0"+
- "\10\3\1\0\42\3\35\0\4\3\164\0\42\3\1\0\5\3\1\0"+
- "\2\3\45\0\6\3\112\0\46\3\12\0\51\3\7\0\132\3\5\0"+
- "\104\3\5\0\122\3\6\0\7\3\1\0\77\3\1\0\1\3\1\0"+
- "\4\3\2\0\7\3\1\0\1\3\1\0\4\3\2\0\47\3\1\0"+
- "\1\3\1\0\4\3\2\0\37\3\1\0\1\3\1\0\4\3\2\0"+
- "\7\3\1\0\1\3\1\0\4\3\2\0\7\3\1\0\7\3\1\0"+
- "\27\3\1\0\37\3\1\0\1\3\1\0\4\3\2\0\7\3\1\0"+
- "\47\3\1\0\23\3\105\0\125\3\14\0\u026c\3\2\0\10\3\12\0"+
- "\32\3\5\0\113\3\3\0\3\3\17\0\15\3\1\0\4\3\16\0"+
- "\22\3\16\0\22\3\16\0\15\3\1\0\3\3\17\0\64\3\43\0"+
- "\1\3\3\0\2\3\103\0\130\3\10\0\51\3\127\0\35\3\63\0"+
- "\36\3\2\0\5\3\u038b\0\154\3\224\0\234\3\4\0\132\3\6\0"+
- "\26\3\2\0\6\3\2\0\46\3\2\0\6\3\2\0\10\3\1\0"+
- "\1\3\1\0\1\3\1\0\1\3\1\0\37\3\2\0\65\3\1\0"+
- "\7\3\1\0\1\3\3\0\3\3\1\0\7\3\3\0\4\3\2\0"+
- "\6\3\4\0\15\3\5\0\3\3\1\0\7\3\102\0\2\3\23\0"+
- "\1\3\34\0\1\3\15\0\1\3\40\0\22\3\120\0\1\3\4\0"+
- "\1\3\2\0\12\3\1\0\1\3\3\0\5\3\6\0\1\3\1\0"+
- "\1\3\1\0\1\3\1\0\4\3\1\0\3\3\1\0\7\3\3\0"+
- "\3\3\5\0\5\3\26\0\44\3\u0e81\0\3\3\31\0\11\3\7\0"+
- "\5\3\2\0\5\3\4\0\126\3\6\0\3\3\1\0\137\3\5\0"+
- "\50\3\4\0\136\3\21\0\30\3\70\0\20\3\u0200\0\u19b6\3\112\0"+
- "\u51a6\3\132\0\u048d\3\u0773\0\u2ba4\3\u215c\0\u012e\3\2\0\73\3\225\0"+
- "\7\3\14\0\5\3\5\0\1\3\1\0\12\3\1\0\15\3\1\0"+
- "\5\3\1\0\1\3\1\0\2\3\1\0\2\3\1\0\154\3\41\0"+
- "\u016b\3\22\0\100\3\2\0\66\3\50\0\15\3\66\0\2\3\30\0"+
- "\3\3\31\0\1\3\6\0\5\3\1\0\207\3\7\0\1\3\34\0"+
- "\32\3\4\0\1\3\1\0\32\3\12\0\132\3\3\0\6\3\2\0"+
- "\6\3\2\0\6\3\2\0\3\3\3\0\2\3\3\0\2\3\31\0";
+ "\11\0\1\1\1\12\1\0\2\1\22\0\1\1\3\0\1\3\5\0"+
+ "\1\10\3\0\1\4\1\7\12\2\6\0\1\11\32\3\1\5\1\13"+
+ "\1\6\1\0\1\3\1\0\32\3\47\0\4\3\4\0\1\3\12\0"+
+ "\1\3\4\0\1\3\5\0\27\3\1\0\37\3\1\0\u013f\3\31\0"+
+ "\162\3\4\0\14\3\16\0\5\3\11\0\1\3\213\0\1\3\13\0"+
+ "\1\3\1\0\3\3\1\0\1\3\1\0\24\3\1\0\54\3\1\0"+
+ "\46\3\1\0\5\3\4\0\202\3\10\0\105\3\1\0\46\3\2\0"+
+ "\2\3\6\0\20\3\41\0\46\3\2\0\1\3\7\0\47\3\110\0"+
+ "\33\3\5\0\3\3\56\0\32\3\5\0\13\3\43\0\2\3\1\0"+
+ "\143\3\1\0\1\3\17\0\2\3\7\0\2\3\12\0\3\3\2\0"+
+ "\1\3\20\0\1\3\1\0\36\3\35\0\3\3\60\0\46\3\13\0"+
+ "\1\3\u0152\0\66\3\3\0\1\3\22\0\1\3\7\0\12\3\43\0"+
+ "\10\3\2\0\2\3\2\0\26\3\1\0\7\3\1\0\1\3\3\0"+
+ "\4\3\3\0\1\3\36\0\2\3\1\0\3\3\16\0\4\3\21\0"+
+ "\6\3\4\0\2\3\2\0\26\3\1\0\7\3\1\0\2\3\1\0"+
+ "\2\3\1\0\2\3\37\0\4\3\1\0\1\3\23\0\3\3\20\0"+
+ "\11\3\1\0\3\3\1\0\26\3\1\0\7\3\1\0\2\3\1\0"+
+ "\5\3\3\0\1\3\22\0\1\3\17\0\2\3\17\0\1\3\23\0"+
+ "\10\3\2\0\2\3\2\0\26\3\1\0\7\3\1\0\2\3\1\0"+
+ "\5\3\3\0\1\3\36\0\2\3\1\0\3\3\17\0\1\3\21\0"+
+ "\1\3\1\0\6\3\3\0\3\3\1\0\4\3\3\0\2\3\1\0"+
+ "\1\3\1\0\2\3\3\0\2\3\3\0\3\3\3\0\10\3\1\0"+
+ "\3\3\77\0\1\3\13\0\10\3\1\0\3\3\1\0\27\3\1\0"+
+ "\12\3\1\0\5\3\46\0\2\3\43\0\10\3\1\0\3\3\1\0"+
+ "\27\3\1\0\12\3\1\0\5\3\3\0\1\3\40\0\1\3\1\0"+
+ "\2\3\43\0\10\3\1\0\3\3\1\0\27\3\1\0\20\3\46\0"+
+ "\2\3\43\0\22\3\3\0\30\3\1\0\11\3\1\0\1\3\2\0"+
+ "\7\3\72\0\60\3\1\0\2\3\13\0\10\3\72\0\2\3\1\0"+
+ "\1\3\2\0\2\3\1\0\1\3\2\0\1\3\6\0\4\3\1\0"+
+ "\7\3\1\0\3\3\1\0\1\3\1\0\1\3\2\0\2\3\1\0"+
+ "\4\3\1\0\2\3\11\0\1\3\2\0\5\3\1\0\1\3\25\0"+
+ "\2\3\42\0\1\3\77\0\10\3\1\0\42\3\35\0\4\3\164\0"+
+ "\42\3\1\0\5\3\1\0\2\3\45\0\6\3\112\0\46\3\12\0"+
+ "\51\3\7\0\132\3\5\0\104\3\5\0\122\3\6\0\7\3\1\0"+
+ "\77\3\1\0\1\3\1\0\4\3\2\0\7\3\1\0\1\3\1\0"+
+ "\4\3\2\0\47\3\1\0\1\3\1\0\4\3\2\0\37\3\1\0"+
+ "\1\3\1\0\4\3\2\0\7\3\1\0\1\3\1\0\4\3\2\0"+
+ "\7\3\1\0\7\3\1\0\27\3\1\0\37\3\1\0\1\3\1\0"+
+ "\4\3\2\0\7\3\1\0\47\3\1\0\23\3\105\0\125\3\14\0"+
+ "\u026c\3\2\0\10\3\12\0\32\3\5\0\113\3\3\0\3\3\17\0"+
+ "\15\3\1\0\4\3\16\0\22\3\16\0\22\3\16\0\15\3\1\0"+
+ "\3\3\17\0\64\3\43\0\1\3\3\0\2\3\103\0\130\3\10\0"+
+ "\51\3\127\0\35\3\63\0\36\3\2\0\5\3\u038b\0\154\3\224\0"+
+ "\234\3\4\0\132\3\6\0\26\3\2\0\6\3\2\0\46\3\2\0"+
+ "\6\3\2\0\10\3\1\0\1\3\1\0\1\3\1\0\1\3\1\0"+
+ "\37\3\2\0\65\3\1\0\7\3\1\0\1\3\3\0\3\3\1\0"+
+ "\7\3\3\0\4\3\2\0\6\3\4\0\15\3\5\0\3\3\1\0"+
+ "\7\3\102\0\2\3\23\0\1\3\34\0\1\3\15\0\1\3\40\0"+
+ "\22\3\120\0\1\3\4\0\1\3\2\0\12\3\1\0\1\3\3\0"+
+ "\5\3\6\0\1\3\1\0\1\3\1\0\1\3\1\0\4\3\1\0"+
+ "\3\3\1\0\7\3\3\0\3\3\5\0\5\3\26\0\44\3\u0e81\0"+
+ "\3\3\31\0\11\3\7\0\5\3\2\0\5\3\4\0\126\3\6\0"+
+ "\3\3\1\0\137\3\5\0\50\3\4\0\136\3\21\0\30\3\70\0"+
+ "\20\3\u0200\0\u19b6\3\112\0\u51a6\3\132\0\u048d\3\u0773\0\u2ba4\3\u215c\0"+
+ "\u012e\3\2\0\73\3\225\0\7\3\14\0\5\3\5\0\1\3\1\0"+
+ "\12\3\1\0\15\3\1\0\5\3\1\0\1\3\1\0\2\3\1\0"+
+ "\2\3\1\0\154\3\41\0\u016b\3\22\0\100\3\2\0\66\3\50\0"+
+ "\15\3\66\0\2\3\30\0\3\3\31\0\1\3\6\0\5\3\1\0"+
+ "\207\3\7\0\1\3\34\0\32\3\4\0\1\3\1\0\32\3\12\0"+
+ "\132\3\3\0\6\3\2\0\6\3\2\0\6\3\2\0\3\3\3\0"+
+ "\2\3\3\0\2\3\31\0";
/**
* Translates characters to character classes
@@ -143,10 +159,10 @@ class _KDocLexer implements FlexLexer {
private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
private static final String ZZ_ROWMAP_PACKED_0 =
- "\0\0\0\15\0\32\0\47\0\64\0\101\0\116\0\133"+
- "\0\101\0\150\0\165\0\202\0\217\0\133\0\234\0\101"+
- "\0\251\0\266\0\165\0\133\0\303\0\101\0\133\0\320"+
- "\0\101\0\335\0\101\0\101";
+ "\0\0\0\14\0\30\0\44\0\60\0\74\0\110\0\124"+
+ "\0\74\0\140\0\154\0\170\0\204\0\124\0\220\0\74"+
+ "\0\234\0\250\0\154\0\124\0\264\0\74\0\124\0\300"+
+ "\0\74\0\314\0\74\0\74";
private static int [] zzUnpackRowMap() {
int [] result = new int[28];
@@ -172,19 +188,19 @@ class _KDocLexer implements FlexLexer {
private static final int [] ZZ_TRANS = zzUnpackTrans();
private static final String ZZ_TRANS_PACKED_0 =
- "\10\6\1\7\1\10\1\6\1\0\1\6\1\11\1\12"+
- "\4\11\1\13\2\11\1\14\1\11\1\12\1\15\1\11"+
- "\1\12\4\11\1\13\2\11\1\16\1\17\1\12\1\15"+
- "\1\20\1\21\1\20\1\22\2\20\1\23\2\20\1\24"+
- "\1\20\1\21\1\20\1\11\1\12\4\11\1\13\2\11"+
- "\1\16\1\11\1\12\1\15\26\0\1\25\13\0\1\26"+
- "\1\27\4\0\1\12\11\0\1\12\4\0\1\30\21\0"+
- "\1\26\1\14\11\0\2\31\10\0\1\32\12\0\1\21"+
- "\11\0\1\21\3\0\3\22\21\0\1\33\5\0\4\30"+
- "\1\0\1\34\7\0\2\32\11\0";
+ "\7\6\1\7\1\10\1\6\1\0\1\6\1\11\1\12"+
+ "\3\11\1\13\2\11\1\14\1\11\1\12\1\15\1\11"+
+ "\1\12\3\11\1\13\2\11\1\16\1\17\1\12\1\15"+
+ "\1\20\1\21\1\20\1\22\1\20\1\23\2\20\1\24"+
+ "\1\20\1\21\1\20\1\11\1\12\3\11\1\13\2\11"+
+ "\1\16\1\11\1\12\1\15\24\0\1\25\12\0\1\26"+
+ "\1\27\4\0\1\12\10\0\1\12\4\0\1\30\17\0"+
+ "\1\26\1\14\10\0\2\31\10\0\1\32\11\0\1\21"+
+ "\10\0\1\21\3\0\3\22\17\0\1\33\5\0\3\30"+
+ "\1\0\1\34\7\0\2\32\10\0";
private static int [] zzUnpackTrans() {
- int [] result = new int[234];
+ int [] result = new int[216];
int offset = 0;
offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
return result;
@@ -333,7 +349,7 @@ class _KDocLexer implements FlexLexer {
char [] map = new char[0x10000];
int i = 0; /* index in packed string */
int j = 0; /* index in unpacked array */
- while (i < 1220) {
+ while (i < 1208) {
int count = packed.charAt(i++);
char value = packed.charAt(i++);
do map[j++] = value; while (--count > 0);
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementType.java b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementType.java
index 4993d8b2a08..86c2f06b4f9 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementType.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementType.java
@@ -17,26 +17,26 @@
package org.jetbrains.kotlin.kdoc.parser;
import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.JetLanguage;
-import org.jetbrains.kotlin.kdoc.psi.impl.KDocElementImpl;
import java.lang.reflect.Constructor;
public class KDocElementType extends IElementType {
- private final Constructor extends KDocElementImpl> psiFactory;
+ private final Constructor extends PsiElement> psiFactory;
- public KDocElementType(String debugName, @NotNull Class extends KDocElementImpl> psiClass) {
+ public KDocElementType(String debugName, @NotNull Class extends PsiElement> psiClass) {
super(debugName, JetLanguage.INSTANCE);
try {
- psiFactory = psiClass != null ? psiClass.getConstructor(ASTNode.class) : null;
+ psiFactory = psiClass.getConstructor(ASTNode.class);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Must have a constructor with ASTNode");
}
}
- public KDocElementImpl createPsi(ASTNode node) {
+ public PsiElement createPsi(ASTNode node) {
assert node.getElementType() == this;
try {
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementTypes.java b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementTypes.java
index 6ff530e4cf4..0faea9b570f 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementTypes.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementTypes.java
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.kdoc.parser;
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink;
+import org.jetbrains.kotlin.kdoc.psi.impl.KDocName;
import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection;
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag;
@@ -24,4 +25,5 @@ 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);
+ public static final KDocElementType KDOC_NAME = new KDocElementType("KDOC_NAME", KDocName.class);
}
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocLinkParser.kt b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocLinkParser.kt
new file mode 100644
index 00000000000..35c151b0aad
--- /dev/null
+++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocLinkParser.kt
@@ -0,0 +1,69 @@
+/*
+ * 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.parser
+
+import com.intellij.lang.PsiParser
+import com.intellij.psi.tree.IElementType
+import com.intellij.lang.PsiBuilder
+import com.intellij.lang.ASTNode
+import org.jetbrains.kotlin.lexer.JetTokens
+
+/**
+ * Parses the contents of a Markdown link in KDoc. Uses the standard Kotlin lexer.
+ */
+class KDocLinkParser(): PsiParser {
+ override fun parse(root: IElementType, builder: PsiBuilder): ASTNode {
+ builder.setDebugMode(true)
+ val rootMarker = builder.mark()
+ if (builder.getTokenType() == JetTokens.LBRACKET) {
+ builder.advanceLexer()
+ }
+ parseQualifiedName(builder)
+ if (!builder.eof() && builder.getTokenType() != JetTokens.RBRACKET) {
+ builder.error("Closing bracket expected")
+ while (!builder.eof() && builder.getTokenType() != JetTokens.RBRACKET) {
+ builder.advanceLexer()
+ }
+ }
+ if (builder.getTokenType() == JetTokens.RBRACKET) {
+ builder.advanceLexer()
+ }
+ rootMarker.done(root)
+ return builder.getTreeBuilt()
+ }
+
+ private fun parseQualifiedName(builder: PsiBuilder) {
+ var marker = builder.mark()
+ while (true) {
+ // don't highlight a word in a link as an error if it happens to be a Kotlin keyword
+ if (!isName(builder.getTokenType())) {
+ marker.drop()
+ builder.error("Identifier expected")
+ break
+ }
+ builder.advanceLexer()
+ marker.done(KDocElementTypes.KDOC_NAME)
+ if (builder.getTokenType() != JetTokens.DOT) {
+ break
+ }
+ marker = marker.precede()
+ builder.advanceLexer()
+ }
+ }
+
+ private fun isName(tokenType: IElementType) = tokenType == JetTokens.IDENTIFIER || tokenType in JetTokens.KEYWORDS
+}
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocParser.java b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocParser.java
index 288346f243b..4a347858a4e 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocParser.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocParser.java
@@ -74,7 +74,9 @@ public class KDocParser implements PsiParser {
if (knownTag != null && knownTag.isReferenceRequired() && builder.getTokenType() == KDocTokens.TEXT_OR_LINK) {
PsiBuilder.Marker referenceMarker = builder.mark();
+ PsiBuilder.Marker nameMarker = builder.mark();
builder.advanceLexer();
+ nameMarker.done(KDocElementTypes.KDOC_NAME);
referenceMarker.done(KDocElementTypes.KDOC_LINK);
}
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/impl/KDocName.kt b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/impl/KDocName.kt
new file mode 100644
index 00000000000..61391115ee0
--- /dev/null
+++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/impl/KDocName.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.kotlin.psi.JetElementImpl
+
+/**
+ * A single part of a qualified name in the tag subject or link.
+ */
+public class KDocName(node: ASTNode): JetElementImpl(node) {
+
+}
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParserDefinition.java b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParserDefinition.java
index 66a812a949f..f03dbb9dd49 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParserDefinition.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParserDefinition.java
@@ -33,7 +33,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.JetNodeType;
import org.jetbrains.kotlin.JetNodeTypes;
import org.jetbrains.kotlin.idea.JetLanguage;
+import org.jetbrains.kotlin.kdoc.lexer.KDocTokens;
import org.jetbrains.kotlin.kdoc.parser.KDocElementType;
+import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink;
import org.jetbrains.kotlin.lexer.JetLexer;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.psi.JetFile;
@@ -106,6 +108,9 @@ public class JetParserDefinition implements ParserDefinition {
else if (elementType instanceof KDocElementType) {
return ((KDocElementType) elementType).createPsi(astNode);
}
+ else if (elementType == KDocTokens.MARKDOWN_LINK) {
+ return new KDocLink(astNode);
+ }
else {
return ((JetNodeType) elementType).createPsi(astNode);
}
diff --git a/compiler/testData/psi/kdoc/Markdown.txt b/compiler/testData/psi/kdoc/Markdown.txt
index 3dc99a1e0f3..19db5898e7a 100644
--- a/compiler/testData/psi/kdoc/Markdown.txt
+++ b/compiler/testData/psi/kdoc/Markdown.txt
@@ -8,7 +8,11 @@ JetFile: Markdown.kt
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' ')
KDOC_LINK
- PsiElement(KDOC_MARKDOWN_LINK)('[WikiLink]')
+ KDOC_MARKDOWN_LINK
+ PsiElement(LBRACKET)('[')
+ KDOC_NAME
+ PsiElement(IDENTIFIER)('WikiLink')
+ PsiElement(RBRACKET)(']')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' ')
@@ -18,7 +22,11 @@ JetFile: Markdown.kt
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' [')
KDOC_LINK
- PsiElement(KDOC_MARKDOWN_LINK)('[DoubleQuotedLink]')
+ KDOC_MARKDOWN_LINK
+ PsiElement(LBRACKET)('[')
+ KDOC_NAME
+ PsiElement(IDENTIFIER)('DoubleQuotedLink')
+ PsiElement(RBRACKET)(']')
PsiElement(KDOC_TEXT)(']')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
diff --git a/compiler/testData/psi/kdoc/MarkdownQualifiedName.kt b/compiler/testData/psi/kdoc/MarkdownQualifiedName.kt
new file mode 100644
index 00000000000..27ead6e4e0e
--- /dev/null
+++ b/compiler/testData/psi/kdoc/MarkdownQualifiedName.kt
@@ -0,0 +1,5 @@
+/**
+ * [A.B.C]
+ * [[System.out]]
+ * [System.in]
+ */
diff --git a/compiler/testData/psi/kdoc/MarkdownQualifiedName.txt b/compiler/testData/psi/kdoc/MarkdownQualifiedName.txt
new file mode 100644
index 00000000000..058ba87e026
--- /dev/null
+++ b/compiler/testData/psi/kdoc/MarkdownQualifiedName.txt
@@ -0,0 +1,48 @@
+JetFile: MarkdownQualifiedName.kt
+ PACKAGE_DIRECTIVE
+
+ KDoc
+ PsiElement(KDOC_START)('/**')
+ PsiWhiteSpace('\n ')
+ KDOC_SECTION
+ PsiElement(KDOC_LEADING_ASTERISK)('*')
+ PsiElement(KDOC_TEXT)(' ')
+ KDOC_LINK
+ KDOC_MARKDOWN_LINK
+ PsiElement(LBRACKET)('[')
+ KDOC_NAME
+ KDOC_NAME
+ KDOC_NAME
+ PsiElement(IDENTIFIER)('A')
+ PsiElement(DOT)('.')
+ PsiElement(IDENTIFIER)('B')
+ PsiElement(DOT)('.')
+ PsiElement(IDENTIFIER)('C')
+ PsiElement(RBRACKET)(']')
+ PsiWhiteSpace('\n ')
+ PsiElement(KDOC_LEADING_ASTERISK)('*')
+ PsiElement(KDOC_TEXT)(' [')
+ KDOC_LINK
+ KDOC_MARKDOWN_LINK
+ PsiElement(LBRACKET)('[')
+ KDOC_NAME
+ KDOC_NAME
+ PsiElement(IDENTIFIER)('System')
+ PsiElement(DOT)('.')
+ PsiElement(IDENTIFIER)('out')
+ PsiElement(RBRACKET)(']')
+ PsiElement(KDOC_TEXT)(']')
+ PsiWhiteSpace('\n ')
+ PsiElement(KDOC_LEADING_ASTERISK)('*')
+ PsiElement(KDOC_TEXT)(' ')
+ KDOC_LINK
+ KDOC_MARKDOWN_LINK
+ PsiElement(LBRACKET)('[')
+ KDOC_NAME
+ KDOC_NAME
+ PsiElement(IDENTIFIER)('System')
+ PsiElement(DOT)('.')
+ PsiElement(in)('in')
+ PsiElement(RBRACKET)(']')
+ PsiWhiteSpace('\n ')
+ PsiElement(KDOC_END)('*/')
\ No newline at end of file
diff --git a/compiler/testData/psi/kdoc/ParamTag.txt b/compiler/testData/psi/kdoc/ParamTag.txt
index 9c59b997775..ba38939f4a3 100644
--- a/compiler/testData/psi/kdoc/ParamTag.txt
+++ b/compiler/testData/psi/kdoc/ParamTag.txt
@@ -11,7 +11,8 @@ JetFile: ParamTag.kt
PsiElement(KDOC_TAG_NAME)('@param')
PsiWhiteSpace(' ')
KDOC_LINK
- PsiElement(KDOC_TEXT_OR_LINK)('a')
+ KDOC_NAME
+ PsiElement(KDOC_TEXT_OR_LINK)('a')
PsiElement(KDOC_TEXT)(' The description of a.')
PsiWhiteSpace('\n ')
PsiElement(KDOC_END)('*/')
\ No newline at end of file
diff --git a/compiler/testData/psi/kdoc/ParamTagAtStart.txt b/compiler/testData/psi/kdoc/ParamTagAtStart.txt
index 54d53bf16a7..7ef28c97ccb 100644
--- a/compiler/testData/psi/kdoc/ParamTagAtStart.txt
+++ b/compiler/testData/psi/kdoc/ParamTagAtStart.txt
@@ -9,6 +9,7 @@ JetFile: ParamTagAtStart.kt
PsiElement(KDOC_TAG_NAME)('@param')
PsiWhiteSpace(' ')
KDOC_LINK
- PsiElement(KDOC_TEXT_OR_LINK)('a')
+ KDOC_NAME
+ PsiElement(KDOC_TEXT_OR_LINK)('a')
PsiElement(KDOC_TEXT)(' this is a ')
PsiElement(KDOC_END)('*/')
\ No newline at end of file
diff --git a/compiler/testData/psi/kdoc/ReturnWithBrackets.txt b/compiler/testData/psi/kdoc/ReturnWithBrackets.txt
index 554d1a069e9..88a29c7d6d6 100644
--- a/compiler/testData/psi/kdoc/ReturnWithBrackets.txt
+++ b/compiler/testData/psi/kdoc/ReturnWithBrackets.txt
@@ -18,7 +18,11 @@ JetFile: ReturnWithBrackets.kt
KDOC_TAG
PsiElement(KDOC_TAG_NAME)('@return')
KDOC_LINK
- PsiElement(KDOC_MARKDOWN_LINK)('[x]')
+ KDOC_MARKDOWN_LINK
+ PsiElement(LBRACKET)('[')
+ KDOC_NAME
+ PsiElement(IDENTIFIER)('x')
+ PsiElement(RBRACKET)(']')
PsiElement(KDOC_TEXT)(' This is a reference')
PsiWhiteSpace('\n ')
PsiElement(KDOC_END)('*/')
\ No newline at end of file
diff --git a/compiler/testData/psi/kdoc/Sections.txt b/compiler/testData/psi/kdoc/Sections.txt
index 30080e32e6c..fea98521a10 100644
--- a/compiler/testData/psi/kdoc/Sections.txt
+++ b/compiler/testData/psi/kdoc/Sections.txt
@@ -14,7 +14,8 @@ JetFile: Sections.kt
PsiElement(KDOC_TAG_NAME)('@param')
PsiWhiteSpace(' ')
KDOC_LINK
- PsiElement(KDOC_TEXT_OR_LINK)('T')
+ KDOC_NAME
+ PsiElement(KDOC_TEXT_OR_LINK)('T')
PsiElement(KDOC_TEXT)(' a type parameter.')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
@@ -32,7 +33,8 @@ JetFile: Sections.kt
PsiElement(KDOC_TAG_NAME)('@param')
PsiWhiteSpace(' ')
KDOC_LINK
- PsiElement(KDOC_TEXT_OR_LINK)('a')
+ KDOC_NAME
+ PsiElement(KDOC_TEXT_OR_LINK)('a')
PsiElement(KDOC_TEXT)(' a constructor parameter.')
PsiWhiteSpace('\n ')
PsiElement(KDOC_END)('*/')
\ No newline at end of file
diff --git a/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java
index 81223dfb149..7f458996a41 100644
--- a/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java
@@ -1085,6 +1085,12 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
doParsingTest(fileName);
}
+ @TestMetadata("MarkdownQualifiedName.kt")
+ public void testMarkdownQualifiedName() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/kdoc/MarkdownQualifiedName.kt");
+ doParsingTest(fileName);
+ }
+
@TestMetadata("ParamTag.kt")
public void testParamTag() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/kdoc/ParamTag.kt");