Search in sources :

Example 1 with JSElementIndexingData

use of com.intellij.lang.javascript.psi.stubs.JSElementIndexingData in project intellij-plugins by JetBrains.

the class AngularJSIndexingHandler method processAnyProperty.

@Nullable
@Override
public JSElementIndexingData processAnyProperty(@NotNull JSProperty property, @Nullable JSElementIndexingData outData) {
    final String name = property.getName();
    if (name == null)
        return outData;
    final Pair<JSCallExpression, Integer> pair = findImmediatelyWrappingCall(property);
    if (pair == null)
        return outData;
    final JSCallExpression callExpression = pair.getFirst();
    final int level = pair.getSecond();
    final JSExpression methodExpression = callExpression.getMethodExpression();
    if (!(methodExpression instanceof JSReferenceExpression) || ((JSReferenceExpression) methodExpression).getQualifier() == null) {
        return outData;
    }
    final String command = ((JSReferenceExpression) methodExpression).getReferenceName();
    final PairProcessor<JSProperty, JSElementIndexingData> customProcessor = CUSTOM_PROPERTY_PROCESSORS.get(command);
    JSElementIndexingData localOutData;
    if (customProcessor != null && customProcessor.process(property, (localOutData = (outData == null ? new JSElementIndexingDataImpl() : outData)))) {
        return localOutData;
    }
    // for 'standard' properties, keep indexing only for properties - immediate children of function calls parameters
    if (level > 1)
        return outData;
    final PsiElement parent = property.getParent();
    final StubIndexKey<String, JSImplicitElementProvider> index = INDEXERS.get(command);
    if (index == null)
        return outData;
    if (callExpression.getArguments()[0] != parent)
        return outData;
    if (outData == null)
        outData = new JSElementIndexingDataImpl();
    addImplicitElements(property, command, index, name, null, outData);
    return outData;
}
Also used : JSElementIndexingData(com.intellij.lang.javascript.psi.stubs.JSElementIndexingData) JSElementIndexingDataImpl(com.intellij.lang.javascript.psi.stubs.impl.JSElementIndexingDataImpl) PsiElement(com.intellij.psi.PsiElement) Nullable(org.jetbrains.annotations.Nullable)

Example 2 with JSElementIndexingData

use of com.intellij.lang.javascript.psi.stubs.JSElementIndexingData in project intellij-plugins by JetBrains.

the class AngularJSIndexingHandler method addImplicitElements.

