Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2017-09-13 18:48:46 +03:00
53 changed files with 594 additions and 200 deletions
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.TestFrameworks;
import com.intellij.execution.*;
import com.intellij.execution.junit2.info.MethodLocation;
import com.intellij.execution.testframework.SourceScope;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.progress.ProgressManager;
@@ -278,7 +279,7 @@ public class JUnitUtil {
return aPackage != null && aPackage.getDirectories(scope).length > 0;
};
return foundCondition.value(TEST5_PACKAGE_FQN);
return ReadAction.compute(() -> foundCondition.value(TEST5_PACKAGE_FQN));
}
public static boolean isTestAnnotated(final PsiMethod method) {
@@ -163,7 +163,8 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
stmt = (PsiStatement)CodeStyleManager.getInstance(psiManager.getProject()).reformat(stmt);
method.getBody().add(stmt);
GenerateMembersUtil.copyAnnotations(methodCandidate.getElement().getModifierList(), method.getModifierList(), SuppressWarnings.class.getName());
GenerateMembersUtil.copyAnnotations(methodCandidate.getElement().getModifierList(), method.getModifierList(),
SuppressWarnings.class.getName(), Override.class.getName());
if (isMethodStatic || modifierList != null && modifierList.hasModifierProperty(PsiModifier.STATIC)) {
PsiUtil.setModifierProperty(method, PsiModifier.STATIC, true);
@@ -16,7 +16,6 @@
package com.intellij.psi;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.search.GlobalSearchScope;
@@ -83,13 +82,17 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
glb = substitutedBoundType;
}
else {
glb = GenericsUtil.getGreatestLowerBound(glb, substitutedBoundType);
glb = getGreatestLowerBound(glb, substitutedBoundType, wildcardType);
}
}
return glb;
}
private static PsiType getGreatestLowerBound(PsiType glb, PsiType bound, Object guardObject) {
return guard.doPreventingRecursion(guardObject, true, () -> GenericsUtil.getGreatestLowerBound(glb, bound));
}
@Override
public boolean equals(Object o) {
if (!(o instanceof PsiCapturedWildcardType)) {
@@ -60,7 +60,7 @@ public class PsiIntersectionType extends PsiType.Stub {
@NotNull
private static PsiType[] flattenAndRemoveDuplicates(@NotNull PsiType[] conjuncts) {
try {
final Set<PsiType> flattenConjuncts = PsiCapturedWildcardType.guard.doPreventingRecursion(conjuncts, true, () -> flatten(conjuncts, ContainerUtil.newLinkedHashSet()));
final Set<PsiType> flattenConjuncts = flatten(conjuncts, ContainerUtil.newLinkedHashSet());
if (flattenConjuncts == null) {
return conjuncts;
}
@@ -0,0 +1,5 @@
class Zoo {
void zoo(String fooBar, String __foo_bar) {
foo<caret>
}
}
@@ -0,0 +1,21 @@
abstract class Bug {
void m1(){
D<?> jobHandler = m();
}
abstract <J extends C<? extends B>> J m();
}
interface B {
}
abstract class C<T extends B> {
}
abstract class D<T extends E> extends C<T> {
}
abstract class E<T extends String> implements B { }
@@ -0,0 +1,17 @@
interface I {
void foo();
}
class A implements I {
@Override
public void foo() {
}
}
class B {
A a;
public void foo() {
a.foo();
}
}
@@ -0,0 +1,14 @@
interface I {
void foo();
}
class A implements I {
@Override
public void foo() {
}
}
class B {
A a;
<caret>
}
@@ -58,6 +58,7 @@ public class DelegateMethodsTest extends LightCodeInsightTestCase {
public void testMultipleOverrideAnnotations() { doTest(); }
public void testStripSuppressWarningsAnnotation() { doTest(); }
public void testDoNotOverrideFinal() { doTest(); }
public void testEnsureCorrectOverride() { doTest(); }
public void testAllowDelegateToFinal() { doTest(); }
public void testDelegateWithSubstitutionOverrides() { doTest(); }
public void testDelegateWithSubstitutionNoOverrides() { doTest(); }
@@ -443,6 +443,10 @@ interface TxANotAnno {}
checkPreferredItems(0, 'fooBar', '_fooBar', 'FooBar')
}
void testDispreferUnderscoredCaseMatch() {
checkPreferredItems(0, 'fooBar', '__foo_bar')
}
void testStatisticsMattersOnNextCompletion() {
configureByFile(getTestName(false) + ".java")
myFixture.completeBasic()
@@ -116,6 +116,7 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
public void testIDEA149774() { doTest(); }
public void testDisjunctionTypes() { doTest(); }
public void testValidIntersectionTypeWithCapturedBounds() { doTest(); }
public void testValidIntersectionTypeWithCapturedBounds1() { doTest(); }
public void testPushErasedStateToArguments() { doTest(); }
public void testStopAtStandaloneConditional() { doTest(); }
public void testTransitiveInferenceVariableDependencies() { doTest(); }
@@ -25,6 +25,7 @@ import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel
import com.intellij.testFramework.LightIdeaTestCase
import com.intellij.testFramework.configureInspections
import com.intellij.testFramework.createProfile
import com.intellij.testFramework.runInInitMode
import junit.framework.TestCase
import org.assertj.core.api.Assertions.assertThat
@@ -33,23 +34,25 @@ class SingleInspectionProfilePanelTest : LightIdeaTestCase() {
// see IDEA-85700
fun testSettingsModification() {
val project = ProjectManager.getInstance().defaultProject
val profile = configureInspections(arrayOf(myInspection), project, testRootDisposable)
runInInitMode {
val project = ProjectManager.getInstance().defaultProject
val profile = configureInspections(arrayOf(myInspection), project, testRootDisposable)
val model = profile.modifiableModel
val panel = SingleInspectionProfilePanel(ProjectInspectionProfileManager.getInstance(project), model)
panel.isVisible = true
panel.reset()
val model = profile.modifiableModel
val panel = SingleInspectionProfilePanel(ProjectInspectionProfileManager.getInstance(project), model)
panel.isVisible = true
panel.reset()
val tool = getInspection(model)
assertEquals("", tool.myAdditionalJavadocTags)
tool.myAdditionalJavadocTags = "foo"
model.setModified(true)
panel.apply()
assertThat(InspectionProfileTest.countInitializedTools(model)).isEqualTo(1)
val tool = getInspection(model)
assertEquals("", tool.myAdditionalJavadocTags)
tool.myAdditionalJavadocTags = "foo"
model.setModified(true)
panel.apply()
assertThat(InspectionProfileTest.countInitializedTools(model)).isEqualTo(1)
assertThat(getInspection(profile).myAdditionalJavadocTags).isEqualTo("foo")
panel.disposeUI()
assertThat(getInspection(profile).myAdditionalJavadocTags).isEqualTo("foo")
panel.disposeUI()
}
}
fun testModifyInstantiatedTool() {
@@ -6,15 +6,16 @@ use Mac::Files qw( NewAliasMinimal );
$name = $ARGV[0];
$bg_pic = $ARGV[1];
$mountName = $ARGV[2];
&writeDSDBEntries("/Volumes/$name/.DS_Store",
&writeDSDBEntries("/Volumes/$mountName/.DS_Store",
&makeEntries(".background", Iloc_xy => [ 560, 170 ]),
&makeEntries(".DS_Store", Iloc_xy => [ 610, 170 ]),
&makeEntries(".fseventsd", Iloc_xy => [ 660, 170 ]),
&makeEntries(".Trashes", Iloc_xy => [ 710, 170 ]),
&makeEntries(" ", Iloc_xy => [ 335, 120 ]),
&makeEntries(".",
BKGD_alias => NewAliasMinimal("/Volumes/$name/.background/$bg_pic"),
BKGD_alias => NewAliasMinimal("/Volumes/$mountName/.background/$bg_pic"),
ICVO => 1,
fwi0_flds => [ 100, 400, 396, 855, "icnv", 0, 0 ],
fwsw => 170,
@@ -37,17 +37,17 @@ echo "Creating unpacked r/w disk image ${VOLNAME}..."
hdiutil create -srcfolder ./${EXPLODED} -volname "$VOLNAME" -anyowners -nospotlight -quiet -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW $2.temp.dmg
# check if the image already mounted
if [ -d "/Volumes/$VOLNAME" ]; then
if [ -d "/Volumes/$1" ]; then
attempt=1
limit=5
while [ $attempt -le $limit ]
do
echo "/Volumes/$VOLNAME - the image is already mounted. This build will wait for unmount for 1 min (up to 5 times)."
echo "/Volumes/$1 - the image is already mounted. This build will wait for unmount for 1 min (up to 5 times)."
sleep 60;
let "attempt += 1"
if [ -d "/Volumes/$VOLNAME" ]; then
if [ $attempt -eq $limit ]; then
echo "/Volumes/$VOLNAME - the image is still mounted. By the reason the build will be stopped."
if [ -d "/Volumes/$1" ]; then
if [ $attempt -ge $limit ]; then
echo "/Volumes/$1 - the image is still mounted. By the reason the build will be stopped."
rm -rf ${EXPLODED}
rm -f $2.temp.dmg
exit 1
@@ -58,16 +58,17 @@ fi
# mount this image
echo "Mounting unpacked r/w disk image..."
device=$(hdiutil attach -readwrite -noverify -noautoopen $2.temp.dmg | egrep '^/dev/' | sed 1q | awk '{print $1.dmg}')
device=$(hdiutil attach -readwrite -noverify -mountpoint /Volumes/"$1" -noautoopen $2.temp.dmg | egrep '^/dev/' | sed 1q | awk '{print $1.dmg}')
echo "Mounted as ${device}."
sleep 10
find /Volumes/"$VOLNAME" -maxdepth 1
find /Volumes/"$1" -maxdepth 1
# set properties
echo "Updating $VOLNAME disk image styles..."
stat /Volumes/"$VOLNAME"/DSStorePlaceHolder || true
rm /Volumes/"$VOLNAME"/DSStorePlaceHolder
perl makedmg.pl "$VOLNAME" ${BG_PIC}
stat /Volumes/"$1"/DSStorePlaceHolder || true
rm /Volumes/"$1"/DSStorePlaceHolder
perl makedmg.pl "$VOLNAME" ${BG_PIC} "$1"
sync;sync;sync
hdiutil detach ${device}
@@ -24,12 +24,64 @@ import java.util.List;
/**
* @see com.intellij.psi.PsiLanguageInjectionHost
* @see MultiHostRegistrar
*/
public interface MultiHostInjector {
ExtensionPointName<MultiHostInjector> MULTIHOST_INJECTOR_EP_NAME = ExtensionPointName.create("com.intellij.multiHostInjector");
/**
* Provides list of places to inject a language to. <br>
*
* For example, to inject "RegExp" language to java string literal, you can override this method with something like this:
* <code><pre>
* class MyRegExpToJavaInjector implements MultiHostInjector {
* void getLanguagesToInject(MultiHostRegistrar registrar, PsiElement context) {
* if (context instanceof PsiLiteralExpression && looksLikeAGoodPlaceToInject(context)) {
* registrar.startInjecting(REGEXP_LANG).addPlace(null,null,context,innerRangeStrippingQuotes(context));
* }
* }
* }
* </pre></code>
*
* Also, we may need to inject into several fragments at once. For example, if we have this really bizarre XML-based DSL:
* <pre>
* {@code
*
* <myDSL>
* <method>
* <name>foo</name>
* <body>System.out.println(42);</body>
* </method>
* </myDSL>
* }
* </pre>
*
* which should be converted to Java:
* <code><pre>class MyDsl { void foo() { System.out.println(42);} }</pre></code>
*
* Then we can inject Java into several places at once - method name and its body:
* <code><pre>
* class MyBizarreDSLInjector implements MultiHostInjector {
* void getLanguagesToInject(MultiHostRegistrar registrar, PsiElement context) {
* if (isMethodTag(context)) {
* registrar.startInjecting(JavaLanguage.INSTANCE);
* // construct class header, method header, inject method name, append code block start
* registrar.addPlace("class MyDsl { void ", "() {", context, rangeForMethodName(context));
* // inject method body, append closing braces to form a valid Java class structure
* registrar.addPlace(null, "}}", context, rangeForBody(context));
* registrar.doneInjecting();
* }
* }
* }
* </pre></code>
*
* Now, then we look at this XML in the editor, "foo" will feel like a method name
* and "System.out.println(42);" will look and feel like a method body - with highlighting, completion, goto definitions etc.
*
*/
void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context);
@NotNull
List<? extends Class<? extends PsiElement>> elementsToInjectIn();
}
@@ -259,14 +259,17 @@ class VirtualFilePointerContainerImpl extends TraceableDisposable implements Vir
return myList.hashCode();
}
@NotNull
protected VirtualFilePointer create(@NotNull VirtualFile file) {
return myVirtualFilePointerManager.create(file, myParent, myListener);
}
@NotNull
protected VirtualFilePointer create(@NotNull String url) {
return myVirtualFilePointerManager.create(url, myParent, myListener);
}
@NotNull
protected VirtualFilePointer duplicate(@NotNull VirtualFilePointer virtualFilePointer) {
return myVirtualFilePointerManager.duplicate(virtualFilePointer, myParent, myListener);
}
@@ -300,5 +303,6 @@ class VirtualFilePointerContainerImpl extends TraceableDisposable implements Vir
assert !myDisposed;
myDisposed = true;
kill(null);
clear();
}
}
@@ -63,14 +63,26 @@ public class CamelHumpMatcher extends PrefixMatcher {
@Override
public boolean prefixMatches(@NotNull final String name) {
if (name.startsWith("_") &&
myPrefix.length() > 0 && Character.isLetter(myPrefix.charAt(0)) &&
CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE == CodeInsightSettings.FIRST_LETTER) {
CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE == CodeInsightSettings.FIRST_LETTER &&
firstLetterCaseDiffers(name)) {
return false;
}
return myMatcher.matches(name);
}
private boolean firstLetterCaseDiffers(String name) {
int nameFirst = skipUnderscores(name);
int prefixFirst = skipUnderscores(myPrefix);
return nameFirst < name.length() &&
prefixFirst < myPrefix.length() &&
caseDiffers(name.charAt(nameFirst), myPrefix.charAt(prefixFirst));
}
private static boolean caseDiffers(char c1, char c2) {
return Character.isLowerCase(c1) != Character.isLowerCase(c2) || Character.isUpperCase(c1) != Character.isUpperCase(c2);
}
@Override
public boolean prefixMatches(@NotNull final LookupElement element) {
return prefixMatchersInternal(element, !element.isCaseSensitive());
@@ -112,8 +112,9 @@ public class ExternalToolPass extends ProgressableTextEditorHighlightingPass {
String shortName = annotator.getPairedBatchInspectionShortName();
if (shortName != null) {
HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
LOG.assertTrue(key != null, "Paired tool '" + shortName + "' not found for external annotator: " + annotator);
if (!profile.isToolEnabled(key, myFile)) continue;
LOG.assertTrue(key != null || ApplicationManager.getApplication().isUnitTestMode(),
"Paired tool '" + shortName + "' not found for external annotator: " + annotator);
if (key == null || !profile.isToolEnabled(key, myFile)) continue; //test should register corresponding paired tool for annotator to run
}
Object collectedInfo = editor != null ? annotator.collectInformation(psiRoot, editor, errorFound) : annotator.collectInformation(psiRoot);
@@ -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.
@@ -529,7 +529,7 @@ public class BraceHighlightingHandler {
myAlarm.addRequest(() -> {
if (myProject.isDisposed()) return;
PsiDocumentManager.getInstance(myProject).performLaterWhenAllCommitted(() -> {
if (!myEditor.getComponent().isShowing()) return;
if (myEditor.isDisposed() || !myEditor.getComponent().isShowing()) return;
Rectangle viewRect = myEditor.getScrollingModel().getVisibleArea();
if (y < viewRect.y) {
int start = lbraceStart;
@@ -464,6 +464,8 @@ public class IdeDocumentHistoryImpl extends IdeDocumentHistory implements Projec
}
private PlaceInfo createPlaceInfo(@NotNull final FileEditor fileEditor, final FileEditorProvider fileProvider) {
if (!fileEditor.isValid()) return null;
final VirtualFile file = myEditorManager.getFile(fileEditor);
LOG.assertTrue(file != null);
@@ -30,7 +30,7 @@ com.intellij.apacheConfig 144.3713 143.2287.2 143.381.48 142.5266 141.388 139.78
org.intellij.clojure 0.2.1.178
net.nicoulaj.idea.markdown 0.9.7 0.9.6 0.9.5 0.9.4 0.9.3 0.9.2 0.9.1 0.8.3 0.8.2 0.8.1 0.8 0.7 0.6.1 0.6 0.5.1 0.5 0.4 0.3 0.2 0.1
zielu.gittoolbox 13.1.0 13.5.2
mobi.hsz.idea.gitignore 1.2 1.3 1.3.3 1.4.1 1.5 1.6 1.7.5 1.7.6 2.0.4
mobi.hsz.idea.gitignore 1.2 1.3 1.3.3 1.4.1 1.5 1.6 1.7.5 1.7.6 2.0.4 2.1.1 2.2.0
com.vladsch.idea.multimarkdown 1.4.2 1.4.7
com.jetbrains.chronon 134.1221 134.1414 134.1618 135.1291 135.476 135.666
ArgoUML.Integration 0.1.1 0.1.2
@@ -323,8 +323,8 @@
</group>
<group id="FileHistory.KeymapGroup" text="File History">
<reference id="Vcs.ShowHistoryForBlock"/>
<reference id="Vcs.GetVersion"/>
<reference id="FileHistory.AnnotateRevision"/>
<add-to-group group-id="Vcs.KeymapGroup"/>
</group>
@@ -339,6 +339,7 @@
<reference ref="Show.Current.Revision"/>
<reference ref="Vcs.ShowHistoryForBlock"/>
<reference ref="Vcs.ShowTabbedFileHistory"/>
<reference ref="Vcs.ShowHistoryForRevision"/>
<reference ref="VcsHistory.ShowAllAffected"/>
<reference ref="Compare.Specified"/>
<reference ref="Compare.Selected"/>
@@ -46,15 +46,12 @@ public class UsageViewTreeTest extends UsefulTestCase {
super.setUp();
myFixtureBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder("moduleGroups");
myFixture = IdeaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(myFixtureBuilder.getFixture());
myDisposable = new Disposable() {
@Override
public void dispose() {
try {
myFixture.tearDown();
}
catch (Exception e) {
throw new RuntimeException(e);
}
myDisposable = () -> {
try {
myFixture.tearDown();
}
catch (Exception e) {
throw new RuntimeException(e);
}
};
myFixture.setUp();
@@ -72,7 +69,7 @@ public class UsageViewTreeTest extends UsefulTestCase {
public void testSimpleModule() throws Exception {
addModule("main");
PsiFile file = myFixture.addFileToProject("main/A.txt", "hello");
Usage[] usages = new Usage[] {new UsageInfo2UsageAdapter(new UsageInfo(file))};
Usage[] usages = {new UsageInfo2UsageAdapter(new UsageInfo(file))};
assertUsageViewStructureEquals(usages, "Usage (1 usage)\n" +
" Non-code usages (1 usage)\n" +
" main (1 usage)\n" +
@@ -83,7 +80,7 @@ public class UsageViewTreeTest extends UsefulTestCase {
public void testModuleWithQualifiedName() throws Exception {
addModule("xxx.main");
PsiFile file = myFixture.addFileToProject("xxx.main/A.txt", "hello");
Usage[] usages = new Usage[] {new UsageInfo2UsageAdapter(new UsageInfo(file))};
Usage[] usages = {new UsageInfo2UsageAdapter(new UsageInfo(file))};
UsageViewSettings.getInstance().FLATTEN_MODULES = false;
ModuleGroupTestsKt.runWithQualifiedModuleNamesEnabled(() -> {
assertUsageViewStructureEquals(usages, "Usage (1 usage)\n" +
@@ -16,21 +16,19 @@
package com.intellij.util;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class AlarmTest extends PlatformTestCase {
public void testTwoAddsWithZeroDelayMustExecuteSequentially() throws Exception {
@@ -93,7 +91,12 @@ public class AlarmTest extends PlatformTestCase {
UIUtil.dispatchAllInvocationEvents();
}
Map<Thread, StackTraceElement[]> after = Thread.getAllStackTraces();
assertTrue("before: "+before.size()+"; after: "+after.size(), after.size() - before.size() < 10);
Map<Thread, List<StackTraceElement>> diff = new HashMap<>();
after.forEach((key, value) -> diff.put(key, Arrays.asList(value)));
before.keySet().forEach(diff::remove);
if (!(after.size() - before.size() < 10)) {
fail("before: "+before.size()+"; after: "+after.size()+"Diff:\n"+diff);
}
}
public void testManyAlarmsDoNotStartTooManyThreads() {
@@ -20,6 +20,7 @@ import com.intellij.openapi.components.ExpandMacroToPathMap;
import com.intellij.openapi.components.impl.ComponentManagerImpl;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
import com.intellij.openapi.fileEditor.impl.EditorHistoryManager;
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
import com.intellij.openapi.fileEditor.impl.FileEditorProviderManagerImpl;
import com.intellij.openapi.util.Disposer;
@@ -73,6 +74,9 @@ public abstract class FileEditorManagerTestCase extends LightPlatformCodeInsight
myOldDockContainers = null;
((ComponentManagerImpl)getProject()).registerComponentInstance(FileEditorManager.class, myOldManager);
myManager.closeAllFiles();
for (VirtualFile file : EditorHistoryManager.getInstance(getProject()).getFiles()) {
EditorHistoryManager.getInstance(getProject()).removeFile(file);
}
((FileEditorProviderManagerImpl)FileEditorProviderManager.getInstance()).clearSelectedProviders();
}
finally {
@@ -82,11 +86,6 @@ public abstract class FileEditorManagerTestCase extends LightPlatformCodeInsight
}
}
@Override
protected boolean isWriteActionRequired() {
return false;
}
protected VirtualFile getFile(String path) {
String fullPath = getTestDataPath() + path;
VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath);
@@ -15,6 +15,7 @@
*/
package com.intellij.testFramework;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.RunResult;
@@ -34,6 +35,7 @@ import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -247,6 +249,20 @@ public class PsiTestUtil {
public static void addLibrary(Module module, String libName, String libPath, String... jarArr) {
ModuleRootModificationUtil.updateModel(module, model -> addLibrary(module, model, libName, libPath, jarArr));
}
public static void addLibrary(@NotNull Disposable parent, Module module, String libName, String libPath, String... jarArr) {
Ref<Library> ref = new Ref<>();
ModuleRootModificationUtil.updateModel(module, model -> ref.set(addLibrary(module, model, libName, libPath, jarArr)));
Disposer.register(parent, () -> {
Library library = ref.get();
ModuleRootModificationUtil.updateModel(module, model -> model.removeOrderEntry(model.findLibraryOrderEntry(library)));
WriteCommandAction.runWriteCommandAction(null, ()-> {
LibraryTable table = ProjectLibraryTable.getInstance(module.getProject());
LibraryTable.ModifiableModel model = table.getModifiableModel();
model.removeLibrary(library);
model.commit();
});
});
}
public static void addProjectLibrary(Module module, String libName, List<String> classesRootPaths) {
List<VirtualFile> roots = ContainerUtil.map(classesRootPaths, path -> VirtualFileManager.getInstance().refreshAndFindFileByUrl(VfsUtil.getUrlForLibraryRoot(new File(path))));
@@ -263,6 +279,7 @@ public class PsiTestUtil {
return result.get();
}
@NotNull
private static Library addProjectLibrary(Module module,
ModifiableRootModel model,
String libName,
@@ -302,11 +319,12 @@ public class PsiTestUtil {
return result.getResultObject();
}
public static void addLibrary(Module module,
ModifiableRootModel model,
String libName,
String libPath,
String... jarArr) {
@NotNull
public static Library addLibrary(Module module,
ModifiableRootModel model,
String libName,
String libPath,
String... jarArr) {
List<VirtualFile> classesRoots = new ArrayList<>();
for (String jar : jarArr) {
if (!libPath.endsWith("/") && !jar.startsWith("/")) {
@@ -323,7 +341,7 @@ public class PsiTestUtil {
assert root != null : "Library root folder not found: " + path + "!/";
classesRoots.add(root);
}
addProjectLibrary(module, model, libName, classesRoots, Collections.emptyList());
return addProjectLibrary(module, model, libName, classesRoots, Collections.emptyList());
}
public static void addLibrary(Module module,
@@ -23,6 +23,8 @@ import com.intellij.codeInspection.ex.*
import com.intellij.openapi.Disposable
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.profile.codeInspection.BaseInspectionProfileManager
import com.intellij.profile.codeInspection.InspectionProfileManager
import com.intellij.profile.codeInspection.InspectionProjectProfileManager
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager
import com.intellij.testFramework.fixtures.impl.GlobalInspectionContextForTests
@@ -35,21 +37,21 @@ import java.util.*
fun configureInspections(tools: Array<InspectionProfileEntry>,
project: Project,
parentDisposable: Disposable): InspectionProfileImpl {
runInInitMode {
val profile = createSimple(UUID.randomUUID().toString(), project, tools.mapSmart { InspectionToolRegistrar.wrapTool(it) })
val profileManager = ProjectInspectionProfileManager.getInstance(project)
// we don't restore old project profile because in tests it must be in any case null - app default profile
Disposer.register(parentDisposable, Disposable {
profileManager.deleteProfile(profile)
profileManager.setCurrentProfile(null)
clearAllToolsIn(BASE_PROFILE)
})
val profile = InspectionProfileImpl(UUID.randomUUID().toString(),
{ tools.mapSmart { InspectionToolRegistrar.wrapTool(it) } },
InspectionProfileManager.getInstance() as BaseInspectionProfileManager)
val profileManager = ProjectInspectionProfileManager.getInstance(project)
// we don't restore old project profile because in tests it must be in any case null - app default profile
Disposer.register(parentDisposable, Disposable {
profileManager.deleteProfile(profile)
profileManager.setCurrentProfile(null)
clearAllToolsIn(BASE_PROFILE)
})
profileManager.addProfile(profile)
profile.initInspectionTools(project)
profileManager.setCurrentProfile(profile)
return profile
}
profileManager.addProfile(profile)
profileManager.setCurrentProfile(profile)
enableInspectionTools(project, parentDisposable, *tools)
return profile
}
@JvmOverloads
@@ -303,6 +303,6 @@ public class UnsafeWeakList<T> extends AbstractList<T> {
}
private T throwNotRandomAccess() {
throw new IncorrectOperationException("UnsafeWeakList is not RandomAccess, use list.iterator() instead.");
throw new IncorrectOperationException("index/size-based operations in UnsafeWeakList are not supported because they don't make sense in the presence of weak references. Use list.iterator() (which retains elements to avoid sudden GC) instead.");
}
}
@@ -137,7 +137,6 @@ public class CoverageDataManagerImpl extends CoverageDataManager {
@Override
public void readExternal(Element element) throws InvalidDataException {
//noinspection unchecked
for (Element suiteElement : element.getChildren(SUITE)) {
final CoverageRunner coverageRunner = BaseCoverageSuite.readRunnerAttribute(suiteElement);
// skip unknown runners
+2
View File
@@ -26,6 +26,8 @@
<coverageRunner implementation="com.intellij.coverage.JaCoCoCoverageRunner"/>
<coverageEngine implementation="com.intellij.coverage.JavaCoverageEngine" order = "last"/>
<projectViewNodeDecorator implementation="com.intellij.coverage.CoverageProjectViewClassNodeDecorator"/>
<projectService serviceImplementation="com.intellij.coverage.JavaCoverageOptionsProvider"/>
<coverageOptions implementation="com.intellij.coverage.JavaCoverageOptions"/>
<projectService serviceInterface="com.intellij.coverage.JavaCoverageAnnotator"
serviceImplementation="com.intellij.coverage.JavaCoverageAnnotator"/>
@@ -654,8 +654,11 @@ public class JavaCoverageEngine extends CoverageEngine {
@Override
public boolean isGeneratedCode(Project project, String qualifiedName, Object lineData) {
PsiClass psiClass = ReadAction.compute(() -> ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), qualifiedName));
return PackageAnnotator.isGeneratedDefaultConstructor(psiClass, ((LineData)lineData).getMethodSignature());
if (JavaCoverageOptionsProvider.getInstance(project).ignoreEmptyPrivateConstructors()) {
PsiClass psiClass = ReadAction.compute(() -> ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), qualifiedName));
return PackageAnnotator.isGeneratedDefaultConstructor(psiClass, ((LineData)lineData).getMethodSignature());
}
return super.isGeneratedCode(project, qualifiedName, lineData);
}
@Override
@@ -0,0 +1,84 @@
/*
* 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.
* 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 com.intellij.coverage;
import com.intellij.ui.IdeBorderFactory;
import javax.swing.*;
import java.awt.*;
public class JavaCoverageOptions extends CoverageOptions {
private final JavaCoverageOptionsProvider myCoverageOptionsProvider;
private JavaCoverageOptionsEditor myEditor;
public JavaCoverageOptions(JavaCoverageOptionsProvider coverageOptionsProvider) {
myCoverageOptionsProvider = coverageOptionsProvider;
}
@Override
public JComponent getComponent() {
myEditor = new JavaCoverageOptionsEditor();
return myEditor.getComponent();
}
@Override
public boolean isModified() {
return myEditor.isModified(myCoverageOptionsProvider);
}
@Override
public void apply() {
myEditor.apply(myCoverageOptionsProvider);
}
@Override
public void reset() {
myEditor.reset(myCoverageOptionsProvider);
}
@Override
public void disposeUIResources() {
myEditor = null;
}
private static class JavaCoverageOptionsEditor {
private JPanel myPanel = new JPanel(new BorderLayout(0, 10));
private JCheckBox myCheckBox = new JCheckBox("Ignore empty private and implicit constructors", true);
public JavaCoverageOptionsEditor() {
myPanel.setBorder(IdeBorderFactory.createTitledBorder("Java coverage"));
myPanel.add(myCheckBox, BorderLayout.NORTH);
}
public JPanel getComponent() {
return myPanel;
}
public boolean isModified(JavaCoverageOptionsProvider provider) {
return myCheckBox.isSelected() != provider.ignoreEmptyPrivateConstructors();
}
public void apply(JavaCoverageOptionsProvider provider) {
provider.setIgnoreEmptyPrivateConstructors(myCheckBox.isSelected());
}
public void reset(JavaCoverageOptionsProvider provider) {
myCheckBox.setSelected(provider.ignoreEmptyPrivateConstructors());
}
}
}
@@ -0,0 +1,60 @@
/*
* 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.
* 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 com.intellij.coverage;
import com.intellij.openapi.components.*;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.Nullable;
@State(
name = "JavaCoverageOptionsProvider",
storages = {
@Storage(StoragePathMacros.WORKSPACE_FILE)
}
)
public class JavaCoverageOptionsProvider implements PersistentStateComponent<JavaCoverageOptionsProvider.State> {
private State myState = new State();
public static JavaCoverageOptionsProvider getInstance(Project project) {
return ServiceManager.getService(project, JavaCoverageOptionsProvider.class);
}
public void setIgnoreEmptyPrivateConstructors(boolean state) {
myState.myIgnoreEmptyPrivateConstructors = state;
}
public boolean ignoreEmptyPrivateConstructors() {
return myState.myIgnoreEmptyPrivateConstructors;
}
@Nullable
@Override
public JavaCoverageOptionsProvider.State getState() {
return myState;
}
@Override
public void loadState(JavaCoverageOptionsProvider.State state) {
myState.myIgnoreEmptyPrivateConstructors = state.myIgnoreEmptyPrivateConstructors;
}
public static class State {
public boolean myIgnoreEmptyPrivateConstructors = true;
}
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -37,6 +38,7 @@ import com.intellij.rt.coverage.data.LineData;
import com.intellij.rt.coverage.data.ProjectData;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.SmartHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
import org.jetbrains.jps.model.java.JavaSourceRootType;
@@ -57,12 +59,14 @@ public class PackageAnnotator {
private final Project myProject;
private final PsiManager myManager;
private final CoverageDataManager myCoverageManager;
private final boolean myIgnoreEmptyPrivateConstructors;
public PackageAnnotator(final PsiPackage aPackage) {
myPackage = aPackage;
myProject = myPackage.getProject();
myManager = PsiManager.getInstance(myProject);
myCoverageManager = CoverageDataManager.getInstance(myProject);
myIgnoreEmptyPrivateConstructors = JavaCoverageOptionsProvider.getInstance(myProject).ignoreEmptyPrivateConstructors();
}
public interface Annotator {
@@ -455,7 +459,7 @@ public class PackageAnnotator {
touchedClass = true;
}
if (isGeneratedDefaultConstructor(psiClass, (String)nameAndSig)) {
if (myIgnoreEmptyPrivateConstructors && isGeneratedDefaultConstructor(psiClass, (String)nameAndSig)) {
continue;
}
@@ -505,16 +509,16 @@ public class PackageAnnotator {
* in the bytecode, so we need to look at the PSI to see if the class defines such a constructor.
*/
public static boolean isGeneratedDefaultConstructor(@Nullable final PsiClass aClass, String nameAndSig) {
if (aClass == null) {
return false;
}
if (DEFAULT_CONSTRUCTOR_NAME_SIGNATURE.equals(nameAndSig)) {
return hasGeneratedOrEmptyPrivateConstructor(aClass);
}
return false;
}
private static boolean hasGeneratedOrEmptyPrivateConstructor(@Nullable final PsiClass aClass) {
if (aClass == null) {
return false;
}
private static boolean hasGeneratedOrEmptyPrivateConstructor(@NotNull final PsiClass aClass) {
return ReadAction.compute(() -> {
PsiMethod[] constructors = aClass.getConstructors();
if (constructors.length == 1 && constructors[0].hasModifierProperty(PsiModifier.PRIVATE)) {
@@ -563,6 +567,6 @@ public class PackageAnnotator {
if (coverageSuite == null) return false;
return SourceLineCounterUtil
.collectNonCoveredClassInfo(classCoverageInfo, packageCoverageInfo, content, coverageSuite.isTracingEnabled(),
psiClass);
myIgnoreEmptyPrivateConstructors ? description -> !isGeneratedDefaultConstructor(psiClass, description) : Condition.TRUE);
}
}
@@ -17,6 +17,7 @@ package com.intellij.coverage;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.ClassUtil;
@@ -29,11 +30,10 @@ import java.util.List;
import java.util.Set;
public class SourceLineCounterUtil {
public static boolean collectNonCoveredClassInfo(final PackageAnnotator.ClassCoverageInfo classCoverageInfo,
final PackageAnnotator.PackageCoverageInfo packageCoverageInfo,
byte[] content,
public static boolean collectNonCoveredClassInfo(final PackageAnnotator.ClassCoverageInfo classCoverageInfo,
final PackageAnnotator.PackageCoverageInfo packageCoverageInfo, byte[] content,
final boolean excludeLines,
final PsiClass psiClass) {
final Condition<String> includeDescriptionCondition) {
if (content == null) return false;
ClassReader reader = new ClassReader(content, 0, content.length);
@@ -42,13 +42,13 @@ public class SourceLineCounterUtil {
Set<Object> descriptions = new HashSet<>();
TIntObjectHashMap<?> lines = counter.getSourceLines();
lines.forEachEntry((line, description) -> {
if (!PackageAnnotator.isGeneratedDefaultConstructor(psiClass, (String)description)) {
classCoverageInfo.totalLineCount ++;
packageCoverageInfo.totalLineCount ++;
descriptions.add(description);
}
return true;
});
if (includeDescriptionCondition.value((String)description)) {
classCoverageInfo.totalLineCount++;
packageCoverageInfo.totalLineCount++;
descriptions.add(description);
}
return true;
});
classCoverageInfo.totalMethodCount += descriptions.size();
packageCoverageInfo.totalMethodCount += descriptions.size();
@@ -68,10 +68,16 @@ public class SourceLineCounterUtil {
reader.accept(collector, 0);
String qualifiedName = reader.getClassName();
PsiClass psiClass = ReadAction.compute(() -> ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), qualifiedName));
boolean ignoreEmptyPrivateConstructors = JavaCoverageOptionsProvider.getInstance(project).ignoreEmptyPrivateConstructors();
PsiClass psiClass = ignoreEmptyPrivateConstructors
? ReadAction.compute(() -> ClassUtil.findPsiClassByJVMName(PsiManager.getInstance(project), qualifiedName))
: null;
Condition<String> includeDescriptionCondition = ignoreEmptyPrivateConstructors
? description -> !PackageAnnotator.isGeneratedDefaultConstructor(psiClass, description)
: Condition.TRUE;
TIntObjectHashMap<?> lines = collector.getSourceLines();
lines.forEachEntry((line, description) -> {
if (!PackageAnnotator.isGeneratedDefaultConstructor(psiClass, (String)description)) {
if (includeDescriptionCondition.value((String)description)) {
line--;
uncoveredLines.add(line);
}
@@ -415,20 +415,10 @@ public class ControlFlowUtils {
}
private static boolean statementIsLastInBlock(@NotNull GrStatementOwner block, @NotNull GrStatement statement) {
final GrStatement[] statements = block.getStatements();
for (int i = statements.length - 1; i >= 0; i--) {
final GrStatement childStatement = statements[i];
if (statement.equals(childStatement)) {
return true;
}
if (!(childStatement instanceof GrReturnStatement)) {
return false;
}
}
return false;
GrStatement lastStatement = ArrayUtil.getLastElement(block.getStatements());
return statement == lastStatement;
}
@NotNull
public static List<GrStatement> collectReturns(@Nullable PsiElement element) {
return collectReturns(element, element instanceof GrCodeBlock || element instanceof GroovyFile);
@@ -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.
@@ -18,14 +18,11 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,18 +35,16 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrArrayD
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrBuiltInTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrAnonymousClassType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClassReferenceType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.GrCallExpressionImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.GrInnerClassConstructorUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.typing.GrTypeCalculator;
import java.util.ArrayList;
import java.util.List;
@@ -59,33 +54,6 @@ import java.util.List;
*/
public class GrNewExpressionImpl extends GrCallExpressionImpl implements GrNewExpression {
private static final Function<GrNewExpressionImpl,PsiType> MY_TYPE_CALCULATOR =
(NullableFunction<GrNewExpressionImpl, PsiType>)newExpression -> {
final GrAnonymousClassDefinition anonymous = newExpression.getAnonymousClassDefinition();
if (anonymous != null) {
return new GrAnonymousClassType(LanguageLevel.JDK_1_5, anonymous.getResolveScope(),
JavaPsiFacade.getInstance(newExpression.getProject()), anonymous);
}
PsiType type = null;
GrCodeReferenceElement refElement = newExpression.getReferenceElement();
if (refElement != null) {
type = new GrClassReferenceType(refElement);
}
else {
GrBuiltInTypeElement builtin = newExpression.findChildByClass(GrBuiltInTypeElement.class);
if (builtin != null) type = builtin.getType();
}
if (type != null) {
for (int i = 0; i < newExpression.getArrayCount(); i++) {
type = type.createArrayType();
}
return type;
}
return null;
};
private static final ResolveCache.PolyVariantResolver<MyFakeReference> RESOLVER = new ResolveCache.PolyVariantResolver<MyFakeReference>() {
@NotNull
@Override
@@ -111,7 +79,7 @@ public class GrNewExpressionImpl extends GrCallExpressionImpl implements GrNewEx
@Override
public PsiType getType() {
return TypeInferenceHelper.getCurrentContext().getExpressionType(this, MY_TYPE_CALCULATOR);
return TypeInferenceHelper.getCurrentContext().getExpressionType(this, GrTypeCalculator::getTypeFromCalculators);
}
@Override
@@ -69,6 +69,11 @@ public class GrDefaultMethodComparator extends GrMethodComparator {
PsiParameter[] params1 = method1.getParameterList().getParameters();
PsiParameter[] params2 = method2.getParameterList().getParameters();
if (argTypes != null && argTypes.length == 0) {
if (params2.length == 1 && params2[0].getType() instanceof PsiArrayType) return true;
}
if (argTypes == null && params1.length != params2.length) return false;
if (params1.length < params2.length) {
@@ -0,0 +1,52 @@
/*
* 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.
* 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.jetbrains.plugins.groovy.lang.typing
import com.intellij.pom.java.LanguageLevel
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiType
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrBuiltInTypeElement
import org.jetbrains.plugins.groovy.lang.psi.impl.GrAnonymousClassType
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClassReferenceType
class DefaultNewExpressionTypeCalculator : GrTypeCalculator<GrNewExpression> {
override fun getType(expression: GrNewExpression): PsiType? {
return getAnonymousType(expression) ?:
getRegularType(expression)
}
private fun getAnonymousType(expression: GrNewExpression): PsiType? {
val anonymous = expression.anonymousClassDefinition ?: return null
return GrAnonymousClassType(
LanguageLevel.JDK_1_5,
anonymous.resolveScope,
JavaPsiFacade.getInstance(expression.project),
anonymous
)
}
private fun getRegularType(expression: GrNewExpression): PsiType? {
var type: PsiType = expression.referenceElement?.let { GrClassReferenceType(it) } ?:
(expression.typeElement as? GrBuiltInTypeElement)?.type ?:
return null
repeat(expression.arrayCount) {
type = type.createArrayType()
}
return type
}
}
+2
View File
@@ -170,6 +170,8 @@
<typeCalculator forClass="org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall"
implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.GrDescriptorReturnTypeCalculator"/>
<typeCalculator forClass="org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression"
implementationClass="org.jetbrains.plugins.groovy.lang.typing.DefaultNewExpressionTypeCalculator" order="last"/>
<typeCalculator forClass="org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap" order="last"
implementationClass="org.jetbrains.plugins.groovy.lang.typing.DefaultListOrMapTypeCalculator"/>
<typeCalculator forClass="org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty" order="last"
@@ -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.
@@ -292,6 +292,21 @@ for(i in []) {
print 4
}
}
for (i in []) {
if (cond) {
continue
}
return
}
for (i in []) {
if (cond) {
<warning descr="continue is unnecessary as the last statement in a loop">continue</warning>
} else {
return
}
}
''', GroovyUnnecessaryContinueInspection)
}
@@ -19,6 +19,7 @@ package org.jetbrains.plugins.groovy.lang.resolve
import com.intellij.psi.*
import com.intellij.psi.util.PropertyUtil
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression
@@ -2292,4 +2293,19 @@ new SomeClass().si<caret>ze()
''', GrMethodImpl
}
void 'test prefer varargs in no-arg call'() {
def file = fixture.configureByText('_.groovy', '''\
class A {
A(String... a) { println "varargs" }
A(A a) { println "single" }
}
new A()
''') as GroovyFile
def expression = file.statements.last() as GrNewExpression
def resolved = expression.resolveMethod()
assert resolved instanceof GrMethod
assert resolved.isVarArgs()
}
}
@@ -26,6 +26,8 @@ import com.intellij.ide.structureView.newStructureView.StructureViewComponent
import com.intellij.ide.util.treeView.AbstractTreeNode
import com.intellij.openapi.application.PluginPathManager
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
import com.intellij.openapi.fileEditor.impl.EditorHistoryManager
import com.intellij.openapi.fileTypes.StdFileTypes
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.io.FileUtil
@@ -45,6 +47,14 @@ class IdeaDecompilerTest : LightCodeInsightFixtureTestCase() {
myFixture.testDataPath = "${PluginPathManager.getPluginHomePath("java-decompiler")}/plugin/testData"
}
override fun tearDown() {
FileEditorManagerEx.getInstanceEx(project).closeAllFiles()
for (file in EditorHistoryManager.getInstance(project).files) {
EditorHistoryManager.getInstance(project).removeFile(file)
}
super.tearDown()
}
fun testSimple() {
val file = getTestFile("${PlatformTestUtil.getRtJarPath()}!/java/lang/String.class")
val decompiled = IdeaDecompiler().getText(file).toString()
@@ -15,15 +15,11 @@
*/
package com.intellij.tasks.generic;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.XmlElementFactory;
import com.intellij.psi.xml.XmlTag;
import com.intellij.tasks.Task;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.LanguageTextField;
@@ -31,7 +27,6 @@ import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.FormBuilder;
import com.intellij.util.xmlb.annotations.Tag;
import com.intellij.xml.util.XmlUtil;
import org.intellij.lang.regexp.RegExpLanguage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -117,14 +112,6 @@ public final class RegExResponseHandler extends ResponseHandler {
for (int i = 0; i < max && matcher.find(); i++) {
String id = matcher.group(placeholders.indexOf(ID_PLACEHOLDER) + 1);
String summary = matcher.group(placeholders.indexOf(SUMMARY_PLACEHOLDER) + 1);
// temporary workaround to make AssemblaIntegrationTestPass
final String finalSummary = summary;
summary = ReadAction.compute(() -> {
XmlElementFactory factory = XmlElementFactory.getInstance(ProjectManager.getInstance().getDefaultProject());
XmlTag text = factory.createTagFromText("<a>" + finalSummary + "</a>");
String trimmedText = text.getValue().getTrimmedText();
return XmlUtil.decode(trimmedText);
});
tasks.add(new GenericTask(id, summary, myRepository));
}
return tasks.toArray(new Task[tasks.size()]);
@@ -157,8 +157,6 @@
</actions>
<extensions defaultExtensionNs="com.intellij">
<projectService serviceInterface="com.intellij.codeInsight.documentation.DocumentationManager"
serviceImplementation="com.jetbrains.edu.learning.StudyDocumentationManager" overrides="true"/>
<applicationConfigurable groupId="tools" instance="com.jetbrains.edu.learning.settings.StudyConfigurable"
id="com.jetbrains.edu.learning.settings.StudyConfigurable"
displayName="Education"/>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 B

After

Width:  |  Height:  |  Size: 423 B

@@ -105,6 +105,9 @@
<projectService serviceImplementation="com.jetbrains.python.findUsages.PyFindUsagesOptions"/>
<projectService serviceInterface="com.intellij.codeInsight.documentation.DocumentationManager"
serviceImplementation="com.jetbrains.python.PyDocumentationManager" overrides="true"/>
<applicationService serviceInterface="com.jetbrains.python.packaging.PyPackageService"
serviceImplementation="com.jetbrains.python.packaging.PyPackageService"/>
<applicationService serviceInterface="com.jetbrains.python.packaging.PyCondaPackageService"
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.jetbrains.edu.learning;
package com.jetbrains.python;
import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.codeInsight.documentation.DocumentationManager;
@@ -26,15 +26,17 @@ import com.intellij.openapi.wm.WindowManager;
import java.awt.*;
public class StudyDocumentationManager extends DocumentationManager {
public class PyDocumentationManager extends DocumentationManager {
public StudyDocumentationManager(Project project, ActionManager manager, TargetElementUtil targetElementUtil) {
public PyDocumentationManager(Project project, ActionManager manager, TargetElementUtil targetElementUtil) {
super(project, manager, targetElementUtil);
}
@Override
protected void setToolwindowDefaultState() {
final Rectangle rectangle = WindowManager.getInstance().getIdeFrame(myProject).suggestChildFrameBounds();
myToolWindow.setDefaultState(ToolWindowAnchor.RIGHT, ToolWindowType.DOCKED, new Rectangle(rectangle.width/2, rectangle.height));
myToolWindow.setDefaultState(ToolWindowAnchor.RIGHT, ToolWindowType.DOCKED, new Rectangle(rectangle.width/4, rectangle.height));
myToolWindow.setType(ToolWindowType.DOCKED, null);
myToolWindow.setAutoHide(false);
}
}
@@ -32,7 +32,10 @@ import com.intellij.openapi.options.FontSize;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.ToolWindowType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiManager;
import com.intellij.util.ui.UIUtil;
@@ -52,8 +55,6 @@ public class PySciViewAction extends ToggleAction implements DumbAware {
private static final String TEXT_SCI_VIEW = "Scientific Mode";
private boolean wasConsoleVisible = false;
private ToolWindowType myDocumentationType = ToolWindowType.FLOATING;
private boolean myDocumentationAutoHide = true;
public static final String ACTION_ID = "PySciView";
private ToolWindowType myDataViewType = ToolWindowType.FLOATING;
@@ -135,14 +136,6 @@ public class PySciViewAction extends ToggleAction implements DumbAware {
}
setDocFontSize();
final ToolWindow window = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.DOCUMENTATION);
if (window != null) {
window.setAnchor(ToolWindowAnchor.RIGHT, null);
myDocumentationType = window.getType();
myDocumentationAutoHide = window.isAutoHide();
window.setType(ToolWindowType.DOCKED, null);
window.setAutoHide(false);
}
}
private static void setDocFontSize() {
@@ -167,8 +160,6 @@ public class PySciViewAction extends ToggleAction implements DumbAware {
final ToolWindow window = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.DOCUMENTATION);
if (window != null) {
window.setType(myDocumentationType, null);
window.setAutoHide(myDocumentationAutoHide);
DocumentationManager.getInstance(project).restorePopupBehavior();
final JBPopup hint = DocumentationManager.getInstance(project).getDocInfoHint();
if (hint != null) {
@@ -23,6 +23,7 @@ import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.testFramework.PsiTestUtil;
import com.jetbrains.python.documentation.PyDocumentationSettings;
import com.jetbrains.python.documentation.docstrings.DocStringFormat;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.psi.LanguageLevel;
@@ -1067,7 +1068,7 @@ public class PythonCompletionTest extends PyTestCase {
"@six.add_metaclass(M)\n" +
"class C(object):\n" +
" def foo(self):\n" +
" C.ba<caret>x()");
" C.ba<caret>()");
assertNotNull(suggested);
assertContainsElements(suggested, "baz");
@@ -1081,7 +1082,7 @@ public class PythonCompletionTest extends PyTestCase {
"@a_m(M)\n" +
"class C(object):\n" +
" def foo(self):\n" +
" C.ba<caret>x()");
" C.ba<caret>()");
assertNotNull(suggested);
assertContainsElements(suggested, "baz");
@@ -16,6 +16,8 @@
package com.jetbrains.python.pyi;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.jetbrains.python.fixtures.PyTestCase;
@@ -27,6 +29,18 @@ import org.jetbrains.annotations.NotNull;
* @author vlan
*/
public class PyiInspectionsTest extends PyTestCase {
private Disposable myRootsDisposable;
@Override
protected void tearDown() throws Exception {
if (myRootsDisposable != null) {
Disposer.dispose(myRootsDisposable);
myRootsDisposable = null;
}
super.tearDown();
}
private void doTestByExtension(@NotNull Class<? extends LocalInspectionTool> inspectionClass, @NotNull String extension) {
doTestByFileName(inspectionClass, getTestName(false) + extension);
}
@@ -106,7 +120,7 @@ public class PyiInspectionsTest extends PyTestCase {
}
public void testPyiRelativeImports() {
PyiTypeTest.addPyiStubsToContentRoot(myFixture);
myRootsDisposable = PyiTypeTest.addPyiStubsToContentRoot(myFixture);
doTestByFileName(PyUnresolvedReferencesInspection.class, "package_with_stub_in_path/a.pyi");
}
}
@@ -15,8 +15,11 @@
*/
package com.jetbrains.python.pyi;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.StandardFileSystems;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
@@ -35,12 +38,23 @@ import org.jetbrains.annotations.Nullable;
* @author vlan
*/
public class PyiTypeTest extends PyTestCase {
public static void addPyiStubsToContentRoot(CodeInsightTestFixture fixture) {
private Disposable myDisposable;
// return Disposable which undoes configuration
public static Disposable addPyiStubsToContentRoot(CodeInsightTestFixture fixture) {
final String path = fixture.getTestDataPath() + "/pyi/pyiStubs";
final VirtualFile file = StandardFileSystems.local().refreshAndFindFileByPath(path);
assertNotNull(file);
file.refresh(false, true);
ModuleRootModificationUtil.addContentRoot(fixture.getModule(), path);
return ()->ModuleRootModificationUtil.updateModel(fixture.getModule(), model -> {
for (ContentEntry entry : model.getContentEntries()) {
if (file.equals(entry.getFile())) {
model.removeContentEntry(entry);
}
}
});
}
@Nullable
@@ -57,6 +71,10 @@ public class PyiTypeTest extends PyTestCase {
@Override
public void tearDown() throws Exception {
if (myDisposable != null) {
Disposer.dispose(myDisposable);
myDisposable = null;
}
setLanguageLevel(null);
super.tearDown();
}
@@ -97,7 +115,7 @@ public class PyiTypeTest extends PyTestCase {
}
public void testPyiOnPythonPath() {
addPyiStubsToContentRoot(myFixture);
myDisposable = addPyiStubsToContentRoot(myFixture);
doTest("int");
}
@@ -155,7 +155,7 @@ fun mergeStubs(paths: List<String>, stubsFilePath: String, projectPath: String,
for (path in paths) {
println("Reading stubs from $path")
var count = 0
val fromStorageFile = File(stubsFilePath + ".input")
val fromStorageFile = File(path + ".input")
val fromStorage = PersistentHashMap<HashCode, SerializedStubTree>(fromStorageFile,
HashCodeDescriptor.instance, stubExternalizer)