Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vassiliy.Kudryashov
2017-08-15 23:19:02 +03:00
36 changed files with 320 additions and 206 deletions
@@ -28,6 +28,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.impl.storage.ClassPathStorageUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.util.PsiTreeUtil;
@@ -159,7 +160,12 @@ public class SuppressFix extends AbstractBatchSuppressByNoInspectionCommentFix {
protected boolean use15Suppressions(@NotNull PsiJavaDocumentedElement container) {
return JavaSuppressionUtil.canHave15Suppressions(container) &&
!JavaSuppressionUtil.alreadyHas14Suppressions(container);
!JavaSuppressionUtil.alreadyHas14Suppressions(container) &&
!isInjectedToStringLiteral(container); // quotes will be imbalanced when insert annotation value in quotes into literal expression
}
private static boolean isInjectedToStringLiteral(@NotNull PsiJavaDocumentedElement container) {
return JavaResolveUtil.findParentContextOfClass(container, PsiLiteralExpression.class, true) != null;
}
private String getID(@NotNull PsiElement place) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -562,40 +562,22 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta
super.ignoreElement(refEntity);
}
@Override
public void amnesty(RefEntity refEntity) {
myIgnoreElements.remove(refEntity);
}
@Override
public void cleanup() {
super.cleanup();
myIgnoreElements.clear();
}
@Override
public void finalCleanup() {
super.finalCleanup();
}
@Override
public boolean isGraphNeeded() {
return true;
}
@Override
public boolean isElementIgnored(final RefEntity element) {
return myIgnoreElements.contains(element);
}
@NotNull
@Override
public FileStatus getElementStatus(final RefEntity element) {
return FileStatus.NOT_CHANGED;
}
@Override
@NotNull
public Set<RefEntity> getIgnoredRefElements() {
@@ -528,7 +528,7 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase {
checkResultWithInlays("class C { void m() { System.setProperty(<hint text=\"key:\"/>System.getProperty(<hint text=\"key:\"/>, <HINT text=\"def:\"/><caret>), <hint text=\"value:\"/>) } }");
}
public void testHintPopupContents() throws Exception {
public void testHintPopupContentsForMethodWithOverloads() throws Exception {
configureJava("class C { void m() { System.getPro<caret> } }");
complete("getProperty(String key, String def)");
waitForAllAsyncStuff();
@@ -544,6 +544,21 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase {
"<html>@NotNull String key, <b>String def</b></html>");
}
public void testHintPopupContentsForMethodWithoutOverloads() throws Exception {
configureJava("class C { void m() { System.setPro<caret> } }");
complete("setProperty");
waitForAllAsyncStuff();
checkResultWithInlays("class C { void m() { System.setProperty(<HINT text=\"key:\"/><caret>, <hint text=\"value:\"/>) } }");
checkHintContents("<html>@NotNull String</html>");
next();
waitForAllAsyncStuff();
checkResultWithInlays("class C { void m() { System.setProperty(<hint text=\"key:\"/>, <HINT text=\"value:\"/><caret>) } }");
checkHintContents("<html>String</html>");
myFixture.performEditorAction(IdeActions.ACTION_EDITOR_SHOW_PARAMETER_INFO);
waitForAllAsyncStuff();
checkHintContents("<html>@NotNull String key, <b>String value</b></html>");
}
private void checkResult(String text) {
myFixture.checkResult(text);
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
@@ -113,6 +114,12 @@ public class OutputChecker {
assert outs.exists() || outs.mkdirs() : outs;
File outFile = new File(outs, myTestName + ".out");
if (JavaSdkUtil.isJdkAtLeast(jdk, JavaSdkVersion.JDK_1_9)) {
File jdk9Out = new File(outs, myTestName + ".jdk9.out");
if (jdk9Out.exists()) {
outFile = jdk9Out;
}
}
if (!outFile.exists()) {
if (SystemInfo.isWindows) {
final File winOut = new File(outs, myTestName + ".win.out");
@@ -332,7 +332,6 @@ public final class LoadTextUtil {
toolkit.setEnforce8Bit(true);
Charset charset = toolkit.guessFromBOM();
if (charset != null) {
byte[] bom = ObjectUtils.notNull(CharsetToolkit.getMandatoryBom(charset), CharsetToolkit.UTF8_BOM);
return Trinity.create(charset, null, bom);
}
@@ -340,29 +339,39 @@ public final class LoadTextUtil {
if (guessed == CharsetToolkit.GuessedEncoding.VALID_UTF8) {
return Trinity.create(CharsetToolkit.UTF8_CHARSET, CharsetToolkit.GuessedEncoding.VALID_UTF8, null); //UTF detected, ignore all directives
}
if (guessed == CharsetToolkit.GuessedEncoding.SEVEN_BIT) {
return Trinity.create(null, CharsetToolkit.GuessedEncoding.SEVEN_BIT, null);
}
return Trinity.create(null, guessed, null);
}
/**
* Tries to detect text in the {@code bytes} and call the {@code fileTextProcessor} with the text (if detected) or with null if not
*/
public static String getTextFromBytesOrNull(@NotNull byte[] bytes,
int startOffset, int endOffset) {
Trinity<Charset, CharsetToolkit.GuessedEncoding, byte[]> info = guessFromBytes(bytes, startOffset, endOffset, CharsetToolkit.UTF8_CHARSET);
Charset internalCharset = info.getFirst();
CharsetToolkit.GuessedEncoding guessed = info.getSecond();
if (internalCharset == null || guessed == CharsetToolkit.GuessedEncoding.BINARY || guessed == CharsetToolkit.GuessedEncoding.INVALID_UTF8) {
// the charset was not detected so the file is likely binary
return null;
public static String getTextFromBytesOrNull(@NotNull byte[] bytes, int startOffset, int endOffset) {
Charset defaultCharset = EncodingManager.getInstance().getDefaultCharset();
Trinity<Charset, CharsetToolkit.GuessedEncoding, byte[]> info = guessFromBytes(bytes, startOffset, endOffset, defaultCharset);
Charset charset;
if (info.getFirst() != null) {
charset = info.getFirst(); // hardcoded charset
}
else {
byte[] bom = info.getThird();
Pair<CharSequence, String> result = convertBytes(bytes, Math.min(startOffset+(bom==null?0:bom.length), endOffset), endOffset, internalCharset);
return result.getFirst().toString();
CharsetToolkit.GuessedEncoding guessed = info.getSecond();
switch (guessed) {
case SEVEN_BIT:
charset = CharsetToolkit.US_ASCII_CHARSET;
break;
case VALID_UTF8:
charset = CharsetToolkit.UTF8_CHARSET;
break;
case INVALID_UTF8:
case BINARY:
// the charset was not detected so the file is likely binary
return null;
default:
throw new IllegalStateException(String.valueOf(guessed));
}
}
byte[] bom = info.getThird();
Pair<CharSequence, String> result = convertBytes(bytes, Math.min(startOffset+(bom==null?0:bom.length), endOffset), endOffset, charset);
return result.getFirst().toString();
}
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ import com.intellij.codeInsight.daemon.impl.actions.ShowErrorDescriptionAction;
import com.intellij.codeInsight.hint.LineTooltipRenderer;
import com.intellij.codeInsight.hint.TooltipLinkHandlerEP;
import com.intellij.codeInsight.hint.TooltipRenderer;
import com.intellij.codeInspection.ui.DefaultInspectionToolPresentation;
import com.intellij.codeInspection.ui.InspectionNodeInfo;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.ErrorStripTooltipRendererProvider;
import com.intellij.openapi.editor.impl.TrafficTooltipRenderer;
@@ -141,7 +141,7 @@ public class DaemonTooltipRendererProvider implements ErrorStripTooltipRendererP
if (ref != null) {
String description = TooltipLinkHandlerEP.getDescription(ref, editor);
if (description != null) {
description = DefaultInspectionToolPresentation.stripUIRefsFromInspectionDescription(UIUtil.getHtmlBody(new Html(description).setKeepFont(true)));
description = InspectionNodeInfo.stripUIRefsFromInspectionDescription(UIUtil.getHtmlBody(new Html(description).setKeepFont(true)));
text += UIUtil.getHtmlBody(new Html(problem).setKeepFont(true)).replace(DaemonBundle.message("inspection.extended.description"),
DaemonBundle.message("inspection.collapse.description")) +
END_MARKER + "<p>" + description + UIUtil.BORDER_LINE;
@@ -234,7 +234,7 @@ public class ParameterInfoComponent extends JPanel {
context.i = i;
final Object o = myObjects[i];
if (singleParameterInfo && !context.isHighlighted()) {
if (singleParameterInfo && myObjects.length > 1 && !context.isHighlighted()) {
setVisible(i, false);
}
else {
@@ -104,6 +104,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
private final NotNullLazyValue<ContentManager> myContentManager;
private volatile InspectionResultsView myView;
private volatile String myOutputPath;
private Content myContent;
private volatile boolean myViewClosed = true;
private long myInspectionStartedTimestamp;
@@ -193,13 +194,13 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
setCurrentScope(scope);
final Runnable action = () -> {
DefaultInspectionToolPresentation.setOutputPath(outputPath);
myOutputPath = outputPath;
try {
performInspectionsWithProgress(scope, runGlobalToolsOnly, isOfflineInspections);
exportResults(inspectionsResults, outputPath);
}
finally {
DefaultInspectionToolPresentation.setOutputPath(null);
myOutputPath = null;
}
};
if (isOfflineInspections) {
@@ -305,6 +306,10 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
return myView;
}
public String getOutputPath() {
return myOutputPath;
}
private void ignoreElementRecursively(@NotNull InspectionToolWrapper toolWrapper, final RefEntity refElement) {
if (refElement != null) {
InspectionToolPresentation presentation = getPresentation(toolWrapper);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@ import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.ui.InspectionToolPresentation;
import com.intellij.codeInspection.ui.ProblemDescriptionNode;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FileStatus;
import org.jetbrains.annotations.NotNull;
public class OfflineProblemDescriptorNode extends ProblemDescriptionNode {
@@ -48,11 +47,6 @@ public class OfflineProblemDescriptorNode extends ProblemDescriptionNode {
offlineDescriptor);
}
@Override
public FileStatus getNodeStatus() {
return FileStatus.NOT_CHANGED;
}
@NotNull
@Override
protected String calculatePresentableName() {
@@ -23,6 +23,7 @@ import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ex.*;
import com.intellij.codeInspection.reference.*;
import com.intellij.concurrency.ConcurrentCollectionFactory;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PathMacroManager;
@@ -31,6 +32,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vfs.CharsetToolkit;
@@ -40,7 +42,6 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.concurrency.ConcurrentCollectionFactory;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import gnu.trove.Equality;
@@ -53,15 +54,12 @@ import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.util.*;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DefaultInspectionToolPresentation implements ProblemDescriptionsProcessor, InspectionToolPresentation {
@NotNull private final InspectionToolWrapper myToolWrapper;
protected static final Logger LOG = Logger.getInstance(DefaultInspectionToolPresentation.class);
@NotNull
private final GlobalInspectionContextImpl myContext;
private static String ourOutputPath;
@NotNull private final InspectionToolWrapper myToolWrapper;
@NotNull private final GlobalInspectionContextImpl myContext;
protected InspectionNode myToolNode;
private static final Object lock = new Object();
@@ -74,7 +72,6 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
private final Map<RefEntity, Set<QuickFix>> myQuickFixActions = Collections.synchronizedMap(ContainerUtil.newIdentityTroveMap());
private final Map<RefEntity, CommonProblemDescriptor[]> myIgnoredElements = Collections.synchronizedMap(ContainerUtil.newIdentityTroveMap());
protected static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.DescriptorProviderInspection");
private volatile boolean isDisposed;
public DefaultInspectionToolPresentation(@NotNull InspectionToolWrapper toolWrapper, @NotNull GlobalInspectionContextImpl context) {
@@ -82,23 +79,6 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
myContext = context;
}
public static String stripUIRefsFromInspectionDescription(@NotNull String description) {
final int descriptionEnd = description.indexOf("<!-- tooltip end -->");
if (descriptionEnd < 0) {
final Pattern pattern = Pattern.compile(".*Use.*(the (panel|checkbox|checkboxes|field|button|controls).*below).*", Pattern.DOTALL);
final Matcher matcher = pattern.matcher(description);
int startFindIdx = 0;
while (matcher.find(startFindIdx)) {
final int end = matcher.end(1);
startFindIdx = end;
description = description.substring(0, matcher.start(1)) + " inspection settings " + description.substring(end);
}
} else {
description = description.substring(0, descriptionEnd);
}
return description;
}
@Override
public HighlightSeverity getSeverity(@NotNull RefElement element) {
final PsiElement psiElement = element.getPointer().getContainingFile();
@@ -183,7 +163,7 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
if (refElement == null) return;
if (descriptors.length == 0) return;
if (filterSuppressed) {
if (!isOutputPathSet() || !(myToolWrapper instanceof LocalInspectionToolWrapper)) {
if (myContext.getOutputPath() == null || !(myToolWrapper instanceof LocalInspectionToolWrapper)) {
synchronized (lock) {
Map<RefEntity, CommonProblemDescriptor[]> problemElements = getProblemElements();
CommonProblemDescriptor[] problems = problemElements.get(refElement);
@@ -259,11 +239,11 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
final List<Element> list = parentNode.getChildren();
@NonNls final String ext = ".xml";
final String fileName = ourOutputPath + File.separator + myToolWrapper.getShortName() + ext;
final String fileName = myContext.getOutputPath() + File.separator + myToolWrapper.getShortName() + ext;
final PathMacroManager pathMacroManager = PathMacroManager.getInstance(getContext().getProject());
PrintWriter printWriter = null;
try {
new File(ourOutputPath).mkdirs();
FileUtil.createDirectory(new File(myContext.getOutputPath()));
final File file = new File(fileName);
final StringWriter writer = new StringWriter();
if (!file.exists()) {
@@ -320,11 +300,6 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
getProblemElements().getOrDefault(refEntity, CommonProblemDescriptor.EMPTY_ARRAY)));
}
@Override
public void amnesty(RefEntity refEntity) {
getIgnoredElements().remove(refEntity);
}
@Override
public void amnesty(RefEntity refEntity, CommonProblemDescriptor descriptor) {
final CommonProblemDescriptor[] ignoredDescriptors = getIgnoredElements().get(refEntity);
@@ -527,11 +502,6 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
}
}
@Override
public boolean isGraphNeeded() {
return false;
}
@Override
public boolean hasReportedProblems() {
return !myProblemToElements.isEmpty();
@@ -674,18 +644,6 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
return descriptors != null && ArrayUtil.contains(descriptor, descriptors);
}
@Override
@NotNull
public FileStatus getProblemStatus(@NotNull final CommonProblemDescriptor descriptor) {
return FileStatus.NOT_CHANGED;
}
@NotNull
@Override
public FileStatus getElementStatus(final RefEntity element) {
return FileStatus.NOT_CHANGED;
}
@NotNull
@Override
public Set<RefEntity> getIgnoredRefElements() {
@@ -770,12 +728,4 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
}
};
}
public static synchronized void setOutputPath(final String output) {
ourOutputPath = output;
}
private static synchronized boolean isOutputPathSet() {
return ourOutputPath != null;
}
}
@@ -40,6 +40,8 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Dmitry Batkovich
@@ -82,7 +84,7 @@ public class InspectionNodeInfo extends JPanel {
String descriptionText = toolWrapper.loadDescription();
LOG.assertTrue(descriptionText != null, "Inspection '" + toolWrapper.getShortName() + "' has no description");
final String toolDescription =
DefaultInspectionToolPresentation.stripUIRefsFromInspectionDescription(StringUtil.notNullize(descriptionText));
stripUIRefsFromInspectionDescription(StringUtil.notNullize(descriptionText));
SingleInspectionProfilePanel.readHTML(description, SingleInspectionProfilePanel.toHTML(description, toolDescription == null ? "" : toolDescription, false));
JScrollPane pane = ScrollPaneFactory.createScrollPane(description, true);
int maxWidth = getFontMetrics(UIUtil.getLabelFont()).charWidth('f') * 110 - pane.getMinimumSize().width;
@@ -122,4 +124,21 @@ public class InspectionNodeInfo extends JPanel {
new JBInsets(15, 9, 9, 0), 0, 0));
}
public static String stripUIRefsFromInspectionDescription(@NotNull String description) {
final int descriptionEnd = description.indexOf("<!-- tooltip end -->");
if (descriptionEnd < 0) {
final Pattern pattern = Pattern.compile(".*Use.*(the (panel|checkbox|checkboxes|field|button|controls).*below).*", Pattern.DOTALL);
final Matcher matcher = pattern.matcher(description);
int startFindIdx = 0;
while (matcher.find(startFindIdx)) {
final int end = matcher.end(1);
startFindIdx = end;
description = description.substring(0, matcher.start(1)) + " inspection settings " + description.substring(end);
}
} else {
description = description.substring(0, descriptionEnd);
}
return description;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@ import com.intellij.codeInspection.reference.RefElement;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.reference.RefModule;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.vcs.FileStatus;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -66,15 +65,11 @@ public interface InspectionToolPresentation extends ProblemDescriptionsProcessor
Map<String, Set<RefEntity>> getContent();
void ignoreCurrentElement(RefEntity refEntity);
void amnesty(RefEntity refEntity);
void amnesty(RefEntity refEntity, CommonProblemDescriptor descriptor);
void cleanup();
void finalCleanup();
boolean isGraphNeeded();
boolean isElementIgnored(final RefEntity element);
@NotNull
FileStatus getElementStatus(final RefEntity element);
@NotNull
Set<RefEntity> getIgnoredRefElements();
@Nullable
IntentionAction findQuickFixes(@NotNull CommonProblemDescriptor descriptor, final String hint);
@@ -89,8 +84,6 @@ public interface InspectionToolPresentation extends ProblemDescriptionsProcessor
Map<RefEntity, CommonProblemDescriptor[]> getProblemElements();
@NotNull
Collection<CommonProblemDescriptor> getProblemDescriptors();
@NotNull
FileStatus getProblemStatus(@NotNull CommonProblemDescriptor descriptor);
boolean isProblemResolved(RefEntity refEntity, CommonProblemDescriptor descriptor);
void ignoreCurrentElementProblem(RefEntity refEntity, CommonProblemDescriptor descriptor);
void addProblemElement(RefEntity refElement, boolean filterSuppressed, @NotNull CommonProblemDescriptor... descriptions);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -91,11 +91,6 @@ class InspectionTreeCellRenderer extends ColoredTreeCellRenderer {
}
}
}
final FileStatus nodeStatus = node.getNodeStatus();
if (nodeStatus != FileStatus.NOT_CHANGED) {
foreground =
new SimpleTextAttributes(foreground.getBgColor(), nodeStatus.getColor(), foreground.getWaveColor(), foreground.getStyle());
}
return foreground;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,10 +79,6 @@ public abstract class InspectionTreeNode extends DefaultMutableTreeNode {
return null;
}
public FileStatus getNodeStatus() {
return FileStatus.NOT_CHANGED;
}
public void excludeElement(ExcludedInspectionTreeNodesManager excludedManager) {
excludedManager.exclude(this);
Enumeration enumeration = children();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,10 +23,8 @@ import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemDescriptorUtil;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.codeInspection.reference.RefElement;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.psi.PsiElement;
import com.intellij.xml.util.XmlStringUtil;
import gnu.trove.TObjectIntHashMap;
@@ -134,14 +132,6 @@ public class ProblemDescriptionNode extends SuppressableInspectionTreeNode {
super.amnestyElement(manager);
}
@Override
public FileStatus getNodeStatus() {
if (myElement instanceof RefElement) {
return getPresentation().getProblemStatus(myDescriptor);
}
return FileStatus.NOT_CHANGED;
}
@Override
protected void dropCache(Project project) {
if (!isQuickFixAppliedFromView()) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -85,11 +85,6 @@ public class RefElementNode extends SuppressableInspectionTreeNode {
super.amnestyElement(excludedManager);
}
@Override
public FileStatus getNodeStatus() {
return getPresentation().getElementStatus(getElement());
}
@Override
public void add(MutableTreeNode newChild) {
checkHasDescriptorUnder(newChild);
@@ -17,14 +17,12 @@ package com.intellij.ide.ui.laf.darcula.ui;
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTextAreaUI;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;
import javax.swing.text.*;
import java.awt.event.KeyEvent;
public class DarculaTextAreaUI extends BasicTextAreaUI{
@@ -51,4 +49,9 @@ public class DarculaTextAreaUI extends BasicTextAreaUI{
int position = DarculaUIUtil.getPatchedNextVisualPositionFrom(t, pos, direction);
return position != -1 ? position : super.getNextVisualPositionFrom(t, pos, b, direction, biasRet);
}
@Override
protected Caret createCaret() {
return Registry.is("ide.text.mouse.selection.new") ? new TextFieldWithPopupHandlerUI.MyCaret(getComponent()) : super.createCaret();
}
}
@@ -36,10 +36,7 @@ import javax.swing.event.DocumentListener;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicTextFieldUI;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
@@ -201,6 +198,11 @@ public abstract class TextFieldWithPopupHandlerUI extends BasicTextFieldUI imple
return position != -1 ? position : super.getNextVisualPositionFrom(t, pos, b, direction, biasRet);
}
@Override
protected Caret createCaret() {
return Registry.is("ide.text.mouse.selection.new") ? new MyCaret(getComponent()) : super.createCaret();
}
@Override
public boolean value(Object o) {
if (o instanceof MouseEvent) {
@@ -632,4 +634,24 @@ public abstract class TextFieldWithPopupHandlerUI extends BasicTextFieldUI imple
return "clear";
}
}
static class MyCaret extends BasicCaret {
private final JTextComponent myComponent;
public MyCaret(JTextComponent component) {
myComponent = component;
}
@Override
public void mouseDragged(MouseEvent e) {
if (e.getID() == MouseEvent.MOUSE_DRAGGED && !myComponent.getText().contains("\n")) {
boolean consumed = e.isConsumed();
e = new MouseEvent(e.getComponent(), e.getID(), e.getWhen(), e.getModifiers() | e.getModifiersEx(), e.getX(),
myComponent.getHeight() / 2,
e.getClickCount(), e.isPopupTrigger(), e.getButton());
if (consumed) e.consume();
}
super.mouseDragged(e);
}
}
}
@@ -37,7 +37,7 @@ abstract class FoldRegionsTree {
private static final Comparator<FoldRegion> BY_END_OFFSET = Comparator.comparingInt(RangeMarker::getEndOffset);
private static final Comparator<? super FoldRegion> BY_END_OFFSET_REVERSE = Collections.reverseOrder(BY_END_OFFSET);
private static final TObjectHashingStrategy<FoldRegion> OFFSET_BASED_HASHING_STRATEGY = new TObjectHashingStrategy<FoldRegion>() {
static final TObjectHashingStrategy<FoldRegion> OFFSET_BASED_HASHING_STRATEGY = new TObjectHashingStrategy<FoldRegion>() {
@Override
public int computeHashCode(FoldRegion o) {
return o.getStartOffset() * 31 + o.getEndOffset();
@@ -77,13 +77,14 @@ abstract class FoldRegionsTree {
public boolean process(int offset, @NotNull FoldRegionImpl region, boolean atStart, @NotNull Collection<FoldRegionImpl> overlapping) {
if (atStart) {
if (sameRange(region, lastRegion)) {
if (region.getUserData(VISIBLE) == null) {
if (region.getUserData(VISIBLE) == null || lastRegion.getUserData(VISIBLE) != null && region.isExpanded()) {
duplicatesToKill.add(region);
return true;
}
else {
duplicatesToKill.add(lastRegion);
if (!visible.isEmpty() && lastRegion == visible.get(visible.size() - 1)) removeFromVisible(visible.size() - 1);
if (lastRegion == lastCollapsedRegion) lastCollapsedRegion = null;
}
}
lastRegion = region;
@@ -34,12 +34,13 @@ import com.intellij.openapi.util.ModificationTracker;
import com.intellij.util.DocumentUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.awt.*;
import java.util.Arrays;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
@@ -622,10 +623,57 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedInternalDocu
@TestOnly
void validateState() {
for (FoldRegion region : getAllFoldRegions()) {
LOG.assertTrue (!region.isValid() ||
!DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), region.getStartOffset()) &&
!DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), region.getEndOffset()));
if (myEditor.getDocument().isInBulkUpdate()) return;
FoldRegion[] allFoldRegions = getAllFoldRegions();
boolean[] invisibleRegions = new boolean[allFoldRegions.length];
for (int i = 0; i < allFoldRegions.length; i++) {
FoldRegion r1 = allFoldRegions[i];
LOG.assertTrue(r1.isValid() &&
!DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), r1.getStartOffset()) &&
!DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), r1.getEndOffset()),
"Invalid region");
for (int j = i + 1; j < allFoldRegions.length; j++) {
FoldRegion r2 = allFoldRegions[j];
int r1s = r1.getStartOffset();
int r1e = r1.getEndOffset();
int r2s = r2.getStartOffset();
int r2e = r2.getEndOffset();
LOG.assertTrue(r1s < r2s && (r1e <= r2s || r1e >= r2e) ||
r1s == r2s && r1e != r2e ||
r1s > r2s && r1s < r2e && r1e <= r2e ||
r1s >= r2e,
"Disallowed relative position of regions");
if (!r1.isExpanded() && r1s <= r2s && r1e >= r2e) invisibleRegions[j] = true;
if (!r2.isExpanded() && r2s <= r1s && r2e >= r1e) invisibleRegions[i] = true;
}
}
Set<FoldRegion> visibleRegions = new THashSet<>(FoldRegionsTree.OFFSET_BASED_HASHING_STRATEGY);
List<FoldRegion> topLevelRegions = new ArrayList<>();
for (int i = 0; i < allFoldRegions.length; i++) {
if (!invisibleRegions[i]) {
FoldRegion region = allFoldRegions[i];
LOG.assertTrue(visibleRegions.add(region), "Duplicate visible regions");
if (!region.isExpanded()) topLevelRegions.add(region);
}
}
Collections.sort(topLevelRegions, Comparator.comparingInt(r -> r.getStartOffset()));
FoldRegion[] actualVisibles = fetchVisible();
if (actualVisibles != null) {
for (FoldRegion r : actualVisibles) {
LOG.assertTrue(visibleRegions.remove(r), "Unexpected visible region");
}
LOG.assertTrue(visibleRegions.isEmpty(), "Missing visible region");
}
FoldRegion[] actualTopLevels = fetchTopLevel();
if (actualTopLevels != null) {
LOG.assertTrue(actualTopLevels.length == topLevelRegions.size(), "Wrong number of top-level regions");
for (int i = 0; i < actualTopLevels.length; i++) {
LOG.assertTrue(FoldRegionsTree.OFFSET_BASED_HASHING_STRATEGY.equals(actualTopLevels[i], topLevelRegions.get(i)),
"Unexpected top-level region");
}
}
}
@@ -350,4 +350,11 @@ public class FoldingTest extends AbstractEditorTest {
addCollapsedFoldRegion(11, 12, "innermost");
Assert.assertArrayEquals(new FoldRegion[]{inner}, myModel.fetchTopLevel());
}
public void testIdenticalRegionsOtherCase() {
FoldRegion inner = addCollapsedFoldRegion(10, 15, "inner");
addFoldRegion(10, 20, "outer");
WriteCommandAction.runWriteCommandAction(ourProject, () -> myEditor.getDocument().deleteString(15, 20));
Assert.assertArrayEquals(new FoldRegion[]{inner}, myModel.fetchTopLevel());
}
}
@@ -1079,6 +1079,8 @@ ide.text.effect.new.scale=true
ide.text.effect.new.scale.description=Enables scalable effect painter for text
ide.text.effect.new.metrics=true
ide.text.effect.new.metrics.description=Use line metrics to calculate text offset in the effect painter
ide.text.mouse.selection.new=true
ide.text.mouse.selection.description=Use improved mouse-drag processing in single-line text components when mouse pointer is out of area
ide.intellij.laf.win10.ui=true
ide.intellij.laf.win10.restartRequired=true
@@ -15,20 +15,13 @@
*/
package com.intellij.openapi.vcs.ui;
import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry;
import com.intellij.openapi.editor.impl.FontFallbackIterator;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
public class FontUtil {
@Nullable
public static Font getFontAbleToDisplay(char c, int size, int style, @NotNull String family) {
Font font = ComplementaryFontsRegistry.getFontAbleToDisplay(c, size, style, family, null).getFont();
return font.canDisplay(c) ? font : null;
}
@NotNull
public static String getHtmlWithFonts(@NotNull String input) {
Font font = UIUtil.getLabelFont();
@@ -40,26 +33,29 @@ public class FontUtil {
int start = baseFont.canDisplayUpTo(input);
if (start == -1) return input;
Font font = null;
StringBuilder result = new StringBuilder(input.substring(0, start));
for (int i = start; i < input.length(); i++) {
char c = input.charAt(i);
if (baseFont.canDisplay(c)) {
if (font != null) result.append("</font>");
result.append(c);
font = null;
StringBuilder result = new StringBuilder();
FontFallbackIterator it = new FontFallbackIterator();
it.setPreferredFont(baseFont.getFamily(), baseFont.getSize());
it.setFontStyle(style);
it.start(input, 0, input.length());
while (!it.atEnd()) {
Font font = it.getFont();
boolean insideFallbackBlock = !font.getFamily().equals(baseFont.getFamily());
if (insideFallbackBlock) {
result.append("<font face=\"").append(font.getFamily()).append("\">");
}
else if (font != null && font.canDisplay(c)) {
result.append(c);
}
else {
if (font != null) result.append("</font>");
font = getFontAbleToDisplay(c, baseFont.getSize(), style, baseFont.getFamily());
if (font != null) result.append("<font face=\"").append(font.getFamily()).append("\">");
result.append(c);
result.append(input, it.getStart(), it.getEnd());
if (insideFallbackBlock) {
result.append("</font>");
}
it.advance();
}
if (font != null) result.append("</font>");
return result.toString();
}
@@ -139,7 +139,7 @@ public class XLightBreakpointPropertiesPanel implements XSuspendPolicyPanel.Dele
myConditionEnabledCheckbox = new JBCheckBox(XDebuggerBundle.message("xbreakpoints.condition.checkbox"));
myConditionComboBox = new XDebuggerExpressionComboBox(project, debuggerEditorsProvider, CONDITION_HISTORY_ID, myBreakpoint.getSourcePosition(), true);
JComponent conditionComponent = myConditionComboBox.getComponent();
conditionComponent.setBorder(JBUI.Borders.emptyRight(3));
conditionComponent.setBorder(JBUI.Borders.empty(0, 4));
myConditionExpressionPanel.add(conditionComponent, BorderLayout.CENTER);
myConditionEnabledCheckbox.addActionListener(e -> onCheckboxChanged());
DebuggerUIUtil.focusEditorOnCheck(myConditionEnabledCheckbox, myConditionComboBox.getEditorComponent());
@@ -244,7 +244,7 @@ public class XLightBreakpointPropertiesPanel implements XSuspendPolicyPanel.Dele
myConditionEnabledPanel.removeAll();
if (hideCheckbox) {
JBLabel label = new JBLabel(XDebuggerBundle.message("xbreakpoints.condition.checkbox"));
label.setBorder(JBUI.Borders.empty(0, 4));
label.setBorder(JBUI.Borders.emptyLeft(4));
label.setLabelFor(myConditionComboBox.getComboBox());
myConditionEnabledPanel.add(label);
}
@@ -327,7 +327,8 @@ public abstract class AbstractValueHint {
}
protected <D> void showTreePopup(@NotNull DebuggerTreeCreator<D> creator, @NotNull D descriptor) {
DebuggerTreeWithHistoryPopup.showTreePopup(creator, descriptor, getEditor(), myPoint, getProject(), myHideRunnable);
Point point = new Point(myPoint.x, myPoint.y + myEditor.getLineHeight());
DebuggerTreeWithHistoryPopup.showTreePopup(creator, descriptor, myEditor, point, getProject(), myHideRunnable);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,4 +79,6 @@ public abstract class GroovyQuickFixFactory {
public abstract IntentionAction createRemoveUnusedGrParameterFix(GrParameter parameter);
public abstract IntentionAction createInvestigateFix(String reason);
public abstract GroovyFix createMultipleAssignmentFix(int size);
}
@@ -32,7 +32,7 @@ import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.codeInspection.assignment.GrReplaceMultiAssignmentFix;
import org.jetbrains.plugins.groovy.codeInspection.GroovyQuickFixFactory;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
@@ -92,7 +92,7 @@ public class GroovyStaticTypeCheckVisitor extends GroovyTypeCheckVisitor {
registerError(
initializer,
GroovyBundle.message("multiple.assignments.without.list.expr"),
new LocalQuickFix[]{new GrReplaceMultiAssignmentFix(types.length)},
new LocalQuickFix[]{GroovyQuickFixFactory.getInstance().createMultipleAssignmentFix(types.length)},
ProblemHighlightType.GENERIC_ERROR
);
}
@@ -999,7 +999,7 @@ public class GroovyTypeCheckVisitor extends BaseInspectionVisitor {
final GrVariableDeclaration tuple = (GrVariableDeclaration)parent;
final GrExpression initializer = tuple.getTupleInitializer();
if (initializer == null) return;
if (!(initializer instanceof GrListOrMap)) {
if (!(initializer instanceof GrListOrMap) && !PsiUtil.isCompileStatic(variable)) {
PsiType type = initializer.getType();
if (type == null) return;
PsiType valueType = extractIterableTypeParameter(type, false);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -142,4 +142,9 @@ public class EmptyGroovyQuickFixFactory extends GroovyQuickFixFactory {
public IntentionAction createInvestigateFix(String reason) {
return QuickFixes.EMPTY_ACTION;
}
@Override
public GroovyFix createMultipleAssignmentFix(int size) {
return GroovyFix.EMPTY_FIX;
}
}
@@ -504,6 +504,8 @@ public abstract class GrMethodBaseImpl extends GrStubElementBase<GrMethodStub> i
@Override
@Nullable
public GrDocComment getDocComment() {
final GrMethodStub stub = getStub();
if (stub != null && !stub.hasComment()) return null;
return GrDocCommentUtil.findDocComment(this);
}
@@ -31,6 +31,7 @@ import org.jetbrains.plugins.groovy.lang.psi.stubs.elements.GrMethodElementType;
public class GrMethodStub extends StubBase<GrMethod> implements NamedStub<GrMethod> {
public static final byte IS_DEPRECATED_BY_DOC_TAG = 0b1;
public static final byte HAS_BLOCK = 0b10;
public static final byte HAS_COMMENT = 0b100;
private final StringRef myName;
private final String[] myAnnotations;
@@ -54,7 +55,8 @@ public class GrMethodStub extends StubBase<GrMethod> implements NamedStub<GrMeth
}
@Override
@NotNull public String getName() {
@NotNull
public String getName() {
return StringRef.toString(myName);
}
@@ -80,16 +82,16 @@ public class GrMethodStub extends StubBase<GrMethod> implements NamedStub<GrMeth
return (myFlags & HAS_BLOCK) != 0;
}
public boolean hasComment() {
return (myFlags & HAS_COMMENT) != 0;
}
public static byte buildFlags(GrMethod method) {
byte f = 0;
if (PsiImplUtil.isDeprecatedByDocTag(method)) {
f |= IS_DEPRECATED_BY_DOC_TAG;
}
if (method.hasBlock()) {
f |= HAS_BLOCK;
}
if (PsiImplUtil.isDeprecatedByDocTag(method)) f |= IS_DEPRECATED_BY_DOC_TAG;
if (method.hasBlock()) f |= HAS_BLOCK;
if (method.getDocComment() != null) f |= HAS_COMMENT;
return f;
}
@@ -40,7 +40,7 @@ import java.io.IOException;
* @author ilyas
*/
public class GrStubFileElementType extends IStubFileElementType<GrFileStub> {
public static final int STUB_VERSION = 36;
public static final int STUB_VERSION = 37;
public GrStubFileElementType(Language language) {
super(language);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicProperty
import org.jetbrains.plugins.groovy.codeInspection.bugs.AddClassToExtendsFix;
import org.jetbrains.plugins.groovy.codeInspection.bugs.AddMethodFix;
import org.jetbrains.plugins.groovy.codeInspection.confusing.ReplaceWithImportFix;
import org.jetbrains.plugins.groovy.codeInspection.cs.GrReplaceMultiAssignmentFix;
import org.jetbrains.plugins.groovy.codeInspection.local.RemoveUnusedGrParameterFix;
import org.jetbrains.plugins.groovy.codeInspection.naming.RenameFix;
import org.jetbrains.plugins.groovy.dsl.InvestigateFix;
@@ -150,4 +151,9 @@ public class GroovyQuickFixFactoryImpl extends GroovyQuickFixFactory {
public IntentionAction createInvestigateFix(String reason) {
return new InvestigateFix(reason);
}
@Override
public GroovyFix createMultipleAssignmentFix(int size) {
return new GrReplaceMultiAssignmentFix(size);
}
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.codeInspection.assignment
package org.jetbrains.plugins.groovy.codeInspection.cs
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
@@ -27,8 +27,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner
import org.jetbrains.plugins.groovy.refactoring.DefaultGroovyVariableNameValidator
import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil
internal val fixVariableName = "storedList"
internal val defaultFixVariableName = "storedList"
class GrReplaceMultiAssignmentFix(val size: Int) : GroovyFix() {
override fun doFix(project: Project, descriptor: ProblemDescriptor) {
@@ -39,7 +41,8 @@ class GrReplaceMultiAssignmentFix(val size: Int) : GroovyFix() {
var initializer = element.text
if (element !is GrReferenceExpression || element.resolve() !is GrVariable) {
val factory = GroovyPsiElementFactory.getInstance(element.project)
val varDefinition = factory.createStatementFromText("def $fixVariableName = ${initializer}")
val fixVariableName = generateVariableName(element)
val varDefinition = factory.createStatementFromText("def ${fixVariableName} = ${initializer}")
grStatementOwner.addStatementBefore(varDefinition, grStatement)
initializer = fixVariableName
}
@@ -47,7 +50,13 @@ class GrReplaceMultiAssignmentFix(val size: Int) : GroovyFix() {
GrInspectionUtil.replaceExpression(element, generateListLiteral(initializer))
}
fun generateListLiteral(varName: String): String {
private fun generateVariableName(expression: GrExpression): String {
val validator = DefaultGroovyVariableNameValidator(expression)
val suggestedNames = GroovyNameSuggestionUtil.suggestVariableNameByType(expression.type, validator)
return if (suggestedNames.isNotEmpty()) suggestedNames[0] else defaultFixVariableName
}
private fun generateListLiteral(varName: String): String {
return (0..(size - 1)).joinToString(", ", "[", "]") { "$varName[$it]" }
}
@@ -833,6 +833,29 @@ def foo() {
'''
}
void testMultiAssignmentWithTypeError() {
testHighlighting'''
import groovy.transform.CompileStatic
@CompileStatic
def foo() {
def list = ["", ""]
def (Integer a, b) = <error>list</error>
}
'''
}
void testMultiAssignmentLiteralWithTypeError() {
testHighlighting'''
import groovy.transform.CompileStatic
@CompileStatic
def foo() {
def (Integer <error>a</error>, b) = ["", ""]
}
'''
}
void testMultiAssignment() {
testHighlighting'''
import groovy.transform.CompileStatic
@@ -295,4 +295,33 @@ class C {
fixture.configureByText '_.groovy', 'C.staticVoidMethod()'
fixture.checkHighlighting()
}
void 'test do not load AST when method has no comment'() {
def file = fixture.tempDirFixture.createFile('classes.groovy', '''\
class C {
static void someMethod() {}
/**
*
*/
static void someMethodWithDocs() {}
}
''')
def psiFile = psiManager.findFile(file) as GroovyFileImpl
assert !psiFile.contentsLoaded
def typeDefinition = psiFile.typeDefinitions.first()
assert !psiFile.contentsLoaded
def method = typeDefinition.findMethodsByName('someMethod', false).first()
assert !psiFile.contentsLoaded
assert method.docComment == null
assert !psiFile.contentsLoaded
def methodWithDocs = typeDefinition.findMethodsByName('someMethodWithDocs', false).first()
assert !psiFile.contentsLoaded
assert methodWithDocs.docComment != null
assert psiFile.contentsLoaded
}
}