private static void addImplicitElements(@NotNull final JSImplicitElementProvider elementProvider, @Nullable final String command, @NotNull final StubIndexKey<String, JSImplicitElementProvider> index, @Nullable String defaultName, @Nullable final String value, @NotNull final JSElementIndexingData outData) {
    if (defaultName == null)
        return;
    final List<String> keys = INDEXES.getKeysByValue(index);
    assert keys != null && keys.size() == 1;
    final Consumer<JSImplicitElementImpl.Builder> adder = builder -> {
        builder.setType(elementProvider instanceof JSDocComment ? JSImplicitElement.Type.Tag : JSImplicitElement.Type.Class).setTypeString(value);
        builder.setUserString(keys.get(0));
        final JSImplicitElementImpl implicitElement = builder.toImplicitElement();
        outData.addImplicitElement(implicitElement);
    };
    final Function<String, List<String>> variants = POLY_NAME_CONVERTERS.get(command);
    final Function<String, String> converter = command != null ? NAME_CONVERTERS.get(command) : null;
    final String name = converter != null ? converter.fun(defaultName) : defaultName;
    if (variants != null) {
        final List<String> strings = variants.fun(name);
        for (String string : strings) {
            adder.consume(new JSImplicitElementImpl.Builder(string, elementProvider));
        }
    } else {
        adder.consume(new JSImplicitElementImpl.Builder(JSQualifiedNameImpl.fromQualifiedName(name), elementProvider));
    }
    if (!StringUtil.equals(defaultName, name)) {
        JSImplicitElementImpl.Builder symbolElementBuilder = new JSImplicitElementImpl.Builder(defaultName, elementProvider).setType(elementProvider instanceof JSDocComment ? JSImplicitElement.Type.Tag : JSImplicitElement.Type.Class).setTypeString(value);
        final List<String> symbolKeys = INDEXES.getKeysByValue(AngularSymbolIndex.KEY);
        assert symbolKeys != null && symbolKeys.size() == 1;
        symbolElementBuilder.setUserString(symbolKeys.get(0));
        final JSImplicitElementImpl implicitElement2 = symbolElementBuilder.toImplicitElement();
        outData.addImplicitElement(implicitElement2);
    }
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) FrameworkIndexingHandler(com.intellij.lang.javascript.index.FrameworkIndexingHandler) THashSet(gnu.trove.THashSet) CompositeElement(com.intellij.psi.impl.source.tree.CompositeElement) JSCallExpressionImpl(com.intellij.lang.javascript.psi.impl.JSCallExpressionImpl) PsiTreeUtil(com.intellij.psi.util.PsiTreeUtil) JSImplicitElementImpl(com.intellij.lang.javascript.psi.stubs.impl.JSImplicitElementImpl) AngularJSFilterExpression(org.angularjs.lang.psi.AngularJSFilterExpression) JSElementIndexingData(com.intellij.lang.javascript.psi.stubs.JSElementIndexingData) PsiNamedElement(com.intellij.psi.PsiNamedElement) BidirectionalMap(com.intellij.util.containers.BidirectionalMap) LightVirtualFile(com.intellij.testFramework.LightVirtualFile) JSDocumentationUtils(com.intellij.lang.javascript.documentation.JSDocumentationUtils) JSDocTag(com.intellij.lang.javascript.psi.jsdoc.JSDocTag) JSSymbolUtil(com.intellij.lang.javascript.index.JSSymbolUtil) JSNamedType(com.intellij.lang.javascript.psi.types.JSNamedType) JSImplicitElement(com.intellij.lang.javascript.psi.stubs.JSImplicitElement) JSTreeUtil(com.intellij.lang.javascript.psi.util.JSTreeUtil) JSLibraryUtil(com.intellij.lang.javascript.library.JSLibraryUtil) JSDocComment(com.intellij.lang.javascript.psi.jsdoc.JSDocComment) Nullable(org.jetbrains.annotations.Nullable) JSDocTagValue(com.intellij.lang.javascript.psi.jsdoc.JSDocTagValue) StubIndexKey(com.intellij.psi.stubs.StubIndexKey) com.intellij.util(com.intellij.util) AngularJSAsExpression(org.angularjs.lang.psi.AngularJSAsExpression) NotNull(org.jetbrains.annotations.NotNull) JSLiteralImplicitElementProvider(com.intellij.lang.javascript.psi.literal.JSLiteralImplicitElementProvider) Ref(com.intellij.openapi.util.Ref) java.util(java.util) JSTypeEvaluator(com.intellij.lang.javascript.psi.resolve.JSTypeEvaluator) JSDocTokenTypes(com.intellij.lang.javascript.JSDocTokenTypes) AngularJSLanguage(org.angularjs.lang.AngularJSLanguage) JSImplicitElementStructure(com.intellij.lang.javascript.psi.stubs.JSImplicitElementStructure) JSReferenceExpressionImpl(com.intellij.lang.javascript.psi.impl.JSReferenceExpressionImpl) DirectiveUtil(org.angularjs.codeInsight.DirectiveUtil) JSContext(com.intellij.lang.javascript.psi.types.JSContext) JSTypeSourceFactory(com.intellij.lang.javascript.psi.types.JSTypeSourceFactory) PsiElement(com.intellij.psi.PsiElement) PsiWhiteSpace(com.intellij.psi.PsiWhiteSpace) JSTypeSource(com.intellij.lang.javascript.psi.types.JSTypeSource) StringUtil(com.intellij.openapi.util.text.StringUtil) FileViewProvider(com.intellij.psi.FileViewProvider) com.intellij.lang.javascript.psi(com.intellij.lang.javascript.psi) JSPsiImplUtils(com.intellij.lang.javascript.psi.impl.JSPsiImplUtils) AngularJSRepeatExpression(org.angularjs.lang.psi.AngularJSRepeatExpression) ASTNode(com.intellij.lang.ASTNode) AngularJSUiRouterConstants(org.angularjs.codeInsight.router.AngularJSUiRouterConstants) Pair(com.intellij.openapi.util.Pair) JSElementIndexingDataImpl(com.intellij.lang.javascript.psi.stubs.impl.JSElementIndexingDataImpl) IndexSink(com.intellij.psi.stubs.IndexSink) JSDocComment(com.intellij.lang.javascript.psi.jsdoc.JSDocComment) JSImplicitElementImpl(com.intellij.lang.javascript.psi.stubs.impl.JSImplicitElementImpl)

