All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jetbrains.jet.checkers.DebugInfoUtil Maven / Gradle / Ivy
/*
* Copyright 2010-2013 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.jet.checkers;
import com.google.common.collect.Maps;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lexer.JetTokens;
import java.util.Collection;
import java.util.Map;
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lexer.JetTokens.*;
public class DebugInfoUtil {
private static final TokenSet EXCLUDED = TokenSet.create(
COLON, AS_KEYWORD, AS_SAFE, IS_KEYWORD, NOT_IS, OROR, ANDAND, EQ, EQEQEQ, EXCLEQEQEQ, ELVIS, EXCLEXCL, IN_KEYWORD, NOT_IN);
public interface DebugInfoReporter {
void reportElementWithErrorType(@NotNull JetReferenceExpression expression);
void reportMissingUnresolved(@NotNull JetReferenceExpression expression);
void reportUnresolvedWithTarget(@NotNull JetReferenceExpression expression, @NotNull String target);
}
public static void markDebugAnnotations(
@NotNull PsiElement root,
@NotNull final BindingContext bindingContext,
@NotNull final DebugInfoReporter debugInfoReporter
) {
final Map> markedWithErrorElements = Maps.newHashMap();
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
DiagnosticFactory factory = diagnostic.getFactory();
if (Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS.contains(diagnostic.getFactory())) {
markedWithErrorElements.put((JetReferenceExpression) diagnostic.getPsiElement(), factory);
}
else if (factory == Errors.SUPER_IS_NOT_AN_EXPRESSION
|| factory == Errors.SUPER_NOT_AVAILABLE) {
JetSuperExpression superExpression = (JetSuperExpression) diagnostic.getPsiElement();
markedWithErrorElements.put(superExpression.getInstanceReference(), factory);
}
else if (factory == Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND) {
markedWithErrorElements.put((JetSimpleNameExpression) diagnostic.getPsiElement(), factory);
}
else if (factory == Errors.UNSUPPORTED) {
for (JetReferenceExpression reference : PsiTreeUtil.findChildrenOfType(diagnostic.getPsiElement(),
JetReferenceExpression.class)) {
markedWithErrorElements.put(reference, factory);
}
}
}
root.acceptChildren(new JetTreeVisitorVoid() {
@Override
public void visitReferenceExpression(@NotNull JetReferenceExpression expression) {
super.visitReferenceExpression(expression);
if (!BindingContextUtils.isExpressionWithValidReference(expression, bindingContext)){
return;
}
if (expression instanceof JetSimpleNameExpression) {
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) expression;
IElementType elementType = expression.getNode().getElementType();
if (elementType == JetNodeTypes.OPERATION_REFERENCE) {
IElementType referencedNameElementType = nameExpression.getReferencedNameElementType();
if (EXCLUDED.contains(referencedNameElementType)) {
return;
}
}
if (elementType == JetNodeTypes.LABEL ||
nameExpression.getReferencedNameElementType() == JetTokens.THIS_KEYWORD) {
return;
}
}
String target = null;
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, expression);
if (declarationDescriptor != null) {
target = declarationDescriptor.toString();
}
if (target == null) {
PsiElement labelTarget = bindingContext.get(LABEL_TARGET, expression);
if (labelTarget != null) {
target = labelTarget.getText();
}
}
if (target == null) {
Collection declarationDescriptors =
bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, expression);
if (declarationDescriptors != null) {
target = "[" + declarationDescriptors.size() + " descriptors]";
}
}
if (target == null) {
Collection labelTargets = bindingContext.get(AMBIGUOUS_LABEL_TARGET, expression);
if (labelTargets != null) {
target = "[" + labelTargets.size() + " elements]";
}
}
boolean resolved = target != null;
boolean markedWithError = markedWithErrorElements.containsKey(expression);
if (expression instanceof JetArrayAccessExpression &&
markedWithErrorElements.containsKey(((JetArrayAccessExpression) 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;
}
JetType expressionType = bindingContext.get(EXPRESSION_TYPE, 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);
}
}
});
}
}