use of com.intellij.lang.LighterASTNode in project intellij-community by JetBrains.
the class LightTreeUtil method findLeafElementAt.
@Nullable
public static LighterASTNode findLeafElementAt(@NotNull LighterAST tree, final int offset) {
LighterASTNode eachNode = tree.getRoot();
if (!containsOffset(eachNode, offset))
return null;
while (eachNode != null) {
List<LighterASTNode> children = tree.getChildren(eachNode);
if (children.isEmpty())
return eachNode;
eachNode = findChildAtOffset(offset, children);
}
return null;
}
use of com.intellij.lang.LighterASTNode in project intellij-community by JetBrains.
the class DuplicatesInspectionBase method checkFile.
@Nullable
@Override
public ProblemDescriptor[] checkFile(@NotNull final PsiFile psiFile, @NotNull final InspectionManager manager, final boolean isOnTheFly) {
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (!(virtualFile instanceof VirtualFileWithId) || /*!isOnTheFly || */
!DuplicatesIndex.ourEnabled)
return ProblemDescriptor.EMPTY_ARRAY;
final DuplicatesProfile profile = DuplicatesIndex.findDuplicatesProfile(psiFile.getFileType());
if (profile == null)
return ProblemDescriptor.EMPTY_ARRAY;
final Ref<DuplicatedCodeProcessor> myProcessorRef = new Ref<>();
final FileASTNode node = psiFile.getNode();
boolean usingLightProfile = profile instanceof LightDuplicateProfile && node.getElementType() instanceof ILightStubFileElementType && DuplicatesIndex.ourEnabledLightProfiles;
if (usingLightProfile) {
LighterAST ast = node.getLighterAST();
((LightDuplicateProfile) profile).process(ast, new LightDuplicateProfile.Callback() {
DuplicatedCodeProcessor<LighterASTNode> myProcessor;
@Override
public void process(int hash, int hash2, @NotNull final LighterAST ast, @NotNull final LighterASTNode... nodes) {
class LightDuplicatedCodeProcessor extends DuplicatedCodeProcessor<LighterASTNode> {
private LightDuplicatedCodeProcessor(VirtualFile file, Project project) {
super(file, project, myFilterOutGeneratedCode);
}
@Override
protected TextRange getRangeInElement(LighterASTNode node) {
return null;
}
@Override
protected PsiElement getPsi(LighterASTNode node) {
return ((TreeBackedLighterAST) ast).unwrap(node).getPsi();
}
@Override
protected int getStartOffset(LighterASTNode node) {
return node.getStartOffset();
}
@Override
protected int getEndOffset(LighterASTNode node) {
return node.getEndOffset();
}
@Override
protected boolean isLightProfile() {
return true;
}
}
if (myProcessor == null) {
myProcessor = new LightDuplicatedCodeProcessor(virtualFile, psiFile.getProject());
myProcessorRef.set(myProcessor);
}
myProcessor.process(hash, hash2, nodes[0]);
}
});
} else {
final DuplocatorState state = profile.getDuplocatorState(psiFile.getLanguage());
profile.createVisitor(new FragmentsCollector() {
DuplicatedCodeProcessor<PsiFragment> myProcessor;
@Override
public void add(int hash, final int cost, @Nullable final PsiFragment frag) {
if (!DuplicatesIndex.isIndexedFragment(frag, cost, profile, state)) {
return;
}
class OldDuplicatedCodeProcessor extends DuplicatedCodeProcessor<PsiFragment> {
private OldDuplicatedCodeProcessor(VirtualFile file, Project project) {
super(file, project, myFilterOutGeneratedCode);
}
@Override
protected TextRange getRangeInElement(PsiFragment node) {
PsiElement[] elements = node.getElements();
TextRange rangeInElement = null;
if (elements.length > 1) {
PsiElement lastElement = elements[elements.length - 1];
rangeInElement = new TextRange(elements[0].getStartOffsetInParent(), lastElement.getStartOffsetInParent() + lastElement.getTextLength());
}
return rangeInElement;
}
@Override
protected PsiElement getPsi(PsiFragment node) {
PsiElement[] elements = node.getElements();
return elements.length > 1 ? elements[0].getParent() : elements[0];
}
@Override
protected int getStartOffset(PsiFragment node) {
return node.getStartOffset();
}
@Override
protected int getEndOffset(PsiFragment node) {
return node.getEndOffset();
}
@Override
protected boolean isLightProfile() {
return false;
}
}
if (myProcessor == null) {
myProcessor = new OldDuplicatedCodeProcessor(virtualFile, psiFile.getProject());
myProcessorRef.set(myProcessor);
}
myProcessor.process(hash, 0, frag);
}
}, true).visitNode(psiFile);
}
DuplicatedCodeProcessor<?> processor = myProcessorRef.get();
final SmartList<ProblemDescriptor> descriptors = new SmartList<>();
if (processor != null) {
final VirtualFile baseDir = psiFile.getProject().getBaseDir();
for (Map.Entry<Integer, TextRange> entry : processor.reportedRanges.entrySet()) {
final Integer offset = entry.getKey();
if (!usingLightProfile && processor.fragmentSize.get(offset) < MIN_FRAGMENT_SIZE)
continue;
final VirtualFile file = processor.reportedFiles.get(offset);
String path = null;
if (file.equals(virtualFile))
path = "this file";
else if (baseDir != null) {
path = VfsUtilCore.getRelativePath(file, baseDir);
}
if (path == null) {
path = file.getPath();
}
String message = "Found duplicated code in " + path;
PsiElement targetElement = processor.reportedPsi.get(offset);
TextRange rangeInElement = entry.getValue();
final int offsetInOtherFile = processor.reportedOffsetInOtherFiles.get(offset);
LocalQuickFix fix = createNavigateToDupeFix(file, offsetInOtherFile);
long hash = processor.fragmentHash.get(offset);
LocalQuickFix viewAllDupesFix = hash != 0 ? createShowOtherDupesFix(virtualFile, offset, (int) hash, (int) (hash >> 32), psiFile.getProject()) : null;
ProblemDescriptor descriptor = manager.createProblemDescriptor(targetElement, rangeInElement, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly, fix, viewAllDupesFix);
descriptors.add(descriptor);
}
}
return descriptors.isEmpty() ? null : descriptors.toArray(new ProblemDescriptor[descriptors.size()]);
}
use of com.intellij.lang.LighterASTNode in project intellij-community by JetBrains.
the class ContractInferenceInterpreter method visitExpression.
@NotNull
private List<PreContract> visitExpression(final List<ValueConstraint[]> states, @Nullable LighterASTNode expr) {
if (expr == null)
return emptyList();
if (states.isEmpty())
return emptyList();
// too complex
if (states.size() > 300)
return emptyList();
IElementType type = expr.getTokenType();
if (type == POLYADIC_EXPRESSION || type == BINARY_EXPRESSION) {
return visitPolyadic(states, expr);
}
if (type == CONDITIONAL_EXPRESSION) {
List<LighterASTNode> children = getExpressionChildren(myTree, expr);
if (children.size() != 3)
return emptyList();
List<PreContract> conditionResults = visitExpression(states, children.get(0));
return ContainerUtil.concat(visitExpression(antecedentsReturning(conditionResults, TRUE_VALUE), children.get(1)), visitExpression(antecedentsReturning(conditionResults, FALSE_VALUE), children.get(2)));
}
if (type == PARENTH_EXPRESSION) {
return visitExpression(states, findExpressionChild(myTree, expr));
}
if (type == TYPE_CAST_EXPRESSION) {
return visitExpression(states, findExpressionChild(myTree, expr));
}
if (isNegationExpression(expr)) {
return ContainerUtil.mapNotNull(visitExpression(states, findExpressionChild(myTree, expr)), PreContract::negate);
}
if (type == INSTANCE_OF_EXPRESSION) {
final int parameter = resolveParameter(findExpressionChild(myTree, expr));
if (parameter >= 0) {
return asPreContracts(ContainerUtil.mapNotNull(states, state -> contractWithConstraint(state, parameter, NULL_VALUE, FALSE_VALUE)));
}
}
if (type == NEW_EXPRESSION || type == THIS_EXPRESSION) {
return asPreContracts(toContracts(states, NOT_NULL_VALUE));
}
if (type == METHOD_CALL_EXPRESSION) {
return singletonList(new MethodCallContract(ExpressionRange.create(expr, myBody.getStartOffset()), ContainerUtil.map(states, Arrays::asList)));
}
final ValueConstraint constraint = getLiteralConstraint(expr);
if (constraint != null) {
return asPreContracts(toContracts(states, constraint));
}
int paramIndex = resolveParameter(expr);
if (paramIndex >= 0) {
List<MethodContract> result = ContainerUtil.newArrayList();
for (ValueConstraint[] state : states) {
if (state[paramIndex] != ANY_VALUE) {
// the second 'o' reference in cases like: if (o != null) return o;
result.add(new MethodContract(state, state[paramIndex]));
} else if (JavaTokenType.BOOLEAN_KEYWORD == getPrimitiveParameterType(paramIndex)) {
// if (boolValue) ...
ContainerUtil.addIfNotNull(result, contractWithConstraint(state, paramIndex, TRUE_VALUE, TRUE_VALUE));
ContainerUtil.addIfNotNull(result, contractWithConstraint(state, paramIndex, FALSE_VALUE, FALSE_VALUE));
}
}
return asPreContracts(result);
}
return emptyList();
}
use of com.intellij.lang.LighterASTNode in project intellij-community by JetBrains.
the class ContractInferenceInterpreter method getPrimitiveParameterType.
@Nullable
private IElementType getPrimitiveParameterType(int paramIndex) {
LighterASTNode typeElement = firstChildOfType(myTree, getParameters().get(paramIndex), TYPE);
LighterASTNode primitive = firstChildOfType(myTree, typeElement, ElementType.PRIMITIVE_TYPE_BIT_SET);
return primitive == null ? null : primitive.getTokenType();
}
use of com.intellij.lang.LighterASTNode in project intellij-community by JetBrains.
the class JavaNullMethodArgumentIndex method getMethodName.
@Nullable
private static String getMethodName(LighterAST lighterAst, @NotNull LighterASTNode call, IElementType elementType) {
if (elementType == NEW_EXPRESSION || elementType == ANONYMOUS_CLASS) {
final List<LighterASTNode> refs = LightTreeUtil.getChildrenOfType(lighterAst, call, JAVA_CODE_REFERENCE);
if (refs.isEmpty())
return null;
final LighterASTNode lastRef = refs.get(refs.size() - 1);
return JavaLightTreeUtil.getNameIdentifierText(lighterAst, lastRef);
}
LOG.assertTrue(elementType == METHOD_CALL_EXPRESSION);
final LighterASTNode methodReference = lighterAst.getChildren(call).get(0);
if (methodReference.getTokenType() == REFERENCE_EXPRESSION) {
return JavaLightTreeUtil.getNameIdentifierText(lighterAst, methodReference);
}
return null;
}
Aggregations