Example 3 with JSElementIndexingData

use of com.intellij.lang.javascript.psi.stubs.JSElementIndexingData in project intellij-plugins by JetBrains.

the class AngularJSIndexingHandler method createLiteralImplicitElementProvider.

@Override
public JSLiteralImplicitElementProvider createLiteralImplicitElementProvider(@NotNull final String command) {
    return new JSLiteralImplicitElementProvider() {

        @Override
        public void fillIndexingData(@NotNull JSLiteralExpression argument, @NotNull JSCallExpression callExpression, @NotNull JSElementIndexingData outIndexingData) {
            JSExpression[] arguments = callExpression.getArguments();
            if (arguments.length == 0 || arguments[0] != argument)
                return;
            final JSExpression methodExpression = callExpression.getMethodExpression();
            if (!(methodExpression instanceof JSReferenceExpression))
                return;
            JSExpression qualifier = ((JSReferenceExpression) methodExpression).getQualifier();
            if (qualifier == null)
                return;
            final StubIndexKey<String, JSImplicitElementProvider> index = INDEXERS.get(command);
            if (index != null) {
                if (argument.isQuotedLiteral()) {
                    final Processor<JSArgumentList> argumentListProcessor = ARGUMENT_LIST_CHECKERS.get(command);
                    if (argumentListProcessor != null && !argumentListProcessor.process(callExpression.getArgumentList()))
                        return;
                    final Function<PsiElement, String> calculator = DATA_CALCULATORS.get(command);
                    final String data = calculator != null ? calculator.fun(argument) : null;
                    final String argumentText = unquote(argument);
                    addImplicitElements(argument, command, index, argumentText, data, outIndexingData);
                }
            } else if (INJECTABLE_METHODS.contains(command)) {
                // INTERESTING_METHODS are contained in INJECTABLE_METHODS
                if (argument.isQuotedLiteral()) {
                    generateNamespace(argument, outIndexingData);
                }
            }
            if (START_SYMBOL.equals(command) || END_SYMBOL.equals(command)) {
                while (qualifier != null) {
                    if (qualifier instanceof JSReferenceExpression) {
                        if ("$interpolateProvider".equals(((JSReferenceExpression) qualifier).getReferenceName())) {
                            if (argument.isQuotedLiteral()) {
                                String interpolation = unquote(argument);
                                // '//' interpolations are usually dragged from examples folder and not supposed to be used by real users
                                if ("//".equals(interpolation))
                                    return;
                                FileViewProvider provider = qualifier.getContainingFile().getOriginalFile().getViewProvider();
                                VirtualFile virtualFile = provider.getVirtualFile();
                                virtualFile = virtualFile instanceof LightVirtualFile ? ((LightVirtualFile) virtualFile).getOriginalFile() : virtualFile;
                                if (JSLibraryUtil.isProbableLibraryFile(virtualFile))
                                    return;
                                addImplicitElements(argument, null, AngularInjectionDelimiterIndex.KEY, command, interpolation, outIndexingData);
                            }
                        }
                        qualifier = ((JSReferenceExpression) qualifier).getQualifier();
                    } else {
                        qualifier = qualifier instanceof JSCallExpression ? ((JSCallExpression) qualifier).getMethodExpression() : null;
                    }
                }
            }
        }
    };
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) LightVirtualFile(com.intellij.testFramework.LightVirtualFile) JSLiteralImplicitElementProvider(com.intellij.lang.javascript.psi.literal.JSLiteralImplicitElementProvider) NotNull(org.jetbrains.annotations.NotNull) JSElementIndexingData(com.intellij.lang.javascript.psi.stubs.JSElementIndexingData) FileViewProvider(com.intellij.psi.FileViewProvider) LightVirtualFile(com.intellij.testFramework.LightVirtualFile) PsiElement(com.intellij.psi.PsiElement)

