Search in sources :

Example 11 with LighterASTNode

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;
}
Also used : LighterASTNode(com.intellij.lang.LighterASTNode) Nullable(org.jetbrains.annotations.Nullable)

Example 12 with LighterASTNode

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()]);
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) DuplicatesProfile(com.intellij.dupLocator.DuplicatesProfile) ILightStubFileElementType(com.intellij.psi.tree.ILightStubFileElementType) FileASTNode(com.intellij.lang.FileASTNode) PsiFragment(com.intellij.dupLocator.util.PsiFragment) FragmentsCollector(com.intellij.dupLocator.treeHash.FragmentsCollector) VirtualFileWithId(com.intellij.openapi.vfs.VirtualFileWithId) LightDuplicateProfile(com.intellij.dupLocator.LightDuplicateProfile) PsiElement(com.intellij.psi.PsiElement) LighterASTNode(com.intellij.lang.LighterASTNode) TreeBackedLighterAST(com.intellij.lang.TreeBackedLighterAST) LighterAST(com.intellij.lang.LighterAST) TextRange(com.intellij.openapi.util.TextRange) DuplocatorState(com.intellij.dupLocator.DuplocatorState) Project(com.intellij.openapi.project.Project) Ref(com.intellij.openapi.util.Ref) TreeBackedLighterAST(com.intellij.lang.TreeBackedLighterAST) SmartList(com.intellij.util.SmartList) TIntLongHashMap(gnu.trove.TIntLongHashMap) Map(java.util.Map) TIntObjectHashMap(gnu.trove.TIntObjectHashMap) TIntIntHashMap(gnu.trove.TIntIntHashMap) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap) Nullable(org.jetbrains.annotations.Nullable) Nullable(org.jetbrains.annotations.Nullable)

Example 13 with LighterASTNode

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();
}
Also used : Arrays(java.util.Arrays) JavaTokenType(com.intellij.psi.JavaTokenType) IElementType(com.intellij.psi.tree.IElementType) Collections.emptyList(java.util.Collections.emptyList) JavaElementType(com.intellij.psi.impl.source.tree.JavaElementType) ContainerUtil(com.intellij.util.containers.ContainerUtil) JavaLightTreeUtil(com.intellij.psi.impl.source.JavaLightTreeUtil) JavaLightTreeUtil.getExpressionChildren(com.intellij.psi.impl.source.JavaLightTreeUtil.getExpressionChildren) ArrayList(java.util.ArrayList) Collections.singletonList(java.util.Collections.singletonList) Nullable(org.jetbrains.annotations.Nullable) List(java.util.List) ElementType(com.intellij.psi.impl.source.tree.ElementType) JavaLightTreeUtil.findExpressionChild(com.intellij.psi.impl.source.JavaLightTreeUtil.findExpressionChild) ValueConstraint(com.intellij.codeInspection.dataFlow.MethodContract.ValueConstraint) LightTreeUtil.firstChildOfType(com.intellij.psi.impl.source.tree.LightTreeUtil.firstChildOfType) LighterAST(com.intellij.lang.LighterAST) LighterASTNode(com.intellij.lang.LighterASTNode) LightTreeUtil.getChildrenOfType(com.intellij.psi.impl.source.tree.LightTreeUtil.getChildrenOfType) NotNull(org.jetbrains.annotations.NotNull) LighterASTNode(com.intellij.lang.LighterASTNode) ValueConstraint(com.intellij.codeInspection.dataFlow.MethodContract.ValueConstraint) ValueConstraint(com.intellij.codeInspection.dataFlow.MethodContract.ValueConstraint) IElementType(com.intellij.psi.tree.IElementType) Arrays(java.util.Arrays) NotNull(org.jetbrains.annotations.NotNull)

Example 14 with LighterASTNode

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();
}
Also used : LighterASTNode(com.intellij.lang.LighterASTNode) Nullable(org.jetbrains.annotations.Nullable)

Example 15 with LighterASTNode

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;
}
Also used : LighterASTNode(com.intellij.lang.LighterASTNode) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

LighterASTNode (com.intellij.lang.LighterASTNode)48 IElementType (com.intellij.psi.tree.IElementType)14 Nullable (org.jetbrains.annotations.Nullable)12 NotNull (org.jetbrains.annotations.NotNull)11 PsiBuilder (com.intellij.lang.PsiBuilder)6 LighterAST (com.intellij.lang.LighterAST)4 ValueConstraint (com.intellij.codeInspection.dataFlow.MethodContract.ValueConstraint)3 TypeInfo (com.intellij.psi.impl.cache.TypeInfo)3 SmartList (com.intellij.util.SmartList)3 JavaTokenType (com.intellij.psi.JavaTokenType)2 JavaLightTreeUtil (com.intellij.psi.impl.source.JavaLightTreeUtil)2 JavaLightTreeUtil.findExpressionChild (com.intellij.psi.impl.source.JavaLightTreeUtil.findExpressionChild)2 JavaLightTreeUtil.getExpressionChildren (com.intellij.psi.impl.source.JavaLightTreeUtil.getExpressionChildren)2 ElementType (com.intellij.psi.impl.source.tree.ElementType)2 JavaElementType (com.intellij.psi.impl.source.tree.JavaElementType)2 LightTreeUtil.firstChildOfType (com.intellij.psi.impl.source.tree.LightTreeUtil.firstChildOfType)2 LightTreeUtil.getChildrenOfType (com.intellij.psi.impl.source.tree.LightTreeUtil.getChildrenOfType)2 ContainerUtil (com.intellij.util.containers.ContainerUtil)2 DuplicatesProfile (com.intellij.dupLocator.DuplicatesProfile)1 DuplocatorState (com.intellij.dupLocator.DuplocatorState)1