Extract PSI to separate module

This commit is contained in:
Simon Ogorodnik
2018-03-13 18:07:10 +03:00
parent 55c93bc8b6
commit c0b0f6d1ca
332 changed files with 344 additions and 257 deletions
+1 -8
View File
@@ -4,27 +4,20 @@ apply { plugin("jps-compatible") }
jvmTarget = "1.6"
val jflexPath by configurations.creating
dependencies {
compile(project(":core:descriptors"))
compile(project(":core:deserialization"))
compile(project(":compiler:util"))
compile(project(":compiler:container"))
compile(project(":compiler:resolution"))
compile(project(":compiler:psi"))
compile(project(":kotlin-script-runtime"))
compile(commonDep("io.javaslang","javaslang"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
compileOnly(intellijDep()) { includeJars("annotations", "trove4j", "guava", rootProject = rootProject) }
jflexPath(commonDep("org.jetbrains.intellij.deps.jflex", "jflex"))
}
sourceSets {
"main" { projectDefault() }
"test" {}
}
ant.importBuild("buildLexer.xml")
ant.properties["builddir"] = buildDir.absolutePath
ant.properties["flex.classpath"] = jflexPath.asPath
-57
View File
@@ -1,57 +0,0 @@
<project name="KotlinLexer" default="lexer">
<property name="home" value="${basedir}"/>
<property name="builddir" value="${basedir}/build"/>
<property name="flex.classpath" value=""/>
<property name="out.dir" value="${builddir}/tmpout"/>
<macrodef name="flex">
<attribute name="flexfile"/>
<attribute name="destdir"/>
<attribute name="skeleton" default="${builddir}/idea-flex.skeleton"/>
<sequential>
<delete dir="${out.dir}"/>
<mkdir dir="${out.dir}"/>
<java classname="jflex.Main"
jvmargs="-Xmx512M"
fork="true"
failonerror="true">
<arg value="-skel"/>
<arg value="@{skeleton}"/>
<arg value="-d"/>
<arg value="${out.dir}"/>
<arg value="@{flexfile}"/>
<classpath>
<pathelement path="${flex.classpath}"/>
</classpath>
</java>
<move todir="@{destdir}">
<fileset dir="${out.dir}">
<include name="*.java"/>
</fileset>
</move>
<delete dir="${out.dir}"/>
</sequential>
</macrodef>
<target name="check-idea-flex.skeleton.exists">
<available file="${builddir}/idea-flex.skeleton" property="skeleton.exists"/>
</target>
<target name="get-idea-flex.skeleton.if.not.exists" depends="check-idea-flex.skeleton.exists" unless="skjeleton.exisits">
<get src="https://raw.github.com/JetBrains/intellij-community/master/tools/lexer/idea-flex.skeleton"
dest="${builddir}/idea-flex.skeleton" usetimestamp="true"/>
</target>
<target name="lexer" depends="get-idea-flex.skeleton.if.not.exists">
<flex flexfile="${home}/src/org/jetbrains/kotlin/lexer/Kotlin.flex"
destdir="${home}/src/org/jetbrains/kotlin/lexer/"/>
<!-- This is a hack, but we don't want to alter the skeleton we are using now, because being in sync with IDEA is more important-->
<replaceregexp file="${home}/src/org/jetbrains/kotlin/lexer/_JetLexer.java"
match="throw new KotlinLexerException\(message\);"
replace="throw new KotlinLexerException(message + &quot;\\\\n at '&quot; + yytext() + &quot;'\\\\n&quot; + zzBuffer);"/>
<flex flexfile="${home}/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex"
destdir="${home}/src/org/jetbrains/kotlin/kdoc/lexer/"/>
</target>
</project>
@@ -1,64 +0,0 @@
/*
* 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;
import com.intellij.lang.ASTNode;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import org.jetbrains.kotlin.psi.KtElement;
import org.jetbrains.kotlin.psi.KtElementImpl;
import java.lang.reflect.Constructor;
public class KtNodeType extends IElementType {
private final Constructor<? extends KtElement> myPsiFactory;
public KtNodeType(@NotNull @NonNls String debugName, Class<? extends KtElement> psiClass) {
super(debugName, KotlinLanguage.INSTANCE);
try {
myPsiFactory = psiClass != null ? psiClass.getConstructor(ASTNode.class) : null;
} catch (NoSuchMethodException e) {
throw new RuntimeException("Must have a constructor with ASTNode");
}
}
public KtElement createPsi(ASTNode node) {
assert node.getElementType() == this;
try {
if (myPsiFactory == null) {
return new KtElementImpl(node);
}
return myPsiFactory.newInstance(node);
} catch (Exception e) {
throw new RuntimeException("Error creating psi element for node", e);
}
}
public static class KtLeftBoundNodeType extends KtNodeType {
public KtLeftBoundNodeType(@NotNull @NonNls String debugName, Class<? extends KtElement> psiClass) {
super(debugName, psiClass);
}
@Override
public boolean isLeftBound() {
return true;
}
}
}
@@ -1,166 +0,0 @@
/*
* Copyright 2010-2017 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;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IFileElementType;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
public interface KtNodeTypes {
IFileElementType KT_FILE = new IFileElementType(KotlinLanguage.INSTANCE);
IElementType CLASS = KtStubElementTypes.CLASS;
IElementType FUN = KtStubElementTypes.FUNCTION;
IElementType PROPERTY = KtStubElementTypes.PROPERTY;
IElementType DESTRUCTURING_DECLARATION = new KtNodeType("DESTRUCTURING_DECLARATION", KtDestructuringDeclaration.class);
IElementType DESTRUCTURING_DECLARATION_ENTRY = new KtNodeType("DESTRUCTURING_DECLARATION_ENTRY", KtDestructuringDeclarationEntry.class);
IElementType OBJECT_DECLARATION = KtStubElementTypes.OBJECT_DECLARATION;
IElementType TYPEALIAS = KtStubElementTypes.TYPEALIAS;
IElementType ENUM_ENTRY = KtStubElementTypes.ENUM_ENTRY;
IElementType CLASS_INITIALIZER = KtStubElementTypes.CLASS_INITIALIZER;
IElementType SCRIPT_INITIALIZER = new KtNodeType("SCRIPT_INITIALIZER", KtScriptInitializer.class);
IElementType SECONDARY_CONSTRUCTOR = KtStubElementTypes.SECONDARY_CONSTRUCTOR;
IElementType PRIMARY_CONSTRUCTOR = KtStubElementTypes.PRIMARY_CONSTRUCTOR;
IElementType TYPE_PARAMETER_LIST = KtStubElementTypes.TYPE_PARAMETER_LIST;
IElementType TYPE_PARAMETER = KtStubElementTypes.TYPE_PARAMETER;
IElementType SUPER_TYPE_LIST = KtStubElementTypes.SUPER_TYPE_LIST;
IElementType DELEGATED_SUPER_TYPE_ENTRY = KtStubElementTypes.DELEGATED_SUPER_TYPE_ENTRY;
IElementType SUPER_TYPE_CALL_ENTRY = KtStubElementTypes.SUPER_TYPE_CALL_ENTRY;
IElementType SUPER_TYPE_ENTRY = KtStubElementTypes.SUPER_TYPE_ENTRY;
KtNodeType PROPERTY_DELEGATE = new KtNodeType("PROPERTY_DELEGATE", KtPropertyDelegate.class);
IElementType CONSTRUCTOR_CALLEE = KtStubElementTypes.CONSTRUCTOR_CALLEE;
IElementType VALUE_PARAMETER_LIST = KtStubElementTypes.VALUE_PARAMETER_LIST;
IElementType VALUE_PARAMETER = KtStubElementTypes.VALUE_PARAMETER;
IElementType CLASS_BODY = KtStubElementTypes.CLASS_BODY;
IElementType IMPORT_LIST = KtStubElementTypes.IMPORT_LIST;
IElementType FILE_ANNOTATION_LIST = KtStubElementTypes.FILE_ANNOTATION_LIST;
IElementType IMPORT_DIRECTIVE = KtStubElementTypes.IMPORT_DIRECTIVE;
IElementType IMPORT_ALIAS = KtStubElementTypes.IMPORT_ALIAS;
IElementType MODIFIER_LIST = KtStubElementTypes.MODIFIER_LIST;
IElementType ANNOTATION = KtStubElementTypes.ANNOTATION;
IElementType ANNOTATION_ENTRY = KtStubElementTypes.ANNOTATION_ENTRY;
IElementType ANNOTATION_TARGET = KtStubElementTypes.ANNOTATION_TARGET;
IElementType TYPE_ARGUMENT_LIST = KtStubElementTypes.TYPE_ARGUMENT_LIST;
KtNodeType VALUE_ARGUMENT_LIST = new KtNodeType("VALUE_ARGUMENT_LIST", KtValueArgumentList.class);
KtNodeType VALUE_ARGUMENT = new KtNodeType("VALUE_ARGUMENT", KtValueArgument.class);
KtNodeType LAMBDA_ARGUMENT = new KtNodeType("LAMBDA_ARGUMENT", KtLambdaArgument.class);
KtNodeType VALUE_ARGUMENT_NAME = new KtNodeType("VALUE_ARGUMENT_NAME", KtValueArgumentName.class);
IElementType TYPE_REFERENCE = KtStubElementTypes.TYPE_REFERENCE;
IElementType USER_TYPE = KtStubElementTypes.USER_TYPE;
IElementType DYNAMIC_TYPE = KtStubElementTypes.DYNAMIC_TYPE;
IElementType FUNCTION_TYPE = KtStubElementTypes.FUNCTION_TYPE;
IElementType FUNCTION_TYPE_RECEIVER = KtStubElementTypes.FUNCTION_TYPE_RECEIVER;
KtNodeType SELF_TYPE = new KtNodeType("SELF_TYPE", KtSelfType.class);
IElementType NULLABLE_TYPE = KtStubElementTypes.NULLABLE_TYPE;
IElementType TYPE_PROJECTION = KtStubElementTypes.TYPE_PROJECTION;
// TODO: review
IElementType PROPERTY_ACCESSOR = KtStubElementTypes.PROPERTY_ACCESSOR;
IElementType INITIALIZER_LIST = KtStubElementTypes.INITIALIZER_LIST;
IElementType TYPE_CONSTRAINT_LIST = KtStubElementTypes.TYPE_CONSTRAINT_LIST;
IElementType TYPE_CONSTRAINT = KtStubElementTypes.TYPE_CONSTRAINT;
IElementType CONSTRUCTOR_DELEGATION_CALL = new KtNodeType.KtLeftBoundNodeType("CONSTRUCTOR_DELEGATION_CALL", KtConstructorDelegationCall.class);
KtNodeType CONSTRUCTOR_DELEGATION_REFERENCE = new KtNodeType.KtLeftBoundNodeType("CONSTRUCTOR_DELEGATION_REFERENCE", KtConstructorDelegationReferenceExpression.class);
// TODO: Not sure if we need separate NT for each kind of constants
KtNodeType NULL = new KtNodeType("NULL", KtConstantExpression.class);
KtNodeType BOOLEAN_CONSTANT = new KtNodeType("BOOLEAN_CONSTANT", KtConstantExpression.class);
KtNodeType FLOAT_CONSTANT = new KtNodeType("FLOAT_CONSTANT", KtConstantExpression.class);
KtNodeType CHARACTER_CONSTANT = new KtNodeType("CHARACTER_CONSTANT", KtConstantExpression.class);
KtNodeType INTEGER_CONSTANT = new KtNodeType("INTEGER_CONSTANT", KtConstantExpression.class);
KtNodeType STRING_TEMPLATE = new KtNodeType("STRING_TEMPLATE", KtStringTemplateExpression.class);
KtNodeType LONG_STRING_TEMPLATE_ENTRY = new KtNodeType("LONG_STRING_TEMPLATE_ENTRY", KtBlockStringTemplateEntry.class);
KtNodeType SHORT_STRING_TEMPLATE_ENTRY = new KtNodeType("SHORT_STRING_TEMPLATE_ENTRY", KtSimpleNameStringTemplateEntry.class);
KtNodeType LITERAL_STRING_TEMPLATE_ENTRY = new KtNodeType("LITERAL_STRING_TEMPLATE_ENTRY", KtLiteralStringTemplateEntry.class);
KtNodeType ESCAPE_STRING_TEMPLATE_ENTRY = new KtNodeType("ESCAPE_STRING_TEMPLATE_ENTRY", KtEscapeStringTemplateEntry.class);
KtNodeType PARENTHESIZED = new KtNodeType("PARENTHESIZED", KtParenthesizedExpression.class);
KtNodeType RETURN = new KtNodeType("RETURN", KtReturnExpression.class);
KtNodeType THROW = new KtNodeType("THROW", KtThrowExpression.class);
KtNodeType CONTINUE = new KtNodeType("CONTINUE", KtContinueExpression.class);
KtNodeType BREAK = new KtNodeType("BREAK", KtBreakExpression.class);
KtNodeType IF = new KtNodeType("IF", KtIfExpression.class);
KtNodeType CONDITION = new KtNodeType("CONDITION", KtContainerNode.class);
KtNodeType THEN = new KtNodeType("THEN", KtContainerNodeForControlStructureBody.class);
KtNodeType ELSE = new KtNodeType("ELSE", KtContainerNodeForControlStructureBody.class);
KtNodeType TRY = new KtNodeType("TRY", KtTryExpression.class);
KtNodeType CATCH = new KtNodeType("CATCH", KtCatchClause.class);
KtNodeType FINALLY = new KtNodeType("FINALLY", KtFinallySection.class);
KtNodeType FOR = new KtNodeType("FOR", KtForExpression.class);
KtNodeType WHILE = new KtNodeType("WHILE", KtWhileExpression.class);
KtNodeType DO_WHILE = new KtNodeType("DO_WHILE", KtDoWhileExpression.class);
KtNodeType LOOP_RANGE = new KtNodeType("LOOP_RANGE", KtContainerNode.class);
KtNodeType BODY = new KtNodeType("BODY", KtContainerNodeForControlStructureBody.class);
KtNodeType BLOCK = new KtNodeType("BLOCK", KtBlockExpression.class);
IElementType LAMBDA_EXPRESSION = new LambdaExpressionElementType();
KtNodeType FUNCTION_LITERAL = new KtNodeType("FUNCTION_LITERAL", KtFunctionLiteral.class);
KtNodeType ANNOTATED_EXPRESSION = new KtNodeType("ANNOTATED_EXPRESSION", KtAnnotatedExpression.class);
IElementType REFERENCE_EXPRESSION = KtStubElementTypes.REFERENCE_EXPRESSION;
IElementType ENUM_ENTRY_SUPERCLASS_REFERENCE_EXPRESSION = KtStubElementTypes.ENUM_ENTRY_SUPERCLASS_REFERENCE_EXPRESSION;
KtNodeType OPERATION_REFERENCE = new KtNodeType("OPERATION_REFERENCE", KtOperationReferenceExpression.class);
KtNodeType LABEL = new KtNodeType("LABEL", KtLabelReferenceExpression.class);
KtNodeType LABEL_QUALIFIER = new KtNodeType("LABEL_QUALIFIER", KtContainerNode.class);
KtNodeType THIS_EXPRESSION = new KtNodeType("THIS_EXPRESSION", KtThisExpression.class);
KtNodeType SUPER_EXPRESSION = new KtNodeType("SUPER_EXPRESSION", KtSuperExpression.class);
KtNodeType BINARY_EXPRESSION = new KtNodeType("BINARY_EXPRESSION", KtBinaryExpression.class);
KtNodeType BINARY_WITH_TYPE = new KtNodeType("BINARY_WITH_TYPE", KtBinaryExpressionWithTypeRHS.class);
KtNodeType IS_EXPRESSION = new KtNodeType("IS_EXPRESSION", KtIsExpression.class); // TODO:
KtNodeType PREFIX_EXPRESSION = new KtNodeType("PREFIX_EXPRESSION", KtPrefixExpression.class);
KtNodeType POSTFIX_EXPRESSION = new KtNodeType("POSTFIX_EXPRESSION", KtPostfixExpression.class);
KtNodeType LABELED_EXPRESSION = new KtNodeType("LABELED_EXPRESSION", KtLabeledExpression.class);
KtNodeType CALL_EXPRESSION = new KtNodeType("CALL_EXPRESSION", KtCallExpression.class);
KtNodeType ARRAY_ACCESS_EXPRESSION = new KtNodeType("ARRAY_ACCESS_EXPRESSION", KtArrayAccessExpression.class);
KtNodeType INDICES = new KtNodeType("INDICES", KtContainerNode.class);
IElementType DOT_QUALIFIED_EXPRESSION = KtStubElementTypes.DOT_QUALIFIED_EXPRESSION;
KtNodeType CALLABLE_REFERENCE_EXPRESSION = new KtNodeType("CALLABLE_REFERENCE_EXPRESSION", KtCallableReferenceExpression.class);
KtNodeType CLASS_LITERAL_EXPRESSION = new KtNodeType("CLASS_LITERAL_EXPRESSION", KtClassLiteralExpression.class);
KtNodeType SAFE_ACCESS_EXPRESSION = new KtNodeType("SAFE_ACCESS_EXPRESSION", KtSafeQualifiedExpression.class);
KtNodeType OBJECT_LITERAL = new KtNodeType("OBJECT_LITERAL", KtObjectLiteralExpression.class);
KtNodeType WHEN = new KtNodeType("WHEN", KtWhenExpression.class);
KtNodeType WHEN_ENTRY = new KtNodeType("WHEN_ENTRY", KtWhenEntry.class);
KtNodeType WHEN_CONDITION_IN_RANGE = new KtNodeType("WHEN_CONDITION_IN_RANGE", KtWhenConditionInRange.class);
KtNodeType WHEN_CONDITION_IS_PATTERN = new KtNodeType("WHEN_CONDITION_IS_PATTERN", KtWhenConditionIsPattern.class);
KtNodeType WHEN_CONDITION_EXPRESSION = new KtNodeType("WHEN_CONDITION_WITH_EXPRESSION", KtWhenConditionWithExpression.class);
KtNodeType COLLECTION_LITERAL_EXPRESSION = new KtNodeType("COLLECTION_LITERAL_EXPRESSION", KtCollectionLiteralExpression.class);
IElementType PACKAGE_DIRECTIVE = KtStubElementTypes.PACKAGE_DIRECTIVE;
IElementType SCRIPT = KtStubElementTypes.SCRIPT;
IFileElementType TYPE_CODE_FRAGMENT = new KtTypeCodeFragmentType();
IFileElementType EXPRESSION_CODE_FRAGMENT = new KtExpressionCodeFragmentType();
IFileElementType BLOCK_CODE_FRAGMENT = new KtBlockCodeFragmentType();
}
@@ -1,173 +0,0 @@
/*
* Copyright 2010-2017 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;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiBuilderFactory;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IErrorCounterReparseableElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import org.jetbrains.kotlin.lexer.KotlinLexer;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.parsing.KotlinParser;
import org.jetbrains.kotlin.psi.KtFunctionLiteral;
import org.jetbrains.kotlin.psi.KtLambdaExpression;
import org.jetbrains.kotlin.psi.KtParameterList;
class LambdaExpressionElementType extends IErrorCounterReparseableElementType {
public LambdaExpressionElementType() {
super("LAMBDA_EXPRESSION", KotlinLanguage.INSTANCE);
}
@Override
public ASTNode parseContents(ASTNode chameleon) {
Project project = chameleon.getPsi().getProject();
PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(
project, chameleon, null, KotlinLanguage.INSTANCE, chameleon.getChars());
return KotlinParser.parseLambdaExpression(builder).getFirstChildNode();
}
@Override
public ASTNode createNode(CharSequence text) {
return new KtLambdaExpression(text);
}
@Override
public boolean isParsable(@Nullable ASTNode parent, CharSequence buffer, Language fileLanguage, Project project) {
return super.isParsable(parent, buffer, fileLanguage, project) &&
!wasArrowMovedOrDeleted(parent, buffer) && !wasParameterCommaMovedOrDeleted(parent, buffer);
}
private static boolean wasArrowMovedOrDeleted(@Nullable ASTNode parent, CharSequence buffer) {
KtLambdaExpression lambdaExpression = findLambdaExpression(parent);
if (lambdaExpression == null) {
return false;
}
KtFunctionLiteral literal = lambdaExpression.getFunctionLiteral();
PsiElement arrow = literal.getArrow();
// No arrow in original node
if (arrow == null) return false;
int arrowOffset = arrow.getStartOffsetInParent() + literal.getStartOffsetInParent();
return hasTokenMoved(lambdaExpression.getText(), buffer, arrowOffset, KtTokens.ARROW);
}
private static boolean wasParameterCommaMovedOrDeleted(@Nullable ASTNode parent, CharSequence buffer) {
KtLambdaExpression lambdaExpression = findLambdaExpression(parent);
if (lambdaExpression == null) {
return false;
}
KtFunctionLiteral literal = lambdaExpression.getFunctionLiteral();
KtParameterList valueParameterList = literal.getValueParameterList();
if (valueParameterList == null || valueParameterList.getParameters().size() <= 1) {
return false;
}
PsiElement comma = valueParameterList.getFirstComma();
if (comma == null) {
return false;
}
int commaOffset = comma.getTextOffset() - lambdaExpression.getTextOffset();
return hasTokenMoved(lambdaExpression.getText(), buffer, commaOffset, KtTokens.COMMA);
}
private static KtLambdaExpression findLambdaExpression(@Nullable ASTNode parent) {
if (parent == null) return null;
PsiElement parentPsi = parent.getPsi();
KtLambdaExpression[] lambdaExpressions = PsiTreeUtil.getChildrenOfType(parentPsi, KtLambdaExpression.class);
if (lambdaExpressions == null || lambdaExpressions.length != 1) return null;
// Now works only when actual node can be spotted ambiguously. Need change in API.
return lambdaExpressions[0];
}
private static boolean hasTokenMoved(String oldText, CharSequence buffer, int oldOffset, IElementType tokenType) {
Lexer oldLexer = new KotlinLexer();
oldLexer.start(oldText);
Lexer newLexer = new KotlinLexer();
newLexer.start(buffer);
while (true) {
IElementType oldType = oldLexer.getTokenType();
if (oldType == null) break; // Didn't find an expected token. Consider it as no token was present.
IElementType newType = newLexer.getTokenType();
if (newType == null) return true; // New text was finished before reaching expected token in old text
if (newType != oldType) {
if (newType == KtTokens.WHITE_SPACE) {
newLexer.advance();
continue;
}
else if (oldType == KtTokens.WHITE_SPACE) {
oldLexer.advance();
continue;
}
return true; // Expected token was moved or deleted
}
if (oldType == tokenType && oldLexer.getCurrentPosition().getOffset() == oldOffset) {
break;
}
oldLexer.advance();
newLexer.advance();
}
return false;
}
@Override
public int getErrorsCount(CharSequence seq, Language fileLanguage, Project project) {
Lexer lexer = new KotlinLexer();
lexer.start(seq);
if (lexer.getTokenType() != KtTokens.LBRACE) return IErrorCounterReparseableElementType.FATAL_ERROR;
lexer.advance();
int balance = 1;
while (true) {
IElementType type = lexer.getTokenType();
if (type == null) break;
if (balance == 0) {
return IErrorCounterReparseableElementType.FATAL_ERROR;
}
if (type == KtTokens.LBRACE) {
balance++;
}
else if (type == KtTokens.RBRACE) {
balance--;
}
lexer.advance();
}
return balance;
}
}
@@ -469,7 +469,7 @@ class ControlFlowInformationProvider private constructor(
report(Errors.CAPTURED_VAL_INITIALIZATION.on(expression, variableDescriptor), ctxt)
}
} else {
if (KtPsiUtil.isBackingFieldReference(variableDescriptor)) {
if (isBackingFieldReference(variableDescriptor)) {
reportValReassigned(expression, variableDescriptor, ctxt)
} else {
report(Errors.VAL_REASSIGNMENT.on(expression, variableDescriptor), ctxt)
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
import org.jetbrains.kotlin.psi.KtPropertyAccessor
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
@@ -23,3 +24,7 @@ fun PropertyAccessorDescriptor.hasBody(): Boolean {
val ktAccessor = DescriptorToSourceUtils.getSourceFromDescriptor(this) as? KtPropertyAccessor
return ktAccessor != null && ktAccessor.hasBody()
}
fun isBackingFieldReference(descriptor: DeclarationDescriptor?): Boolean {
return descriptor is SyntheticFieldDescriptor
}
@@ -21,8 +21,6 @@ import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public interface DiagnosticSink {
@@ -44,7 +42,8 @@ public interface DiagnosticSink {
PsiFile psiFile = diagnostic.getPsiFile();
List<TextRange> textRanges = diagnostic.getTextRanges();
String diagnosticText = DefaultErrorMessages.render(diagnostic);
throw new IllegalStateException(diagnostic.getFactory().getName() + ": " + diagnosticText + " " + DiagnosticUtils.atLocation(psiFile, textRanges.get(0)));
throw new IllegalStateException(diagnostic.getFactory().getName() + ": " + diagnosticText + " " + PsiDiagnosticUtils
.atLocation(psiFile, textRanges.get(0)));
}
}
@@ -21,14 +21,12 @@ import com.intellij.lang.ASTNode;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiInvalidElementAccessException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.psi.KtExpression;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics;
@@ -55,105 +53,35 @@ public class DiagnosticUtils {
element = DescriptorToSourceUtils.descriptorToDeclaration(descriptor.getOriginal());
}
if (element == null && descriptor instanceof ASTNode) {
element = getClosestPsiElement((ASTNode) descriptor);
element = PsiUtilsKt.closestPsiElement((ASTNode) descriptor);
}
if (element != null) {
return atLocation(element);
return PsiDiagnosticUtils.atLocation(element);
} else {
return "unknown location";
}
}
public static String atLocation(KtExpression expression) {
return atLocation(expression.getNode());
}
public static String atLocation(@NotNull PsiElement element) {
if (element.isValid()) {
return atLocation(element.getContainingFile(), element.getTextRange());
}
PsiFile file = null;
int offset = -1;
try {
file = element.getContainingFile();
offset = element.getTextOffset();
}
catch (PsiInvalidElementAccessException invalidException) {
// ignore
}
return "at offset: " + (offset != -1 ? offset : "<unknown>") + " file: " + (file != null ? file : "<unknown>");
}
public static String atLocation(@NotNull ASTNode node) {
int startOffset = node.getStartOffset();
PsiElement element = getClosestPsiElement(node);
if (element != null) {
return atLocation(element);
}
return "at offset " + startOffset + " (line and file unknown: no PSI element)";
}
@Nullable
public static PsiElement getClosestPsiElement(@NotNull ASTNode node) {
while (node.getPsi() == null) {
node = node.getTreeParent();
}
return node.getPsi();
}
@NotNull
public static PsiFile getContainingFile(@NotNull ASTNode node) {
PsiElement closestPsiElement = getClosestPsiElement(node);
PsiElement closestPsiElement = PsiUtilsKt.closestPsiElement(node);
assert closestPsiElement != null : "This node is not contained by a file";
return closestPsiElement.getContainingFile();
}
@NotNull
public static String atLocation(@NotNull PsiFile file, @NotNull TextRange textRange) {
Document document = file.getViewProvider().getDocument();
return atLocation(file, textRange, document);
}
@NotNull
public static String atLocation(PsiFile file, TextRange textRange, Document document) {
int offset = textRange.getStartOffset();
VirtualFile virtualFile = file.getVirtualFile();
String pathSuffix = " in " + (virtualFile == null ? file.getName() : virtualFile.getPath());
return offsetToLineAndColumn(document, offset).toString() + pathSuffix;
}
@NotNull
public static LineAndColumn getLineAndColumn(@NotNull Diagnostic diagnostic) {
public static PsiDiagnosticUtils.LineAndColumn getLineAndColumn(@NotNull Diagnostic diagnostic) {
PsiFile file = diagnostic.getPsiFile();
List<TextRange> textRanges = diagnostic.getTextRanges();
if (textRanges.isEmpty()) return LineAndColumn.NONE;
if (textRanges.isEmpty()) return PsiDiagnosticUtils.LineAndColumn.NONE;
TextRange firstRange = firstRange(textRanges);
return getLineAndColumnInPsiFile(file, firstRange);
}
@NotNull
public static LineAndColumn getLineAndColumnInPsiFile(PsiFile file, TextRange range) {
public static PsiDiagnosticUtils.LineAndColumn getLineAndColumnInPsiFile(PsiFile file, TextRange range) {
Document document = file.getViewProvider().getDocument();
return offsetToLineAndColumn(document, range.getStartOffset());
}
@NotNull
public static LineAndColumn offsetToLineAndColumn(@Nullable Document document, int offset) {
if (document == null) {
return new LineAndColumn(-1, offset, null);
}
int lineNumber = document.getLineNumber(offset);
int lineStartOffset = document.getLineStartOffset(lineNumber);
int column = offset - lineStartOffset;
int lineEndOffset = document.getLineEndOffset(lineNumber);
CharSequence lineContent = document.getCharsSequence().subSequence(lineStartOffset, lineEndOffset);
return new LineAndColumn(lineNumber + 1, column + 1, lineContent.toString());
return PsiDiagnosticUtils.offsetToLineAndColumn(document, range.getStartOffset());
}
public static void throwIfRunningOnServer(Throwable e) {
@@ -194,43 +122,6 @@ public class DiagnosticUtils {
return result;
}
public static final class LineAndColumn {
public static final LineAndColumn NONE = new LineAndColumn(-1, -1, null);
private final int line;
private final int column;
private final String lineContent;
public LineAndColumn(int line, int column, @Nullable String lineContent) {
this.line = line;
this.column = column;
this.lineContent = lineContent;
}
public int getLine() {
return line;
}
public int getColumn() {
return column;
}
@Nullable
public String getLineContent() {
return lineContent;
}
// NOTE: This method is used for presenting positions to the user
@Override
public String toString() {
if (line < 0) {
return "(offset: " + column + " line unknown)";
}
return "(" + line + "," + column + ")";
}
}
public static boolean hasError(Diagnostics diagnostics) {
for (Diagnostic diagnostic : diagnostics.all()) {
if (diagnostic.getSeverity() == Severity.ERROR) return true;
@@ -1,69 +0,0 @@
/*
* 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.idea;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.NotNullLazyValue;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class KotlinFileType extends LanguageFileType {
public static final String EXTENSION = "kt";
public static final KotlinFileType INSTANCE = new KotlinFileType();
private final NotNullLazyValue<Icon> myIcon = new NotNullLazyValue<Icon>() {
@NotNull
@Override
protected Icon compute() {
return IconLoader.getIcon("/org/jetbrains/kotlin/idea/icons/kotlin_file.png");
}
};
private KotlinFileType() {
super(KotlinLanguage.INSTANCE);
}
@Override
@NotNull
public String getName() {
return KotlinLanguage.NAME;
}
@Override
@NotNull
public String getDescription() {
return getName();
}
@Override
@NotNull
public String getDefaultExtension() {
return EXTENSION;
}
@Override
public Icon getIcon() {
return myIcon.getValue();
}
@Override
public boolean isJVMDebuggingSupported() {
return true;
}
}
@@ -1,40 +0,0 @@
/*
* 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.idea;
import com.intellij.lang.Language;
import org.jetbrains.annotations.NotNull;
public class KotlinLanguage extends Language {
public static final KotlinLanguage INSTANCE = new KotlinLanguage();
public static final String NAME = "Kotlin";
private KotlinLanguage() {
super("kotlin");
}
@NotNull
@Override
public String getDisplayName() {
return NAME;
}
@Override
public boolean isCaseSensitive() {
return true;
}
}
@@ -1,81 +0,0 @@
/*
* 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.idea;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class KotlinModuleFileType implements FileType {
public static final String EXTENSION = "kotlin_module";
public static final KotlinModuleFileType INSTANCE = new KotlinModuleFileType();
private final NotNullLazyValue<Icon> myIcon = new NotNullLazyValue<Icon>() {
@NotNull
@Override
protected Icon compute() {
return IconLoader.getIcon("/org/jetbrains/kotlin/idea/icons/kotlin_file.png");
}
};
private KotlinModuleFileType() {}
@Override
@NotNull
public String getName() {
return EXTENSION;
}
@Override
@NotNull
public String getDescription() {
return "Kotlin module info: contains package part mappings";
}
@Override
@NotNull
public String getDefaultExtension() {
return EXTENSION;
}
@Override
public Icon getIcon() {
return myIcon.getValue();
}
@Override
public boolean isBinary() {
return true;
}
@Override
public boolean isReadOnly() {
return true;
}
@Nullable
@Override
public String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) {
return null;
}
}
@@ -1,213 +0,0 @@
package org.jetbrains.kotlin.kdoc.lexer;
import com.intellij.lexer.FlexLexer;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.text.CharArrayUtil;
import java.lang.Character;
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag;
%%
%unicode
%class _KDocLexer
%implements FlexLexer
%{
public _KDocLexer() {
this((java.io.Reader)null);
}
private boolean isLastToken() {
return zzMarkedPos == zzBuffer.length();
}
private boolean yytextContainLineBreaks() {
return CharArrayUtil.containLineBreaks(zzBuffer, zzStartRead, zzMarkedPos);
}
private boolean nextIsNotWhitespace() {
return zzMarkedPos <= zzBuffer.length() && !Character.isWhitespace(zzBuffer.charAt(zzMarkedPos + 1));
}
private boolean prevIsNotWhitespace() {
return zzMarkedPos != 0 && !Character.isWhitespace(zzBuffer.charAt(zzMarkedPos - 1));
}
%}
%function advance
%type IElementType
%eof{
return;
%eof}
%state LINE_BEGINNING
%state CONTENTS_BEGINNING
%state TAG_BEGINNING
%state TAG_TEXT_BEGINNING
%state CONTENTS
%state CODE_BLOCK
%state CODE_BLOCK_LINE_BEGINNING
%state CODE_BLOCK_CONTENTS_BEGINNING
%state INDENTED_CODE_BLOCK
WHITE_SPACE_CHAR =[\ \t\f\n]
NOT_WHITE_SPACE_CHAR=[^\ \t\f\n]
DIGIT=[0-9]
ALPHA=[:jletter:]
TAG_NAME={ALPHA}({ALPHA}|{DIGIT})*
IDENTIFIER={ALPHA}({ALPHA}|{DIGIT}|".")*
QUALIFIED_NAME_START={ALPHA}
QUALIFIED_NAME_CHAR={ALPHA}|{DIGIT}|[\.]
QUALIFIED_NAME={QUALIFIED_NAME_START}{QUALIFIED_NAME_CHAR}*
CODE_LINK=\[{QUALIFIED_NAME}\]
CODE_FENCE_START=("```" | "~~~").*
CODE_FENCE_END=("```" | "~~~")
%%
<YYINITIAL> "/**" { yybegin(CONTENTS_BEGINNING);
return KDocTokens.START; }
"*"+ "/" { if (isLastToken()) return KDocTokens.END;
else return KDocTokens.TEXT; }
<LINE_BEGINNING> "*"+ { yybegin(CONTENTS_BEGINNING);
return KDocTokens.LEADING_ASTERISK; }
<CONTENTS_BEGINNING> "@"{TAG_NAME} {
KDocKnownTag tag = KDocKnownTag.Companion.findByTagName(zzBuffer.subSequence(zzStartRead, zzMarkedPos));
yybegin(tag != null && tag.isReferenceRequired() ? TAG_BEGINNING : TAG_TEXT_BEGINNING);
return KDocTokens.TAG_NAME;
}
<TAG_BEGINNING> {
{WHITE_SPACE_CHAR}+ {
if (yytextContainLineBreaks()) {
yybegin(LINE_BEGINNING);
}
return TokenType.WHITE_SPACE;
}
/* Example: @return[x] The return value of function x
^^^
*/
{CODE_LINK} { yybegin(TAG_TEXT_BEGINNING);
return KDocTokens.MARKDOWN_LINK; }
/* Example: @param aaa The value of aaa
^^^
*/
{QUALIFIED_NAME} {
yybegin(TAG_TEXT_BEGINNING);
return KDocTokens.MARKDOWN_LINK;
}
. {
yybegin(CONTENTS);
return KDocTokens.TEXT;
}
}
<TAG_TEXT_BEGINNING> {
{WHITE_SPACE_CHAR}+ {
if (yytextContainLineBreaks()) {
yybegin(LINE_BEGINNING);
}
return TokenType.WHITE_SPACE;
}
/* Example: @return[x] The return value of function x
^^^
*/
{CODE_LINK} { yybegin(CONTENTS);
return KDocTokens.MARKDOWN_LINK; }
. {
yybegin(CONTENTS);
return KDocTokens.TEXT;
}
}
<LINE_BEGINNING, CONTENTS_BEGINNING, CONTENTS> {
([\ ]{4}[\ ]*)|([\t]+) {
if(yystate() == CONTENTS_BEGINNING) {
yybegin(INDENTED_CODE_BLOCK);
return KDocTokens.CODE_BLOCK_TEXT;
}
}
{WHITE_SPACE_CHAR}+ {
if (yytextContainLineBreaks()) {
yybegin(LINE_BEGINNING);
return TokenType.WHITE_SPACE;
} else {
yybegin(yystate() == CONTENTS_BEGINNING ? CONTENTS_BEGINNING : CONTENTS);
return KDocTokens.TEXT; // internal white space
}
}
"\\"[\[\]] {
yybegin(CONTENTS);
return KDocTokens.MARKDOWN_ESCAPED_CHAR;
}
"[" [^\[]* "](" [^)]* ")" {
yybegin(CONTENTS);
return KDocTokens.MARKDOWN_INLINE_LINK;
}
{CODE_FENCE_START} {
yybegin(CODE_BLOCK_LINE_BEGINNING);
return KDocTokens.TEXT;
}
/* We're only interested in parsing links that can become code references,
meaning they contain only identifier characters and characters that can be
used in type declarations. No brackets, backticks, asterisks or anything like that.
Also if a link is followed by [ or (, then its destination is a regular HTTP
link and not a Kotlin identifier, so we don't need to do our parsing and resolution. */
{CODE_LINK} / [^\(\[] {
yybegin(CONTENTS);
return KDocTokens.MARKDOWN_LINK;
}
. {
yybegin(CONTENTS);
return KDocTokens.TEXT;
}
}
<CODE_BLOCK_LINE_BEGINNING> {
"*"+ {
yybegin(CODE_BLOCK_CONTENTS_BEGINNING);
return KDocTokens.LEADING_ASTERISK;
}
}
<CODE_BLOCK_LINE_BEGINNING, CODE_BLOCK_CONTENTS_BEGINNING> {
{CODE_FENCE_END} / [ \t\f]* [\n] [ \t\f]* {
// Code fence end
yybegin(CONTENTS);
return KDocTokens.TEXT;
}
}
<INDENTED_CODE_BLOCK, CODE_BLOCK_LINE_BEGINNING, CODE_BLOCK_CONTENTS_BEGINNING, CODE_BLOCK> {
{WHITE_SPACE_CHAR}+ {
if (yytextContainLineBreaks()) {
yybegin(yystate() == INDENTED_CODE_BLOCK ? LINE_BEGINNING : CODE_BLOCK_LINE_BEGINNING);
return TokenType.WHITE_SPACE;
}
return KDocTokens.CODE_BLOCK_TEXT;
}
. {
yybegin(yystate() == INDENTED_CODE_BLOCK ? INDENTED_CODE_BLOCK : CODE_BLOCK);
return KDocTokens.CODE_BLOCK_TEXT;
}
}
. { return TokenType.BAD_CHARACTER; }
@@ -1,34 +0,0 @@
/*
* 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.lexer;
import com.intellij.lexer.FlexAdapter;
import com.intellij.lexer.MergingLexerAdapter;
import com.intellij.psi.tree.TokenSet;
import java.io.Reader;
public class KDocLexer extends MergingLexerAdapter {
public KDocLexer() {
super(
new FlexAdapter(
new _KDocLexer((Reader) null)
),
TokenSet.create(KDocTokens.TEXT, KDocTokens.CODE_BLOCK_TEXT)
);
}
}
@@ -1,27 +0,0 @@
/*
* 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.lexer;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.lexer.KtToken;
public class KDocToken extends KtToken {
public KDocToken(@NotNull @NonNls String debugName) {
super(debugName);
}
}
@@ -1,73 +0,0 @@
/*
* 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.lexer;
import com.intellij.lang.ASTNode;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiBuilderFactory;
import com.intellij.lang.PsiParser;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.ILazyParseableElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import org.jetbrains.kotlin.kdoc.parser.KDocLinkParser;
import org.jetbrains.kotlin.kdoc.parser.KDocParser;
import org.jetbrains.kotlin.kdoc.psi.impl.KDocImpl;
public interface KDocTokens {
ILazyParseableElementType KDOC = new ILazyParseableElementType("KDoc", KotlinLanguage.INSTANCE) {
@Override
public ASTNode parseContents(ASTNode chameleon) {
PsiElement parentElement = chameleon.getTreeParent().getPsi();
Project project = parentElement.getProject();
PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, new KDocLexer(), getLanguage(),
chameleon.getText());
PsiParser parser = new KDocParser();
return parser.parse(this, builder).getFirstChildNode();
}
@Nullable
@Override
public ASTNode createNode(CharSequence text) {
return new KDocImpl(text);
}
};
KDocToken START = new KDocToken("KDOC_START");
KDocToken END = new KDocToken("KDOC_END");
KDocToken LEADING_ASTERISK = new KDocToken("KDOC_LEADING_ASTERISK");
KDocToken TEXT = new KDocToken("KDOC_TEXT");
KDocToken CODE_BLOCK_TEXT = new KDocToken("KDOC_CODE_BLOCK_TEXT");
KDocToken TAG_NAME = new KDocToken("KDOC_TAG_NAME");
ILazyParseableElementType MARKDOWN_LINK = new ILazyParseableElementType("KDOC_MARKDOWN_LINK", KotlinLanguage.INSTANCE) {
@Override
public ASTNode parseContents(ASTNode chameleon) {
return KDocLinkParser.parseMarkdownLink(this, chameleon);
}
};
KDocToken MARKDOWN_ESCAPED_CHAR = new KDocToken("KDOC_MARKDOWN_ESCAPED_CHAR");
KDocToken MARKDOWN_INLINE_LINK = new KDocToken("KDOC_MARKDOWN_INLINE_LINK");
TokenSet KDOC_HIGHLIGHT_TOKENS = TokenSet.create(START, END, LEADING_ASTERISK, TEXT, CODE_BLOCK_TEXT, MARKDOWN_LINK, MARKDOWN_ESCAPED_CHAR, MARKDOWN_INLINE_LINK);
TokenSet CONTENT_TOKENS = TokenSet.create(TEXT, CODE_BLOCK_TEXT, TAG_NAME, MARKDOWN_LINK, MARKDOWN_ESCAPED_CHAR, MARKDOWN_INLINE_LINK);
}
@@ -1,738 +0,0 @@
/* The following code was generated by JFlex 1.7.0-SNAPSHOT tweaked for IntelliJ platform */
package org.jetbrains.kotlin.kdoc.lexer;
import com.intellij.lexer.FlexLexer;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.text.CharArrayUtil;
import java.lang.Character;
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag;
/**
* This class is a scanner generated by
* <a href="http://www.jflex.de/">JFlex</a> 1.7.0-SNAPSHOT
* from the specification file <tt>/home/user/Workspace/Kotlin/kotlin/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex</tt>
*/
class _KDocLexer implements FlexLexer {
/** This character denotes the end of file */
public static final int YYEOF = -1;
/** initial size of the lookahead buffer */
private static final int ZZ_BUFFERSIZE = 16384;
/** lexical states */
public static final int YYINITIAL = 0;
public static final int LINE_BEGINNING = 2;
public static final int CONTENTS_BEGINNING = 4;
public static final int TAG_BEGINNING = 6;
public static final int TAG_TEXT_BEGINNING = 8;
public static final int CONTENTS = 10;
public static final int CODE_BLOCK = 12;
public static final int CODE_BLOCK_LINE_BEGINNING = 14;
public static final int CODE_BLOCK_CONTENTS_BEGINNING = 16;
public static final int INDENTED_CODE_BLOCK = 18;
/**
* ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
* ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l
* at the beginning of a line
* l is of the form l = 2*k, k a non negative integer
*/
private static final int ZZ_LEXSTATE[] = {
0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
8, 8, 6, 6
};
/**
* Translates characters to character classes
* Chosen bits are [11, 6, 4]
* Total runtime size is 9472 bytes
*/
public static int ZZ_CMAP(int ch) {
return ZZ_CMAP_A[(ZZ_CMAP_Y[(ZZ_CMAP_Z[ch>>10]<<6)|((ch>>4)&0x3f)]<<4)|(ch&0xf)];
}
/* The ZZ_CMAP_Z table has 1088 entries */
static final char ZZ_CMAP_Z[] = zzUnpackCMap(
"\1\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\3\11\1\12\6\13\1\14\23\13\1\15\1\13"+
"\1\16\1\11\12\13\1\17\10\11\1\20\1\21\1\22\1\23\1\24\62\11\1\25\12\11\51\13"+
"\1\26\24\11\1\27\u0381\11");
/* The ZZ_CMAP_Y table has 1536 entries */
static final char ZZ_CMAP_Y[] = zzUnpackCMap(
"\1\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\1\1\11\1\12\1\13\1\14\1\13\1\14\23"+
"\13\1\15\1\1\7\13\1\16\1\17\1\20\10\1\1\21\1\22\1\13\1\23\1\13\1\24\2\13\1"+
"\25\10\13\1\26\3\13\1\24\2\13\1\27\1\13\2\1\1\30\1\13\1\31\1\30\1\13\1\32"+
"\4\1\1\13\1\33\1\34\2\1\1\30\2\33\1\1\1\35\1\30\5\13\1\36\1\37\1\40\1\1\1"+
"\41\1\13\1\1\1\42\3\1\2\13\1\43\1\44\24\1\1\45\2\13\1\46\1\1\1\47\1\17\1\1"+
"\1\50\1\51\1\52\1\53\1\1\1\54\1\17\1\55\1\56\1\51\1\52\1\57\1\1\1\60\1\1\1"+
"\61\1\62\1\23\1\52\1\63\1\1\1\64\1\17\1\44\1\50\1\51\1\52\1\63\1\1\1\54\1"+
"\17\1\44\1\65\1\66\1\67\1\70\3\1\1\71\1\72\1\41\1\52\1\73\2\1\1\17\1\1\1\72"+
"\1\41\1\52\1\74\1\1\1\75\1\17\1\1\1\72\1\41\1\52\1\76\2\1\1\17\1\1\1\77\1"+
"\100\1\13\1\101\1\15\3\1\1\30\2\13\1\102\1\15\3\1\1\103\1\104\1\105\1\106"+
"\1\107\1\110\2\1\1\64\3\1\1\111\1\13\1\33\1\1\1\112\7\1\2\13\1\113\2\1\1\43"+
"\4\1\2\13\1\43\2\13\1\114\5\13\1\115\4\13\1\116\4\13\1\76\1\14\3\13\2\117"+
"\2\13\1\117\1\13\1\24\2\120\1\14\1\24\1\13\1\24\1\120\2\13\1\14\1\33\4\1\5"+
"\13\1\121\1\30\45\13\1\122\1\15\1\30\1\33\4\13\1\123\1\64\1\124\1\17\1\13"+
"\1\17\1\13\1\17\1\124\1\64\3\13\1\55\1\1\1\125\4\1\5\13\1\32\2\13\1\114\5"+
"\1\1\13\1\126\3\1\1\13\1\127\1\121\70\1\6\13\1\130\11\1\11\13\1\130\5\13\1"+
"\76\1\13\1\131\2\13\1\131\1\132\1\13\1\127\3\13\1\133\1\134\1\135\1\126\1"+
"\134\2\1\1\136\1\137\1\64\1\140\1\1\1\141\2\1\1\13\1\17\4\1\1\142\1\143\1"+
"\144\1\145\1\146\1\1\2\13\1\55\147\1\1\147\1\1\1\150\1\151\1\30\4\13\1\152"+
"\1\30\5\13\1\77\1\13\1\126\1\30\4\13\1\24\1\1\1\13\1\32\3\1\1\13\40\1\133"+
"\13\1\43\4\1\132\13\1\43\5\1\10\13\1\126\67\1\72\13\1\55\25\1\22\13\1\127"+
"\3\13\1\33\11\1\1\15\1\153\1\52\1\154\1\155\6\13\1\17\1\1\1\156\25\13\1\127"+
"\1\1\4\13\1\157\2\13\1\32\2\1\1\126\3\1\1\160\1\42\1\1\1\71\1\161\7\13\1\126"+
"\1\140\1\1\1\30\1\162\1\30\1\33\1\77\4\13\1\24\1\163\1\164\1\165\1\1\1\166"+
"\1\13\1\14\1\167\2\127\2\1\7\13\1\33\40\1\1\13\1\24\1\1\1\13\1\33\3\1\1\13"+
"\1\127\6\1\11\13\1\127\66\1\1\170\2\13\1\171\74\1\5\13\1\161\3\13\1\124\1"+
"\172\1\173\1\174\3\13\1\175\1\176\1\13\1\177\1\200\1\41\24\13\1\201\1\13\1"+
"\41\1\202\1\13\1\202\1\13\1\161\1\13\1\161\1\24\1\13\1\24\1\13\1\52\1\13\1"+
"\52\1\13\1\203\3\1\55\13\1\15\22\1\41\13\1\127\36\1");
/* The ZZ_CMAP_A table has 2112 entries */
static final char ZZ_CMAP_A[] = zzUnpackCMap(
"\11\0\1\1\1\11\1\12\1\13\1\12\22\0\1\17\3\0\1\3\3\0\1\21\1\22\1\15\3\0\1\4"+
"\1\14\12\2\6\0\1\16\32\3\1\5\1\20\1\6\1\0\1\3\1\7\32\3\3\0\1\10\6\0\1\12\14"+
"\0\4\3\4\0\1\3\12\0\1\3\4\0\1\3\5\0\27\3\1\0\17\3\11\0\2\3\4\0\14\3\16\0\5"+
"\3\11\0\1\3\13\0\1\3\13\0\1\3\1\0\3\3\1\0\1\3\1\0\4\3\1\0\34\3\1\0\6\3\1\0"+
"\5\3\4\0\2\3\10\0\14\3\2\0\2\3\7\0\26\3\2\0\1\3\6\0\10\3\10\0\13\3\5\0\3\3"+
"\33\0\6\3\1\0\1\3\17\0\2\3\7\0\2\3\12\0\3\3\2\0\2\3\1\0\16\3\15\0\11\3\13"+
"\0\1\3\22\0\26\3\3\0\1\3\2\0\1\3\7\0\10\3\5\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\16\0\2\3\1\0\5\3\21\0\6\3\4\0\2\3\1\0\2\3\1\0\2"+
"\3\1\0\2\3\17\0\4\3\1\0\1\3\3\0\3\3\20\0\11\3\1\0\2\3\1\0\2\3\1\0\5\3\3\0"+
"\1\3\2\0\1\3\22\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\17\0\1\3\13\0\10\3\1\0\6\3\1\0\5\3\6\0\4\3\1"+
"\0\5\3\3\0\1\3\20\0\1\3\1\0\12\3\13\0\22\3\3\0\10\3\1\0\11\3\1\0\1\3\2\0\1"+
"\3\1\0\2\3\13\0\1\3\1\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\2\0\10\3\1\0\7\3\10\0\4\3\4\0\2\3\1\0\5\3\1\0\2\3\5\0\11\3\7\0"+
"\12\3\5\0\4\3\5\0\17\3\1\0\1\3\1\0\4\3\2\0\1\3\1\0\4\3\2\0\7\3\1\0\5\3\13"+
"\0\15\3\2\0\14\3\3\0\17\3\1\0\2\3\7\0\1\3\3\0\2\3\3\0\15\3\3\0\16\3\2\0\14"+
"\3\4\0\6\3\2\0\6\3\2\0\10\3\1\0\1\3\1\0\1\3\1\0\1\3\1\0\6\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\14\0\2\12\25\0\1\3\4\0\1\3\14\0\1\3\15"+
"\0\1\3\2\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\13\0\3\3\11\0\11\3\7\0\5\3\2\0\5\3"+
"\3\0\7\3\6\0\3\3\3\0\5\3\5\0\1\3\1\0\10\3\1\0\5\3\1\0\1\3\1\0\2\3\1\0\2\3"+
"\1\0\12\3\3\0\15\3\2\0\16\3\3\0\2\3\13\0\5\3\1\0\25\3\4\0\1\3\2\0\6\3\2\0"+
"\6\3\2\0\6\3\2\0\3\3\3\0\2\3\3\0\2\3\11\0\14\3\1\0\16\3\1\0\2\3\1\0\7\3\2"+
"\0\1\3\1\0\14\3\1\0\2\3\3\0\1\3\2\0\1\3\2\0\1\3\2\0\2\3\2\0\4\3\1\0\14\3\1"+
"\0\1\3\1\0\7\3\1\0\21\3\1\0\4\3\2\0\10\3\1\0\7\3\1\0\14\3\1\0\4\3\1\0\5\3"+
"\1\0\1\3\3\0\12\3\4\0\23\3\1\0\7\3\1\0\6\3\6\0");
/**
* Translates DFA states to action switch labels.
*/
private static final int [] ZZ_ACTION = zzUnpackAction();
private static final String ZZ_ACTION_PACKED_0 =
"\11\0\3\1\1\2\1\3\3\2\1\4\1\5\1\4"+
"\3\2\1\6\1\7\2\2\1\10\1\11\3\10\1\12"+
"\1\0\1\13\6\0\1\4\1\14\1\15\4\0\1\16"+
"\2\0\1\17\1\4\1\20\1\21\1\0\2\22\1\0"+
"\1\23\1\3\1\24\1\23";
private static int [] zzUnpackAction() {
int [] result = new int[63];
int offset = 0;
offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
return result;
}
private static int zzUnpackAction(String packed, int offset, int [] result) {
int i = 0; /* index in packed string */
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
int count = packed.charAt(i++);
int value = packed.charAt(i++);
do result[j++] = value; while (--count > 0);
}
return j;
}
/**
* Translates a state to a row index in the transition table
*/
private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
private static final String ZZ_ROWMAP_PACKED_0 =
"\0\0\0\23\0\46\0\71\0\114\0\137\0\162\0\205"+
"\0\230\0\253\0\276\0\321\0\253\0\344\0\367\0\u010a"+
"\0\u011d\0\u0130\0\u0143\0\u0156\0\u0169\0\321\0\u017c\0\u018f"+
"\0\u01a2\0\u01b5\0\u01c8\0\253\0\u01db\0\321\0\u01ee\0\u0201"+
"\0\u0214\0\u0227\0\253\0\321\0\u023a\0\u024d\0\u0260\0\u0273"+
"\0\u0286\0\u0299\0\253\0\u02ac\0\u02bf\0\u02d2\0\u02e5\0\u02f8"+
"\0\253\0\u030b\0\u031e\0\u0331\0\u0344\0\253\0\253\0\u0357"+
"\0\u023a\0\u0260\0\u036a\0\u023a\0\u0344\0\u037d\0\253";
private static int [] zzUnpackRowMap() {
int [] result = new int[63];
int offset = 0;
offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
return result;
}
private static int zzUnpackRowMap(String packed, int offset, int [] result) {
int i = 0; /* index in packed string */
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
int high = packed.charAt(i++) << 16;
result[j++] = high | packed.charAt(i++);
}
return j;
}
/**
* The transition table of the DFA
*/
private static final int [] ZZ_TRANS = zzUnpackTrans();
private static final String ZZ_TRANS_PACKED_0 =
"\11\12\3\0\1\13\1\14\5\12\1\15\1\16\3\15"+
"\1\17\1\15\1\20\1\21\1\22\1\0\1\22\1\15"+
"\1\23\1\15\1\24\1\25\3\15\1\16\3\15\1\17"+
"\1\15\1\20\1\21\1\22\1\0\1\22\1\15\1\26"+
"\1\27\1\24\1\25\3\15\1\30\1\15\1\31\1\15"+
"\1\32\3\15\1\30\1\0\1\30\1\15\1\26\1\15"+
"\1\30\4\15\1\30\3\15\1\33\3\15\1\30\1\0"+
"\1\30\1\15\1\26\1\15\1\30\4\15\1\16\3\15"+
"\1\17\1\15\1\20\1\21\1\22\1\0\1\22\1\15"+
"\1\26\1\15\1\24\1\25\2\15\1\34\1\35\7\34"+
"\1\35\1\0\1\35\1\34\1\36\1\34\1\35\4\34"+
"\1\35\5\34\1\37\1\40\1\35\1\0\1\35\1\34"+
"\1\41\1\34\1\35\4\34\1\35\5\34\1\37\1\40"+
"\1\35\1\0\1\35\1\34\1\36\1\34\1\35\3\34"+
"\40\0\1\42\21\0\1\43\1\44\6\0\1\16\7\0"+
"\1\22\1\0\1\22\3\0\1\22\3\0\3\45\1\46"+
"\1\45\1\0\1\47\14\45\7\0\1\50\23\0\1\51"+
"\13\0\1\22\7\0\1\22\1\0\1\22\3\0\1\22"+
"\17\0\1\43\1\23\6\0\1\22\7\0\1\22\1\0"+
"\1\22\3\0\1\52\10\0\2\53\17\0\1\54\20\0"+
"\1\30\7\0\1\30\1\0\1\30\3\0\1\30\5\0"+
"\3\31\21\0\1\55\22\0\1\56\20\0\1\35\7\0"+
"\1\35\1\0\1\35\3\0\1\35\12\0\1\57\23\0"+
"\1\60\26\0\1\43\1\41\22\0\1\61\5\0\5\45"+
"\1\0\1\47\16\45\3\46\1\0\1\62\21\45\1\0"+
"\1\47\12\45\1\63\1\45\7\0\1\64\23\0\1\64"+
"\13\0\1\22\7\0\1\22\1\0\1\22\3\0\1\65"+
"\5\0\2\54\21\0\3\55\1\0\1\66\16\0\3\56"+
"\1\0\1\67\23\0\1\70\23\0\1\70\12\0\5\71"+
"\1\0\1\72\12\71\1\63\1\71\5\63\1\73\14\63"+
"\1\74\11\64\3\0\7\64\1\0\1\22\7\0\1\22"+
"\1\0\1\22\3\0\1\75\4\0\1\70\7\0\1\76"+
"\1\0\1\70\3\0\1\70\3\0\22\73\1\77\1\0"+
"\1\76\11\0\1\76\3\0\1\76\3\0";
private static int [] zzUnpackTrans() {
int [] result = new int[912];
int offset = 0;
offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
return result;
}
private static int zzUnpackTrans(String packed, int offset, int [] result) {
int i = 0; /* index in packed string */
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
int count = packed.charAt(i++);
int value = packed.charAt(i++);
value--;
do result[j++] = value; while (--count > 0);
}
return j;
}
/* error codes */
private static final int ZZ_UNKNOWN_ERROR = 0;
private static final int ZZ_NO_MATCH = 1;
private static final int ZZ_PUSHBACK_2BIG = 2;
/* error messages for the codes above */
private static final String[] ZZ_ERROR_MSG = {
"Unknown internal scanner error",
"Error: could not match input",
"Error: pushback value was too large"
};
/**
* ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
*/
private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
private static final String ZZ_ATTRIBUTE_PACKED_0 =
"\11\0\1\11\2\1\1\11\16\1\1\11\5\1\1\0"+
"\1\11\6\0\1\1\1\11\1\1\4\0\1\11\2\0"+
"\2\1\2\11\1\0\2\1\1\0\3\1\1\11";
private static int [] zzUnpackAttribute() {
int [] result = new int[63];
int offset = 0;
offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
return result;
}
private static int zzUnpackAttribute(String packed, int offset, int [] result) {
int i = 0; /* index in packed string */
int j = offset; /* index in unpacked array */
int l = packed.length();
while (i < l) {
int count = packed.charAt(i++);
int value = packed.charAt(i++);
do result[j++] = value; while (--count > 0);
}
return j;
}
/** the input device */
private java.io.Reader zzReader;
/** the current state of the DFA */
private int zzState;
/** the current lexical state */
private int zzLexicalState = YYINITIAL;
/** this buffer contains the current text to be matched and is
the source of the yytext() string */
private CharSequence zzBuffer = "";
/** the textposition at the last accepting state */
private int zzMarkedPos;
/** the current text position in the buffer */
private int zzCurrentPos;
/** startRead marks the beginning of the yytext() string in the buffer */
private int zzStartRead;
/** endRead marks the last character in the buffer, that has been read
from input */
private int zzEndRead;
/**
* zzAtBOL == true <=> the scanner is currently at the beginning of a line
*/
private boolean zzAtBOL = true;
/** zzAtEOF == true <=> the scanner is at the EOF */
private boolean zzAtEOF;
/** denotes if the user-EOF-code has already been executed */
private boolean zzEOFDone;
/* user code: */
public _KDocLexer() {
this((java.io.Reader)null);
}
private boolean isLastToken() {
return zzMarkedPos == zzBuffer.length();
}
private boolean yytextContainLineBreaks() {
return CharArrayUtil.containLineBreaks(zzBuffer, zzStartRead, zzMarkedPos);
}
private boolean nextIsNotWhitespace() {
return zzMarkedPos <= zzBuffer.length() && !Character.isWhitespace(zzBuffer.charAt(zzMarkedPos + 1));
}
private boolean prevIsNotWhitespace() {
return zzMarkedPos != 0 && !Character.isWhitespace(zzBuffer.charAt(zzMarkedPos - 1));
}
/**
* Creates a new scanner
*
* @param in the java.io.Reader to read input from.
*/
_KDocLexer(java.io.Reader in) {
this.zzReader = in;
}
/**
* Unpacks the compressed character translation table.
*
* @param packed the packed character translation table
* @return the unpacked character translation table
*/
private static char [] zzUnpackCMap(String packed) {
int size = 0;
for (int i = 0, length = packed.length(); i < length; i += 2) {
size += packed.charAt(i);
}
char[] map = new char[size];
int i = 0; /* index in packed string */
int j = 0; /* index in unpacked array */
while (i < packed.length()) {
int count = packed.charAt(i++);
char value = packed.charAt(i++);
do map[j++] = value; while (--count > 0);
}
return map;
}
public final int getTokenStart() {
return zzStartRead;
}
public final int getTokenEnd() {
return getTokenStart() + yylength();
}
public void reset(CharSequence buffer, int start, int end, int initialState) {
zzBuffer = buffer;
zzCurrentPos = zzMarkedPos = zzStartRead = start;
zzAtEOF = false;
zzAtBOL = true;
zzEndRead = end;
yybegin(initialState);
}
/**
* Refills the input buffer.
*
* @return <code>false</code>, iff there was new input.
*
* @exception java.io.IOException if any I/O-Error occurs
*/
private boolean zzRefill() throws java.io.IOException {
return true;
}
/**
* Returns the current lexical state.
*/
public final int yystate() {
return zzLexicalState;
}
/**
* Enters a new lexical state
*
* @param newState the new lexical state
*/
public final void yybegin(int newState) {
zzLexicalState = newState;
}
/**
* Returns the text matched by the current regular expression.
*/
public final CharSequence yytext() {
return zzBuffer.subSequence(zzStartRead, zzMarkedPos);
}
/**
* Returns the character at position <tt>pos</tt> from the
* matched text.
*
* It is equivalent to yytext().charAt(pos), but faster
*
* @param pos the position of the character to fetch.
* A value from 0 to yylength()-1.
*
* @return the character at position pos
*/
public final char yycharat(int pos) {
return zzBuffer.charAt(zzStartRead+pos);
}
/**
* Returns the length of the matched text region.
*/
public final int yylength() {
return zzMarkedPos-zzStartRead;
}
/**
* Reports an error that occured while scanning.
*
* In a wellformed scanner (no or only correct usage of
* yypushback(int) and a match-all fallback rule) this method
* will only be called with things that "Can't Possibly Happen".
* If this method is called, something is seriously wrong
* (e.g. a JFlex bug producing a faulty scanner etc.).
*
* Usual syntax/scanner level error handling should be done
* in error fallback rules.
*
* @param errorCode the code of the errormessage to display
*/
private void zzScanError(int errorCode) {
String message;
try {
message = ZZ_ERROR_MSG[errorCode];
}
catch (ArrayIndexOutOfBoundsException e) {
message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];
}
throw new Error(message);
}
/**
* Pushes the specified amount of characters back into the input stream.
*
* They will be read again by then next call of the scanning method
*
* @param number the number of characters to be read again.
* This number must not be greater than yylength()!
*/
public void yypushback(int number) {
if ( number > yylength() )
zzScanError(ZZ_PUSHBACK_2BIG);
zzMarkedPos -= number;
}
/**
* Contains user EOF-code, which will be executed exactly once,
* when the end of file is reached
*/
private void zzDoEOF() {
if (!zzEOFDone) {
zzEOFDone = true;
return;
}
}
/**
* Resumes scanning until the next regular expression is matched,
* the end of input is encountered or an I/O-Error occurs.
*
* @return the next token
* @exception java.io.IOException if any I/O-Error occurs
*/
public IElementType advance() throws java.io.IOException {
int zzInput;
int zzAction;
// cached fields:
int zzCurrentPosL;
int zzMarkedPosL;
int zzEndReadL = zzEndRead;
CharSequence zzBufferL = zzBuffer;
int [] zzTransL = ZZ_TRANS;
int [] zzRowMapL = ZZ_ROWMAP;
int [] zzAttrL = ZZ_ATTRIBUTE;
while (true) {
zzMarkedPosL = zzMarkedPos;
zzAction = -1;
zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
zzState = ZZ_LEXSTATE[zzLexicalState];
// set up zzAction for empty match case:
int zzAttributes = zzAttrL[zzState];
if ( (zzAttributes & 1) == 1 ) {
zzAction = zzState;
}
zzForAction: {
while (true) {
if (zzCurrentPosL < zzEndReadL) {
zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL/*, zzEndReadL*/);
zzCurrentPosL += Character.charCount(zzInput);
}
else if (zzAtEOF) {
zzInput = YYEOF;
break zzForAction;
}
else {
// store back cached positions
zzCurrentPos = zzCurrentPosL;
zzMarkedPos = zzMarkedPosL;
boolean eof = zzRefill();
// get translated positions and possibly new buffer
zzCurrentPosL = zzCurrentPos;
zzMarkedPosL = zzMarkedPos;
zzBufferL = zzBuffer;
zzEndReadL = zzEndRead;
if (eof) {
zzInput = YYEOF;
break zzForAction;
}
else {
zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL/*, zzEndReadL*/);
zzCurrentPosL += Character.charCount(zzInput);
}
}
int zzNext = zzTransL[ zzRowMapL[zzState] + ZZ_CMAP(zzInput) ];
if (zzNext == -1) break zzForAction;
zzState = zzNext;
zzAttributes = zzAttrL[zzState];
if ( (zzAttributes & 1) == 1 ) {
zzAction = zzState;
zzMarkedPosL = zzCurrentPosL;
if ( (zzAttributes & 8) == 8 ) break zzForAction;
}
}
}
// store back cached position
zzMarkedPos = zzMarkedPosL;
if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
zzAtEOF = true;
zzDoEOF();
return null;
}
else {
switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
case 1:
{ return TokenType.BAD_CHARACTER;
}
case 21: break;
case 2:
{ yybegin(CONTENTS);
return KDocTokens.TEXT;
}
case 22: break;
case 3:
{ if(yystate() == CONTENTS_BEGINNING) {
yybegin(INDENTED_CODE_BLOCK);
return KDocTokens.CODE_BLOCK_TEXT;
}
}
case 23: break;
case 4:
{ if (yytextContainLineBreaks()) {
yybegin(LINE_BEGINNING);
return TokenType.WHITE_SPACE;
} else {
yybegin(yystate() == CONTENTS_BEGINNING ? CONTENTS_BEGINNING : CONTENTS);
return KDocTokens.TEXT; // internal white space
}
}
case 24: break;
case 5:
{ yybegin(CONTENTS_BEGINNING);
return KDocTokens.LEADING_ASTERISK;
}
case 25: break;
case 6:
{ if (yytextContainLineBreaks()) {
yybegin(LINE_BEGINNING);
}
return TokenType.WHITE_SPACE;
}
case 26: break;
case 7:
{ yybegin(TAG_TEXT_BEGINNING);
return KDocTokens.MARKDOWN_LINK;
}
case 27: break;
case 8:
{ yybegin(yystate() == INDENTED_CODE_BLOCK ? INDENTED_CODE_BLOCK : CODE_BLOCK);
return KDocTokens.CODE_BLOCK_TEXT;
}
case 28: break;
case 9:
{ if (yytextContainLineBreaks()) {
yybegin(yystate() == INDENTED_CODE_BLOCK ? LINE_BEGINNING : CODE_BLOCK_LINE_BEGINNING);
return TokenType.WHITE_SPACE;
}
return KDocTokens.CODE_BLOCK_TEXT;
}
case 29: break;
case 10:
{ yybegin(CODE_BLOCK_CONTENTS_BEGINNING);
return KDocTokens.LEADING_ASTERISK;
}
case 30: break;
case 11:
{ if (isLastToken()) return KDocTokens.END;
else return KDocTokens.TEXT;
}
case 31: break;
case 12:
{ yybegin(CONTENTS);
return KDocTokens.MARKDOWN_ESCAPED_CHAR;
}
case 32: break;
case 13:
{ KDocKnownTag tag = KDocKnownTag.Companion.findByTagName(zzBuffer.subSequence(zzStartRead, zzMarkedPos));
yybegin(tag != null && tag.isReferenceRequired() ? TAG_BEGINNING : TAG_TEXT_BEGINNING);
return KDocTokens.TAG_NAME;
}
case 33: break;
case 14:
{ yybegin(CONTENTS_BEGINNING);
return KDocTokens.START;
}
case 34: break;
case 15:
{ yybegin(CODE_BLOCK_LINE_BEGINNING);
return KDocTokens.TEXT;
}
case 35: break;
case 16:
{ yybegin(TAG_TEXT_BEGINNING);
return KDocTokens.MARKDOWN_LINK;
}
case 36: break;
case 17:
{ yybegin(CONTENTS);
return KDocTokens.MARKDOWN_LINK;
}
case 37: break;
case 18:
// lookahead expression with fixed lookahead length
zzMarkedPos = Character.offsetByCodePoints
(zzBufferL/*, zzStartRead, zzEndRead - zzStartRead*/, zzMarkedPos, -1);
{ yybegin(CONTENTS);
return KDocTokens.MARKDOWN_LINK;
}
case 38: break;
case 19:
{ yybegin(CONTENTS);
return KDocTokens.MARKDOWN_INLINE_LINK;
}
case 39: break;
case 20:
// lookahead expression with fixed base length
zzMarkedPos = Character.offsetByCodePoints
(zzBufferL/*, zzStartRead, zzEndRead - zzStartRead*/, zzStartRead, 3);
{ // Code fence end
yybegin(CONTENTS);
return KDocTokens.TEXT;
}
case 40: break;
default:
zzScanError(ZZ_NO_MATCH);
}
}
}
}
}
@@ -1,48 +0,0 @@
/*
* 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.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import java.lang.reflect.Constructor;
public class KDocElementType extends IElementType {
private final Constructor<? extends PsiElement> psiFactory;
public KDocElementType(String debugName, @NotNull Class<? extends PsiElement> psiClass) {
super(debugName, KotlinLanguage.INSTANCE);
try {
psiFactory = psiClass.getConstructor(ASTNode.class);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Must have a constructor with ASTNode");
}
}
public PsiElement createPsi(ASTNode node) {
assert node.getElementType() == this;
try {
return psiFactory.newInstance(node);
} catch (Exception e) {
throw new RuntimeException("Error creating psi element for node", e);
}
}
}
@@ -1,27 +0,0 @@
/*
* 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 org.jetbrains.kotlin.kdoc.psi.impl.KDocName;
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_NAME = new KDocElementType("KDOC_NAME", KDocName.class);
}
@@ -1,50 +0,0 @@
/*
* 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.openapi.util.text.StringUtil
enum class KDocKnownTag private constructor(val isReferenceRequired: Boolean, val isSectionStart: Boolean) {
AUTHOR(false, false),
THROWS(true, false),
EXCEPTION(true, false),
PARAM(true, false),
RECEIVER(false, false),
RETURN(false, false),
SEE(true, false),
SINCE(false, false),
CONSTRUCTOR(false, true),
PROPERTY(true, true),
SAMPLE(true, false),
SUPPRESS(false, false);
companion object {
fun findByTagName(tagName: CharSequence): KDocKnownTag? {
var tagName = tagName
if (StringUtil.startsWith(tagName, "@")) {
tagName = tagName.subSequence(1, tagName.length)
}
try {
return valueOf(tagName.toString().toUpperCase())
} catch (ignored: IllegalArgumentException) {
}
return null
}
}
}
@@ -1,98 +0,0 @@
/*
* 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.ASTNode
import com.intellij.lang.PsiBuilder
import com.intellij.lang.PsiBuilderFactory
import com.intellij.lang.PsiParser
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.lexer.KotlinLexer
import org.jetbrains.kotlin.lexer.KtTokens
/**
* Parses the contents of a Markdown link in KDoc. Uses the standard Kotlin lexer.
*/
class KDocLinkParser : PsiParser {
companion object {
@JvmStatic
fun parseMarkdownLink(root: IElementType, chameleon: ASTNode): ASTNode {
val parentElement = chameleon.treeParent.psi
val project = parentElement.project
val builder = PsiBuilderFactory.getInstance().createBuilder(
project,
chameleon,
KotlinLexer(),
root.language,
chameleon.text
)
val parser = KDocLinkParser()
return parser.parse(root, builder).firstChildNode
}
}
override fun parse(root: IElementType, builder: PsiBuilder): ASTNode {
val rootMarker = builder.mark()
val hasLBracket = builder.tokenType == KtTokens.LBRACKET
if (hasLBracket) {
builder.advanceLexer()
}
parseQualifiedName(builder)
if (hasLBracket) {
if (!builder.eof() && builder.tokenType != KtTokens.RBRACKET) {
builder.error("Closing bracket expected")
while (!builder.eof() && builder.tokenType != KtTokens.RBRACKET) {
builder.advanceLexer()
}
}
if (builder.tokenType == KtTokens.RBRACKET) {
builder.advanceLexer()
}
} else {
if (!builder.eof()) {
builder.error("Expression expected")
while (!builder.eof()) {
builder.advanceLexer()
}
}
}
rootMarker.done(root)
return builder.treeBuilt
}
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.tokenType)) {
marker.drop()
builder.error("Identifier expected")
break
}
builder.advanceLexer()
marker.done(KDocElementTypes.KDOC_NAME)
if (builder.tokenType != KtTokens.DOT) {
break
}
marker = marker.precede()
builder.advanceLexer()
}
}
private fun isName(tokenType: IElementType?) = tokenType == KtTokens.IDENTIFIER || tokenType in KtTokens.KEYWORDS
}
@@ -1,92 +0,0 @@
/*
* 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.ASTNode;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiParser;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens;
public class KDocParser implements PsiParser {
@Override
@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) {
currentSectionMarker = parseTag(builder, currentSectionMarker);
}
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 PsiBuilder.Marker parseTag(PsiBuilder builder, PsiBuilder.Marker currentSectionMarker) {
String tagName = builder.getTokenText();
KDocKnownTag knownTag = KDocKnownTag.Companion.findByTagName(tagName);
if (knownTag != null && knownTag.isSectionStart()) {
currentSectionMarker.done(KDocElementTypes.KDOC_SECTION);
currentSectionMarker = builder.mark();
}
PsiBuilder.Marker tagStart = builder.mark();
builder.advanceLexer();
while (!builder.eof() && !isAtEndOfTag(builder)) {
builder.advanceLexer();
}
tagStart.done(KDocElementTypes.KDOC_TAG);
return currentSectionMarker;
}
private static boolean isAtEndOfTag(PsiBuilder builder) {
if (builder.getTokenType() == KDocTokens.END) {
return true;
}
if (builder.getTokenType() == KDocTokens.LEADING_ASTERISK) {
int lookAheadCount = 1;
if (builder.lookAhead(1) == KDocTokens.TEXT) {
lookAheadCount++;
}
if (builder.lookAhead(lookAheadCount) == KDocTokens.TAG_NAME) {
return true;
}
}
return false;
}
}
@@ -1,31 +0,0 @@
/*
* 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.api
import com.intellij.psi.PsiComment
import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
// Don't implement JetElement (or it will be treated as statement)
interface KDoc : PsiComment, KDocElement {
fun getOwner(): KtDeclaration?
fun getDefaultSection(): KDocSection
fun findSectionByName(name: String): KDocSection?
fun findSectionByTag(tag: KDocKnownTag): KDocSection?
fun findSectionByTag(tag: KDocKnownTag, subjectName: String): KDocSection?
}
@@ -1,22 +0,0 @@
/*
* 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.api;
import com.intellij.psi.PsiElement;
public interface KDocElement extends PsiElement {
}
@@ -1,41 +0,0 @@
/*
* 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.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import org.jetbrains.kotlin.kdoc.psi.api.KDocElement;
public abstract class KDocElementImpl extends ASTWrapperPsiElement implements KDocElement {
@NotNull
@Override
public Language getLanguage() {
return KotlinLanguage.INSTANCE;
}
@Override
public String toString() {
return getNode().getElementType().toString();
}
public KDocElementImpl(@NotNull ASTNode node) {
super(node);
}
}
@@ -1,54 +0,0 @@
/*
* 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.Language
import com.intellij.psi.impl.source.tree.LazyParseablePsiElement
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
class KDocImpl(buffer: CharSequence?) : LazyParseablePsiElement(KDocTokens.KDOC, buffer), KDoc {
override fun getLanguage(): Language = KotlinLanguage.INSTANCE
override fun toString(): String = node.elementType.toString()
override fun getTokenType(): IElementType = KtTokens.DOC_COMMENT
override fun getOwner(): KtDeclaration? = getParentOfType<KtDeclaration>(true)
override fun getDefaultSection(): KDocSection = getChildOfType<KDocSection>()!!
override fun findSectionByName(name: String): KDocSection? =
getChildrenOfType<KDocSection>().firstOrNull { it.name == name }
override fun findSectionByTag(tag: KDocKnownTag): KDocSection? =
findSectionByName(tag.name.toLowerCase())
override fun findSectionByTag(tag: KDocKnownTag, subjectName: String): KDocSection? =
getChildrenOfType<KDocSection>().firstOrNull {
it.name == tag.name.toLowerCase() && it.getSubjectName() == subjectName
}
}
@@ -1,48 +0,0 @@
/*
* 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 com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiReference
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
import org.jetbrains.kotlin.psi.KtElementImpl
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
class KDocLink(node: ASTNode) : KtElementImpl(node) {
fun getLinkText(): String = getLinkTextRange().substring(text)
fun getLinkTextRange(): TextRange {
val text = text
if (text.startsWith('[') && text.endsWith(']')) {
return TextRange(1, text.length - 1)
}
return TextRange(0, text.length)
}
/**
* If this link is the subject of a tag, returns the tag. Otherwise, returns null.
*/
fun getTagIfSubject(): KDocTag? {
val tag = getStrictParentOfType<KDocTag>()
return if (tag != null && tag.getSubjectLink() == this) tag else null
}
override fun getReferences(): Array<out PsiReference> =
ReferenceProvidersRegistry.getReferencesFromProviders(this)
}
@@ -1,61 +0,0 @@
/*
* 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.KtElementImpl
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
/**
* A single part of a qualified name in the tag subject or link.
*/
class KDocName(node: ASTNode) : KtElementImpl(node) {
fun getContainingDoc(): KDoc {
val kdoc = getStrictParentOfType<KDoc>()
return kdoc ?: throw IllegalStateException("KDocName must be inside a KDoc")
}
fun getContainingSection(): KDocSection {
val kdoc = getStrictParentOfType<KDocSection>()
return kdoc ?: throw IllegalStateException("KDocName must be inside a KDocSection")
}
fun getQualifier(): KDocName? = getChildOfType()
/**
* Returns the range within the element containing the name (in other words,
* the range of the element excluding the qualifier and dot, if present).
*/
fun getNameTextRange(): TextRange {
val dot = node.findChildByType(KtTokens.DOT)
val textRange = textRange
val nameStart = if (dot != null) dot.textRange.endOffset - textRange.startOffset else 0
return TextRange(nameStart, textRange.length)
}
fun getNameText(): String = getNameTextRange().substring(text)
fun getQualifiedName(): List<String> {
val qualifier = getQualifier()
val nameAsList = listOf(getNameText())
return if (qualifier != null) qualifier.getQualifiedName() + nameAsList else nameAsList
}
}
@@ -1,48 +0,0 @@
/*
* 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.psiUtil.getChildrenOfType
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
/**
* 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.
*/
class KDocSection(node: ASTNode) : KDocTag(node) {
/**
* Returns the name of the section (the name of the doc tag introducing the section,
* or null for the default section).
*/
override fun getName(): String? =
(firstChild as? KDocTag)?.name
override fun getSubjectName(): String? =
(firstChild as? KDocTag)?.getSubjectName()
override fun getContent(): String =
(firstChild as? KDocTag)?.getContent() ?: super.getContent()
fun findTagsByName(name: String): List<KDocTag> {
return getChildrenOfType<KDocTag>().filter { it.name == name }
}
fun findTagByName(name: String): KDocTag? = findTagsByName(name).firstOrNull()
}
@@ -1,157 +0,0 @@
/*
* 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 com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.TokenType
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
import org.jetbrains.kotlin.kdoc.parser.KDocElementTypes
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
open class KDocTag(node: ASTNode) : KDocElementImpl(node) {
/**
* Returns the name of this tag, not including the leading @ character.
*
* @return tag name or null if this tag represents the default section of a doc comment
* or the code has a syntax error.
*/
override fun getName(): String? {
val tagName: PsiElement? = findChildByType(KDocTokens.TAG_NAME)
if (tagName != null) {
return tagName.text.substring(1)
}
return null
}
/**
* Returns the name of the entity documented by this tag (for example, the name of the parameter
* for the @param tag), or null if this tag does not document any specific entity.
*/
open fun getSubjectName(): String? = getSubjectLink()?.getLinkText()
fun getSubjectLink(): KDocLink? {
val children = childrenAfterTagName()
if (hasSubject(children)) {
return children.firstOrNull()?.psi as? KDocLink
}
return null
}
val knownTag: KDocKnownTag?
get() {
return name?.let { KDocKnownTag.findByTagName(it) }
}
private fun hasSubject(contentChildren: List<ASTNode>): Boolean {
if (knownTag?.isReferenceRequired ?: false) {
return contentChildren.firstOrNull()?.elementType == KDocTokens.MARKDOWN_LINK
}
return false
}
private fun childrenAfterTagName(): List<ASTNode> =
node.getChildren(null)
.dropWhile { it.elementType == KDocTokens.TAG_NAME }
.dropWhile { it.elementType == TokenType.WHITE_SPACE }
/**
* Returns the content of this tag (all text following the tag name and the subject if present,
* with leading asterisks removed).
*/
open fun getContent(): String {
val builder = StringBuilder()
val codeBlockBuilder = StringBuilder()
var targetBuilder = builder
var contentStarted = false
var afterAsterisk = false
var indentedCodeBlock = false
fun isCodeBlock() = targetBuilder == codeBlockBuilder
fun startCodeBlock() {
targetBuilder = codeBlockBuilder
}
fun flushCodeBlock() {
if (isCodeBlock()) {
builder.append(trimCommonIndent(codeBlockBuilder, indentedCodeBlock))
codeBlockBuilder.setLength(0)
targetBuilder = builder
}
}
var children = childrenAfterTagName()
if (hasSubject(children)) {
children = children.drop(1)
}
for (node in children) {
val type = node.elementType
if (type == KDocTokens.CODE_BLOCK_TEXT) {
//If first line of code block
if (!isCodeBlock())
indentedCodeBlock = indentedCodeBlock || node.text.startsWith(indentationWhiteSpaces) || node.text.startsWith("\t")
startCodeBlock()
} else if (KDocTokens.CONTENT_TOKENS.contains(type)) {
flushCodeBlock()
indentedCodeBlock = false
}
if (KDocTokens.CONTENT_TOKENS.contains(type)) {
val isPlainContent = afterAsterisk && !isCodeBlock()
// If content not yet started and not part of indented code block
// and not inside fenced code block we should trim leading spaces
val trimLeadingSpaces = !(contentStarted || indentedCodeBlock) || isPlainContent
targetBuilder.append(if (trimLeadingSpaces) node.text.trimStart() else node.text)
contentStarted = true
afterAsterisk = false
}
if (type == KDocTokens.LEADING_ASTERISK) {
afterAsterisk = true
}
if (type == TokenType.WHITE_SPACE && contentStarted) {
targetBuilder.append("\n".repeat(StringUtil.countNewLines(node.text)))
}
if (type == KDocElementTypes.KDOC_TAG) {
break
}
}
flushCodeBlock()
return builder.toString().trimEnd(' ', '\t')
}
private fun trimCommonIndent(builder: StringBuilder, prepend4WhiteSpaces: Boolean = false): String {
val lines = builder.toString().split('\n')
val minIndent = lines.filter { it.trim().isNotEmpty() }.map { it.calcIndent() }.min() ?: 0
var processedLines = lines.map { it.drop(minIndent) }
if (prepend4WhiteSpaces)
processedLines = processedLines.map { if (it.isNotBlank()) it.prependIndent(indentationWhiteSpaces) else it }
return processedLines.joinToString("\n")
}
private fun String.calcIndent() = indexOfFirst { !it.isWhitespace() }
companion object {
val indentationWhiteSpaces = " ".repeat(4)
}
}
@@ -1,329 +0,0 @@
package org.jetbrains.kotlin.lexer;
import java.util.*;
import com.intellij.lexer.*;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.containers.Stack;
import org.jetbrains.kotlin.lexer.KotlinLexerException;
import org.jetbrains.kotlin.lexer.KtTokens;
%%
%unicode
%class _JetLexer
%implements FlexLexer
%{
private static final class State {
final int lBraceCount;
final int state;
public State(int state, int lBraceCount) {
this.state = state;
this.lBraceCount = lBraceCount;
}
@Override
public String toString() {
return "yystate = " + state + (lBraceCount == 0 ? "" : "lBraceCount = " + lBraceCount);
}
}
private final Stack<State> states = new Stack<State>();
private int lBraceCount;
private int commentStart;
private int commentDepth;
private void pushState(int state) {
states.push(new State(yystate(), lBraceCount));
lBraceCount = 0;
yybegin(state);
}
private void popState() {
State state = states.pop();
lBraceCount = state.lBraceCount;
yybegin(state.state);
}
private IElementType commentStateToTokenType(int state) {
switch (state) {
case BLOCK_COMMENT:
return KtTokens.BLOCK_COMMENT;
case DOC_COMMENT:
return KtTokens.DOC_COMMENT;
default:
throw new IllegalArgumentException("Unexpected state: " + state);
}
}
%}
%scanerror KotlinLexerException
%function advance
%type IElementType
%eof{
return;
%eof}
%xstate STRING RAW_STRING SHORT_TEMPLATE_ENTRY BLOCK_COMMENT DOC_COMMENT
%state LONG_TEMPLATE_ENTRY UNMATCHED_BACKTICK
DIGIT=[0-9]
DIGIT_OR_UNDERSCORE = [_0-9]
DIGITS = {DIGIT} {DIGIT_OR_UNDERSCORE}*
HEX_DIGIT=[0-9A-Fa-f]
HEX_DIGIT_OR_UNDERSCORE = [_0-9A-Fa-f]
WHITE_SPACE_CHAR=[\ \n\t\f]
// TODO: prohibit '$' in identifiers?
LETTER = [:letter:]|_
IDENTIFIER_PART=[:digit:]|{LETTER}
PLAIN_IDENTIFIER={LETTER} {IDENTIFIER_PART}*
// TODO: this one MUST allow everything accepted by the runtime
// TODO: Replace backticks by one backslash in the begining
ESCAPED_IDENTIFIER = `[^`\n]+`
IDENTIFIER = {PLAIN_IDENTIFIER}|{ESCAPED_IDENTIFIER}
FIELD_IDENTIFIER = \${IDENTIFIER}
EOL_COMMENT="/""/"[^\n]*
SHEBANG_COMMENT="#!"[^\n]*
INTEGER_LITERAL={DECIMAL_INTEGER_LITERAL}|{HEX_INTEGER_LITERAL}|{BIN_INTEGER_LITERAL}
DECIMAL_INTEGER_LITERAL=(0|([1-9]({DIGIT_OR_UNDERSCORE})*))({LONG_SUFFIX})?
HEX_INTEGER_LITERAL=0[Xx]({HEX_DIGIT_OR_UNDERSCORE})*({LONG_SUFFIX})?
BIN_INTEGER_LITERAL=0[Bb]({DIGIT_OR_UNDERSCORE})*({LONG_SUFFIX})?
LONG_SUFFIX=[Ll]
//FLOAT_LITERAL=(({FLOATING_POINT_LITERAL1})[Ff])|(({FLOATING_POINT_LITERAL2})[Ff])|(({FLOATING_POINT_LITERAL3})[Ff])|(({FLOATING_POINT_LITERAL4})[Ff])
//DOUBLE_LITERAL=(({FLOATING_POINT_LITERAL1})[Dd]?)|(({FLOATING_POINT_LITERAL2})[Dd]?)|(({FLOATING_POINT_LITERAL3})[Dd]?)|(({FLOATING_POINT_LITERAL4})[Dd])
DOUBLE_LITERAL={FLOATING_POINT_LITERAL1}|{FLOATING_POINT_LITERAL2}|{FLOATING_POINT_LITERAL3}|{FLOATING_POINT_LITERAL4}
FLOATING_POINT_LITERAL1=({DIGITS})"."({DIGITS})+({EXPONENT_PART})?({FLOATING_POINT_LITERAL_SUFFIX})?
FLOATING_POINT_LITERAL2="."({DIGITS})({EXPONENT_PART})?({FLOATING_POINT_LITERAL_SUFFIX})?
FLOATING_POINT_LITERAL3=({DIGITS})({EXPONENT_PART})({FLOATING_POINT_LITERAL_SUFFIX})?
FLOATING_POINT_LITERAL4=({DIGITS})({FLOATING_POINT_LITERAL_SUFFIX})
FLOATING_POINT_LITERAL_SUFFIX=[Ff]
EXPONENT_PART=[Ee]["+""-"]?({DIGIT_OR_UNDERSCORE})*
CHARACTER_LITERAL="'"([^\\\'\n]|{ESCAPE_SEQUENCE})*("'"|\\)?
// TODO: introduce symbols (e.g. 'foo) as another way to write string literals
ESCAPE_SEQUENCE=\\(u{HEX_DIGIT}{HEX_DIGIT}{HEX_DIGIT}{HEX_DIGIT}|[^\n])
// ANY_ESCAPE_SEQUENCE = \\[^]
THREE_QUO = (\"\"\")
THREE_OR_MORE_QUO = ({THREE_QUO}\"*)
REGULAR_STRING_PART=[^\\\"\n\$]+
SHORT_TEMPLATE_ENTRY=\${IDENTIFIER}
LONELY_DOLLAR=\$
LONG_TEMPLATE_ENTRY_START=\$\{
LONELY_BACKTICK=`
%%
// String templates
{THREE_QUO} { pushState(RAW_STRING); return KtTokens.OPEN_QUOTE; }
<RAW_STRING> \n { return KtTokens.REGULAR_STRING_PART; }
<RAW_STRING> \" { return KtTokens.REGULAR_STRING_PART; }
<RAW_STRING> \\ { return KtTokens.REGULAR_STRING_PART; }
<RAW_STRING> {THREE_OR_MORE_QUO} {
int length = yytext().length();
if (length <= 3) { // closing """
popState();
return KtTokens.CLOSING_QUOTE;
}
else { // some quotes at the end of a string, e.g. """ "foo""""
yypushback(3); // return the closing quotes (""") to the stream
return KtTokens.REGULAR_STRING_PART;
}
}
\" { pushState(STRING); return KtTokens.OPEN_QUOTE; }
<STRING> \n { popState(); yypushback(1); return KtTokens.DANGLING_NEWLINE; }
<STRING> \" { popState(); return KtTokens.CLOSING_QUOTE; }
<STRING> {ESCAPE_SEQUENCE} { return KtTokens.ESCAPE_SEQUENCE; }
<STRING, RAW_STRING> {REGULAR_STRING_PART} { return KtTokens.REGULAR_STRING_PART; }
<STRING, RAW_STRING> {SHORT_TEMPLATE_ENTRY} {
pushState(SHORT_TEMPLATE_ENTRY);
yypushback(yylength() - 1);
return KtTokens.SHORT_TEMPLATE_ENTRY_START;
}
// Only *this* keyword is itself an expression valid in this position
// *null*, *true* and *false* are also keywords and expression, but it does not make sense to put them
// in a string template for it'd be easier to just type them in without a dollar
<SHORT_TEMPLATE_ENTRY> "this" { popState(); return KtTokens.THIS_KEYWORD; }
<SHORT_TEMPLATE_ENTRY> {IDENTIFIER} { popState(); return KtTokens.IDENTIFIER; }
<STRING, RAW_STRING> {LONELY_DOLLAR} { return KtTokens.REGULAR_STRING_PART; }
<STRING, RAW_STRING> {LONG_TEMPLATE_ENTRY_START} { pushState(LONG_TEMPLATE_ENTRY); return KtTokens.LONG_TEMPLATE_ENTRY_START; }
<LONG_TEMPLATE_ENTRY> "{" { lBraceCount++; return KtTokens.LBRACE; }
<LONG_TEMPLATE_ENTRY> "}" {
if (lBraceCount == 0) {
popState();
return KtTokens.LONG_TEMPLATE_ENTRY_END;
}
lBraceCount--;
return KtTokens.RBRACE;
}
// (Nested) comments
"/**/" {
return KtTokens.BLOCK_COMMENT;
}
"/**" {
pushState(DOC_COMMENT);
commentDepth = 0;
commentStart = getTokenStart();
}
"/*" {
pushState(BLOCK_COMMENT);
commentDepth = 0;
commentStart = getTokenStart();
}
<BLOCK_COMMENT, DOC_COMMENT> {
"/*" {
commentDepth++;
}
<<EOF>> {
int state = yystate();
popState();
zzStartRead = commentStart;
return commentStateToTokenType(state);
}
"*/" {
if (commentDepth > 0) {
commentDepth--;
}
else {
int state = yystate();
popState();
zzStartRead = commentStart;
return commentStateToTokenType(state);
}
}
.|{WHITE_SPACE_CHAR} {}
}
// Mere mortals
({WHITE_SPACE_CHAR})+ { return KtTokens.WHITE_SPACE; }
{EOL_COMMENT} { return KtTokens.EOL_COMMENT; }
{SHEBANG_COMMENT} {
if (zzCurrentPos == 0) {
return KtTokens.SHEBANG_COMMENT;
}
else {
yypushback(yylength() - 1);
return KtTokens.HASH;
}
}
{INTEGER_LITERAL}\.\. { yypushback(2); return KtTokens.INTEGER_LITERAL; }
{INTEGER_LITERAL} { return KtTokens.INTEGER_LITERAL; }
{DOUBLE_LITERAL} { return KtTokens.FLOAT_LITERAL; }
{CHARACTER_LITERAL} { return KtTokens.CHARACTER_LITERAL; }
"typealias" { return KtTokens.TYPE_ALIAS_KEYWORD ;}
"interface" { return KtTokens.INTERFACE_KEYWORD ;}
"continue" { return KtTokens.CONTINUE_KEYWORD ;}
"package" { return KtTokens.PACKAGE_KEYWORD ;}
"return" { return KtTokens.RETURN_KEYWORD ;}
"object" { return KtTokens.OBJECT_KEYWORD ;}
"while" { return KtTokens.WHILE_KEYWORD ;}
"break" { return KtTokens.BREAK_KEYWORD ;}
"class" { return KtTokens.CLASS_KEYWORD ;}
"throw" { return KtTokens.THROW_KEYWORD ;}
"false" { return KtTokens.FALSE_KEYWORD ;}
"super" { return KtTokens.SUPER_KEYWORD ;}
"typeof" { return KtTokens.TYPEOF_KEYWORD ;}
"when" { return KtTokens.WHEN_KEYWORD ;}
"true" { return KtTokens.TRUE_KEYWORD ;}
"this" { return KtTokens.THIS_KEYWORD ;}
"null" { return KtTokens.NULL_KEYWORD ;}
"else" { return KtTokens.ELSE_KEYWORD ;}
"try" { return KtTokens.TRY_KEYWORD ;}
"val" { return KtTokens.VAL_KEYWORD ;}
"var" { return KtTokens.VAR_KEYWORD ;}
"fun" { return KtTokens.FUN_KEYWORD ;}
"for" { return KtTokens.FOR_KEYWORD ;}
"is" { return KtTokens.IS_KEYWORD ;}
"in" { return KtTokens.IN_KEYWORD ;}
"if" { return KtTokens.IF_KEYWORD ;}
"do" { return KtTokens.DO_KEYWORD ;}
"as" { return KtTokens.AS_KEYWORD ;}
{FIELD_IDENTIFIER} { return KtTokens.FIELD_IDENTIFIER; }
{IDENTIFIER} { return KtTokens.IDENTIFIER; }
\!in{IDENTIFIER_PART} { yypushback(3); return KtTokens.EXCL; }
\!is{IDENTIFIER_PART} { yypushback(3); return KtTokens.EXCL; }
"..." { return KtTokens.RESERVED ; }
"===" { return KtTokens.EQEQEQ ; }
"!==" { return KtTokens.EXCLEQEQEQ; }
"!in" { return KtTokens.NOT_IN; }
"!is" { return KtTokens.NOT_IS; }
"as?" { return KtTokens.AS_SAFE; }
"++" { return KtTokens.PLUSPLUS ; }
"--" { return KtTokens.MINUSMINUS; }
"<=" { return KtTokens.LTEQ ; }
">=" { return KtTokens.GTEQ ; }
"==" { return KtTokens.EQEQ ; }
"!=" { return KtTokens.EXCLEQ ; }
"&&" { return KtTokens.ANDAND ; }
"||" { return KtTokens.OROR ; }
"*=" { return KtTokens.MULTEQ ; }
"/=" { return KtTokens.DIVEQ ; }
"%=" { return KtTokens.PERCEQ ; }
"+=" { return KtTokens.PLUSEQ ; }
"-=" { return KtTokens.MINUSEQ ; }
"->" { return KtTokens.ARROW ; }
"=>" { return KtTokens.DOUBLE_ARROW; }
".." { return KtTokens.RANGE ; }
"::" { return KtTokens.COLONCOLON; }
"[" { return KtTokens.LBRACKET ; }
"]" { return KtTokens.RBRACKET ; }
"{" { return KtTokens.LBRACE ; }
"}" { return KtTokens.RBRACE ; }
"(" { return KtTokens.LPAR ; }
")" { return KtTokens.RPAR ; }
"." { return KtTokens.DOT ; }
"*" { return KtTokens.MUL ; }
"+" { return KtTokens.PLUS ; }
"-" { return KtTokens.MINUS ; }
"!" { return KtTokens.EXCL ; }
"/" { return KtTokens.DIV ; }
"%" { return KtTokens.PERC ; }
"<" { return KtTokens.LT ; }
">" { return KtTokens.GT ; }
"?" { return KtTokens.QUEST ; }
":" { return KtTokens.COLON ; }
";;" { return KtTokens.DOUBLE_SEMICOLON;}
";" { return KtTokens.SEMICOLON ; }
"=" { return KtTokens.EQ ; }
"," { return KtTokens.COMMA ; }
"#" { return KtTokens.HASH ; }
"@" { return KtTokens.AT ; }
{LONELY_BACKTICK} { pushState(UNMATCHED_BACKTICK); return TokenType.BAD_CHARACTER; }
// error fallback
. { return TokenType.BAD_CHARACTER; }
// error fallback for exclusive states
<STRING, RAW_STRING, SHORT_TEMPLATE_ENTRY, BLOCK_COMMENT, DOC_COMMENT> .
{ return TokenType.BAD_CHARACTER; }
@@ -1,27 +0,0 @@
/*
* 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.lexer;
import com.intellij.lexer.FlexAdapter;
import java.io.Reader;
public class KotlinLexer extends FlexAdapter {
public KotlinLexer() {
super(new _JetLexer((Reader) null));
}
}
@@ -1,23 +0,0 @@
/*
* 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.lexer;
public class KotlinLexerException extends RuntimeException {
public KotlinLexerException(String message) {
super(message);
}
}
@@ -1,52 +0,0 @@
/*
* 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.lexer;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class KtKeywordToken extends KtSingleValueToken {
/**
* Generate keyword (identifier that has a keyword meaning in all possible contexts)
*/
public static KtKeywordToken keyword(String value) {
return keyword(value, value);
}
public static KtKeywordToken keyword(String debugName, String value) {
return new KtKeywordToken(debugName, value, false);
}
/**
* Generate soft keyword (identifier that has a keyword meaning only in some contexts)
*/
public static KtKeywordToken softKeyword(String value) {
return new KtKeywordToken(value, value, true);
}
private final boolean myIsSoft;
protected KtKeywordToken(@NotNull @NonNls String debugName, @NotNull @NonNls String value, boolean isSoft) {
super(debugName, value);
myIsSoft = isSoft;
}
public boolean isSoft() {
return myIsSoft;
}
}
@@ -1,42 +0,0 @@
/*
* 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.lexer;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/* Modifier keyword is a keyword that can be used in annotation position as part of modifier list.*/
public final class KtModifierKeywordToken extends KtKeywordToken {
/**
* Generate keyword (identifier that has a keyword meaning in all possible contexts)
*/
public static KtModifierKeywordToken keywordModifier(String value) {
return new KtModifierKeywordToken(value, value, false);
}
/**
* Generate soft keyword (identifier that has a keyword meaning only in some contexts)
*/
public static KtModifierKeywordToken softKeywordModifier(String value) {
return new KtModifierKeywordToken(value, value, true);
}
private KtModifierKeywordToken(@NotNull @NonNls String debugName, @NotNull @NonNls String value, boolean isSoft) {
super(debugName, value, isSoft);
}
}
@@ -1,35 +0,0 @@
/*
* 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.lexer;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class KtSingleValueToken extends KtToken {
private final String myValue;
public KtSingleValueToken(@NotNull @NonNls String debugName, @NotNull @NonNls String value) {
super(debugName);
myValue = value;
}
@NotNull @NonNls
public String getValue() {
return myValue;
}
}
@@ -1,28 +0,0 @@
/*
* 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.lexer;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.KotlinLanguage;
public class KtToken extends IElementType {
public KtToken(@NotNull @NonNls String debugName) {
super(debugName, KotlinLanguage.INSTANCE);
}
}
@@ -1,265 +0,0 @@
/*
* 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.lexer;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens;
import org.jetbrains.kotlin.psi.KtPsiUtil;
public interface KtTokens {
KtToken EOF = new KtToken("EOF");
KtToken RESERVED = new KtToken("RESERVED");
KtToken BLOCK_COMMENT = new KtToken("BLOCK_COMMENT");
KtToken EOL_COMMENT = new KtToken("EOL_COMMENT");
KtToken SHEBANG_COMMENT = new KtToken("SHEBANG_COMMENT");
//KtToken DOC_COMMENT = new KtToken("DOC_COMMENT");
IElementType DOC_COMMENT = KDocTokens.KDOC;
IElementType WHITE_SPACE = TokenType.WHITE_SPACE;
KtToken INTEGER_LITERAL = new KtToken("INTEGER_LITERAL");
KtToken FLOAT_LITERAL = new KtToken("FLOAT_CONSTANT");
KtToken CHARACTER_LITERAL = new KtToken("CHARACTER_LITERAL");
KtToken CLOSING_QUOTE = new KtToken("CLOSING_QUOTE");
KtToken OPEN_QUOTE = new KtToken("OPEN_QUOTE");
KtToken REGULAR_STRING_PART = new KtToken("REGULAR_STRING_PART");
KtToken ESCAPE_SEQUENCE = new KtToken("ESCAPE_SEQUENCE");
KtToken SHORT_TEMPLATE_ENTRY_START = new KtToken("SHORT_TEMPLATE_ENTRY_START");
KtToken LONG_TEMPLATE_ENTRY_START = new KtToken("LONG_TEMPLATE_ENTRY_START");
KtToken LONG_TEMPLATE_ENTRY_END = new KtToken("LONG_TEMPLATE_ENTRY_END");
KtToken DANGLING_NEWLINE = new KtToken("DANGLING_NEWLINE");
KtKeywordToken PACKAGE_KEYWORD = KtKeywordToken.keyword("package");
KtKeywordToken AS_KEYWORD = KtKeywordToken.keyword("as");
KtKeywordToken TYPE_ALIAS_KEYWORD = KtKeywordToken.keyword("typealias");
KtKeywordToken CLASS_KEYWORD = KtKeywordToken.keyword("class");
KtKeywordToken THIS_KEYWORD = KtKeywordToken.keyword("this");
KtKeywordToken SUPER_KEYWORD = KtKeywordToken.keyword("super");
KtKeywordToken VAL_KEYWORD = KtKeywordToken.keyword("val");
KtKeywordToken VAR_KEYWORD = KtKeywordToken.keyword("var");
KtKeywordToken FUN_KEYWORD = KtKeywordToken.keyword("fun");
KtKeywordToken FOR_KEYWORD = KtKeywordToken.keyword("for");
KtKeywordToken NULL_KEYWORD = KtKeywordToken.keyword("null");
KtKeywordToken TRUE_KEYWORD = KtKeywordToken.keyword("true");
KtKeywordToken FALSE_KEYWORD = KtKeywordToken.keyword("false");
KtKeywordToken IS_KEYWORD = KtKeywordToken.keyword("is");
KtModifierKeywordToken IN_KEYWORD = KtModifierKeywordToken.keywordModifier("in");
KtKeywordToken THROW_KEYWORD = KtKeywordToken.keyword("throw");
KtKeywordToken RETURN_KEYWORD = KtKeywordToken.keyword("return");
KtKeywordToken BREAK_KEYWORD = KtKeywordToken.keyword("break");
KtKeywordToken CONTINUE_KEYWORD = KtKeywordToken.keyword("continue");
KtKeywordToken OBJECT_KEYWORD = KtKeywordToken.keyword("object");
KtKeywordToken IF_KEYWORD = KtKeywordToken.keyword("if");
KtKeywordToken TRY_KEYWORD = KtKeywordToken.keyword("try");
KtKeywordToken ELSE_KEYWORD = KtKeywordToken.keyword("else");
KtKeywordToken WHILE_KEYWORD = KtKeywordToken.keyword("while");
KtKeywordToken DO_KEYWORD = KtKeywordToken.keyword("do");
KtKeywordToken WHEN_KEYWORD = KtKeywordToken.keyword("when");
KtKeywordToken INTERFACE_KEYWORD = KtKeywordToken.keyword("interface");
// Reserved for future use:
KtKeywordToken TYPEOF_KEYWORD = KtKeywordToken.keyword("typeof");
KtToken AS_SAFE = KtKeywordToken.keyword("AS_SAFE");//new KtToken("as?");
KtToken IDENTIFIER = new KtToken("IDENTIFIER");
KtToken FIELD_IDENTIFIER = new KtToken("FIELD_IDENTIFIER");
KtSingleValueToken LBRACKET = new KtSingleValueToken("LBRACKET", "[");
KtSingleValueToken RBRACKET = new KtSingleValueToken("RBRACKET", "]");
KtSingleValueToken LBRACE = new KtSingleValueToken("LBRACE", "{");
KtSingleValueToken RBRACE = new KtSingleValueToken("RBRACE", "}");
KtSingleValueToken LPAR = new KtSingleValueToken("LPAR", "(");
KtSingleValueToken RPAR = new KtSingleValueToken("RPAR", ")");
KtSingleValueToken DOT = new KtSingleValueToken("DOT", ".");
KtSingleValueToken PLUSPLUS = new KtSingleValueToken("PLUSPLUS", "++");
KtSingleValueToken MINUSMINUS = new KtSingleValueToken("MINUSMINUS", "--");
KtSingleValueToken MUL = new KtSingleValueToken("MUL", "*");
KtSingleValueToken PLUS = new KtSingleValueToken("PLUS", "+");
KtSingleValueToken MINUS = new KtSingleValueToken("MINUS", "-");
KtSingleValueToken EXCL = new KtSingleValueToken("EXCL", "!");
KtSingleValueToken DIV = new KtSingleValueToken("DIV", "/");
KtSingleValueToken PERC = new KtSingleValueToken("PERC", "%");
KtSingleValueToken LT = new KtSingleValueToken("LT", "<");
KtSingleValueToken GT = new KtSingleValueToken("GT", ">");
KtSingleValueToken LTEQ = new KtSingleValueToken("LTEQ", "<=");
KtSingleValueToken GTEQ = new KtSingleValueToken("GTEQ", ">=");
KtSingleValueToken EQEQEQ = new KtSingleValueToken("EQEQEQ", "===");
KtSingleValueToken ARROW = new KtSingleValueToken("ARROW", "->");
KtSingleValueToken DOUBLE_ARROW = new KtSingleValueToken("DOUBLE_ARROW", "=>");
KtSingleValueToken EXCLEQEQEQ = new KtSingleValueToken("EXCLEQEQEQ", "!==");
KtSingleValueToken EQEQ = new KtSingleValueToken("EQEQ", "==");
KtSingleValueToken EXCLEQ = new KtSingleValueToken("EXCLEQ", "!=");
KtSingleValueToken EXCLEXCL = new KtSingleValueToken("EXCLEXCL", "!!");
KtSingleValueToken ANDAND = new KtSingleValueToken("ANDAND", "&&");
KtSingleValueToken OROR = new KtSingleValueToken("OROR", "||");
KtSingleValueToken SAFE_ACCESS = new KtSingleValueToken("SAFE_ACCESS", "?.");
KtSingleValueToken ELVIS = new KtSingleValueToken("ELVIS", "?:");
KtSingleValueToken QUEST = new KtSingleValueToken("QUEST", "?");
KtSingleValueToken COLONCOLON = new KtSingleValueToken("COLONCOLON", "::");
KtSingleValueToken COLON = new KtSingleValueToken("COLON", ":");
KtSingleValueToken SEMICOLON = new KtSingleValueToken("SEMICOLON", ";");
KtSingleValueToken DOUBLE_SEMICOLON = new KtSingleValueToken("DOUBLE_SEMICOLON", ";;");
KtSingleValueToken RANGE = new KtSingleValueToken("RANGE", "..");
KtSingleValueToken EQ = new KtSingleValueToken("EQ", "=");
KtSingleValueToken MULTEQ = new KtSingleValueToken("MULTEQ", "*=");
KtSingleValueToken DIVEQ = new KtSingleValueToken("DIVEQ", "/=");
KtSingleValueToken PERCEQ = new KtSingleValueToken("PERCEQ", "%=");
KtSingleValueToken PLUSEQ = new KtSingleValueToken("PLUSEQ", "+=");
KtSingleValueToken MINUSEQ = new KtSingleValueToken("MINUSEQ", "-=");
KtKeywordToken NOT_IN = KtKeywordToken.keyword("NOT_IN", "!in");
KtKeywordToken NOT_IS = KtKeywordToken.keyword("NOT_IS", "!is");
KtSingleValueToken HASH = new KtSingleValueToken("HASH", "#");
KtSingleValueToken AT = new KtSingleValueToken("AT", "@");
KtSingleValueToken COMMA = new KtSingleValueToken("COMMA", ",");
KtToken EOL_OR_SEMICOLON = new KtToken("EOL_OR_SEMICOLON");
KtKeywordToken FILE_KEYWORD = KtKeywordToken.softKeyword("file");
KtKeywordToken FIELD_KEYWORD = KtKeywordToken.softKeyword("field");
KtKeywordToken PROPERTY_KEYWORD = KtKeywordToken.softKeyword("property");
KtKeywordToken RECEIVER_KEYWORD = KtKeywordToken.softKeyword("receiver");
KtKeywordToken PARAM_KEYWORD = KtKeywordToken.softKeyword("param");
KtKeywordToken SETPARAM_KEYWORD = KtKeywordToken.softKeyword("setparam");
KtKeywordToken DELEGATE_KEYWORD = KtKeywordToken.softKeyword("delegate");
KtKeywordToken IMPORT_KEYWORD = KtKeywordToken.softKeyword("import");
KtKeywordToken WHERE_KEYWORD = KtKeywordToken.softKeyword("where");
KtKeywordToken BY_KEYWORD = KtKeywordToken.softKeyword("by");
KtKeywordToken GET_KEYWORD = KtKeywordToken.softKeyword("get");
KtKeywordToken SET_KEYWORD = KtKeywordToken.softKeyword("set");
KtKeywordToken CONSTRUCTOR_KEYWORD = KtKeywordToken.softKeyword("constructor");
KtKeywordToken INIT_KEYWORD = KtKeywordToken.softKeyword("init");
KtModifierKeywordToken ABSTRACT_KEYWORD = KtModifierKeywordToken.softKeywordModifier("abstract");
KtModifierKeywordToken ENUM_KEYWORD = KtModifierKeywordToken.softKeywordModifier("enum");
KtModifierKeywordToken OPEN_KEYWORD = KtModifierKeywordToken.softKeywordModifier("open");
KtModifierKeywordToken INNER_KEYWORD = KtModifierKeywordToken.softKeywordModifier("inner");
KtModifierKeywordToken OVERRIDE_KEYWORD = KtModifierKeywordToken.softKeywordModifier("override");
KtModifierKeywordToken PRIVATE_KEYWORD = KtModifierKeywordToken.softKeywordModifier("private");
KtModifierKeywordToken PUBLIC_KEYWORD = KtModifierKeywordToken.softKeywordModifier("public");
KtModifierKeywordToken INTERNAL_KEYWORD = KtModifierKeywordToken.softKeywordModifier("internal");
KtModifierKeywordToken PROTECTED_KEYWORD = KtModifierKeywordToken.softKeywordModifier("protected");
KtKeywordToken CATCH_KEYWORD = KtKeywordToken.softKeyword("catch");
KtModifierKeywordToken OUT_KEYWORD = KtModifierKeywordToken.softKeywordModifier("out");
KtModifierKeywordToken VARARG_KEYWORD = KtModifierKeywordToken.softKeywordModifier("vararg");
KtModifierKeywordToken REIFIED_KEYWORD = KtModifierKeywordToken.softKeywordModifier("reified");
KtKeywordToken DYNAMIC_KEYWORD = KtKeywordToken.softKeyword("dynamic");
KtModifierKeywordToken COMPANION_KEYWORD = KtModifierKeywordToken.softKeywordModifier("companion");
KtModifierKeywordToken SEALED_KEYWORD = KtModifierKeywordToken.softKeywordModifier("sealed");
KtModifierKeywordToken DEFAULT_VISIBILITY_KEYWORD = PUBLIC_KEYWORD;
KtKeywordToken FINALLY_KEYWORD = KtKeywordToken.softKeyword("finally");
KtModifierKeywordToken FINAL_KEYWORD = KtModifierKeywordToken.softKeywordModifier("final");
KtModifierKeywordToken LATEINIT_KEYWORD = KtModifierKeywordToken.softKeywordModifier("lateinit");
KtModifierKeywordToken DATA_KEYWORD = KtModifierKeywordToken.softKeywordModifier("data");
KtModifierKeywordToken INLINE_KEYWORD = KtModifierKeywordToken.softKeywordModifier("inline");
KtModifierKeywordToken NOINLINE_KEYWORD = KtModifierKeywordToken.softKeywordModifier("noinline");
KtModifierKeywordToken TAILREC_KEYWORD = KtModifierKeywordToken.softKeywordModifier("tailrec");
KtModifierKeywordToken EXTERNAL_KEYWORD = KtModifierKeywordToken.softKeywordModifier("external");
KtModifierKeywordToken ANNOTATION_KEYWORD = KtModifierKeywordToken.softKeywordModifier("annotation");
KtModifierKeywordToken CROSSINLINE_KEYWORD = KtModifierKeywordToken.softKeywordModifier("crossinline");
KtModifierKeywordToken OPERATOR_KEYWORD = KtModifierKeywordToken.softKeywordModifier("operator");
KtModifierKeywordToken INFIX_KEYWORD = KtModifierKeywordToken.softKeywordModifier("infix");
KtModifierKeywordToken CONST_KEYWORD = KtModifierKeywordToken.softKeywordModifier("const");
KtModifierKeywordToken SUSPEND_KEYWORD = KtModifierKeywordToken.softKeywordModifier("suspend");
KtModifierKeywordToken HEADER_KEYWORD = KtModifierKeywordToken.softKeywordModifier("header");
KtModifierKeywordToken IMPL_KEYWORD = KtModifierKeywordToken.softKeywordModifier("impl");
KtModifierKeywordToken EXPECT_KEYWORD = KtModifierKeywordToken.softKeywordModifier("expect");
KtModifierKeywordToken ACTUAL_KEYWORD = KtModifierKeywordToken.softKeywordModifier("actual");
TokenSet KEYWORDS = TokenSet.create(PACKAGE_KEYWORD, AS_KEYWORD, TYPE_ALIAS_KEYWORD, CLASS_KEYWORD, INTERFACE_KEYWORD,
THIS_KEYWORD, SUPER_KEYWORD, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, FOR_KEYWORD,
NULL_KEYWORD,
TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD,
IN_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD, CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD,
ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD, TRY_KEYWORD, WHEN_KEYWORD,
NOT_IN, NOT_IS, AS_SAFE,
TYPEOF_KEYWORD
);
TokenSet SOFT_KEYWORDS = TokenSet.create(FILE_KEYWORD, IMPORT_KEYWORD, WHERE_KEYWORD, BY_KEYWORD, GET_KEYWORD,
SET_KEYWORD, ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, INNER_KEYWORD,
OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD,
CATCH_KEYWORD, FINALLY_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, REIFIED_KEYWORD,
DYNAMIC_KEYWORD, COMPANION_KEYWORD, CONSTRUCTOR_KEYWORD, INIT_KEYWORD, SEALED_KEYWORD,
FIELD_KEYWORD, PROPERTY_KEYWORD, RECEIVER_KEYWORD, PARAM_KEYWORD, SETPARAM_KEYWORD,
DELEGATE_KEYWORD,
LATEINIT_KEYWORD,
DATA_KEYWORD, INLINE_KEYWORD, NOINLINE_KEYWORD, TAILREC_KEYWORD, EXTERNAL_KEYWORD,
ANNOTATION_KEYWORD, CROSSINLINE_KEYWORD, CONST_KEYWORD, OPERATOR_KEYWORD, INFIX_KEYWORD,
SUSPEND_KEYWORD, HEADER_KEYWORD, IMPL_KEYWORD, EXPECT_KEYWORD, ACTUAL_KEYWORD
);
/*
This array is used in stub serialization:
1. Do not change order.
2. If you add an entry or change order, increase stub version.
*/
KtModifierKeywordToken[] MODIFIER_KEYWORDS_ARRAY =
new KtModifierKeywordToken[] {
ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, INNER_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD,
PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD,
REIFIED_KEYWORD, COMPANION_KEYWORD, SEALED_KEYWORD, LATEINIT_KEYWORD,
DATA_KEYWORD, INLINE_KEYWORD, NOINLINE_KEYWORD, TAILREC_KEYWORD, EXTERNAL_KEYWORD, ANNOTATION_KEYWORD, CROSSINLINE_KEYWORD,
CONST_KEYWORD, OPERATOR_KEYWORD, INFIX_KEYWORD, SUSPEND_KEYWORD,
HEADER_KEYWORD, IMPL_KEYWORD, EXPECT_KEYWORD, ACTUAL_KEYWORD
};
TokenSet MODIFIER_KEYWORDS = TokenSet.create(MODIFIER_KEYWORDS_ARRAY);
TokenSet TYPE_MODIFIER_KEYWORDS = TokenSet.create(SUSPEND_KEYWORD);
TokenSet TYPE_ARGUMENT_MODIFIER_KEYWORDS = TokenSet.create(IN_KEYWORD, OUT_KEYWORD);
TokenSet RESERVED_VALUE_PARAMETER_MODIFIER_KEYWORDS = TokenSet.create(OUT_KEYWORD, VARARG_KEYWORD);
TokenSet VISIBILITY_MODIFIERS = TokenSet.create(PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD);
TokenSet MODALITY_MODIFIERS = TokenSet.create(ABSTRACT_KEYWORD, FINAL_KEYWORD, SEALED_KEYWORD, OPEN_KEYWORD);
TokenSet WHITESPACES = TokenSet.create(TokenType.WHITE_SPACE);
/**
* Don't add KDocTokens to COMMENTS TokenSet, because it is used in KotlinParserDefinition.getCommentTokens(),
* and therefor all COMMENTS tokens will be ignored by PsiBuilder.
*
* @see KtPsiUtil#isInComment(com.intellij.psi.PsiElement)
*/
TokenSet COMMENTS = TokenSet.create(EOL_COMMENT, BLOCK_COMMENT, DOC_COMMENT, SHEBANG_COMMENT);
TokenSet WHITE_SPACE_OR_COMMENT_BIT_SET = TokenSet.orSet(COMMENTS, WHITESPACES);
TokenSet STRINGS = TokenSet.create(CHARACTER_LITERAL, REGULAR_STRING_PART);
TokenSet OPERATIONS = TokenSet.create(AS_KEYWORD, AS_SAFE, IS_KEYWORD, IN_KEYWORD, DOT, PLUSPLUS, MINUSMINUS, EXCLEXCL, MUL, PLUS,
MINUS, EXCL, DIV, PERC, LT, GT, LTEQ, GTEQ, EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR,
SAFE_ACCESS, ELVIS,
RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ,
NOT_IN, NOT_IS,
IDENTIFIER);
TokenSet AUGMENTED_ASSIGNMENTS = TokenSet.create(PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ);
TokenSet ALL_ASSIGNMENTS = TokenSet.create(EQ, PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ);
}
File diff suppressed because it is too large Load Diff
@@ -1,418 +0,0 @@
/*
* 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.parsing;
import com.intellij.lang.PsiBuilder;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.lexer.KtKeywordToken;
import org.jetbrains.kotlin.lexer.KtToken;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.utils.strings.StringsKt;
import java.util.HashMap;
import java.util.Map;
import static org.jetbrains.kotlin.lexer.KtTokens.*;
/*package*/ abstract class AbstractKotlinParsing {
private static final Map<String, KtKeywordToken> SOFT_KEYWORD_TEXTS = new HashMap<>();
static {
for (IElementType type : KtTokens.SOFT_KEYWORDS.getTypes()) {
KtKeywordToken keywordToken = (KtKeywordToken) type;
assert keywordToken.isSoft();
SOFT_KEYWORD_TEXTS.put(keywordToken.getValue(), keywordToken);
}
}
static {
for (IElementType token : KtTokens.KEYWORDS.getTypes()) {
assert token instanceof KtKeywordToken : "Must be KtKeywordToken: " + token;
assert !((KtKeywordToken) token).isSoft() : "Must not be soft: " + token;
}
}
protected final SemanticWhitespaceAwarePsiBuilder myBuilder;
public AbstractKotlinParsing(SemanticWhitespaceAwarePsiBuilder builder) {
this.myBuilder = builder;
}
protected IElementType getLastToken() {
int i = 1;
int currentOffset = myBuilder.getCurrentOffset();
while (i <= currentOffset && WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(-i))) {
i++;
}
return myBuilder.rawLookup(-i);
}
protected boolean expect(KtToken expectation, String message) {
return expect(expectation, message, null);
}
protected PsiBuilder.Marker mark() {
return myBuilder.mark();
}
protected void error(String message) {
myBuilder.error(message);
}
protected boolean expect(KtToken expectation, String message, TokenSet recoverySet) {
if (at(expectation)) {
advance(); // expectation
return true;
}
if (expectation == KtTokens.IDENTIFIER && "`".equals(myBuilder.getTokenText())) {
advance();
}
errorWithRecovery(message, recoverySet);
return false;
}
protected void expectNoAdvance(KtToken expectation, String message) {
if (at(expectation)) {
advance(); // expectation
return;
}
error(message);
}
protected void errorWithRecovery(String message, TokenSet recoverySet) {
IElementType tt = tt();
if (recoverySet == null ||
recoverySet.contains(tt) ||
tt == LBRACE || tt == RBRACE ||
(recoverySet.contains(EOL_OR_SEMICOLON) && (eof() || tt == SEMICOLON || myBuilder.newlineBeforeCurrentToken()))) {
error(message);
}
else {
errorAndAdvance(message);
}
}
protected void errorAndAdvance(String message) {
errorAndAdvance(message, 1);
}
protected void errorAndAdvance(String message, int advanceTokenCount) {
PsiBuilder.Marker err = mark();
advance(advanceTokenCount);
err.error(message);
}
protected boolean eof() {
return myBuilder.eof();
}
protected void advance() {
// TODO: how to report errors on bad characters? (Other than highlighting)
myBuilder.advanceLexer();
}
protected void advance(int advanceTokenCount) {
for (int i = 0; i < advanceTokenCount; i++) {
advance(); // erroneous token
}
}
protected void advanceAt(IElementType current) {
assert _at(current);
myBuilder.advanceLexer();
}
protected IElementType tt() {
return myBuilder.getTokenType();
}
/**
* Side-effect-free version of at()
*/
protected boolean _at(IElementType expectation) {
IElementType token = tt();
return tokenMatches(token, expectation);
}
private boolean tokenMatches(IElementType token, IElementType expectation) {
if (token == expectation) return true;
if (expectation == EOL_OR_SEMICOLON) {
if (eof()) return true;
if (token == SEMICOLON) return true;
if (myBuilder.newlineBeforeCurrentToken()) return true;
}
return false;
}
protected boolean at(IElementType expectation) {
if (_at(expectation)) return true;
IElementType token = tt();
if (token == IDENTIFIER && expectation instanceof KtKeywordToken) {
KtKeywordToken expectedKeyword = (KtKeywordToken) expectation;
if (expectedKeyword.isSoft() && expectedKeyword.getValue().equals(myBuilder.getTokenText())) {
myBuilder.remapCurrentToken(expectation);
return true;
}
}
if (expectation == IDENTIFIER && token instanceof KtKeywordToken) {
KtKeywordToken keywordToken = (KtKeywordToken) token;
if (keywordToken.isSoft()) {
myBuilder.remapCurrentToken(IDENTIFIER);
return true;
}
}
return false;
}
/**
* Side-effect-free version of atSet()
*/
protected boolean _atSet(IElementType... tokens) {
return _atSet(TokenSet.create(tokens));
}
/**
* Side-effect-free version of atSet()
*/
private boolean _atSet(TokenSet set) {
IElementType token = tt();
if (set.contains(token)) return true;
if (set.contains(EOL_OR_SEMICOLON)) {
if (eof()) return true;
if (token == SEMICOLON) return true;
if (myBuilder.newlineBeforeCurrentToken()) return true;
}
return false;
}
protected boolean atSet(IElementType... tokens) {
return atSet(TokenSet.create(tokens));
}
protected boolean atSet(TokenSet set) {
if (_atSet(set)) return true;
IElementType token = tt();
if (token == IDENTIFIER) {
KtKeywordToken keywordToken = SOFT_KEYWORD_TEXTS.get(myBuilder.getTokenText());
if (keywordToken != null && set.contains(keywordToken)) {
myBuilder.remapCurrentToken(keywordToken);
return true;
}
}
else {
// We know at this point that <code>set</code> does not contain <code>token</code>
if (set.contains(IDENTIFIER) && token instanceof KtKeywordToken) {
if (((KtKeywordToken) token).isSoft()) {
myBuilder.remapCurrentToken(IDENTIFIER);
return true;
}
}
}
return false;
}
protected IElementType lookahead(int k) {
return myBuilder.lookAhead(k);
}
protected boolean consumeIf(KtToken token) {
if (at(token)) {
advance(); // token
return true;
}
return false;
}
// TODO: Migrate to predicates
protected void skipUntil(TokenSet tokenSet) {
boolean stopAtEolOrSemi = tokenSet.contains(EOL_OR_SEMICOLON);
while (!eof() && !tokenSet.contains(tt()) && !(stopAtEolOrSemi && at(EOL_OR_SEMICOLON))) {
advance();
}
}
protected void errorUntil(String message, TokenSet tokenSet) {
assert tokenSet.contains(LBRACE) : "Cannot include LBRACE into error element!";
assert tokenSet.contains(RBRACE) : "Cannot include RBRACE into error element!";
PsiBuilder.Marker error = mark();
skipUntil(tokenSet);
error.error(message);
}
protected static void errorIf(PsiBuilder.Marker marker, boolean condition, String message) {
if (condition) {
marker.error(message);
}
else {
marker.drop();
}
}
protected class OptionalMarker {
private final PsiBuilder.Marker marker;
private final int offset;
public OptionalMarker(boolean actuallyMark) {
marker = actuallyMark ? mark() : null;
offset = myBuilder.getCurrentOffset();
}
public void done(IElementType elementType) {
if (marker == null) return;
marker.done(elementType);
}
public void error(String message) {
if (marker == null) return;
if (offset == myBuilder.getCurrentOffset()) {
marker.drop(); // no empty errors
}
else {
marker.error(message);
}
}
public void drop() {
if (marker == null) return;
marker.drop();
}
}
protected int matchTokenStreamPredicate(TokenStreamPattern pattern) {
PsiBuilder.Marker currentPosition = mark();
Stack<IElementType> opens = new Stack<>();
int openAngleBrackets = 0;
int openBraces = 0;
int openParentheses = 0;
int openBrackets = 0;
while (!eof()) {
if (pattern.processToken(
myBuilder.getCurrentOffset(),
pattern.isTopLevel(openAngleBrackets, openBrackets, openBraces, openParentheses))) {
break;
}
if (at(LPAR)) {
openParentheses++;
opens.push(LPAR);
}
else if (at(LT)) {
openAngleBrackets++;
opens.push(LT);
}
else if (at(LBRACE)) {
openBraces++;
opens.push(LBRACE);
}
else if (at(LBRACKET)) {
openBrackets++;
opens.push(LBRACKET);
}
else if (at(RPAR)) {
openParentheses--;
if (opens.isEmpty() || opens.pop() != LPAR) {
if (pattern.handleUnmatchedClosing(RPAR)) {
break;
}
}
}
else if (at(GT)) {
openAngleBrackets--;
}
else if (at(RBRACE)) {
openBraces--;
}
else if (at(RBRACKET)) {
openBrackets--;
}
advance(); // skip token
}
currentPosition.rollbackTo();
return pattern.result();
}
protected boolean eol() {
return myBuilder.newlineBeforeCurrentToken() || eof();
}
protected static void closeDeclarationWithCommentBinders(@NotNull PsiBuilder.Marker marker, @NotNull IElementType elementType, boolean precedingNonDocComments) {
marker.done(elementType);
marker.setCustomEdgeTokenBinders(precedingNonDocComments ? PrecedingCommentsBinder.INSTANCE : PrecedingDocCommentsBinder.INSTANCE,
TrailingCommentsBinder.INSTANCE);
}
protected abstract KotlinParsing create(SemanticWhitespaceAwarePsiBuilder builder);
protected KotlinParsing createTruncatedBuilder(int eofPosition) {
return create(new TruncatedSemanticWhitespaceAwarePsiBuilder(myBuilder, eofPosition));
}
protected class At extends AbstractTokenStreamPredicate {
private final IElementType lookFor;
private final boolean topLevelOnly;
public At(IElementType lookFor, boolean topLevelOnly) {
this.lookFor = lookFor;
this.topLevelOnly = topLevelOnly;
}
public At(IElementType lookFor) {
this(lookFor, true);
}
@Override
public boolean matching(boolean topLevel) {
return (topLevel || !topLevelOnly) && at(lookFor);
}
}
protected class AtSet extends AbstractTokenStreamPredicate {
private final TokenSet lookFor;
private final TokenSet topLevelOnly;
public AtSet(TokenSet lookFor, TokenSet topLevelOnly) {
this.lookFor = lookFor;
this.topLevelOnly = topLevelOnly;
}
public AtSet(TokenSet lookFor) {
this(lookFor, lookFor);
}
@Override
public boolean matching(boolean topLevel) {
return (topLevel || !atSet(topLevelOnly)) && atSet(lookFor);
}
}
@SuppressWarnings("UnusedDeclaration")
@TestOnly
public String currentContext() {
return StringsKt.substringWithContext(myBuilder.getOriginalText(), myBuilder.getCurrentOffset(), myBuilder.getCurrentOffset(), 20);
}
}
@@ -1,44 +0,0 @@
/*
* 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.parsing;
import com.intellij.psi.tree.IElementType;
public abstract class AbstractTokenStreamPattern implements TokenStreamPattern {
protected int lastOccurrence = -1;
protected void fail() {
lastOccurrence = -1;
}
@Override
public int result() {
return lastOccurrence;
}
@Override
public boolean isTopLevel(int openAngleBrackets, int openBrackets, int openBraces, int openParentheses) {
return openBraces == 0 && openBrackets == 0 && openParentheses == 0 && openAngleBrackets == 0;
}
@Override
public boolean handleUnmatchedClosing(IElementType token) {
return false;
}
}
@@ -1,31 +0,0 @@
/*
* 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.parsing;
public abstract class AbstractTokenStreamPredicate implements TokenStreamPredicate {
@Override
public TokenStreamPredicate or(TokenStreamPredicate other) {
return new AbstractTokenStreamPredicate() {
@Override
public boolean matching(boolean topLevel) {
if (AbstractTokenStreamPredicate.this.matching(topLevel)) return true;
return other.matching(topLevel);
}
};
}
}
@@ -1,21 +0,0 @@
/*
* 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.parsing;
public interface Consumer<T> {
void consume(T item);
}
@@ -1,39 +0,0 @@
/*
* 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.parsing;
public class FirstBefore extends AbstractTokenStreamPattern {
private final TokenStreamPredicate lookFor;
private final TokenStreamPredicate stopAt;
public FirstBefore(TokenStreamPredicate lookFor, TokenStreamPredicate stopAt) {
this.lookFor = lookFor;
this.stopAt = stopAt;
}
@Override
public boolean processToken(int offset, boolean topLevel) {
if (lookFor.matching(topLevel)) {
lastOccurrence = offset;
return true;
}
if (stopAt.matching(topLevel)) {
return true;
}
return false;
}
}
File diff suppressed because it is too large Load Diff
@@ -1,83 +0,0 @@
/*
* 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.parsing;
import com.intellij.lang.ASTNode;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiParser;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.script.ScriptDefinitionProvider;
public class KotlinParser implements PsiParser {
private final ScriptDefinitionProvider scriptDefinitionProvider;
public KotlinParser(Project project) {
scriptDefinitionProvider = ScriptDefinitionProvider.Companion.getInstance(project);
}
@Override
@NotNull
public ASTNode parse(@NotNull IElementType iElementType, @NotNull PsiBuilder psiBuilder) {
throw new IllegalStateException("use another parse");
}
// we need this method because we need psiFile
@NotNull
public ASTNode parse(IElementType iElementType, PsiBuilder psiBuilder, PsiFile psiFile) {
KotlinParsing ktParsing = KotlinParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(psiBuilder));
if (scriptDefinitionProvider != null && scriptDefinitionProvider.isScript(psiFile.getName())
|| psiFile.getName().endsWith(KotlinParserDefinition.STD_SCRIPT_EXT)) {
ktParsing.parseScript();
}
else {
ktParsing.parseFile();
}
return psiBuilder.getTreeBuilt();
}
@NotNull
public static ASTNode parseTypeCodeFragment(PsiBuilder psiBuilder) {
KotlinParsing ktParsing = KotlinParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(psiBuilder));
ktParsing.parseTypeCodeFragment();
return psiBuilder.getTreeBuilt();
}
@NotNull
public static ASTNode parseExpressionCodeFragment(PsiBuilder psiBuilder) {
KotlinParsing ktParsing = KotlinParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(psiBuilder));
ktParsing.parseExpressionCodeFragment();
return psiBuilder.getTreeBuilt();
}
@NotNull
public static ASTNode parseBlockCodeFragment(PsiBuilder psiBuilder) {
KotlinParsing ktParsing = KotlinParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(psiBuilder));
ktParsing.parseBlockCodeFragment();
return psiBuilder.getTreeBuilt();
}
@NotNull
public static ASTNode parseLambdaExpression(PsiBuilder psiBuilder) {
KotlinParsing ktParsing = KotlinParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(psiBuilder));
ktParsing.parseLambdaExpression();
return psiBuilder.getTreeBuilt();
}
}
@@ -1,113 +0,0 @@
/*
* 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.parsing
import com.intellij.extapi.psi.ASTWrapperPsiElement
import com.intellij.lang.ASTNode
import com.intellij.lang.LanguageParserDefinitions
import com.intellij.lang.ParserDefinition
import com.intellij.lang.ParserDefinition.SpaceRequirements.*
import com.intellij.lang.PsiParser
import com.intellij.lexer.Lexer
import com.intellij.openapi.project.Project
import com.intellij.psi.FileViewProvider
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.tree.IFileElementType
import com.intellij.psi.tree.TokenSet
import org.jetbrains.kotlin.KtNodeType
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.idea.KotlinLanguage
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.KotlinLexer
import org.jetbrains.kotlin.lexer.KtKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtWhenEntry
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementType
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
class KotlinParserDefinition : ParserDefinition {
override fun createLexer(project: Project): Lexer = KotlinLexer()
override fun createParser(project: Project): PsiParser = KotlinParser(project)
override fun getFileNodeType(): IFileElementType = KtStubElementTypes.FILE
override fun getWhitespaceTokens(): TokenSet = KtTokens.WHITESPACES
override fun getCommentTokens(): TokenSet = KtTokens.COMMENTS
override fun getStringLiteralElements(): TokenSet = KtTokens.STRINGS
override fun createElement(astNode: ASTNode): PsiElement {
val elementType = astNode.elementType
return when (elementType) {
is KtStubElementType<*, *> -> elementType.createPsiFromAst(astNode)
KtNodeTypes.TYPE_CODE_FRAGMENT, KtNodeTypes.EXPRESSION_CODE_FRAGMENT, KtNodeTypes.BLOCK_CODE_FRAGMENT -> ASTWrapperPsiElement(
astNode
)
is KDocElementType -> elementType.createPsi(astNode)
KDocTokens.MARKDOWN_LINK -> KDocLink(astNode)
else -> (elementType as KtNodeType).createPsi(astNode)
}
}
override fun createFile(fileViewProvider: FileViewProvider): PsiFile = KtFile(fileViewProvider, false)
override fun spaceExistanceTypeBetweenTokens(left: ASTNode, right: ASTNode): ParserDefinition.SpaceRequirements {
val rightTokenType = right.elementType
// get/set from a new line
if (rightTokenType == KtTokens.GET_KEYWORD || rightTokenType == KtTokens.SET_KEYWORD) {
return MUST_LINE_BREAK
}
val leftTokenType = left.elementType
if (leftTokenType is KtKeywordToken && rightTokenType is KtKeywordToken) return MUST
// When entry from a new line
val rightWhenEntry = right.psi.getNonStrictParentOfType<KtWhenEntry>()
if (rightWhenEntry != null) {
val leftWhenEntry = left.psi.getNonStrictParentOfType<KtWhenEntry>()
if (leftWhenEntry != null && leftWhenEntry != rightWhenEntry && leftTokenType != KtTokens.SEMICOLON) {
return MUST_LINE_BREAK
}
}
// Default
return MAY
}
companion object {
@JvmField
val STD_SCRIPT_SUFFIX = "kts"
@JvmField
val STD_SCRIPT_EXT = "." + STD_SCRIPT_SUFFIX
val instance: KotlinParserDefinition
get() = LanguageParserDefinitions.INSTANCE.forLanguage(KotlinLanguage.INSTANCE) as KotlinParserDefinition
}
}
File diff suppressed because it is too large Load Diff
@@ -1,147 +0,0 @@
/*
* 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.parsing
import com.intellij.lang.WhitespacesAndCommentsBinder
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.lexer.KtTokens
object PrecedingCommentsBinder : WhitespacesAndCommentsBinder {
override fun getEdgePosition(
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter
): Int {
if (tokens.isEmpty()) return 0
// 1. bind doc comment
for (idx in tokens.indices.reversed()) {
if (tokens[idx] == KtTokens.DOC_COMMENT) return idx
}
// 2. bind plain comments
var result = tokens.size
tokens@ for (idx in tokens.indices.reversed()) {
val tokenType = tokens[idx]
when (tokenType) {
KtTokens.WHITE_SPACE -> if (StringUtil.getLineBreakCount(getter[idx]) > 1) break@tokens
in KtTokens.COMMENTS -> {
if (idx == 0 || tokens[idx - 1] == KtTokens.WHITE_SPACE && StringUtil.containsLineBreak(getter[idx - 1])) {
result = idx
}
}
else -> break@tokens
}
}
return result
}
}
object PrecedingDocCommentsBinder : WhitespacesAndCommentsBinder {
override fun getEdgePosition(
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter
): Int {
if (tokens.isEmpty()) return 0
for (idx in tokens.indices.reversed()) {
if (tokens[idx] == KtTokens.DOC_COMMENT) return idx
}
return tokens.size
}
}
// Binds comments on the same line
object TrailingCommentsBinder : WhitespacesAndCommentsBinder {
override fun getEdgePosition(
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter
): Int {
if (tokens.isEmpty()) return 0
var result = 0
tokens@ for (idx in tokens.indices) {
val tokenType = tokens[idx]
when (tokenType) {
KtTokens.WHITE_SPACE -> if (StringUtil.containsLineBreak(getter[idx])) break@tokens
KtTokens.EOL_COMMENT, KtTokens.BLOCK_COMMENT -> result = idx + 1
else -> break@tokens
}
}
return result
}
}
private class AllCommentsBinder(val isTrailing: Boolean) : WhitespacesAndCommentsBinder {
override fun getEdgePosition(
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter
): Int {
if (tokens.isEmpty()) return 0
val size = tokens.size
// Skip one whitespace if needed. Expect that there can't be several consecutive whitespaces
val endToken = tokens[if (isTrailing) size - 1 else 0]
val shift = if (endToken == KtTokens.WHITE_SPACE) 1 else 0
return if (isTrailing) size - shift else shift
}
}
@JvmField
val PRECEDING_ALL_COMMENTS_BINDER: WhitespacesAndCommentsBinder = AllCommentsBinder(false)
@JvmField
val TRAILING_ALL_COMMENTS_BINDER: WhitespacesAndCommentsBinder = AllCommentsBinder(true)
object DoNotBindAnything : WhitespacesAndCommentsBinder {
override fun getEdgePosition(
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter
): Int {
return 0
}
}
object BindFirstShebangWithWhitespaceOnly : WhitespacesAndCommentsBinder {
override fun getEdgePosition(
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter
): Int {
if (tokens.firstOrNull() == KtTokens.SHEBANG_COMMENT) {
return if (tokens.getOrNull(1) == KtTokens.WHITE_SPACE) 2 else 1
}
return 0
}
}
class BindAll(val isTrailing: Boolean) : WhitespacesAndCommentsBinder {
override fun getEdgePosition(
tokens: List<IElementType>, atStreamEdge: Boolean, getter: WhitespacesAndCommentsBinder.TokenTextGetter
): Int {
return if (!isTrailing) 0 else tokens.size
}
}
@JvmField
val PRECEDING_ALL_BINDER: WhitespacesAndCommentsBinder = BindAll(false)
@JvmField
val TRAILING_ALL_BINDER: WhitespacesAndCommentsBinder = BindAll(true)
@@ -1,50 +0,0 @@
/*
* 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.parsing;
public class LastBefore extends AbstractTokenStreamPattern {
private final boolean dontStopRightAfterOccurrence;
private final TokenStreamPredicate lookFor;
private final TokenStreamPredicate stopAt;
private boolean previousLookForResult;
public LastBefore(TokenStreamPredicate lookFor, TokenStreamPredicate stopAt, boolean dontStopRightAfterOccurrence) {
this.lookFor = lookFor;
this.stopAt = stopAt;
this.dontStopRightAfterOccurrence = dontStopRightAfterOccurrence;
}
public LastBefore(TokenStreamPredicate lookFor, TokenStreamPredicate stopAt) {
this(lookFor, stopAt, false);
}
@Override
public boolean processToken(int offset, boolean topLevel) {
boolean lookForResult = lookFor.matching(topLevel);
if (lookForResult) {
lastOccurrence = offset;
}
if (stopAt.matching(topLevel)) {
if (topLevel
&& (!dontStopRightAfterOccurrence
|| !previousLookForResult)) return true;
}
previousLookForResult = lookForResult;
return false;
}
}
@@ -1,36 +0,0 @@
/*
* 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.parsing;
import com.intellij.lang.PsiBuilder;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
public interface SemanticWhitespaceAwarePsiBuilder extends PsiBuilder {
// TODO: comments go to wrong place when an empty element is created, see IElementType.isLeftBound()
boolean newlineBeforeCurrentToken();
void disableNewlines();
void enableNewlines();
void restoreNewlinesState();
void restoreJoiningComplexTokensState();
void enableJoiningComplexTokens();
void disableJoiningComplexTokens();
boolean isWhitespaceOrComment(@NotNull IElementType elementType);
}
@@ -1,71 +0,0 @@
/*
* 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.parsing;
import com.intellij.lang.impl.PsiBuilderAdapter;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
public class SemanticWhitespaceAwarePsiBuilderAdapter extends PsiBuilderAdapter implements SemanticWhitespaceAwarePsiBuilder {
private final SemanticWhitespaceAwarePsiBuilder myBuilder;
public SemanticWhitespaceAwarePsiBuilderAdapter(SemanticWhitespaceAwarePsiBuilder builder) {
super(builder);
this.myBuilder = builder;
}
@Override
public boolean newlineBeforeCurrentToken() {
return myBuilder.newlineBeforeCurrentToken();
}
@Override
public void disableNewlines() {
myBuilder.disableNewlines();
}
@Override
public void enableNewlines() {
myBuilder.enableNewlines();
}
@Override
public void restoreNewlinesState() {
myBuilder.restoreNewlinesState();
}
@Override
public void restoreJoiningComplexTokensState() {
myBuilder.restoreJoiningComplexTokensState();
}
@Override
public void enableJoiningComplexTokens() {
myBuilder.enableJoiningComplexTokens();
}
@Override
public void disableJoiningComplexTokens() {
myBuilder.disableJoiningComplexTokens();
}
@Override
public boolean isWhitespaceOrComment(@NotNull IElementType elementType) {
return myBuilder.isWhitespaceOrComment(elementType);
}
}
@@ -1,48 +0,0 @@
/*
* 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.parsing;
public class SemanticWhitespaceAwarePsiBuilderForByClause extends SemanticWhitespaceAwarePsiBuilderAdapter {
private int stackSize = 0;
public SemanticWhitespaceAwarePsiBuilderForByClause(SemanticWhitespaceAwarePsiBuilder builder) {
super(builder);
}
@Override
public void disableNewlines() {
super.disableNewlines();
stackSize++;
}
@Override
public void enableNewlines() {
super.enableNewlines();
stackSize++;
}
@Override
public void restoreNewlinesState() {
super.restoreNewlinesState();
stackSize--;
}
public int getStackSize() {
return stackSize;
}
}
@@ -1,199 +0,0 @@
/*
* 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.parsing;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.impl.PsiBuilderAdapter;
import com.intellij.lang.impl.PsiBuilderImpl;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.lexer.KtTokens;
import static org.jetbrains.kotlin.lexer.KtTokens.*;
public class SemanticWhitespaceAwarePsiBuilderImpl extends PsiBuilderAdapter implements SemanticWhitespaceAwarePsiBuilder {
private final TokenSet complexTokens = TokenSet.create(SAFE_ACCESS, ELVIS, EXCLEXCL);
private final Stack<Boolean> joinComplexTokens = new Stack<>();
private final Stack<Boolean> newlinesEnabled = new Stack<>();
private final PsiBuilderImpl delegateImpl;
public SemanticWhitespaceAwarePsiBuilderImpl(PsiBuilder delegate) {
super(delegate);
newlinesEnabled.push(true);
joinComplexTokens.push(true);
delegateImpl = findPsiBuilderImpl(delegate);
}
@Nullable
private static PsiBuilderImpl findPsiBuilderImpl(PsiBuilder builder) {
// This is a hackish workaround for PsiBuilder interface not exposing isWhitespaceOrComment() method
// We have to unwrap all the adapters to find an Impl inside
while (true) {
if (builder instanceof PsiBuilderImpl) {
return (PsiBuilderImpl) builder;
}
if (!(builder instanceof PsiBuilderAdapter)) {
return null;
}
builder = ((PsiBuilderAdapter) builder).getDelegate();
}
}
@Override
public boolean isWhitespaceOrComment(@NotNull IElementType elementType) {
assert delegateImpl != null : "PsiBuilderImpl not found";
return delegateImpl.whitespaceOrComment(elementType);
}
@Override
public boolean newlineBeforeCurrentToken() {
if (!newlinesEnabled.peek()) return false;
if (eof()) return true;
// TODO: maybe, memoize this somehow?
for (int i = 1; i <= getCurrentOffset(); i++) {
IElementType previousToken = rawLookup(-i);
if (previousToken == KtTokens.BLOCK_COMMENT
|| previousToken == KtTokens.DOC_COMMENT
|| previousToken == KtTokens.EOL_COMMENT
|| previousToken == SHEBANG_COMMENT) {
continue;
}
if (previousToken != TokenType.WHITE_SPACE) {
break;
}
int previousTokenStart = rawTokenTypeStart(-i);
int previousTokenEnd = rawTokenTypeStart(-i + 1);
assert previousTokenStart >= 0;
assert previousTokenEnd < getOriginalText().length();
for (int j = previousTokenStart; j < previousTokenEnd; j++) {
if (getOriginalText().charAt(j) == '\n') {
return true;
}
}
}
return false;
}
@Override
public void disableNewlines() {
newlinesEnabled.push(false);
}
@Override
public void enableNewlines() {
newlinesEnabled.push(true);
}
@Override
public void restoreNewlinesState() {
assert newlinesEnabled.size() > 1;
newlinesEnabled.pop();
}
private boolean joinComplexTokens() {
return joinComplexTokens.peek();
}
@Override
public void restoreJoiningComplexTokensState() {
joinComplexTokens.pop();
}
@Override
public void enableJoiningComplexTokens() {
joinComplexTokens.push(true);
}
@Override
public void disableJoiningComplexTokens() {
joinComplexTokens.push(false);
}
@Override
public IElementType getTokenType() {
if (!joinComplexTokens()) return super.getTokenType();
return getJoinedTokenType(super.getTokenType(), 1);
}
private IElementType getJoinedTokenType(IElementType rawTokenType, int rawLookupSteps) {
if (rawTokenType == QUEST) {
IElementType nextRawToken = rawLookup(rawLookupSteps);
if (nextRawToken == DOT) return SAFE_ACCESS;
if (nextRawToken == COLON) return ELVIS;
}
else if (rawTokenType == EXCL) {
IElementType nextRawToken = rawLookup(rawLookupSteps);
if (nextRawToken == EXCL) return EXCLEXCL;
}
return rawTokenType;
}
@Override
public void advanceLexer() {
if (!joinComplexTokens()) {
super.advanceLexer();
return;
}
IElementType tokenType = getTokenType();
if (complexTokens.contains(tokenType)) {
Marker mark = mark();
super.advanceLexer();
super.advanceLexer();
mark.collapse(tokenType);
}
else {
super.advanceLexer();
}
}
@Override
public String getTokenText() {
if (!joinComplexTokens()) return super.getTokenText();
IElementType tokenType = getTokenType();
if (complexTokens.contains(tokenType)) {
if (tokenType == ELVIS) return "?:";
if (tokenType == SAFE_ACCESS) return "?.";
}
return super.getTokenText();
}
@Override
public IElementType lookAhead(int steps) {
if (!joinComplexTokens()) return super.lookAhead(steps);
if (complexTokens.contains(getTokenType())) {
return super.lookAhead(steps + 1);
}
return getJoinedTokenType(super.lookAhead(steps), 2);
}
}
@@ -1,48 +0,0 @@
/*
* 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.parsing;
import com.intellij.psi.tree.IElementType;
public interface TokenStreamPattern {
/**
* Called on each token
*
* @param offset
* @param topLevel see {@link #isTopLevel(int, int, int, int)}
* @return <code>true</code> to stop
*/
boolean processToken(int offset, boolean topLevel);
/**
* @return the position where the predicate has matched, -1 if no match was found
*/
int result();
/**
* Decides if the combination of open bracket counts makes a "top level position"
* Straightforward meaning would be: if all counts are zero, then it's a top level
*/
boolean isTopLevel(int openAngleBrackets, int openBrackets, int openBraces, int openParentheses);
/**
* Called on right parentheses, brackets, braces and angles (>)
* @param token the closing bracket
* @return true to stop matching, false to proceed
*/
boolean handleUnmatchedClosing(IElementType token);
}
@@ -1,23 +0,0 @@
/*
* 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.parsing;
public interface TokenStreamPredicate {
boolean matching(boolean topLevel);
TokenStreamPredicate or(TokenStreamPredicate other);
}
@@ -1,78 +0,0 @@
/*
* 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.parsing;
import com.intellij.psi.tree.IElementType;
public class TruncatedSemanticWhitespaceAwarePsiBuilder extends SemanticWhitespaceAwarePsiBuilderAdapter {
private final int myEOFPosition;
public TruncatedSemanticWhitespaceAwarePsiBuilder(SemanticWhitespaceAwarePsiBuilder builder, int eofPosition) {
super(builder);
this.myEOFPosition = eofPosition;
}
@Override
public boolean eof() {
return super.eof() || isOffsetBeyondEof(getCurrentOffset());
}
@Override
public String getTokenText() {
if (eof()) return null;
return super.getTokenText();
}
@Override
public IElementType getTokenType() {
if (eof()) return null;
return super.getTokenType();
}
@Override
public IElementType lookAhead(int steps) {
if (eof()) return null;
int rawLookAheadSteps = rawLookAhead(steps);
if (isOffsetBeyondEof(rawTokenTypeStart(rawLookAheadSteps))) return null;
return super.rawLookup(rawLookAheadSteps);
}
private int rawLookAhead(int steps) {
// This code reproduces the behavior of PsiBuilderImpl.lookAhead(), but returns a number of raw steps instead of a token type
// This is required for implementing truncated builder behavior
int cur = 0;
while (steps > 0) {
cur++;
IElementType rawTokenType = rawLookup(cur);
while (rawTokenType != null && isWhitespaceOrComment(rawTokenType)) {
cur++;
rawTokenType = rawLookup(cur);
}
steps--;
}
return cur;
}
private boolean isOffsetBeyondEof(int offsetFromCurrent) {
return myEOFPosition >= 0 && offsetFromCurrent >= myEOFPosition;
}
}
@@ -1,75 +0,0 @@
/*
* Copyright 2010-2017 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import java.util.List;
public interface Call {
// SAFE_ACCESS or DOT or so
@Nullable
ASTNode getCallOperationNode();
default boolean isSemanticallyEquivalentToSafeCall() {
return getCallOperationNode() != null && getCallOperationNode().getElementType() == KtTokens.SAFE_ACCESS;
}
@Nullable
Receiver getExplicitReceiver();
@Nullable
ReceiverValue getDispatchReceiver();
@Nullable
KtExpression getCalleeExpression();
@Nullable
KtValueArgumentList getValueArgumentList();
@ReadOnly
@NotNull
List<? extends ValueArgument> getValueArguments();
@ReadOnly
@NotNull
List<? extends LambdaArgument> getFunctionLiteralArguments();
@ReadOnly
@NotNull
List<KtTypeProjection> getTypeArguments();
@Nullable
KtTypeArgumentList getTypeArgumentList();
@NotNull
KtElement getCallElement();
enum CallType {
DEFAULT, ARRAY_GET_METHOD, ARRAY_SET_METHOD, INVOKE
}
@NotNull
Call.CallType getCallType();
}
@@ -1,94 +0,0 @@
/*
* Copyright 2010-2016 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.psi
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.psiUtil.siblings
object EditCommaSeparatedListHelper {
@JvmOverloads
fun <TItem : KtElement> addItem(list: KtElement, allItems: List<TItem>, item: TItem, prefix: KtToken = KtTokens.LPAR): TItem {
return addItemBefore(list, allItems, item, null, prefix)
}
@JvmOverloads
fun <TItem : KtElement> addItemAfter(
list: KtElement,
allItems: List<TItem>,
item: TItem,
anchor: TItem?,
prefix: KtToken = KtTokens.LPAR
): TItem {
assert(anchor == null || anchor.parent == list)
if (allItems.isEmpty()) {
return if (list.firstChild?.node?.elementType == prefix) {
list.addAfter(item, list.firstChild) as TItem
} else {
list.add(item) as TItem
}
} else {
var comma = KtPsiFactory(list).createComma()
return if (anchor != null) {
comma = list.addAfter(comma, anchor)
list.addAfter(item, comma) as TItem
} else {
comma = list.addBefore(comma, allItems.first())
list.addBefore(item, comma) as TItem
}
}
}
@JvmOverloads
fun <TItem : KtElement> addItemBefore(
list: KtElement,
allItems: List<TItem>,
item: TItem,
anchor: TItem?,
prefix: KtToken = KtTokens.LPAR
): TItem {
val anchorAfter: TItem?
anchorAfter = if (allItems.isEmpty()) {
assert(anchor == null)
null
} else {
if (anchor != null) {
val index = allItems.indexOf(anchor)
assert(index >= 0)
if (index > 0) allItems[index - 1] else null
} else {
allItems[allItems.size - 1]
}
}
return addItemAfter(list, allItems, item, anchorAfter, prefix)
}
fun <TItem : KtElement> removeItem(item: TItem) {
var comma = item.siblings(withItself = false).firstOrNull { it !is PsiWhiteSpace && it !is PsiComment }
if (comma?.node?.elementType != KtTokens.COMMA) {
comma = item.siblings(forward = false, withItself = false).firstOrNull { it !is PsiWhiteSpace && it !is PsiComment }
if (comma?.node?.elementType != KtTokens.COMMA) {
comma = null
}
}
item.delete()
comma?.delete()
}
}
@@ -1,34 +0,0 @@
/*
* Copyright 2010-2016 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.psi.findDocComment
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtDeclarationModifierList
import org.jetbrains.kotlin.psi.psiUtil.allChildren
fun findDocComment(declaration: KtDeclaration): KDoc? {
return declaration.allChildren
.flatMap {
if (it is KtDeclarationModifierList) {
return@flatMap it.children.asSequence()
}
sequenceOf(it)
}
.dropWhile { it !is KDoc }
.firstOrNull() as? KDoc
}
@@ -1,29 +0,0 @@
/*
* 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.psi;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Comes along with @Nullable to indicate null is only possible if parsing error present
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface IfNotParsed {}
@@ -1,22 +0,0 @@
/*
* 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.psi
interface KotlinDeclarationNavigationPolicy {
fun getOriginalElement(declaration: KtDeclaration): KtElement
fun getNavigationElement(declaration: KtDeclaration): KtElement
}
@@ -1,80 +0,0 @@
/*
* 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.psi
import com.intellij.psi.LiteralTextEscaper
import com.intellij.openapi.util.TextRange
import gnu.trove.TIntArrayList
import org.jetbrains.kotlin.psi.psiUtil.getContentRange
import org.jetbrains.kotlin.psi.psiUtil.isSingleQuoted
class KotlinStringLiteralTextEscaper(host: KtStringTemplateExpression) : LiteralTextEscaper<KtStringTemplateExpression>(host) {
private var sourceOffsets: IntArray? = null
override fun decode(rangeInsideHost: TextRange, outChars: StringBuilder): Boolean {
val sourceOffsetsList = TIntArrayList()
var sourceOffset = 0
for (child in myHost.entries) {
val childRange = TextRange.from(child.startOffsetInParent, child.textLength)
if (rangeInsideHost.endOffset <= childRange.startOffset) {
break
}
if (childRange.endOffset <= rangeInsideHost.startOffset) {
continue
}
when (child) {
is KtEscapeStringTemplateEntry -> {
if (!rangeInsideHost.contains(childRange)) {
//don't allow injection if its range starts or ends inside escaped sequence
return false
}
val unescaped = child.unescapedValue
outChars.append(unescaped)
repeat(unescaped.length) {
sourceOffsetsList.add(sourceOffset)
}
sourceOffset += child.getTextLength()
}
else -> {
val textRange = rangeInsideHost.intersection(childRange)!!.shiftRight(-childRange.startOffset)
outChars.append(child.text, textRange.startOffset, textRange.endOffset)
repeat(textRange.length) {
sourceOffsetsList.add(sourceOffset++)
}
}
}
}
sourceOffsetsList.add(sourceOffset)
sourceOffsets = sourceOffsetsList.toNativeArray()
return true
}
override fun getOffsetInHost(offsetInDecoded: Int, rangeInsideHost: TextRange): Int {
val offsets = sourceOffsets
if (offsets == null || offsetInDecoded >= offsets.size) return -1
return Math.min(offsets[offsetInDecoded], rangeInsideHost.length) + rangeInsideHost.startOffset
}
override fun getRelevantTextRange(): TextRange {
return myHost.getContentRange()
}
override fun isOneLine(): Boolean {
return myHost.isSingleQuoted()
}
}
@@ -1,29 +0,0 @@
/*
* 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.psi;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public interface KtAnnotated extends KtElement {
@NotNull
List<KtAnnotation> getAnnotations();
@NotNull
List<KtAnnotationEntry> getAnnotationEntries();
}
@@ -1,53 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.KtNodeTypes;
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
import java.util.List;
public class KtAnnotatedExpression extends KtExpressionImpl implements KtAnnotated, KtAnnotationsContainer {
public KtAnnotatedExpression(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitAnnotatedExpression(this, data);
}
@Nullable
public KtExpression getBaseExpression() {
return findChildByClass(KtExpression.class);
}
@Override
@NotNull
public List<KtAnnotation> getAnnotations() {
return findChildrenByType(KtNodeTypes.ANNOTATION);
}
@Override
@NotNull
public List<KtAnnotationEntry> getAnnotationEntries() {
return KtPsiUtilKt.collectAnnotationEntriesFromStubOrPsi(this);
}
}
@@ -1,59 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub;
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
import java.util.List;
public class KtAnnotation extends KtElementImplStub<KotlinPlaceHolderStub<KtAnnotation>> {
public KtAnnotation(@NotNull ASTNode node) {
super(node);
}
public KtAnnotation(KotlinPlaceHolderStub<KtAnnotation> stub) {
super(stub, KtStubElementTypes.ANNOTATION);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitAnnotation(this, data);
}
public List<KtAnnotationEntry> getEntries() {
return getStubOrPsiChildrenAsList(KtStubElementTypes.ANNOTATION_ENTRY);
}
@Nullable
public KtAnnotationUseSiteTarget getUseSiteTarget() {
return getStubOrPsiChild(KtStubElementTypes.ANNOTATION_TARGET);
}
public void removeEntry(@NotNull KtAnnotationEntry entry) {
if (getEntries().size() > 1) {
entry.delete();
}
else {
delete();
}
}
}
@@ -1,149 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.KtNodeTypes;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.stubs.KotlinAnnotationEntryStub;
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
import java.util.Collections;
import java.util.List;
public class KtAnnotationEntry extends KtElementImplStub<KotlinAnnotationEntryStub> implements KtCallElement {
public KtAnnotationEntry(@NotNull ASTNode node) {
super(node);
}
public KtAnnotationEntry(@NotNull KotlinAnnotationEntryStub stub) {
super(stub, KtStubElementTypes.ANNOTATION_ENTRY);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitAnnotationEntry(this, data);
}
@Nullable @IfNotParsed
public KtTypeReference getTypeReference() {
KtConstructorCalleeExpression calleeExpression = getCalleeExpression();
if (calleeExpression == null) {
return null;
}
return calleeExpression.getTypeReference();
}
@Override
public KtConstructorCalleeExpression getCalleeExpression() {
return getStubOrPsiChild(KtStubElementTypes.CONSTRUCTOR_CALLEE);
}
@Override
public KtValueArgumentList getValueArgumentList() {
KotlinAnnotationEntryStub stub = getStub();
if (stub != null && !stub.hasValueArguments()) {
return null;
}
return (KtValueArgumentList) findChildByType(KtNodeTypes.VALUE_ARGUMENT_LIST);
}
@NotNull
@Override
public List<? extends ValueArgument> getValueArguments() {
KtValueArgumentList list = getValueArgumentList();
return list != null ? list.getArguments() : Collections.<KtValueArgument>emptyList();
}
@NotNull
@Override
public List<KtLambdaArgument> getLambdaArguments() {
return Collections.emptyList();
}
@NotNull
@Override
public List<KtTypeProjection> getTypeArguments() {
KtTypeArgumentList typeArgumentList = getTypeArgumentList();
if (typeArgumentList == null) {
return Collections.emptyList();
}
return typeArgumentList.getArguments();
}
@Override
public KtTypeArgumentList getTypeArgumentList() {
KtTypeReference typeReference = getTypeReference();
if (typeReference == null) {
return null;
}
KtTypeElement typeElement = typeReference.getTypeElement();
if (typeElement instanceof KtUserType) {
KtUserType userType = (KtUserType) typeElement;
return userType.getTypeArgumentList();
}
return null;
}
@Nullable
public PsiElement getAtSymbol() {
return findChildByType(KtTokens.AT);
}
@Nullable
public KtAnnotationUseSiteTarget getUseSiteTarget() {
KtAnnotationUseSiteTarget target = getStubOrPsiChild(KtStubElementTypes.ANNOTATION_TARGET);
if (target == null) {
PsiElement parent = getParentByStub();
if (parent instanceof KtAnnotation) {
return ((KtAnnotation) parent).getUseSiteTarget();
}
}
return target;
}
@Nullable
public Name getShortName() {
KotlinAnnotationEntryStub stub = getStub();
if (stub != null) {
String shortName = stub.getShortName();
if (shortName != null) {
return Name.identifier(shortName);
}
return null;
}
KtTypeReference typeReference = getTypeReference();
assert typeReference != null : "Annotation entry hasn't typeReference " + getText();
KtTypeElement typeElement = typeReference.getTypeElement();
if (typeElement instanceof KtUserType) {
KtUserType userType = (KtUserType) typeElement;
String shortName = userType.getReferencedName();
if (shortName != null) {
return Name.identifier(shortName);
}
}
return null;
}
}
@@ -1,58 +0,0 @@
/*
* Copyright 2010-2016 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.psi
import com.intellij.lang.ASTNode
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.stubs.KotlinAnnotationUseSiteTargetStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
class KtAnnotationUseSiteTarget : KtElementImplStub<KotlinAnnotationUseSiteTargetStub> {
constructor(node: ASTNode) : super(node)
constructor(stub: KotlinAnnotationUseSiteTargetStub) : super(stub, KtStubElementTypes.ANNOTATION_TARGET)
override fun <R, D> accept(visitor: KtVisitor<R, D>, data: D) = visitor.visitAnnotationUseSiteTarget(this, data)
fun getAnnotationUseSiteTarget(): AnnotationUseSiteTarget {
val targetString = stub?.getUseSiteTarget()
if (targetString != null) {
try {
return AnnotationUseSiteTarget.valueOf(targetString)
} catch (e: IllegalArgumentException) {
// Ok, resolve via node tree
}
}
val node = firstChild.node
return when (node.elementType) {
KtTokens.FIELD_KEYWORD -> AnnotationUseSiteTarget.FIELD
KtTokens.FILE_KEYWORD -> AnnotationUseSiteTarget.FILE
KtTokens.PROPERTY_KEYWORD -> AnnotationUseSiteTarget.PROPERTY
KtTokens.GET_KEYWORD -> AnnotationUseSiteTarget.PROPERTY_GETTER
KtTokens.SET_KEYWORD -> AnnotationUseSiteTarget.PROPERTY_SETTER
KtTokens.RECEIVER_KEYWORD -> AnnotationUseSiteTarget.RECEIVER
KtTokens.PARAM_KEYWORD -> AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
KtTokens.SETPARAM_KEYWORD -> AnnotationUseSiteTarget.SETTER_PARAMETER
KtTokens.DELEGATE_KEYWORD -> AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
else -> throw IllegalStateException("Unknown annotation target " + node.text)
}
}
}
@@ -1,20 +0,0 @@
/*
* 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.psi;
public interface KtAnnotationsContainer extends KtElement {
}
@@ -1,60 +0,0 @@
/*
* 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.psi
import com.intellij.lang.ASTNode
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.utils.sure
interface KtAnonymousInitializer : KtDeclaration, KtStatementExpression {
val containingDeclaration: KtDeclaration
val body: KtExpression?
}
class KtClassInitializer : KtDeclarationStub<KotlinPlaceHolderStub<KtClassInitializer>>, KtAnonymousInitializer {
constructor(node: ASTNode) : super(node)
constructor(stub: KotlinPlaceHolderStub<KtClassInitializer>) : super(stub, KtStubElementTypes.CLASS_INITIALIZER)
override fun <R, D> accept(visitor: KtVisitor<R, D>, data: D) = visitor.visitClassInitializer(this, data)
override val body: KtExpression?
get() = findChildByClass(KtExpression::class.java)
val openBraceNode: PsiElement?
get() = (body as? KtBlockExpression)?.lBrace
val initKeyword: PsiElement
get() = findChildByType(KtTokens.INIT_KEYWORD)!!
override val containingDeclaration: KtClassOrObject
get() = getParentOfType<KtClassOrObject>(true).sure { "Should only be present in class or object" }
}
class KtScriptInitializer(node: ASTNode) : KtDeclarationImpl(node), KtAnonymousInitializer {
override val body: KtExpression?
get() = findChildByClass(KtExpression::class.java)
override val containingDeclaration: KtScript
get() = getParentOfType<KtScript>(true).sure { "Should only be present in script" }
override fun <R, D> accept(visitor: KtVisitor<R, D>, data: D) = visitor.visitScriptInitializer(this, data)
}
@@ -1,78 +0,0 @@
/*
* 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.psi;
import com.google.common.collect.Lists;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.KtNodeTypes;
import org.jetbrains.kotlin.lexer.KtTokens;
import java.util.Collections;
import java.util.List;
public class KtArrayAccessExpression extends KtExpressionImpl implements KtReferenceExpression {
public KtArrayAccessExpression(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitArrayAccessExpression(this, data);
}
@Nullable @IfNotParsed
public KtExpression getArrayExpression() {
return findChildByClass(KtExpression.class);
}
@NotNull
public List<KtExpression> getIndexExpressions() {
return PsiTreeUtil.getChildrenOfTypeAsList(getIndicesNode(), KtExpression.class);
}
@NotNull
public KtContainerNode getIndicesNode() {
KtContainerNode indicesNode = findChildByType(KtNodeTypes.INDICES);
assert indicesNode != null : "Can't be null because of parser";
return indicesNode;
}
@NotNull
public List<TextRange> getBracketRanges() {
PsiElement lBracket = getLeftBracket();
PsiElement rBracket = getRightBracket();
if (lBracket == null || rBracket == null) {
return Collections.emptyList();
}
return Lists.newArrayList(lBracket.getTextRange(), rBracket.getTextRange());
}
@Nullable
public PsiElement getLeftBracket() {
return getIndicesNode().findChildByType(KtTokens.LBRACKET);
}
@Nullable
public PsiElement getRightBracket() {
return getIndicesNode().findChildByType(KtTokens.RBRACKET);
}
}
@@ -1,74 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.KtNodeTypes;
public class KtBinaryExpression extends KtExpressionImpl implements KtOperationExpression {
public KtBinaryExpression(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitBinaryExpression(this, data);
}
@Nullable @IfNotParsed
public KtExpression getLeft() {
ASTNode node = getOperationReference().getNode().getTreePrev();
while (node != null) {
PsiElement psi = node.getPsi();
if (psi instanceof KtExpression) {
return (KtExpression) psi;
}
node = node.getTreePrev();
}
return null;
}
@Nullable @IfNotParsed
public KtExpression getRight() {
ASTNode node = getOperationReference().getNode().getTreeNext();
while (node != null) {
PsiElement psi = node.getPsi();
if (psi instanceof KtExpression) {
return (KtExpression) psi;
}
node = node.getTreeNext();
}
return null;
}
@Override
@NotNull
public KtOperationReferenceExpression getOperationReference() {
return (KtOperationReferenceExpression) findChildByType(KtNodeTypes.OPERATION_REFERENCE);
}
@NotNull
public IElementType getOperationToken() {
return getOperationReference().getReferencedNameElementType();
}
}
@@ -1,62 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.KtNodeTypes;
public class KtBinaryExpressionWithTypeRHS extends KtExpressionImpl implements KtOperationExpression {
public KtBinaryExpressionWithTypeRHS(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitBinaryWithTypeRHSExpression(this, data);
}
@NotNull
public KtExpression getLeft() {
KtExpression left = findChildByClass(KtExpression.class);
assert left != null;
return left;
}
@Nullable @IfNotParsed
public KtTypeReference getRight() {
ASTNode node = getOperationReference().getNode();
while (node != null) {
PsiElement psi = node.getPsi();
if (psi instanceof KtTypeReference) {
return (KtTypeReference) psi;
}
node = node.getTreeNext();
}
return null;
}
@Override
@NotNull
public KtSimpleNameExpression getOperationReference() {
return (KtSimpleNameExpression) findChildByType(KtNodeTypes.OPERATION_REFERENCE);
}
}
@@ -1,33 +0,0 @@
/*
* 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.psi
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.KtNodeTypes
class KtBlockCodeFragment(
project: Project,
name: String,
text: CharSequence,
imports: String?,
context: PsiElement?
) : KtCodeFragment(project, name, text, imports, KtNodeTypes.BLOCK_CODE_FRAGMENT, context) {
override fun getContentElement() = findChildByClass(KtBlockExpression::class.java)
?: throw IllegalStateException("Block expression should be parsed for BlockCodeFragment")
}
@@ -1,50 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiBuilderFactory;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.parsing.KotlinParser;
import org.jetbrains.kotlin.psi.stubs.elements.KtFileElementType;
public class KtBlockCodeFragmentType extends KtFileElementType {
private static final String NAME = "kotlin.BLOCK_CODE_FRAGMENT";
public KtBlockCodeFragmentType() {
super(NAME);
}
@NotNull
@Override
public String getExternalId() {
return NAME;
}
@Override
protected ASTNode doParseContents(@NotNull ASTNode chameleon, @NotNull PsiElement psi) {
Project project = psi.getProject();
Language languageForParser = getLanguageForParser(psi);
PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, null, languageForParser, chameleon.getChars());
return KotlinParser.parseBlockCodeFragment(builder).getFirstChildNode();
}
}
@@ -1,68 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifiableCodeBlock;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.kotlin.lexer.KtTokens;
import java.util.Arrays;
import java.util.List;
public class KtBlockExpression extends KtExpressionImpl implements KtStatementExpression, PsiModifiableCodeBlock {
public KtBlockExpression(@NotNull ASTNode node) {
super(node);
}
@Override
public boolean shouldChangeModificationCount(PsiElement place) {
// To prevent OutOfBlockModification increase from JavaCodeBlockModificationListener
return false;
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitBlockExpression(this, data);
}
@ReadOnly
@NotNull
public List<KtExpression> getStatements() {
return Arrays.asList(findChildrenByClass(KtExpression.class));
}
@Nullable
public TextRange getLastBracketRange() {
PsiElement rBrace = getRBrace();
return rBrace != null ? rBrace.getTextRange() : null;
}
@Nullable
public PsiElement getRBrace() {
return findChildByType(KtTokens.RBRACE);
}
@Nullable
public PsiElement getLBrace() {
return findChildByType(KtTokens.LBRACE);
}
}
@@ -1,31 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
public class KtBlockStringTemplateEntry extends KtStringTemplateEntryWithExpression {
public KtBlockStringTemplateEntry(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitBlockStringTemplateEntry(this, data);
}
}
@@ -1,31 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
public class KtBreakExpression extends KtExpressionWithLabel implements KtStatementExpression {
public KtBreakExpression(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitBreakExpression(this, data);
}
}
@@ -1,42 +0,0 @@
/*
* 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.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface KtCallElement extends KtElement {
@Nullable
KtExpression getCalleeExpression();
@Nullable
KtValueArgumentList getValueArgumentList();
@NotNull
List<? extends ValueArgument> getValueArguments();
@NotNull
List<KtLambdaArgument> getLambdaArguments();
@NotNull
List<KtTypeProjection> getTypeArguments();
@Nullable
KtTypeArgumentList getTypeArgumentList();
}
@@ -1,88 +0,0 @@
/*
* 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.psi;
import com.google.common.collect.Lists;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.KtNodeTypes;
import java.util.Collections;
import java.util.List;
public class KtCallExpression extends KtExpressionImpl implements KtCallElement, KtReferenceExpression {
public KtCallExpression(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitCallExpression(this, data);
}
@Override
@Nullable
public KtExpression getCalleeExpression() {
return findChildByClass(KtExpression.class);
}
@Override
@Nullable
public KtValueArgumentList getValueArgumentList() {
return (KtValueArgumentList) findChildByType(KtNodeTypes.VALUE_ARGUMENT_LIST);
}
@Override
@Nullable
public KtTypeArgumentList getTypeArgumentList() {
return (KtTypeArgumentList) findChildByType(KtNodeTypes.TYPE_ARGUMENT_LIST);
}
/**
* Normally there should be only one (or zero) function literal arguments.
* The returned value is a list for better handling of commonly made mistake of a function taking a lambda and returning another function.
* Most of users can simply ignore lists of more than one element.
*/
@Override
@NotNull
public List<KtLambdaArgument> getLambdaArguments() {
return findChildrenByType(KtNodeTypes.LAMBDA_ARGUMENT);
}
@Override
@NotNull
public List<KtValueArgument> getValueArguments() {
KtValueArgumentList list = getValueArgumentList();
List<KtValueArgument> valueArgumentsInParentheses = list != null ? list.getArguments() : Collections.emptyList();
List<KtLambdaArgument> functionLiteralArguments = getLambdaArguments();
if (functionLiteralArguments.isEmpty()) {
return valueArgumentsInParentheses;
}
List<KtValueArgument> allValueArguments = Lists.newArrayList();
allValueArguments.addAll(valueArgumentsInParentheses);
allValueArguments.addAll(functionLiteralArguments);
return allValueArguments;
}
@Override
@NotNull
public List<KtTypeProjection> getTypeArguments() {
KtTypeArgumentList list = getTypeArgumentList();
return list != null ? list.getArguments() : Collections.emptyList();
}
}
@@ -1,43 +0,0 @@
/*
* 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.psi;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface KtCallableDeclaration extends KtNamedDeclaration, KtTypeParameterListOwner {
@Nullable
KtParameterList getValueParameterList();
@NotNull
List<KtParameter> getValueParameters();
@Nullable
KtTypeReference getReceiverTypeReference();
@Nullable
KtTypeReference getTypeReference();
@Nullable
KtTypeReference setTypeReference(@Nullable KtTypeReference typeRef);
@Nullable
PsiElement getColon();
}
@@ -1,45 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
public class KtCallableReferenceExpression extends KtDoubleColonExpression {
public KtCallableReferenceExpression(@NotNull ASTNode node) {
super(node);
}
@NotNull
public KtSimpleNameExpression getCallableReference() {
PsiElement psi = getDoubleColonTokenReference();
while (psi != null) {
if (psi instanceof KtSimpleNameExpression) {
return (KtSimpleNameExpression) psi;
}
psi = psi.getNextSibling();
}
throw new IllegalStateException("Callable reference simple name shouldn't be parsed to null");
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitCallableReferenceExpression(this, data);
}
}
@@ -1,54 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.KtNodeTypes;
import java.util.List;
public class KtCatchClause extends KtElementImpl {
public KtCatchClause(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitCatchSection(this, data);
}
@Nullable @IfNotParsed
public KtParameterList getParameterList() {
return (KtParameterList) findChildByType(KtNodeTypes.VALUE_PARAMETER_LIST);
}
@Nullable @IfNotParsed
public KtParameter getCatchParameter() {
KtParameterList list = getParameterList();
if (list == null) return null;
List<KtParameter> parameters = list.getParameters();
return parameters.size() == 1 ? parameters.get(0) : null;
}
@Nullable @IfNotParsed
public KtExpression getCatchBody() {
return findChildByClass(KtExpression.class);
}
}
@@ -1,118 +0,0 @@
/*
* Copyright 2010-2017 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.psi
import com.intellij.lang.ASTNode
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.tree.TokenSet
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.stubs.KotlinClassStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import java.util.*
open class KtClass : KtClassOrObject {
constructor(node: ASTNode) : super(node)
constructor(stub: KotlinClassStub) : super(stub, KtStubElementTypes.CLASS)
override fun <R, D> accept(visitor: KtVisitor<R, D>, data: D): R {
return visitor.visitClass(this, data)
}
private val _stub: KotlinClassStub?
get() = stub as? KotlinClassStub
fun getColon(): PsiElement? = findChildByType(KtTokens.COLON)
fun getProperties(): List<KtProperty> = getBody()?.properties.orEmpty()
fun isInterface(): Boolean =
_stub?.isInterface() ?: (findChildByType<PsiElement>(KtTokens.INTERFACE_KEYWORD) != null)
fun isEnum(): Boolean = hasModifier(KtTokens.ENUM_KEYWORD)
fun isData(): Boolean = hasModifier(KtTokens.DATA_KEYWORD)
fun isSealed(): Boolean = hasModifier(KtTokens.SEALED_KEYWORD)
fun isInner(): Boolean = hasModifier(KtTokens.INNER_KEYWORD)
override fun isEquivalentTo(another: PsiElement?): Boolean {
if (this === another) {
return true
}
if (another !is KtClass) {
return false
}
val fq1 = getQualifiedName() ?: return false
val fq2 = another.getQualifiedName() ?: return false
if (fq1 == fq2) {
val thisLocal = isLocal
if (thisLocal != another.isLocal) {
return false
}
// For non-local classes same fqn is enough
// Consider different instances of local classes non-equivalent
return !thisLocal
}
return false
}
protected fun getQualifiedName(): String? {
val stub = stub
if (stub != null) {
val fqName = stub.getFqName()
return fqName?.asString()
}
val parts = ArrayList<String>()
var current: KtClassOrObject? = this
while (current != null) {
parts.add(current.name!!)
current = PsiTreeUtil.getParentOfType<KtClassOrObject>(current, KtClassOrObject::class.java)
}
val file = containingFile as? KtFile ?: return null
val fileQualifiedName = file.packageFqName.asString()
if (!fileQualifiedName.isEmpty()) {
parts.add(fileQualifiedName)
}
Collections.reverse(parts)
return StringUtil.join(parts, ".")
}
override fun getCompanionObjects(): List<KtObjectDeclaration> = getBody()?.allCompanionObjects.orEmpty()
fun getClassOrInterfaceKeyword(): PsiElement? = findChildByType(TokenSet.create(KtTokens.CLASS_KEYWORD, KtTokens.INTERFACE_KEYWORD))
}
fun KtClass.createPrimaryConstructorIfAbsent(): KtPrimaryConstructor {
val constructor = primaryConstructor
if (constructor != null) return constructor
var anchor: PsiElement? = typeParameterList
if (anchor == null) anchor = nameIdentifier
if (anchor == null) anchor = lastChild
return addAfter(KtPsiFactory(project).createPrimaryConstructor(), anchor) as KtPrimaryConstructor
}
fun KtClass.createPrimaryConstructorParameterListIfAbsent(): KtParameterList {
val constructor = createPrimaryConstructorIfAbsent()
val parameterList = constructor.valueParameterList
if (parameterList != null) return parameterList
return constructor.add(KtPsiFactory(project).createParameterList("()")) as KtParameterList
}
@@ -1,63 +0,0 @@
/*
* 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.psi
import com.intellij.lang.ASTNode
import com.intellij.psi.PsiElement
import com.intellij.psi.tree.TokenSet
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes.*
import java.util.*
class KtClassBody : KtElementImplStub<KotlinPlaceHolderStub<KtClassBody>>, KtDeclarationContainer {
constructor(node: ASTNode) : super(node)
constructor(stub: KotlinPlaceHolderStub<KtClassBody>) : super(stub, CLASS_BODY)
override fun getParent() = parentByStub
override fun getDeclarations() = Arrays.asList(*getStubOrPsiChildren(DECLARATION_TYPES, KtDeclaration.ARRAY_FACTORY))
override fun <R, D> accept(visitor: KtVisitor<R, D>, data: D) = visitor.visitClassBody(this, data)
val anonymousInitializers: List<KtAnonymousInitializer>
get() = findChildrenByType(KtNodeTypes.CLASS_INITIALIZER)
internal val secondaryConstructors: List<KtSecondaryConstructor>
get() = getStubOrPsiChildrenAsList(KtStubElementTypes.SECONDARY_CONSTRUCTOR)
val properties: List<KtProperty>
get() = getStubOrPsiChildrenAsList(KtStubElementTypes.PROPERTY)
val allCompanionObjects: List<KtObjectDeclaration>
get() = getStubOrPsiChildrenAsList(KtStubElementTypes.OBJECT_DECLARATION).filter { it.isCompanion() }
val rBrace: PsiElement?
get() = node.getChildren(TokenSet.create(KtTokens.RBRACE)).singleOrNull()?.psi
val lBrace: PsiElement?
get() = node.getChildren(TokenSet.create(KtTokens.LBRACE)).singleOrNull()?.psi
/**
* @return annotations that do not belong to any declaration due to incomplete code or syntax errors
*/
val danglingAnnotations: List<KtAnnotationEntry>
get() = getStubOrPsiChildrenAsList(MODIFIER_LIST).flatMap { it.annotationEntries }
}
@@ -1,25 +0,0 @@
/*
* 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.psi
import com.intellij.lang.ASTNode
class KtClassLiteralExpression(node: ASTNode) : KtDoubleColonExpression(node) {
override fun <R, D> accept(visitor: KtVisitor<R, D>, data: D): R {
return visitor.visitClassLiteralExpression(this, data)
}
}
@@ -1,139 +0,0 @@
/*
* 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.psi
import com.intellij.lang.ASTNode
import com.intellij.navigation.ItemPresentation
import com.intellij.navigation.ItemPresentationProviders
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.impl.CheckUtil
import com.intellij.psi.stubs.IStubElementType
import com.intellij.psi.tree.TokenSet
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
abstract class KtClassOrObject :
KtTypeParameterListOwnerStub<KotlinClassOrObjectStub<out KtClassOrObject>>, KtDeclarationContainer, KtNamedDeclaration,
KtPureClassOrObject {
constructor(node: ASTNode) : super(node)
constructor(stub: KotlinClassOrObjectStub<out KtClassOrObject>, nodeType: IStubElementType<*, *>) : super(stub, nodeType)
fun getSuperTypeList(): KtSuperTypeList? = getStubOrPsiChild(KtStubElementTypes.SUPER_TYPE_LIST)
override fun getSuperTypeListEntries(): List<KtSuperTypeListEntry> = getSuperTypeList()?.entries.orEmpty()
fun addSuperTypeListEntry(superTypeListEntry: KtSuperTypeListEntry): KtSuperTypeListEntry {
getSuperTypeList()?.let {
val single = it.entries.singleOrNull()
if (single != null && single.typeReference?.typeElement == null) {
return single.replace(superTypeListEntry) as KtSuperTypeListEntry
}
return EditCommaSeparatedListHelper.addItem(it, superTypeListEntries, superTypeListEntry)
}
val psiFactory = KtPsiFactory(this)
val specifierListToAdd = psiFactory.createSuperTypeCallEntry("A()").replace(superTypeListEntry).parent
val colon = addBefore(psiFactory.createColon(), getBody())
return (addAfter(specifierListToAdd, colon) as KtSuperTypeList).entries.first()
}
fun removeSuperTypeListEntry(superTypeListEntry: KtSuperTypeListEntry) {
val specifierList = getSuperTypeList() ?: return
assert(superTypeListEntry.parent === specifierList)
if (specifierList.entries.size > 1) {
EditCommaSeparatedListHelper.removeItem<KtElement>(superTypeListEntry)
} else {
deleteChildRange(findChildByType<PsiElement>(KtTokens.COLON) ?: specifierList, specifierList)
}
}
fun getAnonymousInitializers(): List<KtAnonymousInitializer> = getBody()?.anonymousInitializers.orEmpty()
fun getBody(): KtClassBody? = getStubOrPsiChild(KtStubElementTypes.CLASS_BODY)
inline fun <reified T : KtDeclaration> addDeclaration(declaration: T): T {
val body = getOrCreateBody()
val anchor = PsiTreeUtil.skipSiblingsBackward(body.rBrace ?: body.lastChild!!, PsiWhiteSpace::class.java)
return body.addAfter(declaration, anchor) as T
}
inline fun <reified T : KtDeclaration> addDeclarationAfter(declaration: T, anchor: PsiElement?): T {
val anchorBefore = anchor ?: declarations.lastOrNull() ?: return addDeclaration(declaration)
return getOrCreateBody().addAfter(declaration, anchorBefore) as T
}
inline fun <reified T : KtDeclaration> addDeclarationBefore(declaration: T, anchor: PsiElement?): T {
val anchorAfter = anchor ?: declarations.firstOrNull() ?: return addDeclaration(declaration)
return getOrCreateBody().addBefore(declaration, anchorAfter) as T
}
fun isTopLevel(): Boolean = stub?.isTopLevel() ?: (parent is KtFile)
override fun isLocal(): Boolean = stub?.isLocal() ?: KtPsiUtil.isLocal(this)
override fun getDeclarations(): List<KtDeclaration> = getBody()?.declarations.orEmpty()
override fun getPresentation(): ItemPresentation? = ItemPresentationProviders.getItemPresentation(this)
override fun getPrimaryConstructor(): KtPrimaryConstructor? = getStubOrPsiChild(KtStubElementTypes.PRIMARY_CONSTRUCTOR)
override fun getPrimaryConstructorModifierList(): KtModifierList? = primaryConstructor?.modifierList
fun getPrimaryConstructorParameterList(): KtParameterList? = primaryConstructor?.valueParameterList
override fun getPrimaryConstructorParameters(): List<KtParameter> = getPrimaryConstructorParameterList()?.parameters.orEmpty()
override fun hasExplicitPrimaryConstructor(): Boolean = primaryConstructor != null
override fun hasPrimaryConstructor(): Boolean = hasExplicitPrimaryConstructor() || !hasSecondaryConstructors()
private fun hasSecondaryConstructors(): Boolean = !secondaryConstructors.isEmpty()
override fun getSecondaryConstructors(): List<KtSecondaryConstructor> = getBody()?.secondaryConstructors.orEmpty()
fun isAnnotation(): Boolean = hasModifier(KtTokens.ANNOTATION_KEYWORD)
fun getDeclarationKeyword(): PsiElement? =
findChildByType(
TokenSet.create(
KtTokens.CLASS_KEYWORD, KtTokens.INTERFACE_KEYWORD, KtTokens.OBJECT_KEYWORD
)
)
override fun delete() {
CheckUtil.checkWritable(this)
val file = containingKtFile
if (!isTopLevel() || file.declarations.size > 1) {
super.delete()
} else {
file.delete()
}
}
}
fun KtClassOrObject.getOrCreateBody(): KtClassBody {
getBody()?.let { return it }
val newBody = KtPsiFactory(this).createEmptyClassBody()
if (this is KtEnumEntry) return addAfter(newBody, initializerList ?: nameIdentifier) as KtClassBody
return add(newBody) as KtClassBody
}
@@ -1,203 +0,0 @@
/*
* 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.psi
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.psi.*
import com.intellij.psi.impl.PsiManagerEx
import com.intellij.psi.impl.source.tree.FileElement
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.tree.IElementType
import com.intellij.testFramework.LightVirtualFile
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
abstract class KtCodeFragment(
private val _project: Project,
name: String,
text: CharSequence,
imports: String?, // Should be separated by JetCodeFragment.IMPORT_SEPARATOR
elementType: IElementType,
private val context: PsiElement?
) : KtFile(
(PsiManager.getInstance(_project) as PsiManagerEx).fileManager.createFileViewProvider(
LightVirtualFile(
name,
KotlinFileType.INSTANCE,
text
), true
), false
), JavaCodeFragment {
private var viewProvider = super.getViewProvider() as SingleRootFileViewProvider
private var imports = LinkedHashSet<String>()
private val fakeContextForJavaFile: PsiElement? by lazy {
this.getCopyableUserData(FAKE_CONTEXT_FOR_JAVA_FILE)?.invoke()
}
init {
getViewProvider().forceCachedPsi(this)
init(TokenType.CODE_FRAGMENT, elementType)
if (context != null) {
initImports(imports)
}
}
override final fun init(elementType: IElementType, contentElementType: IElementType?) {
super.init(elementType, contentElementType)
}
private var resolveScope: GlobalSearchScope? = null
private var thisType: PsiType? = null
private var superType: PsiType? = null
private var exceptionHandler: JavaCodeFragment.ExceptionHandler? = null
private var isPhysical = true
abstract fun getContentElement(): KtElement?
override fun forceResolveScope(scope: GlobalSearchScope?) {
resolveScope = scope
}
override fun getForcedResolveScope() = resolveScope
override fun isPhysical() = isPhysical
override fun isValid() = true
override fun getContext(): PsiElement? {
if (fakeContextForJavaFile != null) return fakeContextForJavaFile
if (context !is KtElement) {
LOG.warn("CodeFragment with non-kotlin context should have fakeContextForJavaFile set: \noriginalContext = ${context?.getElementTextWithContext()}")
return null
}
return context
}
override fun getResolveScope() = context?.resolveScope ?: super.getResolveScope()
override fun clone(): KtCodeFragment {
val clone = cloneImpl(calcTreeElement().clone() as FileElement) as KtCodeFragment
clone.isPhysical = false
clone.originalFile = this
clone.imports = imports
clone.viewProvider =
SingleRootFileViewProvider(PsiManager.getInstance(_project), LightVirtualFile(name, KotlinFileType.INSTANCE, text), false)
clone.viewProvider.forceCachedPsi(clone)
return clone
}
final override fun getViewProvider() = viewProvider
override fun getThisType() = thisType
override fun setThisType(psiType: PsiType?) {
thisType = psiType
}
override fun getSuperType() = superType
override fun setSuperType(superType: PsiType?) {
this.superType = superType
}
override fun importsToString(): String {
return imports.joinToString(IMPORT_SEPARATOR)
}
override fun addImportsFromString(imports: String?) {
if (imports == null || imports.isEmpty()) return
imports.split(IMPORT_SEPARATOR).forEach {
addImport(it)
}
// we need this code to force re-highlighting, otherwise it does not work by some reason
val tempElement = KtPsiFactory(project).createColon()
add(tempElement).delete()
}
fun addImport(import: String) {
val contextFile = getContextContainingFile()
if (contextFile != null) {
if (contextFile.importDirectives.find { it.text == import } == null) {
imports.add(import)
}
}
}
fun importsAsImportList(): KtImportList? {
if (!imports.isEmpty() && context != null) {
return KtPsiFactory(this).createAnalyzableFile("imports_for_codeFragment.kt", imports.joinToString("\n"), context).importList
}
return null
}
override val importDirectives: List<KtImportDirective>
get() = importsAsImportList()?.imports ?: emptyList()
override fun setVisibilityChecker(checker: JavaCodeFragment.VisibilityChecker?) {}
override fun getVisibilityChecker() = JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE
override fun setExceptionHandler(checker: JavaCodeFragment.ExceptionHandler?) {
exceptionHandler = checker
}
override fun getExceptionHandler() = exceptionHandler
override fun importClass(aClass: PsiClass?): Boolean {
return true
}
fun getContextContainingFile(): KtFile? {
return getOriginalContext()?.containingKtFile
}
fun getOriginalContext(): KtElement? {
val contextElement = getContext() as? KtElement
val contextFile = contextElement?.containingKtFile
if (contextFile is KtCodeFragment) {
return contextFile.getOriginalContext()
}
return contextElement
}
private fun initImports(imports: String?) {
if (imports != null && !imports.isEmpty()) {
val importsWithPrefix = imports.split(IMPORT_SEPARATOR).map { it.takeIf { it.startsWith("import ") } ?: "import ${it.trim()}" }
importsWithPrefix.forEach {
addImport(it)
}
}
}
companion object {
val IMPORT_SEPARATOR: String = ","
val RUNTIME_TYPE_EVALUATOR: Key<Function1<KtExpression, KotlinType?>> = Key.create("RUNTIME_TYPE_EVALUATOR")
val FAKE_CONTEXT_FOR_JAVA_FILE: Key<Function0<KtElement>> = Key.create("FAKE_CONTEXT_FOR_JAVA_FILE")
private val LOG = Logger.getInstance(KtCodeFragment::class.java)
}
}
@@ -1,38 +0,0 @@
/*
* Copyright 2010-2017 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.psi
import com.intellij.lang.ASTNode
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.lexer.KtTokens
class KtCollectionLiteralExpression(node: ASTNode) : KtExpressionImpl(node), KtReferenceExpression {
override fun <R, D> accept(visitor: KtVisitor<R, D>, data: D): R {
return visitor.visitCollectionLiteralExpression(this, data)
}
val leftBracket: PsiElement?
get() = findChildByType(KtTokens.LBRACKET)
val rightBracket: PsiElement?
get() = findChildByType(KtTokens.RBRACKET)
fun getInnerExpressions(): List<KtExpression> {
return PsiTreeUtil.getChildrenOfTypeAsList(this, KtExpression::class.java)
}
}
@@ -1,31 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
public class KtConstantExpression extends KtExpressionImpl {
public KtConstantExpression(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitConstantExpression(this, data);
}
}
@@ -1,96 +0,0 @@
/*
* Copyright 2010-2016 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.psi
import com.intellij.lang.ASTNode
import com.intellij.navigation.ItemPresentationProviders
import com.intellij.psi.PsiElement
import com.intellij.psi.search.SearchScope
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub
import org.jetbrains.kotlin.psi.stubs.elements.KtPlaceHolderStubElementType
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
abstract class KtConstructor<T : KtConstructor<T>> : KtDeclarationStub<KotlinPlaceHolderStub<T>>, KtFunction {
protected constructor(node: ASTNode) : super(node)
protected constructor(stub: KotlinPlaceHolderStub<T>, nodeType: KtPlaceHolderStubElementType<T>) : super(stub, nodeType)
abstract fun getContainingClassOrObject(): KtClassOrObject
override fun isLocal() = false
override fun getValueParameterList() = getStubOrPsiChild(KtStubElementTypes.VALUE_PARAMETER_LIST)
override fun getValueParameters() = valueParameterList?.parameters ?: emptyList()
override fun getReceiverTypeReference() = null
override fun getTypeReference() = null
@Throws(IncorrectOperationException::class)
override fun setTypeReference(typeRef: KtTypeReference?) = throw IncorrectOperationException("setTypeReference to constructor")
override fun getColon() = findChildByType<PsiElement>(KtTokens.COLON)
override fun getBodyExpression(): KtBlockExpression? = null
override fun getEqualsToken() = null
override fun hasBlockBody() = bodyExpression != null
override fun hasBody() = bodyExpression != null
override fun hasDeclaredReturnType() = false
override fun getTypeParameterList() = null
override fun getTypeConstraintList() = null
override fun getTypeConstraints() = emptyList<KtTypeConstraint>()
override fun getTypeParameters() = emptyList<KtTypeParameter>()
override fun getName(): String? = getContainingClassOrObject().name
override fun getNameAsSafeName() = KtPsiUtil.safeName(name)
override fun getFqName() = null
override fun getNameAsName() = nameAsSafeName
override fun getNameIdentifier() = null
@Throws(IncorrectOperationException::class)
override fun setName(name: String): PsiElement = throw IncorrectOperationException("setName to constructor")
override fun getPresentation() = ItemPresentationProviders.getItemPresentation(this)
open fun getConstructorKeyword(): PsiElement? = findChildByType(KtTokens.CONSTRUCTOR_KEYWORD)
fun hasConstructorKeyword(): Boolean = stub != null || getConstructorKeyword() != null
override fun getTextOffset(): Int {
return getConstructorKeyword()?.textOffset
?: valueParameterList?.textOffset
?: super.getTextOffset()
}
override fun getUseScope(): SearchScope {
return getContainingClassOrObject().useScope
}
}
@@ -1,57 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub;
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
public class KtConstructorCalleeExpression extends KtExpressionImplStub<KotlinPlaceHolderStub<KtConstructorCalleeExpression>> {
public KtConstructorCalleeExpression(@NotNull ASTNode node) {
super(node);
}
public KtConstructorCalleeExpression(@NotNull KotlinPlaceHolderStub<KtConstructorCalleeExpression> stub) {
super(stub, KtStubElementTypes.CONSTRUCTOR_CALLEE);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitConstructorCalleeExpression(this, data);
}
@Nullable @IfNotParsed
public KtTypeReference getTypeReference() {
return getStubOrPsiChild(KtStubElementTypes.TYPE_REFERENCE);
}
@Nullable @IfNotParsed
public KtSimpleNameExpression getConstructorReferenceExpression() {
KtTypeReference typeReference = getTypeReference();
if (typeReference == null) {
return null;
}
KtTypeElement typeElement = typeReference.getTypeElement();
if (!(typeElement instanceof KtUserType)) {
return null;
}
return ((KtUserType) typeElement).getReferenceExpression();
}
}
@@ -1,91 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.KtNodeTypes;
import org.jetbrains.kotlin.parsing.KotlinParsing;
import java.util.Collections;
import java.util.List;
public class KtConstructorDelegationCall extends KtElementImpl implements KtCallElement {
public KtConstructorDelegationCall(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitConstructorDelegationCall(this, data);
}
@Override
@Nullable
public KtValueArgumentList getValueArgumentList() {
return (KtValueArgumentList) findChildByType(KtNodeTypes.VALUE_ARGUMENT_LIST);
}
@Override
@NotNull
public List<? extends ValueArgument> getValueArguments() {
KtValueArgumentList list = getValueArgumentList();
return list != null ? list.getArguments() : Collections.<KtValueArgument>emptyList();
}
@NotNull
@Override
public List<KtLambdaArgument> getLambdaArguments() {
return Collections.emptyList();
}
@NotNull
@Override
public List<KtTypeProjection> getTypeArguments() {
return Collections.emptyList();
}
@Override
public KtTypeArgumentList getTypeArgumentList() {
return null;
}
@Nullable
@Override
public KtConstructorDelegationReferenceExpression getCalleeExpression() {
return findChildByClass(KtConstructorDelegationReferenceExpression.class);
}
/**
* @return true if this delegation call is not present in the source code. Note that we always parse delegation calls
* for secondary constructors, even if there's no explicit call in the source (see {@link KotlinParsing#parseSecondaryConstructor}).
*
* class Foo {
* constructor(name: String) // <--- implicit constructor delegation call (empty element after RPAR)
* }
*/
public boolean isImplicit() {
KtConstructorDelegationReferenceExpression callee = getCalleeExpression();
return callee != null && callee.getFirstChild() == null;
}
public boolean isCallToThis() {
KtConstructorDelegationReferenceExpression callee = getCalleeExpression();
return callee != null && callee.isThis();
}
}
@@ -1,31 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.lexer.KtTokens;
public class KtConstructorDelegationReferenceExpression extends KtExpressionImpl implements KtReferenceExpression {
public KtConstructorDelegationReferenceExpression(@NotNull ASTNode node) {
super(node);
}
public boolean isThis() {
return findChildByType(KtTokens.THIS_KEYWORD) != null;
}
}
@@ -1,38 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
public class KtContainerNode extends KtElementImpl {
public KtContainerNode(@NotNull ASTNode node) {
super(node);
}
@Override // for visibility
protected <T> T findChildByClass(Class<T> aClass) {
return super.findChildByClass(aClass);
}
@Override // for visibility
protected PsiElement findChildByType(IElementType type) {
return super.findChildByType(type);
}
}
@@ -1,24 +0,0 @@
/*
* Copyright 2010-2016 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.psi
import com.intellij.lang.ASTNode
class KtContainerNodeForControlStructureBody(node: ASTNode) : KtContainerNode(node) {
val expression: KtExpression?
get() = findChildByClass<KtExpression>(KtExpression::class.java)
}
@@ -1,31 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
public class KtContinueExpression extends KtExpressionWithLabel implements KtStatementExpression {
public KtContinueExpression(@NotNull ASTNode node) {
super(node);
}
@Override
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
return visitor.visitContinueExpression(this, data);
}
}
@@ -1,30 +0,0 @@
/*
* 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.psi;
import com.intellij.util.ArrayFactory;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.kdoc.psi.api.KDoc;
public interface KtDeclaration extends KtExpression, KtModifierListOwner {
KtDeclaration[] EMPTY_ARRAY = new KtDeclaration[0];
ArrayFactory<KtDeclaration> ARRAY_FACTORY = count -> count == 0 ? EMPTY_ARRAY : new KtDeclaration[count];
@Nullable
KDoc getDocComment();
}
@@ -1,28 +0,0 @@
/*
* 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.psi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.ReadOnly;
import java.util.List;
public interface KtDeclarationContainer {
@NotNull
@ReadOnly
List<KtDeclaration> getDeclarations();
}
@@ -1,85 +0,0 @@
/*
* 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.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.KtNodeTypes;
import org.jetbrains.kotlin.kdoc.psi.api.KDoc;
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
import org.jetbrains.kotlin.psi.addRemoveModifier.AddRemoveModifierKt;
import org.jetbrains.kotlin.psi.findDocComment.FindDocCommentKt;
import java.util.Collections;
import java.util.List;
public abstract class KtDeclarationImpl extends KtExpressionImpl implements KtDeclaration {
public KtDeclarationImpl(@NotNull ASTNode node) {
super(node);
}
@Override
@Nullable
public KtModifierList getModifierList() {
return (KtModifierList) findChildByType(KtNodeTypes.MODIFIER_LIST);
}
@Override
public boolean hasModifier(@NotNull KtModifierKeywordToken modifier) {
KtModifierList modifierList = getModifierList();
return modifierList != null && modifierList.hasModifier(modifier);
}
@Override
public void addModifier(@NotNull KtModifierKeywordToken modifier) {
AddRemoveModifierKt.addModifier(this, modifier);
}
@Override
public void removeModifier(@NotNull KtModifierKeywordToken modifier) {
AddRemoveModifierKt.removeModifier(this, modifier);
}
@NotNull
@Override
public KtAnnotationEntry addAnnotationEntry(@NotNull KtAnnotationEntry annotationEntry) {
return AddRemoveModifierKt.addAnnotationEntry(this, annotationEntry);
}
@NotNull
@Override
public List<KtAnnotationEntry> getAnnotationEntries() {
KtModifierList modifierList = getModifierList();
if (modifierList == null) return Collections.emptyList();
return modifierList.getAnnotationEntries();
}
@NotNull
@Override
public List<KtAnnotation> getAnnotations() {
KtModifierList modifierList = getModifierList();
if (modifierList == null) return Collections.emptyList();
return modifierList.getAnnotations();
}
@Nullable
@Override
public KDoc getDocComment() {
return FindDocCommentKt.findDocComment(this);
}
}

Some files were not shown because too many files have changed in this diff Show More