Example 4 with JSElementIndexingData

use of com.intellij.lang.javascript.psi.stubs.JSElementIndexingData in project intellij-plugins by JetBrains.

the class AngularAttributeDescriptor method getCompiledFieldBasedDescriptors.

@NotNull
private static XmlAttributeDescriptor[] getCompiledFieldBasedDescriptors(JSImplicitElement declaration, String decorator, NullableFunction<Pair<PsiElement, String>, XmlAttributeDescriptor> factory) {
    Project project = declaration.getProject();
    Collection<String> keys = StubIndex.getInstance().getAllKeys(AngularDecoratorsIndex.KEY, project);
    GlobalSearchScope scope = GlobalSearchScope.fileScope(declaration.getContainingFile());
    JSAssignmentExpression context = PsiTreeUtil.getContextOfType(declaration, JSAssignmentExpression.class);
    if (context == null)
        return EMPTY;
    final List<XmlAttributeDescriptor> result = new ArrayList<>();
    for (String key : keys) {
        StubIndex.getInstance().processElements(AngularDecoratorsIndex.KEY, key, project, scope, JSImplicitElementProvider.class, (provider) -> {
            JSElementIndexingData data = provider.getIndexingData();
            Collection<JSImplicitElement> elements = data != null ? data.getImplicitElements() : null;
            if (elements != null) {
                for (JSImplicitElement element : elements) {
                    if (key.equals(element.getName())) {
                        String type = element.getTypeString();
                        if (type != null && type.startsWith(decorator + ";") && inContext(context, element)) {
                            ContainerUtil.addIfNotNull(result, factory.fun(Pair.create(element, element.getName())));
                        }
                    }
                }
            }
            return true;
        });
    }
    return result.toArray(new XmlAttributeDescriptor[result.size()]);
}
Also used : Project(com.intellij.openapi.project.Project) JSElementIndexingData(com.intellij.lang.javascript.psi.stubs.JSElementIndexingData) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) BasicXmlAttributeDescriptor(com.intellij.xml.impl.BasicXmlAttributeDescriptor) XmlAttributeDescriptor(com.intellij.xml.XmlAttributeDescriptor) ArrayList(java.util.ArrayList) JSImplicitElement(com.intellij.lang.javascript.psi.stubs.JSImplicitElement) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with JSElementIndexingData

use of com.intellij.lang.javascript.psi.stubs.JSElementIndexingData in project intellij-plugins by JetBrains.

the class AngularJS2IndexingHandler method createLiteralImplicitElementCustomProvider.

