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;
}
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);
}
}
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;
}
}
}
}
};
}
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()]);
}
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;
}
};
}
Aggregations