use of com.intellij.openapi.util.Pair in project intellij-community by JetBrains.
the class StubTreeBuilder method buildStubTree.
@Nullable
public static Stub buildStubTree(final FileContent inputData) {
Stub data = inputData.getUserData(stubElementKey);
if (data != null)
return data;
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (inputData) {
data = inputData.getUserData(stubElementKey);
if (data != null)
return data;
final FileType fileType = inputData.getFileType();
final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType);
if (builder != null) {
data = builder.buildStubTree(inputData);
if (data instanceof PsiFileStubImpl && !((PsiFileStubImpl) data).rootsAreSet()) {
((PsiFileStubImpl) data).setStubRoots(new PsiFileStub[] { (PsiFileStubImpl) data });
}
} else {
CharSequence contentAsText = inputData.getContentAsText();
FileContentImpl fileContent = (FileContentImpl) inputData;
PsiFile psi = fileContent.getPsiFileForPsiDependentIndex();
final FileViewProvider viewProvider = psi.getViewProvider();
psi = viewProvider.getStubBindingRoot();
psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, contentAsText);
// if we load AST, it should be easily gc-able. See PsiFileImpl.createTreeElementPointer()
psi.getManager().startBatchFilesProcessingMode();
try {
IStubFileElementType stubFileElementType = ((PsiFileImpl) psi).getElementTypeForStubBuilder();
if (stubFileElementType != null) {
final StubBuilder stubBuilder = stubFileElementType.getBuilder();
if (stubBuilder instanceof LightStubBuilder) {
LightStubBuilder.FORCED_AST.set(fileContent.getLighterASTForPsiDependentIndex());
}
data = stubBuilder.buildStubTree(psi);
final List<Pair<IStubFileElementType, PsiFile>> stubbedRoots = getStubbedRoots(viewProvider);
final List<PsiFileStub> stubs = new ArrayList<>(stubbedRoots.size());
stubs.add((PsiFileStub) data);
for (Pair<IStubFileElementType, PsiFile> stubbedRoot : stubbedRoots) {
final PsiFile secondaryPsi = stubbedRoot.second;
if (psi == secondaryPsi)
continue;
final StubBuilder stubbedRootBuilder = stubbedRoot.first.getBuilder();
if (stubbedRootBuilder instanceof LightStubBuilder) {
LightStubBuilder.FORCED_AST.set(new TreeBackedLighterAST(secondaryPsi.getNode()));
}
final StubElement element = stubbedRootBuilder.buildStubTree(secondaryPsi);
if (element instanceof PsiFileStub) {
stubs.add((PsiFileStub) element);
}
}
final PsiFileStub[] stubsArray = stubs.toArray(new PsiFileStub[stubs.size()]);
for (PsiFileStub stub : stubsArray) {
if (stub instanceof PsiFileStubImpl) {
((PsiFileStubImpl) stub).setStubRoots(stubsArray);
}
}
}
} finally {
psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, null);
psi.getManager().finishBatchFilesProcessingMode();
}
}
inputData.putUserData(stubElementKey, data);
return data;
}
}
use of com.intellij.openapi.util.Pair in project intellij-community by JetBrains.
the class AddMissingRequiredAnnotationParametersFix method invoke.
@Override
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
final PsiNameValuePair[] addedParameters = myAnnotation.getParameterList().getAttributes();
final TObjectIntHashMap<String> annotationsOrderMap = getAnnotationsOrderMap();
final SortedSet<Pair<String, PsiAnnotationMemberValue>> newParameters = new TreeSet<>(Comparator.comparingInt(o -> annotationsOrderMap.get(o.getFirst())));
final boolean order = isAlreadyAddedOrdered(annotationsOrderMap, addedParameters);
if (order) {
if (addedParameters.length != 0) {
final PsiAnnotationParameterList parameterList = myAnnotation.getParameterList();
parameterList.deleteChildRange(addedParameters[0], addedParameters[addedParameters.length - 1]);
for (final PsiNameValuePair addedParameter : addedParameters) {
final String name = addedParameter.getName();
final PsiAnnotationMemberValue value = addedParameter.getValue();
if (name == null || value == null) {
LOG.error(String.format("Invalid annotation parameter name = %s, value = %s", name, value));
continue;
}
newParameters.add(Pair.create(name, value));
}
}
}
final PsiExpression nullValue = JavaPsiFacade.getElementFactory(project).createExpressionFromText(PsiKeyword.NULL, null);
for (final String misssedParameter : myMissedElements) {
newParameters.add(Pair.create(misssedParameter, nullValue));
}
TemplateBuilderImpl builder = null;
for (final Pair<String, PsiAnnotationMemberValue> newParameter : newParameters) {
final PsiAnnotationMemberValue value = myAnnotation.setDeclaredAttributeValue(newParameter.getFirst(), newParameter.getSecond());
if (myMissedElements.contains(newParameter.getFirst())) {
if (builder == null) {
builder = new TemplateBuilderImpl(myAnnotation.getParameterList());
}
builder.replaceElement(value, new EmptyExpression(), true);
}
}
editor.getCaretModel().moveToOffset(myAnnotation.getParameterList().getTextRange().getStartOffset());
final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
final Document document = documentManager.getDocument(file);
if (document == null) {
throw new IllegalStateException();
}
documentManager.doPostponedOperationsAndUnblockDocument(document);
TemplateManager.getInstance(project).startTemplate(editor, builder.buildInlineTemplate(), null);
}
use of com.intellij.openapi.util.Pair in project intellij-community by JetBrains.
the class PsiSuperMethodImplUtil method buildMethodHierarchy.
@NotNull
private static Map<MethodSignature, HierarchicalMethodSignature> buildMethodHierarchy(@NotNull PsiClass aClass, @Nullable String nameHint, @NotNull PsiSubstitutor substitutor, final boolean includePrivates, @NotNull final Set<PsiClass> visited, boolean isInRawContext, GlobalSearchScope resolveScope) {
ProgressManager.checkCanceled();
Map<MethodSignature, HierarchicalMethodSignature> result = new LinkedHashMap<>(new EqualityPolicy<MethodSignature>() {
@Override
public int getHashCode(MethodSignature object) {
return object.hashCode();
}
@Override
public boolean isEqual(MethodSignature o1, MethodSignature o2) {
if (o1.equals(o2)) {
final PsiMethod method1 = ((MethodSignatureBackedByPsiMethod) o1).getMethod();
final PsiType returnType1 = method1.getReturnType();
final PsiMethod method2 = ((MethodSignatureBackedByPsiMethod) o2).getMethod();
final PsiType returnType2 = method2.getReturnType();
if (method1.hasModifierProperty(PsiModifier.STATIC) || method2.hasModifierProperty(PsiModifier.STATIC)) {
return true;
}
if (MethodSignatureUtil.isReturnTypeSubstitutable(o1, o2, returnType1, returnType2)) {
return true;
}
final PsiClass containingClass1 = method1.getContainingClass();
final PsiClass containingClass2 = method2.getContainingClass();
if (containingClass1 != null && containingClass2 != null) {
return containingClass1.isAnnotationType() || containingClass2.isAnnotationType();
}
}
return false;
}
});
final Map<MethodSignature, List<PsiMethod>> sameParameterErasureMethods = new THashMap<>(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY);
Map<MethodSignature, HierarchicalMethodSignatureImpl> map = new THashMap<>(new TObjectHashingStrategy<MethodSignature>() {
@Override
public int computeHashCode(MethodSignature signature) {
return MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY.computeHashCode(signature);
}
@Override
public boolean equals(MethodSignature o1, MethodSignature o2) {
if (!MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY.equals(o1, o2))
return false;
List<PsiMethod> list = sameParameterErasureMethods.get(o1);
boolean toCheckReturnType = list != null && list.size() > 1;
if (!toCheckReturnType)
return true;
PsiType returnType1 = ((MethodSignatureBackedByPsiMethod) o1).getMethod().getReturnType();
PsiType returnType2 = ((MethodSignatureBackedByPsiMethod) o2).getMethod().getReturnType();
if (returnType1 == null && returnType2 == null)
return true;
if (returnType1 == null || returnType2 == null)
return false;
PsiType erasure1 = TypeConversionUtil.erasure(o1.getSubstitutor().substitute(returnType1));
PsiType erasure2 = TypeConversionUtil.erasure(o2.getSubstitutor().substitute(returnType2));
return erasure1.equals(erasure2);
}
});
PsiMethod[] methods = aClass.getMethods();
if ((nameHint == null || "values".equals(nameHint)) && aClass instanceof PsiClassImpl) {
final PsiMethod valuesMethod = ((PsiClassImpl) aClass).getValuesMethod();
if (valuesMethod != null) {
methods = ArrayUtil.append(methods, valuesMethod);
}
}
for (PsiMethod method : methods) {
if (!method.isValid()) {
throw new PsiInvalidElementAccessException(method, "class.valid=" + aClass.isValid() + "; name=" + method.getName());
}
if (nameHint != null && !nameHint.equals(method.getName()))
continue;
if (!includePrivates && method.hasModifierProperty(PsiModifier.PRIVATE))
continue;
final MethodSignatureBackedByPsiMethod signature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY, isInRawContext);
HierarchicalMethodSignatureImpl newH = new HierarchicalMethodSignatureImpl(MethodSignatureBackedByPsiMethod.create(method, substitutor, isInRawContext));
List<PsiMethod> list = sameParameterErasureMethods.get(signature);
if (list == null) {
list = new SmartList<>();
sameParameterErasureMethods.put(signature, list);
}
list.add(method);
LOG.assertTrue(newH.getMethod().isValid());
result.put(signature, newH);
map.put(signature, newH);
}
final List<PsiClassType.ClassResolveResult> superTypes = PsiClassImplUtil.getScopeCorrectedSuperTypes(aClass, resolveScope);
for (PsiClassType.ClassResolveResult superTypeResolveResult : superTypes) {
PsiClass superClass = superTypeResolveResult.getElement();
if (superClass == null)
continue;
// cyclic inheritance
if (!visited.add(superClass))
continue;
final PsiSubstitutor superSubstitutor = superTypeResolveResult.getSubstitutor();
PsiSubstitutor finalSubstitutor = PsiSuperMethodUtil.obtainFinalSubstitutor(superClass, superSubstitutor, substitutor, isInRawContext);
final boolean isInRawContextSuper = (isInRawContext || PsiUtil.isRawSubstitutor(superClass, superSubstitutor)) && superClass.getTypeParameters().length != 0;
Map<MethodSignature, HierarchicalMethodSignature> superResult = buildMethodHierarchy(superClass, nameHint, finalSubstitutor, false, visited, isInRawContextSuper, resolveScope);
visited.remove(superClass);
List<Pair<MethodSignature, HierarchicalMethodSignature>> flattened = new ArrayList<>();
for (Map.Entry<MethodSignature, HierarchicalMethodSignature> entry : superResult.entrySet()) {
HierarchicalMethodSignature hms = entry.getValue();
MethodSignature signature = MethodSignatureBackedByPsiMethod.create(hms.getMethod(), hms.getSubstitutor(), hms.isRaw());
PsiClass containingClass = hms.getMethod().getContainingClass();
List<HierarchicalMethodSignature> supers = new ArrayList<>(hms.getSuperSignatures());
for (HierarchicalMethodSignature aSuper : supers) {
PsiClass superContainingClass = aSuper.getMethod().getContainingClass();
if (containingClass != null && superContainingClass != null && !containingClass.isInheritor(superContainingClass, true)) {
// methods must be inherited from unrelated classes, so flatten hierarchy here
// class C implements SAM1, SAM2 { void methodimpl() {} }
//hms.getSuperSignatures().remove(aSuper);
flattened.add(Pair.create(signature, aSuper));
}
}
putInMap(aClass, result, map, hms, signature);
}
for (Pair<MethodSignature, HierarchicalMethodSignature> pair : flattened) {
putInMap(aClass, result, map, pair.second, pair.first);
}
}
for (Map.Entry<MethodSignature, HierarchicalMethodSignatureImpl> entry : map.entrySet()) {
HierarchicalMethodSignatureImpl hierarchicalMethodSignature = entry.getValue();
MethodSignature methodSignature = entry.getKey();
if (result.get(methodSignature) == null) {
LOG.assertTrue(hierarchicalMethodSignature.getMethod().isValid());
result.put(methodSignature, hierarchicalMethodSignature);
}
}
return result;
}
use of com.intellij.openapi.util.Pair in project intellij-community by JetBrains.
the class JsonSchemaConflictNotificationProvider method createNotificationPanel.
@Nullable
@Override
public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
final List<Pair<Boolean, String>> descriptors = myJsonSchemaService.getMatchingSchemaDescriptors(file);
if (descriptors == null || descriptors.size() <= 1)
return null;
final Worker worker = new Worker();
final String message = worker.createMessage(descriptors);
if (message == null)
return null;
final EditorNotificationPanel panel = new EditorNotificationPanel(LightColors.RED);
panel.setText(message);
panel.createActionLabel("Edit JSON Schema Mappings", () -> {
ShowSettingsUtil.getInstance().editConfigurable(myProject, new JsonSchemaMappingsConfigurable(myProject));
EditorNotifications.getInstance(myProject).updateNotifications(file);
});
return panel;
}
use of com.intellij.openapi.util.Pair in project intellij-community by JetBrains.
the class JsonLiteralAnnotator method annotate.
@Override
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
final String text = JsonPsiUtil.getElementTextWithoutHostEscaping(element);
if (element instanceof JsonStringLiteral) {
final JsonStringLiteral stringLiteral = (JsonStringLiteral) element;
final int elementOffset = element.getTextOffset();
if (JsonPsiUtil.isPropertyKey(element)) {
holder.createInfoAnnotation(element, Holder.DEBUG ? "property key" : null).setTextAttributes(JsonSyntaxHighlighterFactory.JSON_PROPERTY_KEY);
}
final int length = text.length();
// Check that string literal is closed properly
if (length <= 1 || text.charAt(0) != text.charAt(length - 1) || JsonPsiUtil.isEscapedChar(text, length - 1)) {
holder.createErrorAnnotation(element, JsonBundle.message("syntax.error.missing.closing.quote"));
}
// Check escapes
final List<Pair<TextRange, String>> fragments = stringLiteral.getTextFragments();
for (Pair<TextRange, String> fragment : fragments) {
final String fragmentText = fragment.getSecond();
if (fragmentText.startsWith("\\") && fragmentText.length() > 1 && !VALID_ESCAPE.matcher(fragmentText).matches()) {
final TextRange fragmentRange = fragment.getFirst();
if (fragmentText.startsWith("\\u")) {
holder.createErrorAnnotation(fragmentRange.shiftRight(elementOffset), JsonBundle.message("syntax.error.illegal.unicode.escape.sequence"));
} else {
holder.createErrorAnnotation(fragmentRange.shiftRight(elementOffset), JsonBundle.message("syntax.error.illegal.escape.sequence"));
}
}
}
} else if (element instanceof JsonNumberLiteral) {
if (!VALID_NUMBER_LITERAL.matcher(text).matches()) {
holder.createErrorAnnotation(element, JsonBundle.message("syntax.error.illegal.floating.point.literal"));
}
}
}
Aggregations