use of org.jetbrains.kotlin.diagnostics.Diagnostic in project kotlin by JetBrains.
the class ExpectedResolveData method checkResult.
public final void checkResult(BindingContext bindingContext) {
Set<PsiElement> unresolvedReferences = Sets.newHashSet();
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.getFactory())) {
unresolvedReferences.add(diagnostic.getPsiElement());
}
}
Map<String, PsiElement> nameToDeclaration = Maps.newHashMap();
Map<PsiElement, String> declarationToName = Maps.newHashMap();
for (Map.Entry<String, Position> entry : declarationToPosition.entrySet()) {
String name = entry.getKey();
Position position = entry.getValue();
PsiElement element = position.getElement();
PsiElement ancestorOfType;
if (name.equals("file")) {
ancestorOfType = element.getContainingFile();
} else {
ancestorOfType = getAncestorOfType(KtDeclaration.class, element);
if (ancestorOfType == null) {
KtPackageDirective directive = getAncestorOfType(KtPackageDirective.class, element);
assert directive != null : "Not a declaration: " + name;
ancestorOfType = element;
}
}
nameToDeclaration.put(name, ancestorOfType);
declarationToName.put(ancestorOfType, name);
}
for (Map.Entry<Position, String> entry : positionToReference.entrySet()) {
Position position = entry.getKey();
String name = entry.getValue();
PsiElement element = position.getElement();
KtReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(element, KtReferenceExpression.class);
DeclarationDescriptor referenceTarget = bindingContext.get(REFERENCE_TARGET, referenceExpression);
if ("!".equals(name)) {
assertTrue("Must have been unresolved: " + renderReferenceInContext(referenceExpression) + " but was resolved to " + renderNullableDescriptor(referenceTarget), unresolvedReferences.contains(referenceExpression));
assertTrue(String.format("Reference =%s= has a reference target =%s= but expected to be unresolved", renderReferenceInContext(referenceExpression), renderNullableDescriptor(referenceTarget)), referenceTarget == null);
continue;
}
if ("!!".equals(name)) {
assertTrue("Must have been resolved to multiple descriptors: " + renderReferenceInContext(referenceExpression) + " but was resolved to " + renderNullableDescriptor(referenceTarget), bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, referenceExpression) != null);
continue;
} else if ("!null".equals(name)) {
assertTrue("Must have been resolved to null: " + renderReferenceInContext(referenceExpression) + " but was resolved to " + renderNullableDescriptor(referenceTarget), referenceTarget == null);
continue;
} else if ("!error".equals(name)) {
assertTrue("Must have been resolved to error: " + renderReferenceInContext(referenceExpression) + " but was resolved to " + renderNullableDescriptor(referenceTarget), ErrorUtils.isError(referenceTarget));
continue;
}
PsiElement expected = nameToDeclaration.get(name);
if (expected == null) {
expected = nameToPsiElement.get(name);
}
KtReferenceExpression reference = getAncestorOfType(KtReferenceExpression.class, element);
if (expected == null && name.startsWith(STANDARD_PREFIX)) {
DeclarationDescriptor expectedDescriptor = nameToDescriptor.get(name);
KtTypeReference typeReference = getAncestorOfType(KtTypeReference.class, element);
if (expectedDescriptor != null) {
DeclarationDescriptor actual = bindingContext.get(REFERENCE_TARGET, reference);
assertDescriptorsEqual("Expected: " + name, expectedDescriptor.getOriginal(), actual == null ? null : actual.getOriginal());
continue;
}
KotlinType actualType = bindingContext.get(BindingContext.TYPE, typeReference);
assertNotNull("Type " + name + " not resolved for reference " + name, actualType);
ClassifierDescriptor expectedClass = getBuiltinClass(name.substring(STANDARD_PREFIX.length()));
assertTypeConstructorEquals("Type resolution mismatch: ", expectedClass.getTypeConstructor(), actualType.getConstructor());
continue;
}
assert expected != null : "No declaration for " + name;
if (referenceTarget instanceof PackageViewDescriptor) {
KtPackageDirective expectedDirective = PsiTreeUtil.getParentOfType(expected, KtPackageDirective.class);
FqName expectedFqName;
if (expectedDirective != null) {
expectedFqName = expectedDirective.getFqName();
} else if (expected instanceof PsiQualifiedNamedElement) {
String qualifiedName = ((PsiQualifiedNamedElement) expected).getQualifiedName();
assert qualifiedName != null : "No qualified name for " + name;
expectedFqName = new FqName(qualifiedName);
} else {
throw new IllegalStateException(expected.getClass().getName() + " name=" + name);
}
assertEquals(expectedFqName, ((PackageViewDescriptor) referenceTarget).getFqName());
continue;
}
PsiElement actual = referenceTarget == null ? bindingContext.get(BindingContext.LABEL_TARGET, referenceExpression) : DescriptorToSourceUtils.descriptorToDeclaration(referenceTarget);
if (actual instanceof KtSimpleNameExpression) {
actual = ((KtSimpleNameExpression) actual).getIdentifier();
}
String actualName = null;
if (actual != null) {
actualName = declarationToName.get(actual);
if (actualName == null) {
actualName = actual.toString();
}
}
assertNotNull(element.getText(), reference);
assertEquals("Reference `" + name + "`" + renderReferenceInContext(reference) + " is resolved into " + actualName + ".", expected, actual);
}
for (Map.Entry<Position, String> entry : positionToType.entrySet()) {
Position position = entry.getKey();
String typeName = entry.getValue();
PsiElement element = position.getElement();
KtExpression expression = getAncestorOfType(KtExpression.class, element);
KotlinType expressionType = bindingContext.getType(expression);
TypeConstructor expectedTypeConstructor;
if (typeName.startsWith(STANDARD_PREFIX)) {
String name = typeName.substring(STANDARD_PREFIX.length());
ClassifierDescriptor expectedClass = getBuiltinClass(name);
expectedTypeConstructor = expectedClass.getTypeConstructor();
} else {
Position declarationPosition = declarationToPosition.get(typeName);
assertNotNull("Undeclared: " + typeName, declarationPosition);
PsiElement declElement = declarationPosition.getElement();
assertNotNull(declarationPosition);
KtDeclaration declaration = getAncestorOfType(KtDeclaration.class, declElement);
assertNotNull(declaration);
if (declaration instanceof KtClass) {
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, declaration);
expectedTypeConstructor = classDescriptor.getTypeConstructor();
} else if (declaration instanceof KtTypeParameter) {
TypeParameterDescriptor typeParameterDescriptor = bindingContext.get(BindingContext.TYPE_PARAMETER, (KtTypeParameter) declaration);
expectedTypeConstructor = typeParameterDescriptor.getTypeConstructor();
} else {
fail("Unsupported declaration: " + declaration);
return;
}
}
assertNotNull(expression.getText() + " type is null", expressionType);
assertTypeConstructorEquals("At " + position + ": ", expectedTypeConstructor, expressionType.getConstructor());
}
}
use of org.jetbrains.kotlin.diagnostics.Diagnostic in project kotlin by JetBrains.
the class CheckerTestUtil method getDiagnosticsIncludingSyntaxErrors.
@NotNull
public static List<ActualDiagnostic> getDiagnosticsIncludingSyntaxErrors(@NotNull BindingContext bindingContext, @NotNull PsiElement root, boolean markDynamicCalls, @Nullable List<DeclarationDescriptor> dynamicCallDescriptors, @Nullable String platform) {
List<ActualDiagnostic> diagnostics = new ArrayList<ActualDiagnostic>();
for (Diagnostic diagnostic : bindingContext.getDiagnostics().all()) {
if (PsiTreeUtil.isAncestor(root, diagnostic.getPsiElement(), false)) {
diagnostics.add(new ActualDiagnostic(diagnostic, platform));
}
}
for (PsiErrorElement errorElement : AnalyzingUtils.getSyntaxErrorRanges(root)) {
diagnostics.add(new ActualDiagnostic(new SyntaxErrorDiagnostic(errorElement), platform));
}
diagnostics.addAll(getDebugInfoDiagnostics(root, bindingContext, markDynamicCalls, dynamicCallDescriptors, platform));
return diagnostics;
}
use of org.jetbrains.kotlin.diagnostics.Diagnostic in project kotlin by JetBrains.
the class DebugInfoUtil method markDebugAnnotations.
public static void markDebugAnnotations(@NotNull PsiElement root, @NotNull final BindingContext bindingContext, @NotNull final DebugInfoReporter debugInfoReporter) {
final Map<KtReferenceExpression, DiagnosticFactory<?>> markedWithErrorElements = Maps.newHashMap();
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
DiagnosticFactory<?> factory = diagnostic.getFactory();
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.getFactory())) {
markedWithErrorElements.put((KtReferenceExpression) diagnostic.getPsiElement(), factory);
} else if (factory == Errors.SUPER_IS_NOT_AN_EXPRESSION || factory == Errors.SUPER_NOT_AVAILABLE) {
KtSuperExpression superExpression = (KtSuperExpression) diagnostic.getPsiElement();
markedWithErrorElements.put(superExpression.getInstanceReference(), factory);
} else if (factory == Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND) {
markedWithErrorElements.put((KtSimpleNameExpression) diagnostic.getPsiElement(), factory);
} else if (factory == Errors.UNSUPPORTED) {
for (KtReferenceExpression reference : PsiTreeUtil.findChildrenOfType(diagnostic.getPsiElement(), KtReferenceExpression.class)) {
markedWithErrorElements.put(reference, factory);
}
}
}
root.acceptChildren(new KtTreeVisitorVoid() {
@Override
public void visitForExpression(@NotNull KtForExpression expression) {
KtExpression range = expression.getLoopRange();
reportIfDynamicCall(range, range, LOOP_RANGE_ITERATOR_RESOLVED_CALL);
reportIfDynamicCall(range, range, LOOP_RANGE_HAS_NEXT_RESOLVED_CALL);
reportIfDynamicCall(range, range, LOOP_RANGE_NEXT_RESOLVED_CALL);
super.visitForExpression(expression);
}
@Override
public void visitDestructuringDeclaration(@NotNull KtDestructuringDeclaration destructuringDeclaration) {
for (KtDestructuringDeclarationEntry entry : destructuringDeclaration.getEntries()) {
reportIfDynamicCall(entry, entry, COMPONENT_RESOLVED_CALL);
}
super.visitDestructuringDeclaration(destructuringDeclaration);
}
@Override
public void visitProperty(@NotNull KtProperty property) {
VariableDescriptor descriptor = bindingContext.get(VARIABLE, property);
if (descriptor instanceof PropertyDescriptor && property.getDelegate() != null) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
reportIfDynamicCall(property.getDelegate(), propertyDescriptor, PROVIDE_DELEGATE_RESOLVED_CALL);
reportIfDynamicCall(property.getDelegate(), propertyDescriptor.getGetter(), DELEGATED_PROPERTY_RESOLVED_CALL);
reportIfDynamicCall(property.getDelegate(), propertyDescriptor.getSetter(), DELEGATED_PROPERTY_RESOLVED_CALL);
}
super.visitProperty(property);
}
@Override
public void visitThisExpression(@NotNull KtThisExpression expression) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt.getResolvedCall(expression, bindingContext);
if (resolvedCall != null) {
reportIfDynamic(expression, resolvedCall.getResultingDescriptor(), debugInfoReporter);
}
super.visitThisExpression(expression);
}
@Override
public void visitReferenceExpression(@NotNull KtReferenceExpression expression) {
super.visitReferenceExpression(expression);
if (!BindingContextUtils.isExpressionWithValidReference(expression, bindingContext)) {
return;
}
IElementType referencedNameElementType = null;
if (expression instanceof KtSimpleNameExpression) {
KtSimpleNameExpression nameExpression = (KtSimpleNameExpression) expression;
IElementType elementType = expression.getNode().getElementType();
if (elementType == KtNodeTypes.OPERATION_REFERENCE) {
referencedNameElementType = nameExpression.getReferencedNameElementType();
if (EXCLUDED.contains(referencedNameElementType)) {
return;
}
}
if (elementType == KtNodeTypes.LABEL || nameExpression.getReferencedNameElementType() == KtTokens.THIS_KEYWORD) {
return;
}
}
debugInfoReporter.preProcessReference(expression);
String target = null;
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, expression);
if (declarationDescriptor != null) {
target = declarationDescriptor.toString();
reportIfDynamic(expression, declarationDescriptor, debugInfoReporter);
}
if (target == null) {
PsiElement labelTarget = bindingContext.get(LABEL_TARGET, expression);
if (labelTarget != null) {
target = labelTarget.getText();
}
}
if (target == null) {
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, expression);
if (declarationDescriptors != null) {
target = "[" + declarationDescriptors.size() + " descriptors]";
}
}
if (target == null) {
Collection<? extends PsiElement> labelTargets = bindingContext.get(AMBIGUOUS_LABEL_TARGET, expression);
if (labelTargets != null) {
target = "[" + labelTargets.size() + " elements]";
}
}
if (MAY_BE_UNRESOLVED.contains(referencedNameElementType)) {
return;
}
boolean resolved = target != null;
boolean markedWithError = markedWithErrorElements.containsKey(expression);
if (expression instanceof KtArrayAccessExpression && markedWithErrorElements.containsKey(((KtArrayAccessExpression) expression).getArrayExpression())) {
// if 'foo' in 'foo[i]' is unresolved it means 'foo[i]' is unresolved (otherwise 'foo[i]' is marked as 'missing unresolved')
markedWithError = true;
}
KotlinType expressionType = bindingContext.getType(expression);
DiagnosticFactory<?> factory = markedWithErrorElements.get(expression);
if (declarationDescriptor != null && (ErrorUtils.isError(declarationDescriptor) || ErrorUtils.containsErrorType(expressionType))) {
if (factory != Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND) {
debugInfoReporter.reportElementWithErrorType(expression);
}
}
if (resolved && markedWithError) {
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(factory)) {
debugInfoReporter.reportUnresolvedWithTarget(expression, target);
}
} else if (!resolved && !markedWithError) {
debugInfoReporter.reportMissingUnresolved(expression);
}
}
private <E extends KtElement, K, D extends CallableDescriptor> boolean reportIfDynamicCall(E element, K key, WritableSlice<K, ResolvedCall<D>> slice) {
ResolvedCall<D> resolvedCall = bindingContext.get(slice, key);
if (resolvedCall != null) {
return reportIfDynamic(element, resolvedCall.getResultingDescriptor(), debugInfoReporter);
}
return false;
}
});
}
use of org.jetbrains.kotlin.diagnostics.Diagnostic in project kotlin by JetBrains.
the class KotlinBytecodeToolWindow method getBytecodeForFile.
// public for tests
@NotNull
public static String getBytecodeForFile(@NotNull KtFile ktFile, @NotNull CompilerConfiguration configuration) {
GenerationState state;
try {
state = compileSingleFile(ktFile, configuration);
} catch (ProcessCanceledException e) {
throw e;
} catch (Exception e) {
return printStackTraceToString(e);
}
StringBuilder answer = new StringBuilder();
Collection<Diagnostic> diagnostics = state.getCollectedExtraJvmDiagnostics().all();
if (!diagnostics.isEmpty()) {
answer.append("// Backend Errors: \n");
answer.append("// ================\n");
for (Diagnostic diagnostic : diagnostics) {
answer.append("// Error at ").append(diagnostic.getPsiFile().getName()).append(StringsKt.join(diagnostic.getTextRanges(), ",")).append(": ").append(DefaultErrorMessages.render(diagnostic)).append("\n");
}
answer.append("// ================\n\n");
}
OutputFileCollection outputFiles = state.getFactory();
for (OutputFile outputFile : outputFiles.asList()) {
answer.append("// ================");
answer.append(outputFile.getRelativePath());
answer.append(" =================\n");
answer.append(outputFile.asText()).append("\n\n");
}
return answer.toString();
}
use of org.jetbrains.kotlin.diagnostics.Diagnostic in project kotlin by JetBrains.
the class AbstractDiagnosticMessageTest method doTest.
public void doTest(String filePath) throws Exception {
File file = new File(filePath);
String fileName = file.getName();
String fileData = KotlinTestUtils.doLoadFile(file);
Map<String, String> directives = KotlinTestUtils.parseDirectives(fileData);
int diagnosticNumber = getDiagnosticNumber(directives);
final Set<DiagnosticFactory<?>> diagnosticFactories = getDiagnosticFactories(directives);
MessageType messageType = getMessageTypeDirective(directives);
String explicitLanguageVersion = InTextDirectivesUtils.findStringWithPrefixes(fileData, "// LANGUAGE_VERSION:");
LanguageVersion version = explicitLanguageVersion == null ? null : LanguageVersion.fromVersionString(explicitLanguageVersion);
KtFile psiFile = KotlinTestUtils.createFile(fileName, KotlinTestUtils.doLoadFile(getTestDataPath(), fileName), getProject());
AnalysisResult analysisResult = analyze(psiFile, version);
BindingContext bindingContext = analysisResult.getBindingContext();
List<Diagnostic> diagnostics = ContainerUtil.filter(bindingContext.getDiagnostics().all(), new Condition<Diagnostic>() {
@Override
public boolean value(Diagnostic diagnostic) {
return diagnosticFactories.contains(diagnostic.getFactory());
}
});
assertEquals("Expected diagnostics number mismatch:", diagnosticNumber, diagnostics.size());
int index = 1;
String name = FileUtil.getNameWithoutExtension(fileName);
for (Diagnostic diagnostic : diagnostics) {
String readableDiagnosticText;
String extension;
if (messageType != MessageType.TEXT && IdeErrorMessages.hasIdeSpecificMessage(diagnostic)) {
readableDiagnosticText = FormatHtmlUtilKt.formatHtml(IdeErrorMessages.render(diagnostic));
extension = MessageType.HTML.extension;
} else {
readableDiagnosticText = DefaultErrorMessages.render(diagnostic);
extension = MessageType.TEXT.extension;
}
String errorMessageFileName = name + index;
String path = getTestDataPath() + "/" + errorMessageFileName + "." + extension;
String actualText = "<!-- " + errorMessageFileName + " -->\n" + readableDiagnosticText;
assertSameLinesWithFile(path, actualText);
index++;
}
}
Aggregations