<commit_before>/*
 * Copyright 2005 <NAME>
 *
 * 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.intellij.lang.xpath.xslt.context;

import org.intellij.lang.xpath.context.VariableContext;
import org.intellij.lang.xpath.psi.XPathElement;
import org.intellij.lang.xpath.psi.XPathVariable;
import org.intellij.lang.xpath.psi.XPathVariableReference;
import org.intellij.lang.xpath.psi.impl.ResolveUtil;
import org.intellij.lang.xpath.xslt.XsltSupport;
import org.intellij.lang.xpath.xslt.impl.XsltIncludeIndex;
import org.intellij.lang.xpath.xslt.psi.XsltElementFactory;
import org.intellij.lang.xpath.xslt.psi.XsltParameter;
import org.intellij.lang.xpath.xslt.psi.XsltTemplate;
import org.intellij.lang.xpath.xslt.psi.XsltVariable;
import org.intellij.lang.xpath.xslt.quickfix.CreateParameterFix;
import org.intellij.lang.xpath.xslt.quickfix.CreateVariableFix;
import org.intellij.lang.xpath.xslt.util.ElementProcessor;
import org.intellij.lang.xpath.xslt.util.XsltCodeInsightUtil;

import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

public class XsltVariableContext implements VariableContext<XsltVariable> {
    public static final XsltVariableContext INSTANCE = new XsltVariableContext();
    
    private static final ResolveCache.Resolver RESOLVER = new ResolveCache.Resolver() {
        @Nullable
        public PsiElement resolve(PsiReference psiReference, boolean incompleteCode) {
            return resolveInner((XPathVariableReference)psiReference);
        }
    };

    @NotNull
    public XsltVariable[] getVariablesInScope(XPathElement element) {
        final XmlTag context = getContextTag(element);
        final VariantsProcessor processor = new VariantsProcessor(context);

        ResolveUtil.treeWalkUp(processor, context);
        return processor.getResult();
    }

    public XPathVariable resolve(final XPathVariableReference reference) {
        final PsiManager mgr = reference.getManager();
        if (mgr instanceof PsiManagerEx) {
            return (XPathVariable)((PsiManagerEx)mgr).getResolveCache().resolveWithCaching(reference, RESOLVER, true, false);
        }
        return resolveInner(reference);
    }

    @Nullable
    private static XPathVariable resolveInner(XPathVariableReference reference) {
        final XmlTag context = getContextTag(reference);
        final ResolveProcessor processor = new ResolveProcessor(reference.getReferencedName(), context);

        final XPathVariable variable = (XPathVariable)ResolveUtil.treeWalkUp(processor, context);
        if (variable == null) {
            final XmlFile file = PsiTreeUtil.getParentOfType(context, XmlFile.class, true);
            if (file != null) {
                XsltIncludeIndex.processBackwardDependencies(file, new Processor<XmlFile>() {
                    public boolean process(XmlFile xmlFile) {
                        processor.processExternalFile(xmlFile, context);
                        return processor.shouldContinue();
                    }
                });
                return (XPathVariable)processor.getResult();
            }
        }
        return variable;
    }

    @Nullable
    protected static XmlTag getContextTag(XPathElement element) {
        return PsiTreeUtil.getContextOfType(element, XmlTag.class, true);
    }

    @NotNull
    public IntentionAction[] getUnresolvedVariableFixes(XPathVariableReference reference) {
        return new IntentionAction[] {
                new CreateVariableFix(reference),
                new CreateParameterFix(reference)
        };
    }

    public boolean isReferenceTo(PsiElement element, XPathVariableReference reference) {
        if (element instanceof XsltParameter) {
            final XsltTemplate template = XsltCodeInsightUtil.getTemplate(element, false);
            if (template == null || template.getMatchExpression() == null) return false;

            final XPathVariable t = reference.resolve();
            final PsiReference[] references = element.getReferences();
            for (PsiReference r : references) {
                if (r.isReferenceTo(t)) return true;
            }
        }
        return false;<commit_msg>enable variable name completion in xslt-debugger breakpoint settings<commit_after>/*
 * Copyright 2005 <NAME>
 *
 * 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.intellij.lang.xpath.xslt.context;

import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import org.intellij.lang.xpath.context.VariableContext;
import org.intellij.lang.xpath.psi.XPathElement;
import org.intellij.lang.xpath.psi.XPathVariable;
import org.intellij.lang.xpath.psi.XPathVariableReference;
import org.intellij.lang.xpath.psi.impl.ResolveUtil;
import org.intellij.lang.xpath.xslt.XsltSupport;
import org.intellij.lang.xpath.xslt.impl.XsltIncludeIndex;
import org.intellij.lang.xpath.xslt.psi.XsltElementFactory;
import org.intellij.lang.xpath.xslt.psi.XsltParameter;
import org.intellij.lang.xpath.xslt.psi.XsltTemplate;
import org.intellij.lang.xpath.xslt.psi.XsltVariable;
import org.intellij.lang.xpath.xslt.quickfix.CreateParameterFix;
import org.intellij.lang.xpath.xslt.quickfix.CreateVariableFix;
import org.intellij.lang.xpath.xslt.util.ElementProcessor;
import org.intellij.lang.xpath.xslt.util.XsltCodeInsightUtil;

import java.util.ArrayList;
import java.util.List;

public class XsltVariableContext implements VariableContext<XsltVariable> {
    public static final XsltVariableContext INSTANCE = new XsltVariableContext();
    
    private final ResolveCache.Resolver RESOLVER = new ResolveCache.Resolver() {
        @Nullable
        public PsiElement resolve(PsiReference psiReference, boolean incompleteCode) {
            return resolveInner((XPathVariableReference)psiReference);
        }
    };

    @NotNull
    public XsltVariable[] getVariablesInScope(XPathElement element) {
        final XmlTag context = getContextTagImpl(element);
        final VariantsProcessor processor = new VariantsProcessor(context);

        ResolveUtil.treeWalkUp(processor, context);
        return processor.getResult();
    }

    public XPathVariable resolve(final XPathVariableReference reference) {
        final PsiManager mgr = reference.getManager();
        if (mgr instanceof PsiManagerEx) {
            return (XPathVariable)((PsiManagerEx)mgr).getResolveCache().resolveWithCaching(reference, RESOLVER, true, false);
        }
        return resolveInner(reference);
    }

    @Nullable
    private XPathVariable resolveInner(XPathVariableReference reference) {
        final XmlTag context = getContextTagImpl(reference);
        final ResolveProcessor processor = new ResolveProcessor(reference.getReferencedName(), context);

        final XPathVariable variable = (XPathVariable)ResolveUtil.treeWalkUp(processor, context);
        if (variable == null) {
            final XmlFile file = PsiTreeUtil.getParentOfType(context, XmlFile.class, true);
            if (file != null) {
                XsltIncludeIndex.processBackwardDependencies(file, new Processor<XmlFile>() {
                    public boolean process(XmlFile xmlFile) {
                        processor.processExternalFile(xmlFile, context);
                        return processor.shouldContinue();
                    }
                });
                return (XPathVariable)processor.getResult();
            }
        }
        return variable;
    }

    @Nullable
    protected XmlTag getContextTagImpl(XPathElement element) {
        return PsiTreeUtil.getContextOfType(element, XmlTag.class, true);
    }

    @NotNull
    public IntentionAction[] getUnresolvedVariableFixes(XPathVariableReference reference) {
        return new IntentionAction[] {
                new CreateVariableFix(reference),
                new CreateParameterFix(reference)
        };
    }

    public boolean isReferenceTo(PsiElement element, XPathVariableReference reference) {
        if (element instanceof XsltParameter) {
            final XsltTemplate template = XsltCodeInsightUtil.getTemplate(element, false);
            if (template == null || template.getMatchExpression() == null) return false;

            final XPathVariable t = reference.resolve();
            final PsiReference[] references = element.getReferences();
            for (PsiReference r : references) {
                if (r.isReferenceTo(t)) return true;
            }
        }
        return false;
{'fraction_non_alphanumeric': 0.08717899208341379, 'fraction_numerical': 0.0015446997489862908, 'mean_word_length': 3.4574010327022373, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6277010', 'n_tokens_mistral': 2932, 'n_tokens_neox': 2848, 'n_words': 639}