Extract PSI to separate module
This commit is contained in:
@@ -178,6 +178,7 @@ extra["compilerModules"] = arrayOf(
|
|||||||
":compiler:conditional-preprocessor",
|
":compiler:conditional-preprocessor",
|
||||||
":compiler:resolution",
|
":compiler:resolution",
|
||||||
":compiler:serialization",
|
":compiler:serialization",
|
||||||
|
":compiler:psi",
|
||||||
":compiler:frontend",
|
":compiler:frontend",
|
||||||
":compiler:frontend.java",
|
":compiler:frontend.java",
|
||||||
":compiler:frontend.script",
|
":compiler:frontend.script",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.codegen;
|
|||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils;
|
||||||
import org.jetbrains.kotlin.util.ExceptionUtilKt;
|
import org.jetbrains.kotlin.util.ExceptionUtilKt;
|
||||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments;
|
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments;
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ public class CompilationException extends KotlinExceptionWithAttachments {
|
|||||||
|
|
||||||
public CompilationException(@NotNull String message, @Nullable Throwable cause, @Nullable PsiElement element) {
|
public CompilationException(@NotNull String message, @Nullable Throwable cause, @Nullable PsiElement element) {
|
||||||
super(ExceptionUtilKt.getExceptionMessage("Back-end (JVM)", message, cause,
|
super(ExceptionUtilKt.getExceptionMessage("Back-end (JVM)", message, cause,
|
||||||
element == null ? null : DiagnosticUtils.atLocation(element)),
|
element == null ? null : PsiDiagnosticUtils.atLocation(element)),
|
||||||
cause);
|
cause);
|
||||||
this.element = element;
|
this.element = element;
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME
|
|||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor
|
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
@@ -94,7 +94,7 @@ fun getRangeOrProgressionElementType(rangeType: KotlinType): KotlinType? {
|
|||||||
fun BindingContext.getElementType(forExpression: KtForExpression): KotlinType {
|
fun BindingContext.getElementType(forExpression: KtForExpression): KotlinType {
|
||||||
val loopRange = forExpression.loopRange!!
|
val loopRange = forExpression.loopRange!!
|
||||||
val nextCall = get(BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL, loopRange)
|
val nextCall = get(BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL, loopRange)
|
||||||
?: throw AssertionError("No next() function " + DiagnosticUtils.atLocation(loopRange))
|
?: throw AssertionError("No next() function " + PsiDiagnosticUtils.atLocation(loopRange))
|
||||||
return nextCall.resultingDescriptor.returnType!!
|
return nextCall.resultingDescriptor.returnType!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.range.forLoop
|
|||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext.*
|
import org.jetbrains.kotlin.resolve.BindingContext.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull
|
import org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull
|
||||||
@@ -40,7 +40,7 @@ class IteratorForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForE
|
|||||||
this.iteratorCall = getNotNull(
|
this.iteratorCall = getNotNull(
|
||||||
bindingContext,
|
bindingContext,
|
||||||
LOOP_RANGE_ITERATOR_RESOLVED_CALL, loopRange,
|
LOOP_RANGE_ITERATOR_RESOLVED_CALL, loopRange,
|
||||||
"No .iterator() function " + DiagnosticUtils.atLocation(loopRange)
|
"No .iterator() function " + PsiDiagnosticUtils.atLocation(loopRange)
|
||||||
)
|
)
|
||||||
|
|
||||||
val iteratorType = iteratorCall.resultingDescriptor.returnType!!
|
val iteratorType = iteratorCall.resultingDescriptor.returnType!!
|
||||||
@@ -49,7 +49,7 @@ class IteratorForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForE
|
|||||||
this.nextCall = getNotNull(
|
this.nextCall = getNotNull(
|
||||||
bindingContext,
|
bindingContext,
|
||||||
LOOP_RANGE_NEXT_RESOLVED_CALL, loopRange,
|
LOOP_RANGE_NEXT_RESOLVED_CALL, loopRange,
|
||||||
"No next() function " + DiagnosticUtils.atLocation(loopRange)
|
"No next() function " + PsiDiagnosticUtils.atLocation(loopRange)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ class IteratorForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForE
|
|||||||
val hasNextCall = getNotNull(
|
val hasNextCall = getNotNull(
|
||||||
codegen.bindingContext, LOOP_RANGE_HAS_NEXT_RESOLVED_CALL,
|
codegen.bindingContext, LOOP_RANGE_HAS_NEXT_RESOLVED_CALL,
|
||||||
loopRange!!,
|
loopRange!!,
|
||||||
"No hasNext() function " + DiagnosticUtils.atLocation(loopRange)
|
"No hasNext() function " + PsiDiagnosticUtils.atLocation(loopRange)
|
||||||
)
|
)
|
||||||
val fakeCall = codegen.makeFakeCall(TransientReceiver(iteratorCall.resultingDescriptor.returnType!!))
|
val fakeCall = codegen.makeFakeCall(TransientReceiver(iteratorCall.resultingDescriptor.returnType!!))
|
||||||
val result = codegen.invokeFunction(fakeCall, hasNextCall, StackValue.local(iteratorVarIndex, asmTypeForIterator))
|
val result = codegen.invokeFunction(fakeCall, hasNextCall, StackValue.local(iteratorVarIndex, asmTypeForIterator))
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import com.intellij.psi.PsiFile;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
||||||
|
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils;
|
||||||
|
|
||||||
import static com.intellij.openapi.util.io.FileUtil.toSystemDependentName;
|
import static com.intellij.openapi.util.io.FileUtil.toSystemDependentName;
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ public class MessageUtil {
|
|||||||
public static CompilerMessageLocation psiFileToMessageLocation(
|
public static CompilerMessageLocation psiFileToMessageLocation(
|
||||||
@NotNull PsiFile file,
|
@NotNull PsiFile file,
|
||||||
@Nullable String defaultValue,
|
@Nullable String defaultValue,
|
||||||
@NotNull DiagnosticUtils.LineAndColumn lineAndColumn
|
@NotNull PsiDiagnosticUtils.LineAndColumn lineAndColumn
|
||||||
) {
|
) {
|
||||||
VirtualFile virtualFile = file.getVirtualFile();
|
VirtualFile virtualFile = file.getVirtualFile();
|
||||||
String path = virtualFile != null ? virtualFileToPath(virtualFile) : defaultValue;
|
String path = virtualFile != null ? virtualFileToPath(virtualFile) : defaultValue;
|
||||||
|
|||||||
@@ -4,27 +4,20 @@ apply { plugin("jps-compatible") }
|
|||||||
|
|
||||||
jvmTarget = "1.6"
|
jvmTarget = "1.6"
|
||||||
|
|
||||||
val jflexPath by configurations.creating
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile(project(":core:descriptors"))
|
compile(project(":core:descriptors"))
|
||||||
compile(project(":core:deserialization"))
|
compile(project(":core:deserialization"))
|
||||||
compile(project(":compiler:util"))
|
compile(project(":compiler:util"))
|
||||||
compile(project(":compiler:container"))
|
compile(project(":compiler:container"))
|
||||||
compile(project(":compiler:resolution"))
|
compile(project(":compiler:resolution"))
|
||||||
|
compile(project(":compiler:psi"))
|
||||||
compile(project(":kotlin-script-runtime"))
|
compile(project(":kotlin-script-runtime"))
|
||||||
compile(commonDep("io.javaslang","javaslang"))
|
compile(commonDep("io.javaslang","javaslang"))
|
||||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||||
compileOnly(intellijDep()) { includeJars("annotations", "trove4j", "guava", rootProject = rootProject) }
|
compileOnly(intellijDep()) { includeJars("annotations", "trove4j", "guava", rootProject = rootProject) }
|
||||||
jflexPath(commonDep("org.jetbrains.intellij.deps.jflex", "jflex"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
"main" { projectDefault() }
|
"main" { projectDefault() }
|
||||||
"test" {}
|
"test" {}
|
||||||
}
|
}
|
||||||
|
|
||||||
ant.importBuild("buildLexer.xml")
|
|
||||||
|
|
||||||
ant.properties["builddir"] = buildDir.absolutePath
|
|
||||||
ant.properties["flex.classpath"] = jflexPath.asPath
|
|
||||||
|
|||||||
@@ -469,7 +469,7 @@ class ControlFlowInformationProvider private constructor(
|
|||||||
report(Errors.CAPTURED_VAL_INITIALIZATION.on(expression, variableDescriptor), ctxt)
|
report(Errors.CAPTURED_VAL_INITIALIZATION.on(expression, variableDescriptor), ctxt)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (KtPsiUtil.isBackingFieldReference(variableDescriptor)) {
|
if (isBackingFieldReference(variableDescriptor)) {
|
||||||
reportValReassigned(expression, variableDescriptor, ctxt)
|
reportValReassigned(expression, variableDescriptor, ctxt)
|
||||||
} else {
|
} else {
|
||||||
report(Errors.VAL_REASSIGNMENT.on(expression, variableDescriptor), ctxt)
|
report(Errors.VAL_REASSIGNMENT.on(expression, variableDescriptor), ctxt)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.descriptors
|
package org.jetbrains.kotlin.descriptors
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
|
|
||||||
@@ -23,3 +24,7 @@ fun PropertyAccessorDescriptor.hasBody(): Boolean {
|
|||||||
val ktAccessor = DescriptorToSourceUtils.getSourceFromDescriptor(this) as? KtPropertyAccessor
|
val ktAccessor = DescriptorToSourceUtils.getSourceFromDescriptor(this) as? KtPropertyAccessor
|
||||||
return ktAccessor != null && ktAccessor.hasBody()
|
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.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages;
|
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface DiagnosticSink {
|
public interface DiagnosticSink {
|
||||||
@@ -44,7 +42,8 @@ public interface DiagnosticSink {
|
|||||||
PsiFile psiFile = diagnostic.getPsiFile();
|
PsiFile psiFile = diagnostic.getPsiFile();
|
||||||
List<TextRange> textRanges = diagnostic.getTextRanges();
|
List<TextRange> textRanges = diagnostic.getTextRanges();
|
||||||
String diagnosticText = DefaultErrorMessages.render(diagnostic);
|
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.application.ApplicationManager;
|
||||||
import com.intellij.openapi.editor.Document;
|
import com.intellij.openapi.editor.Document;
|
||||||
import com.intellij.openapi.util.TextRange;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import com.intellij.psi.PsiInvalidElementAccessException;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
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.DescriptorToSourceUtils;
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics;
|
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics;
|
||||||
|
|
||||||
@@ -55,105 +53,35 @@ public class DiagnosticUtils {
|
|||||||
element = DescriptorToSourceUtils.descriptorToDeclaration(descriptor.getOriginal());
|
element = DescriptorToSourceUtils.descriptorToDeclaration(descriptor.getOriginal());
|
||||||
}
|
}
|
||||||
if (element == null && descriptor instanceof ASTNode) {
|
if (element == null && descriptor instanceof ASTNode) {
|
||||||
element = getClosestPsiElement((ASTNode) descriptor);
|
element = PsiUtilsKt.closestPsiElement((ASTNode) descriptor);
|
||||||
}
|
}
|
||||||
if (element != null) {
|
if (element != null) {
|
||||||
return atLocation(element);
|
return PsiDiagnosticUtils.atLocation(element);
|
||||||
} else {
|
} else {
|
||||||
return "unknown location";
|
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
|
@NotNull
|
||||||
public static PsiFile getContainingFile(@NotNull ASTNode node) {
|
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";
|
assert closestPsiElement != null : "This node is not contained by a file";
|
||||||
return closestPsiElement.getContainingFile();
|
return closestPsiElement.getContainingFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String atLocation(@NotNull PsiFile file, @NotNull TextRange textRange) {
|
public static PsiDiagnosticUtils.LineAndColumn getLineAndColumn(@NotNull Diagnostic diagnostic) {
|
||||||
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) {
|
|
||||||
PsiFile file = diagnostic.getPsiFile();
|
PsiFile file = diagnostic.getPsiFile();
|
||||||
List<TextRange> textRanges = diagnostic.getTextRanges();
|
List<TextRange> textRanges = diagnostic.getTextRanges();
|
||||||
if (textRanges.isEmpty()) return LineAndColumn.NONE;
|
if (textRanges.isEmpty()) return PsiDiagnosticUtils.LineAndColumn.NONE;
|
||||||
TextRange firstRange = firstRange(textRanges);
|
TextRange firstRange = firstRange(textRanges);
|
||||||
return getLineAndColumnInPsiFile(file, firstRange);
|
return getLineAndColumnInPsiFile(file, firstRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static LineAndColumn getLineAndColumnInPsiFile(PsiFile file, TextRange range) {
|
public static PsiDiagnosticUtils.LineAndColumn getLineAndColumnInPsiFile(PsiFile file, TextRange range) {
|
||||||
Document document = file.getViewProvider().getDocument();
|
Document document = file.getViewProvider().getDocument();
|
||||||
return offsetToLineAndColumn(document, range.getStartOffset());
|
return PsiDiagnosticUtils.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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void throwIfRunningOnServer(Throwable e) {
|
public static void throwIfRunningOnServer(Throwable e) {
|
||||||
@@ -194,43 +122,6 @@ public class DiagnosticUtils {
|
|||||||
return result;
|
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) {
|
public static boolean hasError(Diagnostics diagnostics) {
|
||||||
for (Diagnostic diagnostic : diagnostics.all()) {
|
for (Diagnostic diagnostic : diagnostics.all()) {
|
||||||
if (diagnostic.getSeverity() == Severity.ERROR) return true;
|
if (diagnostic.getSeverity() == Severity.ERROR) return true;
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.psi.psiUtil
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||||
|
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||||
|
|
||||||
|
fun checkReservedPrefixWord(sink: DiagnosticSink, element: PsiElement, word: String, message: String) {
|
||||||
|
KtPsiUtil.getPreviousWord(element, word)?.let {
|
||||||
|
sink.report(Errors.UNSUPPORTED.on(it, message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkReservedYield(expression: KtSimpleNameExpression?, sink: DiagnosticSink) {
|
||||||
|
// do not force identifier calculation for elements from stubs.
|
||||||
|
if (expression?.getReferencedName() != "yield") return
|
||||||
|
|
||||||
|
val identifier = expression.getIdentifier() ?: return
|
||||||
|
|
||||||
|
if (identifier.node.elementType == KtTokens.IDENTIFIER && "yield" == identifier.text) {
|
||||||
|
sink.report(Errors.YIELD_IS_RESERVED.on(identifier, "Identifier 'yield' is reserved. Use backticks to call it: `yield`"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val MESSAGE_FOR_YIELD_BEFORE_LAMBDA = "Reserved yield block/lambda. Use 'yield() { ... }' or 'yield(fun...)'"
|
||||||
|
|
||||||
|
fun checkReservedYieldBeforeLambda(element: PsiElement, sink: DiagnosticSink) {
|
||||||
|
KtPsiUtil.getPreviousWord(element, "yield")?.let {
|
||||||
|
sink.report(Errors.YIELD_IS_RESERVED.on(it, MESSAGE_FOR_YIELD_BEFORE_LAMBDA))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink;
|
import org.jetbrains.kotlin.diagnostics.DiagnosticSink;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils;
|
||||||
import org.jetbrains.kotlin.psi.KtElement;
|
import org.jetbrains.kotlin.psi.KtElement;
|
||||||
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid;
|
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid;
|
||||||
import org.jetbrains.kotlin.psi.debugText.DebugTextUtilKt;
|
import org.jetbrains.kotlin.psi.debugText.DebugTextUtilKt;
|
||||||
@@ -45,7 +45,7 @@ public class AnalyzingUtils {
|
|||||||
public void visitErrorElement(@NotNull PsiErrorElement element) {
|
public void visitErrorElement(@NotNull PsiErrorElement element) {
|
||||||
throw new IllegalArgumentException(element.getErrorDescription() + "; looking at " +
|
throw new IllegalArgumentException(element.getErrorDescription() + "; looking at " +
|
||||||
element.getNode().getElementType() + " '" +
|
element.getNode().getElementType() + " '" +
|
||||||
element.getText() + DiagnosticUtils.atLocation(element));
|
element.getText() + PsiDiagnosticUtils.atLocation(element));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.FunctionExpressionDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.FunctionExpressionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
|
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -142,7 +142,9 @@ class FunctionDescriptorResolver(
|
|||||||
) {
|
) {
|
||||||
if (functionDescriptor.returnType != null) return
|
if (functionDescriptor.returnType != null) return
|
||||||
assert(function.typeReference == null) {
|
assert(function.typeReference == null) {
|
||||||
"Return type must be initialized early for function: " + function.text + ", at: " + DiagnosticUtils.atLocation(function)
|
"Return type must be initialized early for function: " + function.text + ", at: " + PsiDiagnosticUtils.atLocation(
|
||||||
|
function
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val inferredReturnType = when {
|
val inferredReturnType = when {
|
||||||
|
|||||||
@@ -5,11 +5,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve
|
package org.jetbrains.kotlin.resolve
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
import org.jetbrains.kotlin.container.StorageComponentContainer
|
import org.jetbrains.kotlin.container.StorageComponentContainer
|
||||||
import org.jetbrains.kotlin.container.composeContainer
|
import org.jetbrains.kotlin.container.composeContainer
|
||||||
import org.jetbrains.kotlin.container.useInstance
|
import org.jetbrains.kotlin.container.useInstance
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap
|
import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi.UserDataProperty
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.*
|
import org.jetbrains.kotlin.resolve.calls.checkers.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||||
import org.jetbrains.kotlin.resolve.checkers.*
|
import org.jetbrains.kotlin.resolve.checkers.*
|
||||||
@@ -143,3 +146,6 @@ abstract class PlatformConfigurator(
|
|||||||
|
|
||||||
fun createContainer(id: String, platform: TargetPlatform, init: StorageComponentContainer.() -> Unit) =
|
fun createContainer(id: String, platform: TargetPlatform, init: StorageComponentContainer.() -> Unit) =
|
||||||
composeContainer(id, platform.platformConfigurator.platformSpecificContainer, init)
|
composeContainer(id, platform.platformConfigurator.platformSpecificContainer, init)
|
||||||
|
|
||||||
|
|
||||||
|
var KtFile.targetPlatform: TargetPlatform? by UserDataProperty(Key.create("TARGET_PLATFORM"))
|
||||||
+2
-1
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
|||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
|
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.ReservedCheckingKt;
|
||||||
import org.jetbrains.kotlin.resolve.OverrideResolver;
|
import org.jetbrains.kotlin.resolve.OverrideResolver;
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.ArgumentsUtilsKt;
|
import org.jetbrains.kotlin.resolve.calls.components.ArgumentsUtilsKt;
|
||||||
@@ -181,7 +182,7 @@ public class ValueArgumentsToParametersMapper {
|
|||||||
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(argumentName.getAsName());
|
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(argumentName.getAsName());
|
||||||
KtSimpleNameExpression nameReference = argumentName.getReferenceExpression();
|
KtSimpleNameExpression nameReference = argumentName.getReferenceExpression();
|
||||||
|
|
||||||
KtPsiUtilKt.checkReservedYield(nameReference, candidateCall.getTrace());
|
ReservedCheckingKt.checkReservedYield(nameReference, candidateCall.getTrace());
|
||||||
if (nameReference != null) {
|
if (nameReference != null) {
|
||||||
if (candidate instanceof MemberDescriptor && ((MemberDescriptor) candidate).isExpect() &&
|
if (candidate instanceof MemberDescriptor && ((MemberDescriptor) candidate).isExpect() &&
|
||||||
candidate.getContainingDeclaration() instanceof ClassDescriptor) {
|
candidate.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.lazy;
|
package org.jetbrains.kotlin.resolve.lazy;
|
||||||
|
|
||||||
|
import kotlin.Deprecated;
|
||||||
|
import kotlin.ReplaceWith;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
@@ -26,9 +28,8 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
|||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.name.FqNamesUtilKt;
|
import org.jetbrains.kotlin.name.FqNamesUtilKt;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.name.SpecialNames;
|
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclarationUtil;
|
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -91,21 +92,4 @@ public class ResolveSessionUtils {
|
|||||||
|
|
||||||
return (ClassDescriptor) classifier;
|
return (ClassDescriptor) classifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static Name safeNameForLazyResolve(@NotNull KtNamedDeclaration declaration) {
|
|
||||||
return safeNameForLazyResolve(declaration.getNameAsName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static Name safeNameForLazyResolve(@Nullable Name name) {
|
|
||||||
return SpecialNames.safeIdentifier(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static FqName safeFqNameForLazyResolve(@NotNull KtNamedDeclaration declaration) {
|
|
||||||
//NOTE: should only create special names for package level declarations, so we can safely rely on real fq name for parent
|
|
||||||
FqName parentFqName = KtNamedDeclarationUtil.getParentFqName(declaration);
|
|
||||||
return parentFqName != null ? parentFqName.child(safeNameForLazyResolve(declaration)) : null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-12
@@ -20,7 +20,7 @@ import com.google.common.collect.ArrayListMultimap
|
|||||||
import com.google.common.collect.Sets
|
import com.google.common.collect.Sets
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSessionUtils.safeNameForLazyResolve
|
import org.jetbrains.kotlin.psi.psiUtil.safeNameForLazyResolve
|
||||||
import org.jetbrains.kotlin.resolve.lazy.data.KtClassInfoUtil
|
import org.jetbrains.kotlin.resolve.lazy.data.KtClassInfoUtil
|
||||||
import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo
|
import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo
|
||||||
import org.jetbrains.kotlin.resolve.lazy.data.KtScriptInfo
|
import org.jetbrains.kotlin.resolve.lazy.data.KtScriptInfo
|
||||||
@@ -46,20 +46,20 @@ abstract class AbstractPsiBasedDeclarationProvider(storageManager: StorageManage
|
|||||||
allDeclarations.add(declaration)
|
allDeclarations.add(declaration)
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is KtNamedFunction ->
|
is KtNamedFunction ->
|
||||||
functions.put(safeNameForLazyResolve(declaration), declaration)
|
functions.put(declaration.safeNameForLazyResolve(), declaration)
|
||||||
is KtProperty ->
|
is KtProperty ->
|
||||||
properties.put(safeNameForLazyResolve(declaration), declaration)
|
properties.put(declaration.safeNameForLazyResolve(), declaration)
|
||||||
is KtTypeAlias ->
|
is KtTypeAlias ->
|
||||||
typeAliases.put(safeNameForLazyResolve(declaration.nameAsName), declaration)
|
typeAliases.put(declaration.nameAsName.safeNameForLazyResolve(), declaration)
|
||||||
is KtClassOrObject ->
|
is KtClassOrObject ->
|
||||||
classesAndObjects.put(safeNameForLazyResolve(declaration.nameAsName), KtClassInfoUtil.createClassLikeInfo(declaration))
|
classesAndObjects.put(declaration.nameAsName.safeNameForLazyResolve(), KtClassInfoUtil.createClassLikeInfo(declaration))
|
||||||
is KtScript -> {
|
is KtScript -> {
|
||||||
val scriptInfo = KtScriptInfo(declaration)
|
val scriptInfo = KtScriptInfo(declaration)
|
||||||
classesAndObjects.put(scriptInfo.script.nameAsName, scriptInfo)
|
classesAndObjects.put(scriptInfo.script.nameAsName, scriptInfo)
|
||||||
}
|
}
|
||||||
is KtDestructuringDeclaration -> {
|
is KtDestructuringDeclaration -> {
|
||||||
for (entry in declaration.entries) {
|
for (entry in declaration.entries) {
|
||||||
val name = safeNameForLazyResolve(entry.nameAsName)
|
val name = entry.nameAsName.safeNameForLazyResolve()
|
||||||
destructuringDeclarationsEntries.put(name, entry)
|
destructuringDeclarationsEntries.put(name, entry)
|
||||||
names.add(name)
|
names.add(name)
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ abstract class AbstractPsiBasedDeclarationProvider(storageManager: StorageManage
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is KtNamedDeclaration -> names.add(safeNameForLazyResolve(declaration))
|
is KtNamedDeclaration -> names.add(declaration.safeNameForLazyResolve())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,15 +93,15 @@ abstract class AbstractPsiBasedDeclarationProvider(storageManager: StorageManage
|
|||||||
override fun getDeclarations(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): List<KtDeclaration> =
|
override fun getDeclarations(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): List<KtDeclaration> =
|
||||||
index().allDeclarations
|
index().allDeclarations
|
||||||
|
|
||||||
override fun getFunctionDeclarations(name: Name): List<KtNamedFunction> = index().functions[safeNameForLazyResolve(name)].toList()
|
override fun getFunctionDeclarations(name: Name): List<KtNamedFunction> = index().functions[name.safeNameForLazyResolve()].toList()
|
||||||
|
|
||||||
override fun getPropertyDeclarations(name: Name): List<KtProperty> = index().properties[safeNameForLazyResolve(name)].toList()
|
override fun getPropertyDeclarations(name: Name): List<KtProperty> = index().properties[name.safeNameForLazyResolve()].toList()
|
||||||
|
|
||||||
override fun getDestructuringDeclarationsEntries(name: Name): Collection<KtDestructuringDeclarationEntry> =
|
override fun getDestructuringDeclarationsEntries(name: Name): Collection<KtDestructuringDeclarationEntry> =
|
||||||
index().destructuringDeclarationsEntries[safeNameForLazyResolve(name)].toList()
|
index().destructuringDeclarationsEntries[name.safeNameForLazyResolve()].toList()
|
||||||
|
|
||||||
override fun getClassOrObjectDeclarations(name: Name): Collection<KtClassLikeInfo> =
|
override fun getClassOrObjectDeclarations(name: Name): Collection<KtClassLikeInfo> =
|
||||||
index().classesAndObjects[safeNameForLazyResolve(name)]
|
index().classesAndObjects[name.safeNameForLazyResolve()]
|
||||||
|
|
||||||
override fun getTypeAliasDeclarations(name: Name): Collection<KtTypeAlias> = index().typeAliases[safeNameForLazyResolve(name)]
|
override fun getTypeAliasDeclarations(name: Name): Collection<KtTypeAlias> = index().typeAliases[name.safeNameForLazyResolve()]
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.name.Name;
|
|||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
|
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.ReservedCheckingKt;
|
||||||
import org.jetbrains.kotlin.resolve.*;
|
import org.jetbrains.kotlin.resolve.*;
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver;
|
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver;
|
||||||
@@ -159,7 +160,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KotlinTypeInfo visitSimpleNameExpression(@NotNull KtSimpleNameExpression expression, ExpressionTypingContext context) {
|
public KotlinTypeInfo visitSimpleNameExpression(@NotNull KtSimpleNameExpression expression, ExpressionTypingContext context) {
|
||||||
KtPsiUtilKt.checkReservedYield(expression, context.trace);
|
ReservedCheckingKt.checkReservedYield(expression, context.trace);
|
||||||
|
|
||||||
// TODO : other members
|
// TODO : other members
|
||||||
// TODO : type substitutions???
|
// TODO : type substitutions???
|
||||||
@@ -882,7 +883,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
boolean isStatement
|
boolean isStatement
|
||||||
) {
|
) {
|
||||||
KtSimpleNameExpression labelExpression = expression.getTargetLabel();
|
KtSimpleNameExpression labelExpression = expression.getTargetLabel();
|
||||||
KtPsiUtilKt.checkReservedYield(labelExpression, context.trace);
|
ReservedCheckingKt.checkReservedYield(labelExpression, context.trace);
|
||||||
if (labelExpression != null) {
|
if (labelExpression != null) {
|
||||||
PsiElement labelIdentifier = labelExpression.getIdentifier();
|
PsiElement labelIdentifier = labelExpression.getIdentifier();
|
||||||
UnderscoreChecker.INSTANCE.checkIdentifier(labelIdentifier, context.trace, components.languageVersionSettings);
|
UnderscoreChecker.INSTANCE.checkIdentifier(labelIdentifier, context.trace, components.languageVersionSettings);
|
||||||
|
|||||||
+2
-2
@@ -9,8 +9,8 @@ import com.intellij.openapi.diagnostic.Logger;
|
|||||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
|
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils;
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker;
|
import org.jetbrains.kotlin.incremental.components.LookupTracker;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.psi.codeFragmentUtil.CodeFragmentUtilKt;
|
import org.jetbrains.kotlin.psi.codeFragmentUtil.CodeFragmentUtilKt;
|
||||||
@@ -230,7 +230,7 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<Kotlin
|
|||||||
try {
|
try {
|
||||||
// This trows AssertionError in CLI and reports the error in the IDE
|
// This trows AssertionError in CLI and reports the error in the IDE
|
||||||
LOG.error(
|
LOG.error(
|
||||||
new KotlinExceptionWithAttachments("Exception while analyzing expression at " + DiagnosticUtils.atLocation(expression), e)
|
new KotlinExceptionWithAttachments("Exception while analyzing expression at " + PsiDiagnosticUtils.atLocation(expression), e)
|
||||||
.withAttachment("expression.kt", expression.getText())
|
.withAttachment("expression.kt", expression.getText())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-3
@@ -25,9 +25,9 @@ import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
|
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.checkReservedPrefixWord
|
import org.jetbrains.kotlin.psi.psiUtil.checkReservedPrefixWord
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.checkReservedYieldBeforeLambda
|
import org.jetbrains.kotlin.psi.psiUtil.checkReservedYieldBeforeLambda
|
||||||
@@ -91,7 +91,9 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
|||||||
context.scope.ownerDescriptor, context.scope, function, context.trace, context.dataFlowInfo
|
context.scope.ownerDescriptor, context.scope, function, context.trace, context.dataFlowInfo
|
||||||
)
|
)
|
||||||
assert(statementScope != null) {
|
assert(statementScope != null) {
|
||||||
"statementScope must be not null for function: " + function.name + " at location " + DiagnosticUtils.atLocation(function)
|
"statementScope must be not null for function: " + function.name + " at location " + PsiDiagnosticUtils.atLocation(
|
||||||
|
function
|
||||||
|
)
|
||||||
}
|
}
|
||||||
statementScope!!.addFunctionDescriptor(functionDescriptor)
|
statementScope!!.addFunctionDescriptor(functionDescriptor)
|
||||||
} else {
|
} else {
|
||||||
@@ -176,7 +178,12 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkReservedYield(context: ExpressionTypingContext, expression: PsiElement) {
|
private fun checkReservedYield(context: ExpressionTypingContext, expression: PsiElement) {
|
||||||
checkReservedPrefixWord(context.trace, expression, "yield", "yield block/lambda. Use 'yield() { ... }' or 'yield(fun...)'")
|
checkReservedPrefixWord(
|
||||||
|
context.trace,
|
||||||
|
expression,
|
||||||
|
"yield",
|
||||||
|
"yield block/lambda. Use 'yield() { ... }' or 'yield(fun...)'"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createFunctionLiteralDescriptor(
|
private fun createFunctionLiteralDescriptor(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.util
|
package org.jetbrains.kotlin.util
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||||
|
|
||||||
class KotlinFrontEndException(message: String, cause: Throwable) : KotlinExceptionWithAttachments(message, cause) {
|
class KotlinFrontEndException(message: String, cause: Throwable) : KotlinExceptionWithAttachments(message, cause) {
|
||||||
@@ -14,7 +14,7 @@ class KotlinFrontEndException(message: String, cause: Throwable) : KotlinExcepti
|
|||||||
message: String,
|
message: String,
|
||||||
cause: Throwable,
|
cause: Throwable,
|
||||||
element: PsiElement
|
element: PsiElement
|
||||||
) : this(getExceptionMessage("Front-end", message, cause, DiagnosticUtils.atLocation(element)), cause) {
|
) : this(getExceptionMessage("Front-end", message, cause, PsiDiagnosticUtils.atLocation(element)), cause) {
|
||||||
withAttachment(
|
withAttachment(
|
||||||
"element.kt",
|
"element.kt",
|
||||||
if (element.isValid) {
|
if (element.isValid) {
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
apply { plugin("kotlin") }
|
||||||
|
apply { plugin("jps-compatible") }
|
||||||
|
|
||||||
|
|
||||||
|
jvmTarget = "1.6"
|
||||||
|
|
||||||
|
val jflexPath by configurations.creating
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
val compile by configurations
|
||||||
|
val compileOnly by configurations
|
||||||
|
|
||||||
|
compile(project(":core:descriptors"))
|
||||||
|
compile(project(":compiler:util"))
|
||||||
|
compile(project(":kotlin-script-runtime"))
|
||||||
|
|
||||||
|
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "annotations") }
|
||||||
|
compileOnly(intellijDep()) { includeJars("guava", "trove4j", 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
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.diagnostics;
|
||||||
|
|
||||||
|
import com.intellij.lang.ASTNode;
|
||||||
|
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.psi.KtExpression;
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||||
|
|
||||||
|
public class PsiDiagnosticUtils {
|
||||||
|
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(KtExpression expression) {
|
||||||
|
return atLocation(expression.getNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String atLocation(@NotNull ASTNode node) {
|
||||||
|
int startOffset = node.getStartOffset();
|
||||||
|
PsiElement element = PsiUtilsKt.closestPsiElement(node);
|
||||||
|
if (element != null) {
|
||||||
|
return atLocation(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "at offset " + startOffset + " (line and file unknown: no PSI element)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
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 + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user