@Nullable
@Override
public JSLiteralImplicitElementCustomProvider createLiteralImplicitElementCustomProvider() {
    return new JSLiteralImplicitElementCustomProvider() {

        @Override
        public boolean checkIfCandidate(@NotNull ASTNode literalExpression) {
            ASTNode parent = TreeUtil.findParent(literalExpression, JSStubElementTypes.CALL_EXPRESSION);
            LeafElement leaf = parent != null ? TreeUtil.findFirstLeaf(parent) : null;
            return leaf != null && leaf.getText().startsWith(DECORATE);
        }

        @Override
        public void fillIndexingDataForCandidate(@NotNull JSLiteralExpression argument, @NotNull JSElementIndexingData outIndexingData) {
            String name = argument.isQuotedLiteral() ? AngularJSIndexingHandler.unquote(argument) : null;
            if (name == null)
                return;
            JSCallExpression callExpression = PsiTreeUtil.getParentOfType(argument, JSCallExpression.class);
            if (callExpression == null)
                return;
            JSExpression first = callExpression.getArguments()[0];
            if (!(first instanceof JSArrayLiteralExpression))
                return;
            JSExpression[] expressions = ((JSArrayLiteralExpression) first).getExpressions();
            if (expressions.length != 2)
                return;
            JSExpression decorator = expressions[0];
            String decoratorName = getCallName(decorator);
            if (!isInterestingDecorator(decoratorName))
                return;
            JSExpression metadata = expressions[1];
            String metadataName = getCallName(metadata);
            if (metadataName == null || !metadataName.startsWith("__metadata"))
                return;
            JSExpression[] meta = ((JSCallExpression) metadata).getArguments();
            if (meta.length != 2)
                return;
            if (!(meta[0] instanceof JSLiteralExpression))
                return;
            String type = AngularJSIndexingHandler.unquote(meta[0]);
            if (!"design:type".equals(type))
                return;
            JSImplicitElementImpl.Builder builder = new JSImplicitElementImpl.Builder(getDecoratedName(name, decorator), argument).setUserString(DECORATORS).setTypeString(decoratorName + ";" + meta[1].getText());
            outIndexingData.addImplicitElement(builder.toImplicitElement());
        }

        private String getDecoratedName(String name, JSExpression decorator) {
            if (decorator instanceof JSCallExpression) {
                final JSExpression expression = ((JSCallExpression) decorator).getMethodExpression();
                if (expression instanceof JSReferenceExpression) {
                    JSExpression[] arguments = ((JSCallExpression) decorator).getArguments();
                    if (arguments.length > 0 && arguments[0] instanceof JSLiteralExpression) {
                        Object value = ((JSLiteralExpression) arguments[0]).getValue();
                        if (value instanceof String)
                            return (String) value;
                    }
                }
            }
            return name;
        }

        private String getCallName(JSExpression call) {
            if (call instanceof JSCallExpression) {
                JSExpression expression = ((JSCallExpression) call).getMethodExpression();
                if (expression instanceof JSReferenceExpression) {
                    return ((JSReferenceExpression) expression).getReferenceName();
                }
            }
            return null;
        }
    };
}
Also used : JSImplicitElementImpl(com.intellij.lang.javascript.psi.stubs.impl.JSImplicitElementImpl) JSLiteralImplicitElementCustomProvider(com.intellij.lang.javascript.psi.literal.JSLiteralImplicitElementCustomProvider) NotNull(org.jetbrains.annotations.NotNull) JSElementIndexingData(com.intellij.lang.javascript.psi.stubs.JSElementIndexingData) ASTNode(com.intellij.lang.ASTNode) LeafElement(com.intellij.psi.impl.source.tree.LeafElement) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

JSElementIndexingData (com.intellij.lang.javascript.psi.stubs.JSElementIndexingData)6 NotNull (org.jetbrains.annotations.NotNull)4 JSImplicitElement (com.intellij.lang.javascript.psi.stubs.JSImplicitElement)3 PsiElement (com.intellij.psi.PsiElement)3 Nullable (org.jetbrains.annotations.Nullable)3 ASTNode (com.intellij.lang.ASTNode)2 JSLiteralImplicitElementProvider (com.intellij.lang.javascript.psi.literal.JSLiteralImplicitElementProvider)2 JSElementIndexingDataImpl (com.intellij.lang.javascript.psi.stubs.impl.JSElementIndexingDataImpl)2 JSImplicitElementImpl (com.intellij.lang.javascript.psi.stubs.impl.JSImplicitElementImpl)2 VirtualFile (com.intellij.openapi.vfs.VirtualFile)2 FileViewProvider (com.intellij.psi.FileViewProvider)2 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)2 LightVirtualFile (com.intellij.testFramework.LightVirtualFile)2 JSDocTokenTypes (com.intellij.lang.javascript.JSDocTokenTypes)1 JSDocumentationUtils (com.intellij.lang.javascript.documentation.JSDocumentationUtils)1 FrameworkIndexingHandler (com.intellij.lang.javascript.index.FrameworkIndexingHandler)1 JSSymbolUtil (com.intellij.lang.javascript.index.JSSymbolUtil)1 JSLibraryUtil (com.intellij.lang.javascript.library.JSLibraryUtil)1 com.intellij.lang.javascript.psi (com.intellij.lang.javascript.psi)1 JSCallExpressionImpl (com.intellij.lang.javascript.psi.impl.JSCallExpressionImpl)1