Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2014-10-30 02:32:18 +01:00
79 changed files with 1028 additions and 376 deletions
Binary file not shown.
@@ -37,7 +37,6 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public class CompilerUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompilerUtil");
@@ -74,7 +73,7 @@ public class CompilerUtil {
}
}
public static void refreshOutputDirectories(Set<File> outputs, boolean async) {
public static void refreshOutputDirectories(Collection<File> outputs, boolean async) {
LocalFileSystem fileSystem = LocalFileSystem.getInstance();
List<VirtualFile> toRefresh = new ArrayList<VirtualFile>();
@@ -17,6 +17,7 @@ package com.intellij.compiler.server;
import com.intellij.ProjectTopics;
import com.intellij.compiler.CompilerWorkspaceConfiguration;
import com.intellij.compiler.impl.CompilerUtil;
import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration;
import com.intellij.compiler.server.impl.BuildProcessClasspathManager;
import com.intellij.execution.ExecutionAdapter;
@@ -1266,26 +1267,39 @@ public class BuildManager implements ApplicationComponent{
roots = ArrayUtil.toStringArray(myRootsToRefresh);
myRootsToRefresh.clear();
}
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
if (project.isDisposed()) {
return;
}
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
final LocalFileSystem lfs = LocalFileSystem.getInstance();
final Set<VirtualFile> filesToRefresh = new HashSet<VirtualFile>();
for (String root : roots) {
final VirtualFile rootFile = lfs.refreshAndFindFileByPath(root);
if (rootFile != null && fileIndex.isInSourceContent(rootFile)) {
filesToRefresh.add(rootFile);
if (roots.length != 0) {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
if (project.isDisposed()) {
return;
}
final List<File> rootFiles = new ArrayList<File>(roots.length);
for (String root : roots) {
rootFiles.add(new File(root));
}
// this will ensure that we'll be able to obtain VirtualFile for existing roots
CompilerUtil.refreshOutputDirectories(rootFiles, false);
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
final LocalFileSystem lfs = LocalFileSystem.getInstance();
final Set<VirtualFile> filesToRefresh = new HashSet<VirtualFile>();
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
for (File root : rootFiles) {
final VirtualFile rootFile = lfs.findFileByIoFile(root);
if (rootFile != null && fileIndex.isInSourceContent(rootFile)) {
filesToRefresh.add(rootFile);
}
}
if (!filesToRefresh.isEmpty()) {
lfs.refreshFiles(filesToRefresh, true, true, null);
}
}
});
}
if (!filesToRefresh.isEmpty()) {
lfs.refreshFiles(filesToRefresh, true, true, null);
}
}
});
});
}
}
@Override
@@ -651,10 +651,11 @@ public class HighlightControlFlowUtil {
return null;
}
}
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && isEffectivelyFinal(variable, innerClass, context)) {
final boolean isToBeEffectivelyFinal = languageLevel.isAtLeast(LanguageLevel.JDK_1_8);
if (isToBeEffectivelyFinal && isEffectivelyFinal(variable, innerClass, context)) {
return null;
}
final String description = JavaErrorMessages.message("variable.must.be.final", context.getText());
final String description = JavaErrorMessages.message(isToBeEffectivelyFinal ? "variable.must.be.final.or.effectively.final" : "variable.must.be.final", context.getText());
final HighlightInfo highlightInfo =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(context).descriptionAndTooltip(description).create();
@@ -915,7 +915,8 @@ public class HighlightMethodUtil {
PsiType paramType = i < parameters.length && parameters[i] != null
? substitutor.substitute(parameters[i].getType())
: null;
return paramType != null && TypeConversionUtil.areTypesAssignmentCompatible(paramType, expression);
PsiType expressionType = expression.getType();
return paramType != null && expressionType != null && TypeConversionUtil.isAssignable(paramType, expressionType);
}
@@ -79,6 +79,7 @@ public class CreateFromUsageUtils {
private static final Logger LOG = Logger.getInstance(
"#com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils");
private static final int MAX_GUESSED_MEMBERS_COUNT = 10;
private static final int MAX_RAW_GUESSED_MEMBERS_COUNT = 2 * MAX_GUESSED_MEMBERS_COUNT;
public static boolean isValidReference(PsiReference reference, boolean unresolvedOnly) {
if (!(reference instanceof PsiJavaReference)) return false;
@@ -671,12 +672,12 @@ public class CreateFromUsageUtils {
final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(expression.getProject());
PsiElementFactory factory = facade.getElementFactory();
for (String fieldName : expectedFieldNames) {
PsiField[] fields = cache.getFieldsByName(fieldName, resolveScope);
PsiField[] fields = cache.getFieldsByNameIfNotMoreThan(fieldName, resolveScope, MAX_RAW_GUESSED_MEMBERS_COUNT);
addMemberInfo(fields, expression, typesList, factory);
}
for (String methodName : expectedMethodNames) {
PsiMethod[] methods = cache.getMethodsByName(methodName, resolveScope);
PsiMethod[] methods = cache.getMethodsByNameIfNotMoreThan(methodName, resolveScope, MAX_RAW_GUESSED_MEMBERS_COUNT);
addMemberInfo(methods, expression, typesList, factory);
}
}
@@ -723,12 +724,12 @@ public class CreateFromUsageUtils {
final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(expression.getProject());
PsiElementFactory factory = facade.getElementFactory();
for (String fieldName : expectedFieldNames) {
PsiField[] fields = cache.getFieldsByName(fieldName, resolveScope);
PsiField[] fields = cache.getFieldsByNameIfNotMoreThan(fieldName, resolveScope, MAX_RAW_GUESSED_MEMBERS_COUNT);
addMemberInfo(fields, expression, typesList, factory);
}
for (String methodName : expectedMethodNames) {
PsiMethod[] methods = cache.getMethodsByName(methodName, resolveScope);
PsiMethod[] methods = cache.getMethodsByNameIfNotMoreThan(methodName, resolveScope, MAX_RAW_GUESSED_MEMBERS_COUNT);
addMemberInfo(methods, expression, typesList, factory);
}
}
@@ -26,6 +26,7 @@ import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.CharTable;
import org.jetbrains.annotations.NotNull;
@@ -111,6 +112,9 @@ public class ClassElement extends CompositeElement implements Constants {
for (ASTNode run = anchor; run != null; run = run.getTreeNext()) {
if (run == semicolonPlace) {
anchor = before.booleanValue() ? semicolonPlace.getTreeNext() : semicolonPlace;
if (anchor != null && PsiImplUtil.isWhitespaceOrComment(anchor)) {
anchor = PsiTreeUtil.skipSiblingsForward(anchor.getPsi(), PsiWhiteSpace.class, PsiComment.class).getNode();
}
break;
}
}
@@ -134,6 +134,7 @@ variable.already.assigned=Variable ''{0}'' might already have been assigned to
variable.assigned.in.loop=Variable ''{0}'' might be assigned in loop
assignment.to.final.variable=Cannot assign a value to final variable ''{0}''
variable.must.be.final=Variable ''{0}'' is accessed from within inner class, needs to be declared final
variable.must.be.final.or.effectively.final=Variable ''{0}'' is accessed from within inner class, needs to be final or effectively final
initializer.must.be.able.to.complete.normally=Initializer must be able to complete normally
weaker.privileges={0}; attempting to assign weaker access privileges (''{1}''); was ''{2}''
incompatible.return.type=attempting to use incompatible return type
@@ -108,7 +108,7 @@ class ParameterIsEffectivelyFinal {
new Runnable() {
@Override
public void run() {
System.out.println(<error descr="Variable 'o' is accessed from within inner class, needs to be declared final">o</error>);
System.out.println(<error descr="Variable 'o' is accessed from within inner class, needs to be final or effectively final">o</error>);
}
}.run();
return 0;
@@ -0,0 +1,12 @@
// "Create Field for Parameter 'p1'" "true"
enum Test{
A;//comment
private int myP1;
void f(int p1){
myP1 = p1;
}
}
@@ -0,0 +1,9 @@
// "Create Field for Parameter 'p1'" "true"
enum Test{
A;//comment
void f(int p<caret>1){
}
}
@@ -5,8 +5,10 @@ Compiling files:
src/A.java
End of files
Cleaning output files:
out/production/AddMethod/C.class
out/production/AddMethod/D.class
End of files
Compiling files:
src/C.java
src/D.java
End of files
@@ -0,0 +1,14 @@
Cleaning output files:
out/production/AddVarargMethod/A.class
End of files
Compiling files:
src/A.java
End of files
Cleaning output files:
out/production/AddVarargMethod/C.class
out/production/AddVarargMethod/D.class
End of files
Compiling files:
src/C.java
src/D.java
End of files
@@ -0,0 +1,9 @@
public class A {
void f (String x, Integer y) {
}
void f (String x, Integer y, Long z, String... v){
}
}
@@ -0,0 +1,9 @@
public class A {
void f (String x, Integer y, String... v) {
}
void f (String x, Integer y, Long z, String... v){
}
}
@@ -0,0 +1,5 @@
public class C {
void f (A a){
a.f("1", 2);
}
}
@@ -0,0 +1,5 @@
public class D {
void f(A a){
a.f("1", 2, null, "comment");
}
}
@@ -75,12 +75,13 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testNestedCallsInsideLambdaReturnExpression() { doTest(); }
public void testIDEA123731() { doTest(); }
public void testIDEA123869() { doTest(); }
@Bombed(day = 30, month = Calendar.NOVEMBER)
public void testIDEA123848() { doTest(); }
public void testOnlyLambdaAtTypeParameterPlace() { doTest(); }
public void testLiftedIntersectionType() { doTest(); }
public void testInferenceFromReturnStatements() { doTest(); }
public void testDownUpThroughLambdaReturnStatements() { doTest(); }
@Bombed(day = 30, month = Calendar.OCTOBER)
@Bombed(day = 30, month = Calendar.NOVEMBER)
public void testIDEA124547() { doTest(); }
public void testIDEA118362() { doTest(); }
public void testIDEA126056() { doTest(); }
@@ -134,7 +135,7 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
@Bombed(month = Calendar.OCTOBER, day = 30)
@Bombed(month = Calendar.NOVEMBER, day = 30)
public void testCheckedExceptionsConstraintsSubstitutions() throws Exception {
doTest();
}
@@ -173,7 +173,7 @@ class ClassfileAnalyzer {
}
myUsages.add(UsageRepr.createMethodUsage(myContext, methodName, myType.className, methodDescr));
myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, myType.className, methodDescr));
myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, myType.className));
myUsedArguments.add(methodName);
}
@@ -183,7 +183,7 @@ class ClassfileAnalyzer {
final String methodDescr = "()" + desc;
myUsages.add(UsageRepr.createMethodUsage(myContext, methodName, myType.className, methodDescr));
myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, myType.className, methodDescr));
myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, myType.className));
myUsedArguments.add(methodName);
}
@@ -526,7 +526,7 @@ class ClassfileAnalyzer {
final int methodOwner = myContext.get(owner);
myUsages.add(UsageRepr.createMethodUsage(myContext, methodName, methodOwner, desc));
myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, methodOwner, desc));
myUsages.add(UsageRepr.createMetaMethodUsage(myContext, methodName, methodOwner));
addClassUsage(TypeRepr.getType(myContext, Type.getReturnType(desc)));
super.visitMethodInsn(opcode, owner, name, desc, itf);
@@ -400,16 +400,31 @@ public class Mappings {
private boolean hasOverriddenMethods(final ClassRepr fromClass, final MethodRepr.Predicate predicate) {
for (int superName : fromClass.getSupers()) {
final ClassRepr superClass = reprByName(superName);
if (superClass == null) {
return true; // assumption
if (superName == myObjectClassName) {
continue;
}
for (MethodRepr mm : superClass.findMethods(predicate)) {
if (isVisibleIn(superClass, mm, fromClass)) {
final ClassRepr superClass = reprByName(superName);
if (superClass != null) {
for (MethodRepr mm : superClass.findMethods(predicate)) {
if (isVisibleIn(superClass, mm, fromClass)) {
return true;
}
}
if (hasOverriddenMethods(superClass, predicate)) {
return true;
}
}
if (hasOverriddenMethods(superClass, predicate)) {
}
return false;
}
private boolean extendsLibraryClass(final ClassRepr fromClass) {
for (int superName : fromClass.getSupers()) {
if (superName != myObjectClassName) {
continue;
}
final ClassRepr superClass = reprByName(superName);
if (superClass == null || extendsLibraryClass(superClass)) {
return true;
}
}
@@ -440,6 +455,9 @@ public class Mappings {
void addOverriddenFields(final FieldRepr f, final ClassRepr fromClass, final Collection<Pair<FieldRepr, ClassRepr>> container) {
for (int supername : fromClass.getSupers()) {
if (supername == myObjectClassName) {
continue;
}
final ClassRepr superClass = reprByName(supername);
if (superClass != null) {
final FieldRepr ff = superClass.findField(f.name);
@@ -455,6 +473,9 @@ public class Mappings {
boolean hasOverriddenFields(final FieldRepr f, final ClassRepr fromClass) {
for (int supername : fromClass.getSupers()) {
if (supername == myObjectClassName) {
continue;
}
final ClassRepr superClass = reprByName(supername);
if (superClass != null) {
final FieldRepr ff = superClass.findField(f.name);
@@ -534,15 +555,8 @@ public class Mappings {
return Boolean.FALSE;
}
boolean isMethodVisible(final int className, final MethodRepr m) {
final ClassRepr r = reprByName(className);
if (r != null) {
if (r.findMethods(MethodRepr.equalByJavaRules(m)).size() > 0) {
return true;
}
return hasOverriddenMethods(r, MethodRepr.equalByJavaRules(m));
}
return false;
boolean isMethodVisible(final ClassRepr classRepr, final MethodRepr m) {
return classRepr.findMethods(MethodRepr.equalByJavaRules(m)).size() > 0 || hasOverriddenMethods(classRepr, MethodRepr.equalByJavaRules(m));
}
boolean isFieldVisible(final int className, final FieldRepr field) {
@@ -1082,10 +1096,7 @@ public class Mappings {
}
final ClassRepr oldIt = oldItRef.get();
if (oldIt != null && myPresent.hasOverriddenMethods(oldIt, MethodRepr.equalByJavaRules(m))) {
}
else {
if (oldIt == null || !myPresent.hasOverriddenMethods(oldIt, MethodRepr.equalByJavaRules(m))) {
if (m.myArgumentTypes.length > 0) {
propagated = myFuture.propagateMethodAccess(m, it.name);
debug("Conservative case on overriding methods, affecting method usages");
@@ -1170,10 +1181,13 @@ public class Mappings {
final Collection<File> sourceFileNames = myClassToSourceFile.get(subClass);
if (sourceFileNames != null && !myCompiledFiles.containsAll(sourceFileNames)) {
final int outerClass = r.getOuterClassName();
if (!isEmpty(outerClass) && myFuture.isMethodVisible(outerClass, m)) {
myAffectedFiles.addAll(sourceFileNames);
for (File sourceFileName : sourceFileNames) {
debug("Affecting file due to local overriding: ", sourceFileName);
if (!isEmpty(outerClass)) {
final ClassRepr outerClassRepr = myFuture.reprByName(outerClass);
if (outerClassRepr != null && (myFuture.isMethodVisible(outerClassRepr, m) || myFuture.extendsLibraryClass(outerClassRepr))) {
myAffectedFiles.addAll(sourceFileNames);
for (File sourceFileName : sourceFileNames) {
debug("Affecting file due to local overriding: ", sourceFileName);
}
}
}
}
@@ -112,8 +112,8 @@ class MethodRepr extends ProtoMember {
public void updateClassUsages(final DependencyContext context, final int owner, final Set<UsageRepr.Usage> s) {
myType.updateClassUsages(context, owner, s);
for (int i = 0; i < myArgumentTypes.length; i++) {
myArgumentTypes[i].updateClassUsages(context, owner, s);
for (final TypeRepr.AbstractType argType : myArgumentTypes) {
argType.updateClassUsages(context, owner, s);
}
if (myExceptions != null) {
@@ -124,17 +124,17 @@ class MethodRepr extends ProtoMember {
}
public MethodRepr(final DependencyContext context,
final int a,
final int n,
final int s,
final String d,
final String[] e,
final Object value) {
super(a, s, n, TypeRepr.getType(context, Type.getReturnType(d)), value);
final int accessFlags,
final int name,
final int signature,
final String descriptor,
final String[] exceptions,
final Object defaultValue) {
super(accessFlags, signature, name, TypeRepr.getType(context, Type.getReturnType(descriptor)), defaultValue);
Set<TypeRepr.AbstractType> typeCollection =
e != null ? new THashSet<TypeRepr.AbstractType>(e.length) : Collections.<TypeRepr.AbstractType>emptySet();
myExceptions = (Set<TypeRepr.AbstractType>)TypeRepr.createClassType(context, e, typeCollection);
myArgumentTypes = TypeRepr.getType(context, Type.getArgumentTypes(d));
exceptions != null ? new THashSet<TypeRepr.AbstractType>(exceptions.length) : Collections.<TypeRepr.AbstractType>emptySet();
myExceptions = (Set<TypeRepr.AbstractType>)TypeRepr.createClassType(context, exceptions, typeCollection);
myArgumentTypes = TypeRepr.getType(context, Type.getArgumentTypes(descriptor));
}
public MethodRepr(final DependencyContext context, final DataInput in) {
@@ -216,7 +216,7 @@ class MethodRepr extends ProtoMember {
}
public UsageRepr.Usage createMetaUsage(final DependencyContext context, final int owner) {
return UsageRepr.createMetaMethodUsage(context, name, owner, getDescr(context));
return UsageRepr.createMetaMethodUsage(context, name, owner);
}
@Override
@@ -278,52 +278,18 @@ class UsageRepr {
}
public static class MetaMethodUsage extends FMUsage {
private int myArity;
public MetaMethodUsage(final DependencyContext context, final int n, final int o, final String descr) {
public MetaMethodUsage(final int n, final int o) {
super(n, o);
myArity = TypeRepr.getType(context, Type.getArgumentTypes(descr)).length;
}
public MetaMethodUsage(final DataInput in) {
super(in);
try {
myArity = DataInputOutputUtil.readINT(in);
}
catch (IOException e) {
throw new BuildDataCorruptedException(e);
}
}
@Override
public void save(final DataOutput out) {
save(METAMETHOD_USAGE, out);
try {
DataInputOutputUtil.writeINT(out, myArity);
}
catch (IOException e) {
throw new BuildDataCorruptedException(e);
}
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
MetaMethodUsage that = (MetaMethodUsage)o;
if (myArity != that.myArity) return false;
return super.equals(o);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + myArity;
return result;
}
@Override
@@ -334,7 +300,6 @@ class UsageRepr {
@Override
public void toStream(DependencyContext context, PrintStream stream) {
super.toStream(context, stream);
stream.println(" Arity: " + Integer.toString(myArity));
}
}
@@ -679,8 +644,8 @@ class UsageRepr {
return context.getUsage(new MethodUsage(context, name, owner, descr));
}
public static Usage createMetaMethodUsage(final DependencyContext context, final int name, final int owner, final String descr) {
return context.getUsage(new MetaMethodUsage(context, name, owner, descr));
public static Usage createMetaMethodUsage(final DependencyContext context, final int name, final int owner) {
return context.getUsage(new MetaMethodUsage(name, owner));
}
public static Usage createClassUsage(final DependencyContext context, final int name) {
@@ -42,7 +42,7 @@ import java.util.concurrent.ConcurrentMap;
* Date: 10/7/11
*/
public class BuildDataManager implements StorageOwner {
private static final int VERSION = 25;
private static final int VERSION = 26;
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager");
private static final String SRC_TO_FORM_STORAGE = "src-form";
private static final String OUT_TARGET_STORAGE = "out-target";
@@ -203,4 +203,8 @@ public class MemberChangeTest extends IncrementalTestCase {
public void testAddMethod() {
doTest();
}
public void testAddVarargMethod() {
doTest();
}
}
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
# Clang can be downloaded from http://llvm.org/releases/download.html or found in XCode 4+
clang -arch i386 -mmacosx-version-min=10.5 -framework CoreServices -o fsnotifier fsnotifier.c
clang -arch i386 -arch x86_64 -mmacosx-version-min=10.5 -framework CoreServices -o fsnotifier fsnotifier.c
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

@@ -19,6 +19,7 @@ import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Conditions;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.ui.content.Content;
@@ -26,9 +27,8 @@ import com.intellij.ui.content.ContentManager;
import com.intellij.ui.content.ContentManagerAdapter;
import com.intellij.ui.content.ContentManagerEvent;
import com.intellij.ui.switcher.QuickActionProvider;
import com.intellij.ui.tabs.JBTabs;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.AwtVisitor;
import com.intellij.util.ui.JBSwingUtilities;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -38,7 +38,6 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ContainerAdapter;
import java.awt.event.ContainerEvent;
import java.util.LinkedList;
import java.util.List;
public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider, DataProvider {
@@ -199,14 +198,6 @@ public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider
component instanceof DataProvider ? PlatformDataKeys.CONTENT_MANAGER.getData((DataProvider)component) : null;
if (contentManager != null) contentManager.addContentManagerListener(this);
}
@Override
public void selectionChanged(ContentManagerEvent event) {
Content content = event.getContent();
if (content != null) {
setContentToolbarVisible(content.getComponent(), getVisibilityValue());
}
}
});
}
@@ -233,18 +224,8 @@ public class SimpleToolWindowPanel extends JPanel implements QuickActionProvider
}
private static void setContentToolbarVisible(@NotNull JComponent root, boolean state) {
LinkedList<JComponent> deque = ContainerUtil.newLinkedList(root);
while(!deque.isEmpty()) {
JComponent component = deque.pollFirst();
for (int i = 0, count = component.getComponentCount(); i < count; i++) {
Component c = component.getComponent(i);
if (c instanceof ActionToolbar) {
c.setVisible(state);
}
else if (c instanceof JPanel || c instanceof JLayeredPane || c instanceof JBTabs) {
deque.addLast((JComponent)c);
}
}
for (Component c : JBSwingUtilities.uiTraverser().preOrderTraversal(root).filter(Conditions.instanceOf(ActionToolbar.class))) {
c.setVisible(state);
}
}
}
@@ -1,31 +0,0 @@
/*
* Copyright 2000-2014 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.ui.components;
import com.intellij.openapi.util.Key;
import com.intellij.util.Consumer;
import javax.swing.*;
/**
* @author gregsh
*/
public interface OrphanGuardian {
Key CLIENT_PROPERTY_KEY = Key.create("OrphanGuardian");
void iterateOrphans(Consumer<JComponent> processor);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -21,6 +21,7 @@ import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -41,7 +42,12 @@ public class ActionLink extends LinkLabel implements DataProvider {
public ActionLink(String text, @NotNull AnAction action) {
this(text, ICON, action);
}
public ActionLink(String text, Icon icon, @NotNull AnAction action) {
this(text, icon, action, null);
}
public ActionLink(String text, Icon icon, @NotNull AnAction action, @Nullable final Runnable onDone) {
super(text, icon);
setListener(new LinkListener() {
@Override
@@ -56,6 +62,9 @@ public class ActionLink extends LinkLabel implements DataProvider {
myAction.update(event);
if (event.getPresentation().isEnabled() && event.getPresentation().isVisible()) {
myAction.actionPerformed(event);
if (onDone != null) {
onDone.run();
}
}
}
}, null);
@@ -28,7 +28,6 @@ import com.intellij.openapi.wm.*;
import com.intellij.ui.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.awt.RelativeRectangle;
import com.intellij.ui.components.OrphanGuardian;
import com.intellij.ui.switcher.QuickActionProvider;
import com.intellij.ui.switcher.SwitchProvider;
import com.intellij.ui.switcher.SwitchTarget;
@@ -37,13 +36,10 @@ import com.intellij.ui.tabs.impl.singleRow.SingleRowLayout;
import com.intellij.ui.tabs.impl.singleRow.SingleRowPassInfo;
import com.intellij.ui.tabs.impl.table.TableLayout;
import com.intellij.ui.tabs.impl.table.TablePassInfo;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.Animator;
import com.intellij.util.ui.JBInsets;
import com.intellij.util.ui.TimedDeadzone;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.containers.FluentIterable;
import com.intellij.util.ui.*;
import com.intellij.util.ui.update.ComparableObject;
import com.intellij.util.ui.update.LazyUiDisposable;
import org.jetbrains.annotations.NonNls;
@@ -316,16 +312,19 @@ public class JBTabsImpl extends JComponent
}
}
};
putClientProperty(OrphanGuardian.CLIENT_PROPERTY_KEY, new OrphanGuardian() {
@Override
public void iterateOrphans(Consumer<JComponent> consumer) {
for (TabInfo info : getVisibleInfos()) {
if (info == mySelectedInfo) continue;
consumer.consume(info.getComponent());
UIUtil.putClientProperty(
this, JBSwingUtilities.NOT_IN_HIERARCHY_COMPONENTS, new Iterable<JComponent>() {
@Override
public Iterator<JComponent> iterator() {
return FluentIterable.from(getVisibleInfos()).filter(Conditions.not(Conditions.is(mySelectedInfo))).transform(
new Function<TabInfo, JComponent>() {
@Override
public JComponent fun(TabInfo info) {
return info.getComponent();
}
}).iterator();
}
}
});
});
}
protected SingleRowLayout createSingleRowLayout() {
@@ -19,6 +19,8 @@ import com.intellij.openapi.command.undo.DocumentReference;
import com.intellij.openapi.command.undo.DocumentReferenceManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.WeakList;
import gnu.trove.THashSet;
@@ -41,7 +43,8 @@ class UndoRedoStacksHolder {
@NotNull
LinkedList<UndoableGroup> getStack(@NotNull DocumentReference r) {
return r.getFile() != null ? doGetStackForFile(r) : doGetStackForDocument(r);
VirtualFile file = r.getFile();
return file != null && !(file instanceof LightVirtualFile) ? doGetStackForFile(r) : doGetStackForDocument(r);
}
@NotNull
@@ -74,7 +74,6 @@ import com.intellij.ui.*;
import com.intellij.ui.components.JBLayeredPane;
import com.intellij.ui.components.JBScrollBar;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.OrphanGuardian;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
@@ -491,16 +490,17 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myVerticalScrollBar = (MyScrollBar)myScrollPane.getVerticalScrollBar();
myPanel = new JPanel();
myPanel.putClientProperty(OrphanGuardian.CLIENT_PROPERTY_KEY, new OrphanGuardian() {
@Override
public void iterateOrphans(Consumer<JComponent> consumer) {
JComponent component = getPermanentHeaderComponent();
if (component != null && !component.isValid()) {
consumer.consume(component);
UIUtil.putClientProperty(
myPanel, JBSwingUtilities.NOT_IN_HIERARCHY_COMPONENTS, new Iterable<JComponent>() {
@Override
public Iterator<JComponent> iterator() {
JComponent component = getPermanentHeaderComponent();
if (component != null && !component.isValid()) {
return Collections.singleton(component).iterator();
}
return ContainerUtil.emptyIterator();
}
}
});
});
myHeaderPanel = new MyHeaderPanel();
myGutterComponent = new EditorGutterComponentImpl(this);
@@ -17,7 +17,8 @@ package com.intellij.openapi.wm.impl.welcomeScreen;
import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
import com.intellij.ide.RecentProjectsManager;
import com.intellij.ide.RecentProjectsManagerBase;
import com.intellij.internal.statistic.UsageTrigger;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.MnemonicHelper;
import com.intellij.openapi.actionSystem.*;
@@ -88,7 +89,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
setTitle("Welcome to " + ApplicationNamesInfo.getInstance().getFullProductName());
AppUIUtil.updateWindowIcon(this);
//Rectangle bounds = ScreenUtil.getMainScreenBounds();
if (RecentProjectsManager.getInstance().getRecentProjectsActions(false).length > 0) {
if (RecentProjectsManagerBase.getInstance().getRecentProjectsActions(false).length > 0) {
setSize(666, 460);
} else {
setSize(555, 460);
@@ -166,23 +167,23 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
public StatusBar getStatusBar() {
return null;
}
public static Color getMainBackground() {
return new JBColor(0xf7f7f7, 0x45474a);
}
public static Color getProjectsBackground() {
return new JBColor(Gray.xFF, Gray.x39);
}
public static Color getLinkNormalColor() {
return new JBColor(Gray._0, Gray.xBB);
}
public static Color getListSelectionColor(boolean hasFocus) {
return hasFocus ? new JBColor(0x3875d6, 0x4b6eaf) : new JBColor(Gray.xDD, Gray.x45);
}
public static Color getActionLinkSelectionColor() {
return new JBColor(0xdbe5f5, 0x485875);
}
@@ -195,14 +196,14 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
public FlatWelcomeScreen() {
super(new BorderLayout());
setBackground(getMainBackground());
if (RecentProjectsManager.getInstance().getRecentProjectsActions(false).length > 0) {
if (RecentProjectsManagerBase.getInstance().getRecentProjectsActions(false).length > 0) {
final JComponent recentProjects = createRecentProjects();
add(recentProjects, BorderLayout.WEST);
final JList projectsList = UIUtil.findComponentOfType(recentProjects, JList.class);
if (projectsList != null) {
projectsList.getModel().addListDataListener(new ListDataListener() {
@Override
public void intervalAdded(ListDataEvent e) {
public void intervalAdded(ListDataEvent e) {
}
@Override
@@ -211,7 +212,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
}
private void removeIfNeeded() {
if (RecentProjectsManager.getInstance().getRecentProjectsActions(false).length == 0) {
if (RecentProjectsManagerBase.getInstance().getRecentProjectsActions(false).length == 0) {
FlatWelcomeScreen.this.remove(recentProjects);
FlatWelcomeScreen.this.revalidate();
FlatWelcomeScreen.this.repaint();
@@ -260,7 +261,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
if (register != null) {
Presentation presentation = register.getTemplatePresentation();
register.update(new AnActionEvent(null, DataManager.getInstance().getDataContext(this),
ActionPlaces.WELCOME_SCREEN, presentation, ActionManager.getInstance(), 0));
ActionPlaces.WELCOME_SCREEN, presentation, ActionManager.getInstance(), 0));
if (presentation.isEnabled()) {
ActionLink registerLink = new ActionLink("Register", register);
registerLink.setNormalColor(getLinkNormalColor());
@@ -279,14 +280,14 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.X_AXIS));
toolbar.add(createActionLink("Configure", IdeActions.GROUP_WELCOME_SCREEN_CONFIGURE, AllIcons.General.GearPlain, !registeredVisible));
toolbar.add(createActionLink("Get Help", IdeActions.GROUP_WELCOME_SCREEN_DOC, null, false));
panel.add(toolbar, BorderLayout.EAST);
panel.setBorder(new EmptyBorder(0,0,8,11));
return panel;
}
private JComponent createActionLink(final String text, final String groupId, Icon icon, boolean focusListOnLeft) {
final Ref<ActionLink> ref = new Ref<ActionLink>(null);
AnAction action = new AnAction() {
@@ -294,8 +295,10 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
public void actionPerformed(@NotNull AnActionEvent e) {
ActionGroup configureGroup = (ActionGroup)ActionManager.getInstance().getAction(groupId);
final PopupFactoryImpl.ActionGroupPopup popup = (PopupFactoryImpl.ActionGroupPopup)JBPopupFactory.getInstance()
.createActionGroupPopup(null, new IconsFreeActionGroup(configureGroup), e.getDataContext(), JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false, ActionPlaces.WELCOME_SCREEN);
.createActionGroupPopup(null, new IconsFreeActionGroup(configureGroup), e.getDataContext(), JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false,
ActionPlaces.WELCOME_SCREEN);
popup.showUnderneathOfLabel(ref.get());
UsageTrigger.trigger("welcome.screen." + groupId);
}
};
ref.set(new ActionLink(text, icon, action));
@@ -334,7 +337,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
if (icon.getIconHeight() != 16 || icon.getIconWidth() != 16) {
icon = EmptyIcon.ICON_16;
}
ActionLink link = new ActionLink(text, icon, action);
ActionLink link = new ActionLink(text, icon, action, createUsageTracker(action));
link.setPaintUnderline(false);
link.setNormalColor(getLinkNormalColor());
button.add(link);
@@ -374,16 +377,16 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
appName.setFont(font.deriveFont(36f).deriveFont(Font.PLAIN));
appName.setHorizontalAlignment(SwingConstants.CENTER);
String appVersion = "Version " + app.getFullVersion();
if (app.isEAP() && app.getBuild().getBuildNumber() < Integer.MAX_VALUE) {
appVersion += " (" + app.getBuild().asString() + ")";
}
JLabel version = new JLabel(appVersion);
version.setFont(getProductFont().deriveFont(16f));
version.setHorizontalAlignment(SwingConstants.CENTER);
version.setForeground(Gray._128);
panel.add(appName);
panel.add(version, BorderLayout.SOUTH);
panel.setBorder(new EmptyBorder(0, 0, 20, 0));
@@ -393,9 +396,9 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
private Font getProductFont() {
String name = "/fonts/Roboto-Light.ttf";
URL url = AppUIUtil.class.getResource(name);
if (url == null) {
Logger.getInstance(AppUIUtil.class).warn("Resource missing: " + name);
} else {
if (url == null) {
Logger.getInstance(AppUIUtil.class).warn("Resource missing: " + name);
} else {
try {
InputStream is = url.openStream();
@@ -450,7 +453,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
if (focusListOnLeft) {
if (list != null) {
list.requestFocus();
}
}
} else {
focusPrev(comp);
}
@@ -533,14 +536,15 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
if (child instanceof ActionGroup) {
return new IconsFreeActionGroup((ActionGroup)child);
}
Presentation presentation = child.getTemplatePresentation();
Presentation presentation = child.getTemplatePresentation();
return new AnAction(presentation.getText(),
presentation.getDescription(),
null) {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
child.actionPerformed(e);
UsageTrigger.trigger("welcome.screen." + e.getActionManager().getId(child));
}
@Override
@@ -558,6 +562,15 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
}
}
private static Runnable createUsageTracker(final AnAction action) {
return new Runnable() {
@Override
public void run() {
UsageTrigger.trigger("welcome.screen." + ActionManager.getInstance().getId(action));
}
};
}
private static JLabel createArrow(final ActionLink link) {
JLabel arrow = new JLabel(AllIcons.General.Combo3);
arrow.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
@@ -613,7 +626,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
public static void notifyFrameClosed(JFrame frame) {
saveLocation(frame.getBounds());
}
public static class WelcomeScreenActionsPanel {
private JPanel root;
private JPanel actions;
@@ -20,7 +20,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.components.OrphanGuardian;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.FilteringIterator;
import com.intellij.util.ui.JBSwingUtilities;
@@ -230,47 +229,16 @@ public class IJSwingUtilities extends JBSwingUtilities {
* @param c component
* @see javax.swing.SwingUtilities#updateComponentTreeUI
*/
public static void updateComponentTreeUI(Component c) {
updateComponentTreeUI0(c);
public static void updateComponentTreeUI(@Nullable Component c) {
if (c == null) return;
for (Component component : uiTraverser().postOrderTraversal(c)) {
if (component instanceof JComponent) ((JComponent)component).updateUI();
}
c.invalidate();
c.validate();
c.repaint();
}
private static final Consumer<JComponent> UI_TREE_UPDATER = new Consumer<JComponent>() {
@Override
public void consume(JComponent component) {
updateComponentTreeUI0(component);
}
};
private static void updateComponentTreeUI0(Component c) {
Component[] children = null;
if (c instanceof JMenu) {
children = ((JMenu)c).getMenuComponents();
}
else if (c instanceof Container) {
children = ((Container)c).getComponents();
}
if (children != null) {
for (Component aChildren : children) {
updateComponentTreeUI0(aChildren);
}
}
if (c instanceof JComponent) {
JComponent jc = (JComponent)c;
OrphanGuardian orphans = (OrphanGuardian)jc.getClientProperty(OrphanGuardian.CLIENT_PROPERTY_KEY);
if (orphans != null) {
orphans.iterateOrphans(UI_TREE_UPDATER);
}
jc.updateUI();
JPopupMenu jpm = jc.getComponentPopupMenu();
if (jpm != null && jpm.isVisible() && jpm.getInvoker() == jc) {
updateComponentTreeUI(jpm);
}
}
}
public static void moveMousePointerOn(Component component) {
if (component != null && component.isShowing()) {
UISettings settings = ApplicationManager.getApplication() == null ? null : UISettings.getInstance();
@@ -514,7 +514,7 @@ message.idea.restart.required=Restart {0} to activate changes in plugins?
title.plugins=Plugins
title.plugins.changed=Plugins Changed
plugin.status.not.specified=(not specified)
error.list.of.plugins.was.not.loaded=List of plugins was not loaded: {0}
error.list.of.plugins.was.not.loaded=Unable to update the list of plugins due to the following error: {0}
action.download.and.install.plugin=Download and Install
action.update.plugin=Update Plugin
error.plugin.download.failed=Plugin download failed
@@ -146,6 +146,7 @@ public class MatcherImpl {
visitor.matchContext(matchedNodes);
} finally {
matchedNodes.reset();
matchContext.getOptions().setScope(null);
}
}
@@ -440,6 +441,8 @@ public class MatcherImpl {
MalformedPatternException exception = new MalformedPatternException();
exception.initCause(e);
throw exception;
} finally {
options.setScope(null);
}
return sink.getMatches();
@@ -26,12 +26,14 @@ import java.util.HashMap;
* @author max
*/
public class Conditions {
private Conditions() {}
private Conditions() {
}
@NotNull
public static <T> Condition<T> alwaysTrue() {
return (Condition<T>)TRUE;
}
@NotNull
public static <T> Condition<T> alwaysFalse() {
return (Condition<T>)FALSE;
@@ -67,12 +69,23 @@ public class Conditions {
public static <T> Condition<T> not(Condition<T> c) {
return new Not<T>(c);
}
public static <T> Condition<T> and(Condition<T> c1, Condition<T> c2) {
return new And<T>(c1, c2);
}
public static <T> Condition<T> and2(Condition<? super T> c1, Condition<? super T> c2) {
return new And<T>(c1, c2);
}
public static <T> Condition<T> or(Condition<T> c1, Condition<T> c2) {
return new Or<T>(c1, c2);
}
public static <T> Condition<T> or2(Condition<? super T> c1, Condition<? super T> c2) {
return new Or<T>(c1, c2);
}
public static <T> Condition<T> cached(Condition<T> c) {
return new SoftRefCache<T>(c);
}
@@ -89,11 +102,12 @@ public class Conditions {
return !myCondition.value(value);
}
}
private static class And<T> implements Condition<T> {
private final Condition<T> t1;
private final Condition<T> t2;
public And(final Condition<T> t1, final Condition<T> t2) {
private static class And<T> implements Condition<T> {
private final Condition<? super T> t1;
private final Condition<? super T> t2;
public And(Condition<? super T> t1, Condition<? super T> t2) {
this.t1 = t1;
this.t2 = t2;
}
@@ -103,11 +117,12 @@ public class Conditions {
return t1.value(object) && t2.value(object);
}
}
private static class Or<T> implements Condition<T> {
private final Condition<T> t1;
private final Condition<T> t2;
public Or(final Condition<T> t1, final Condition<T> t2) {
private static class Or<T> implements Condition<T> {
private final Condition<? super T> t1;
private final Condition<? super T> t2;
public Or(Condition<? super T> t1, Condition<? super T> t2) {
this.t1 = t1;
this.t2 = t2;
}
@@ -0,0 +1,282 @@
/*
* Copyright 2000-2014 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.util.containers;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* A pruned version of com.google.common.collect.FluentIterable.
* <p/>
* {@code FluentIterable} provides a rich interface for manipulating {@code Iterable} instances in a
* chained fashion. A {@code FluentIterable} can be created from an {@code Iterable}, or from a set
* of elements. The following types of methods are provided on {@code FluentIterable}:
* <ul>
* <li>chained methods which return a new {@code FluentIterable} based in some way on the contents
* of the current one (for example {@link #transform})
* <li>conversion methods which copy the {@code FluentIterable}'s contents into a new collection or
* array (for example {@link #toList})
* <li>element extraction methods which facilitate the retrieval of certain elements (for example
* {@link #last})
* </ul>
* <p/>
* <p>Here is an example that merges the lists returned by two separate database calls, transforms
* it by invoking {@code toString()} on each element, and returns the first 10 elements as an
* {@code List}: <pre> {@code
* FluentIterable
* .from(database.getClientList())
* .filter(activeInLastMonth())
* .transform(Functions.toStringFunction())
* .toList();}</pre>
* <p/>
* <p>Anything which can be done using {@code FluentIterable} could be done in a different fashion
* (often with {@link Iterables}), however the use of {@code FluentIterable} makes many sets of
* operations significantly more concise.
*
* @author Marcin Mikosik
*/
public abstract class FluentIterable<E> implements Iterable<E> {
// We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof
// checks on the _original_ iterable when FluentIterable.from is used.
private final Iterable<E> myIterable;
/**
* Constructor for use by subclasses.
*/
protected FluentIterable() {
myIterable = this;
}
FluentIterable(@NotNull Iterable<E> iterable) {
myIterable = iterable;
}
/**
* Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it
* is already a {@code FluentIterable}.
*/
public static <E> FluentIterable<E> from(final Iterable<E> iterable) {
return iterable instanceof FluentIterable ? (FluentIterable<E>)iterable :
new FluentIterable<E>(iterable) {
@Override
public Iterator<E> iterator() {
return iterable.iterator();
}
};
}
/**
* Returns a fluent iterable containing {@code elements} in the specified order.
*/
public static <E> FluentIterable<E> of(E[] elements) {
return from(ContainerUtil.newArrayList(elements));
}
/**
* Returns a string representation of this fluent iterable, with the format
* {@code [e1, e2, ..., en]}.
*/
@Override
public String toString() {
return ContainerUtil.toCollection(myIterable).toString();
}
/**
* Returns the number of elements in this fluent iterable.
*/
public final int size() {
int count = 0;
for (E ignored : myIterable) {
count++;
}
return count;
}
/**
* Returns {@code true} if this fluent iterable contains any object for which
* {@code equals(element)} is true.
*/
public final boolean contains(@Nullable Object element) {
if (myIterable instanceof Collection) {
return ((Collection)myIterable).contains(element);
}
for (E e : myIterable) {
if (Comparing.equal(e, element)) return true;
}
return false;
}
/**
* Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable,
* followed by those of {@code other}. The iterators are not polled until necessary.
* <p/>
* <p>The returned iterable's {@code Iterator} supports {@code remove()} when the corresponding
* {@code Iterator} supports it.
*/
public final FluentIterable<E> append(Iterable<? extends E> other) {
return from(ContainerUtil.concat(myIterable, other));
}
/**
* Returns a fluent iterable whose iterators traverse first the elements of this fluent iterable,
* followed by {@code elements}.
*/
public final FluentIterable<E> append(E... elements) {
return append(Arrays.asList(elements));
}
/**
* Returns the elements from this fluent iterable that satisfy a condition. The
* resulting fluent iterable's iterator does not support {@code remove()}.
*/
public final FluentIterable<E> filter(final Condition<? super E> condition) {
return from(new Iterable<E>() {
@Override
public Iterator<E> iterator() {
return FilteringIterator.create(FluentIterable.this.iterator(), condition);
}
});
}
/**
* Returns the elements from this fluent iterable that are instances of class {@code type}.
* @param type the type of elements desired
*/
public final <T> FluentIterable<T> filter(Class<T> type) {
//noinspection unchecked
return (FluentIterable<T>)filter(Conditions.instanceOf(type));
}
/**
* Returns a fluent iterable that applies {@code function} to each element of this
* fluent iterable.
* <p/>
* <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's
* iterator does. After a successful {@code remove()} call, this fluent iterable no longer
* contains the corresponding element.
*/
@NotNull
public final <T> FluentIterable<T> transform(@NotNull final Function<? super E, T> function) {
return from(new Iterable<T>() {
@Override
public Iterator<T> iterator() {
final Iterator<E> iterator = FluentIterable.this.iterator();
return new Iterator<T>() {
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public T next() {
return function.fun(iterator.next());
}
@Override
public void remove() {
iterator.remove();
}
};
}
});
}
/**
* Returns an {@link Optional} containing the first element in this fluent iterable.
* If the iterable is empty, {@code Optional.absent()} is returned.
*/
@Nullable
public final E first() {
Iterator<E> iterator = myIterable.iterator();
return iterator.hasNext() ? iterator.next() : null;
}
/**
* Returns an {@link Optional} containing the last element in this fluent iterable.
* If the iterable is empty, {@code Optional.absent()} is returned.
*/
@Nullable
public final E last() {
if (myIterable instanceof List) {
return ContainerUtil.getLastItem((List<E>)myIterable);
}
Iterator<E> iterator = myIterable.iterator();
E cur = null;
while (iterator.hasNext()) {
cur = iterator.next();
}
return cur;
}
/**
* Determines whether this fluent iterable is empty.
*/
public final boolean isEmpty() {
return !myIterable.iterator().hasNext();
}
/**
* Returns an {@code List} containing all of the elements from this fluent iterable in
* proper sequence.
*/
public final List<E> toList() {
return Collections.unmodifiableList(ContainerUtil.newArrayList(myIterable));
}
/**
* Returns an {@code Set} containing all of the elements from this fluent iterable with
* duplicates removed.
*/
public final Set<E> toSet() {
return Collections.unmodifiableSet(ContainerUtil.newHashSet(myIterable));
}
/**
* Returns an {@code Map} for which the elements of this {@code FluentIterable} are the keys in
* the same order, mapped to values by the given function. If this iterable contains duplicate
* elements, the returned map will contain each distinct element once in the order it first
* appears.
*/
public final <V> Map<E, V> toMap(Convertor<E, V> valueFunction) {
return Collections.unmodifiableMap(ContainerUtil.newMapFromKeys(iterator(), valueFunction));
}
/**
* Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to
* calling {@code Iterables.addAll(collection, this)}.
*
* @param collection the collection to copy elements to
* @return {@code collection}, for convenience
*/
public final <C extends Collection<? super E>> C copyInto(@NotNull C collection) {
if (myIterable instanceof Collection) {
collection.addAll((Collection<E>)myIterable);
}
else {
for (E item : myIterable) {
collection.add(item);
}
}
return collection;
}
}
@@ -0,0 +1,215 @@
/*
* Copyright 2000-2014 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.util.containers;
import com.intellij.util.ObjectUtils;
import com.intellij.util.UnmodifiableIterator;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
/**
* A pruned version of com.google.common.collect.TreeTraverser.
*
* Views elements of a type {@code T} as nodes in a tree, and provides methods to traverse the trees
* induced by this traverser.
*
* <p>For example, the tree
*
* <pre> {@code
* h
* / | \
* / e \
* d g
* /|\ |
* / | \ f
* a b c }</pre>
*
* <p>can be iterated over in preorder (hdabcegf), postorder (abcdefgh), or breadth-first order
* (hdegabcf).
*
* <p>Null nodes are strictly forbidden.
*
* @author Louis Wasserman
*/
public abstract class TreeTraverser<T> {
/**
* Returns the children of the specified node. Must not contain null.
*/
public abstract Iterable<T> children(T root);
/**
* Returns an unmodifiable iterable over the nodes in a tree structure, using pre-order
* traversal. That is, each node's subtrees are traversed after the node itself is returned.
*
* <p>No guarantees are made about the behavior of the traversal when nodes change while
* iteration is in progress or when the iterators generated by {@link #children} are advanced.
*/
public final FluentIterable<T> preOrderTraversal(@NotNull final T root) {
return new FluentIterable<T>() {
@Override
public Iterator<T> iterator() {
return preOrderIterator(root);
}
};
}
Iterator<T> preOrderIterator(@NotNull T root) {
return new PreOrderIterator(root);
}
private final class PreOrderIterator extends UnmodifiableIterator<T> {
private final Deque<Iterator<T>> stack;
PreOrderIterator(@NotNull T root) {
super(null);
this.stack = new ArrayDeque<Iterator<T>>();
stack.addLast(new SingletonIterator<T>(root));
}
@Override
public boolean hasNext() {
return !stack.isEmpty();
}
@Override
public T next() {
Iterator<T> itr = stack.getLast(); // throws NSEE if empty
T result = ObjectUtils.assertNotNull(itr.next());
if (!itr.hasNext()) {
stack.removeLast();
}
Iterator<T> childItr = children(result).iterator();
if (childItr.hasNext()) {
stack.addLast(childItr);
}
return result;
}
}
/**
* Returns an unmodifiable iterable over the nodes in a tree structure, using post-order
* traversal. That is, each node's subtrees are traversed before the node itself is returned.
*
* <p>No guarantees are made about the behavior of the traversal when nodes change while
* iteration is in progress or when the iterators generated by {@link #children} are advanced.
*/
public final FluentIterable<T> postOrderTraversal(@NotNull final T root) {
return new FluentIterable<T>() {
@Override
public Iterator<T> iterator() {
return postOrderIterator(root);
}
};
}
Iterator<T> postOrderIterator(@NotNull T root) {
return new PostOrderIterator(root);
}
private static final class PostOrderNode<T> {
final T root;
final Iterator<T> childIterator;
PostOrderNode(@NotNull T root, @NotNull Iterator<T> childIterator) {
this.root = root;
this.childIterator = childIterator;
}
}
private final class PostOrderIterator extends UnmodifiableIterator<T> {
private final ArrayDeque<PostOrderNode<T>> stack;
PostOrderIterator(T root) {
super(null);
this.stack = new ArrayDeque<PostOrderNode<T>>();
stack.addLast(expand(root));
}
@Override
public boolean hasNext() {
return !stack.isEmpty();
}
@Override
public T next() {
return computeNext();
}
private T computeNext() {
while (!stack.isEmpty()) {
PostOrderNode<T> top = stack.getLast();
if (top.childIterator.hasNext()) {
T child = top.childIterator.next();
stack.addLast(expand(child));
} else {
stack.removeLast();
return top.root;
}
}
return null;
}
private PostOrderNode<T> expand(T t) {
return new PostOrderNode<T>(t, children(t).iterator());
}
}
/**
* Returns an unmodifiable iterable over the nodes in a tree structure, using breadth-first
* traversal. That is, all the nodes of depth 0 are returned, then depth 1, then 2, and so on.
*
* <p>No guarantees are made about the behavior of the traversal when nodes change while
* iteration is in progress or when the iterators generated by {@link #children} are advanced.
*/
public final FluentIterable<T> breadthFirstTraversal(@NotNull final T root) {
return new FluentIterable<T>() {
@Override
public Iterator<T> iterator() {
return new BreadthFirstIterator(root);
}
};
}
private final class BreadthFirstIterator extends UnmodifiableIterator<T> {
private final Deque<T> queue;
BreadthFirstIterator(@NotNull T root) {
super(null);
this.queue = new ArrayDeque<T>();
queue.add(root);
}
@Override
public boolean hasNext() {
return !queue.isEmpty();
}
//@Override
public T peek() {
return queue.element();
}
@Override
public T next() {
T result = queue.remove();
ContainerUtil.addAll(queue, children(result));
return result;
}
}
}
@@ -15,13 +15,25 @@
*/
package com.intellij.util.ui;
import com.intellij.openapi.util.Key;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.TreeTraverser;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Collections;
/**
* @author gregsh
*/
public class JBSwingUtilities {
public static final Key<Iterable<? extends Component>> NOT_IN_HIERARCHY_COMPONENTS = Key.create("NOT_IN_HIERARCHY_COMPONENTS");
/**
* Replaces SwingUtilities#isLeftMouseButton() for consistency with other button-related methods
*
@@ -50,4 +62,32 @@ public class JBSwingUtilities {
public static boolean isRightMouseButton(MouseEvent anEvent) {
return (anEvent.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) > 0;
}
@NotNull
public static TreeTraverser<Component> uiTraverser() {
return new TreeTraverser<Component>() {
@Override
public Iterable<Component> children(Component c) {
Iterable<Component> result = ContainerUtil.emptyIterable();
if (c instanceof JMenu) {
result = Arrays.asList(((JMenu)c).getMenuComponents());
}
else if (c instanceof Container) {
result = Arrays.asList(((Container)c).getComponents());
}
if (c instanceof JComponent) {
JComponent jc = (JComponent)c;
Iterable<? extends Component> orphans = UIUtil.getClientProperty(jc, NOT_IN_HIERARCHY_COMPONENTS);
if (orphans != null) {
result = ContainerUtil.concat(result, orphans);
}
JPopupMenu jpm = jc.getComponentPopupMenu();
if (jpm != null && jpm.isVisible() && jpm.getInvoker() == jc) {
result = ContainerUtil.concat(result, Collections.singletonList(jpm));
}
}
return result;
}
};
}
}
@@ -345,6 +345,10 @@ public class UIUtil {
return (T)component.getClientProperty(key);
}
public static <T> void putClientProperty(@NotNull JComponent component, @NotNull Key<T> key, T value) {
component.putClientProperty(key, value);
}
public static String getHtmlBody(String text) {
int htmlIndex = 6 + text.indexOf("<html>");
if (htmlIndex < 6) {
@@ -440,7 +440,9 @@ public abstract class AbstractVcs<ComList extends CommittedChangeList> extends S
}
public interface RootsConvertor {
List<VirtualFile> convertRoots(List<VirtualFile> result);
@NotNull
List<VirtualFile> convertRoots(@NotNull List<VirtualFile> result);
}
/**
@@ -273,6 +273,7 @@ public class NewMappings {
return FileUtil.startsWith(systemIndependentPath, mapping.systemIndependentPath());
}
@NotNull
public List<VirtualFile> getMappingsAsFilesUnderVcs(@NotNull AbstractVcs vcs) {
final List<VirtualFile> result = new ArrayList<VirtualFile>();
final String vcsName = vcs.getName();
@@ -354,7 +354,8 @@ public class CvsVcs2 extends AbstractVcs<CvsChangeList> implements TransactionPr
@Override
public RootsConvertor getCustomConvertor() {
return new RootsConvertor() {
public List<VirtualFile> convertRoots(List<VirtualFile> result) {
@NotNull
public List<VirtualFile> convertRoots(@NotNull List<VirtualFile> result) {
return FindAllRootsHelper.findVersionedUnder(result);
}
};
@@ -22,6 +22,7 @@ import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcsUtil.VcsUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.util.HgUtil;
@@ -44,8 +45,9 @@ public class HgRootsHandler implements AbstractVcs.RootsConvertor {
return ServiceManager.getService(project, HgRootsHandler.class);
}
@NotNull
@Override
public List<VirtualFile> convertRoots(List<VirtualFile> original) {
public List<VirtualFile> convertRoots(@NotNull List<VirtualFile> original) {
final Set<VirtualFile> result = new THashSet<VirtualFile>(original.size());
for (VirtualFile vf : original) {
final VirtualFile root = convertRoot(vf);
@@ -191,8 +191,9 @@ public class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentState
}
}
public List<VirtualFile> convertRoots(final List<VirtualFile> result) {
if (ThreadLocalDefendedInvoker.isInside()) return result;
@NotNull
public List<VirtualFile> convertRoots(@NotNull List<VirtualFile> result) {
if (ThreadLocalDefendedInvoker.isInside()) return ContainerUtil.newArrayList(result);
synchronized (myMonitor) {
final List<VirtualFile> cachedRoots = myMoreRealMapping.getUnderVcsRoots();
@@ -200,11 +201,8 @@ public class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentState
if (! lonelyRoots.isEmpty()) {
myChecker.reportNoRoots(lonelyRoots);
}
if (cachedRoots.isEmpty()) {
// todo +-
return result;
}
return cachedRoots;
return ContainerUtil.newArrayList(cachedRoots.isEmpty() ? result : cachedRoots);
}
}
@@ -20,6 +20,6 @@ jira.failure.captcha=Login failed. Enter captcha in web-interface.
youtrack.default.query=for: me sort by: updated #Unresolved
## Bugzilla
bugzilla.failure.malformed.response=Cannot decode server response. Check that XMLRPC plugin is enabled.
bugzilla.failure.malformed.response=Cannot decode server response. Check that XML-RPC plugin is enabled.
bugzilla.failure.no.version=Cannot find Bugzilla version. Check that URL ends with "xmlrpc.cgi".
@@ -346,7 +346,8 @@ public class BugzillaRepository extends BaseRepositoryImpl {
return (T)new XmlRpcClient(getUrl()).execute(new XmlRpcRequest(myMethodName, parameters), myTransport);
}
catch (XmlRpcClientException e) {
if (e.getMessage().contains("Error decoding XML-RPC response")) {
// Unfortunately there is no standard error code to identify this kind of error in portable way
if (e.getMessage().equals("Error decoding XML-RPC response")) {
throw new RequestFailedException(TaskBundle.message("bugzilla.failure.malformed.response"), e);
}
throw e;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 151 KiB

@@ -46,9 +46,9 @@ def check_importable_path(path):
try:
import_file(path)
except:
failed("File contains syntax errors", test_file_importable.__name__)
failed("File contains syntax errors", test_file_importable.func_name)
return
passed(test_file_importable.__name__)
passed(test_file_importable.func_name)
def import_file(path):
@@ -126,11 +126,11 @@ def test_text_equals(text, error_text):
failed(error_text)
def test_window_text_deleted(error_text="Don't just delete task text"):
def test_answer_placeholders_text_deleted(error_text="Don't just delete task text"):
"""
Checks that task windows are not empty
Checks that all answer placeholders are not empty
"""
windows = get_task_windows()
windows = get_answer_placeholders()
for window in windows:
if len(window) == 0:
@@ -153,9 +153,9 @@ def passed(name=None):
print("#educational_plugin " + name + " test OK")
def get_task_windows(file_name=None):
def get_answer_placeholders(file_name=None):
"""
Returns all task windows
Returns all answer placeholders text
"""
prefix = "#educational_plugin_window = "
import os
@@ -198,4 +198,4 @@ def run_common_tests(error_text="Please, reload file and try again"):
test_file_importable()
test_is_not_empty()
test_is_initial_text(error_text)
test_window_text_deleted(error_text)
test_answer_placeholders_text_deleted(error_text)
@@ -1,10 +1,10 @@
from test_helper import run_common_tests, failed, passed, get_task_windows
from test_helper import run_common_tests, failed, passed, get_answer_placeholders
def test_task_windows():
windows = get_task_windows()
window = windows[0]
if window == "": # TODO: your condition here
def test_answer_placeholders():
placeholders = get_answer_placeholders()
placeholder = placeholders[0]
if placeholder == "": # TODO: your condition here
passed()
else:
failed()
@@ -12,6 +12,6 @@ def test_task_windows():
if __name__ == '__main__':
run_common_tests()
# test_task_windows() # TODO: uncomment test call
# test_answer_placeholders() # TODO: uncomment test call
@@ -88,7 +88,7 @@ public class CCEditorFactoryListener implements EditorFactoryListener {
@Override
public void handle(ReadOnlyFragmentModificationException e) {
HintManager.getInstance().showErrorHint(myEditor, "Delete task window before editing its borders");
HintManager.getInstance().showErrorHint(myEditor, "Delete answer placeholder before editing its borders");
}
}
}
@@ -24,7 +24,7 @@ public class CCAddTaskWindow extends DumbAwareAction {
private static final Logger LOG = Logger.getInstance(CCAddTaskWindow.class);
public CCAddTaskWindow() {
super("Add Problem to Solve", "Add problem to solve", null);
super("Add Answer Placeholder", "Add answer placeholder", null);
}
@@ -204,7 +204,7 @@ public class CCCreateCourseArchive extends DumbAwareAction {
@Override
public boolean accept(File pathname) {
String name = pathname.getName();
return !name.contains(".answer") && !name.contains("__pycache__") && !name.contains("_windows");
return !name.contains(".answer") && !name.contains("__pycache__") && !name.contains("_windows") && !name.contains(".pyc");
}
}, null);
}
@@ -18,7 +18,7 @@ public class CCDeleteTaskWindow extends CCTaskWindowAction {
private static final Logger LOG = Logger.getInstance(CCDeleteTaskWindow.class);
public CCDeleteTaskWindow() {
super("Delete Problem","Delete problem", null);
super("Delete Answer Placeholder","Delete answer placeholder", null);
}
@Override
@@ -11,7 +11,7 @@ import org.jetbrains.plugins.coursecreator.ui.CreateTaskWindowDialog;
public class CCShowTaskWindowDetails extends CCTaskWindowAction {
public CCShowTaskWindowDetails() {
super("Show Problem Details", "Show problem details", null);
super("Edit Answer Placeholder", "Edit answer placeholder", null);
}
@Override
@@ -18,7 +18,7 @@ import java.io.*;
public class CreateTaskWindowDialog extends DialogWrapper {
public static final String TITLE = "Add Problem to Solve";
public static final String TITLE = "Add Answer Placeholder";
private static final Logger LOG = Logger.getInstance(CreateTaskWindowDialog.class.getName());
private final TaskWindow myTaskWindow;
private final CreateTaskWindowPanel myPanel;
@@ -3,7 +3,6 @@
<id>com.jetbrains.python.edu.learn-python</id>
<name>Educational plugin for PyCharm</name>
<version>1.1</version>
<vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>
<description><![CDATA[
Educational plugin for students. This plugin allows to learn Python
@@ -41,11 +40,11 @@
<action id="CheckAction" class="com.jetbrains.python.edu.actions.StudyCheckAction" text="Check Task"
description="Check current task">
</action>
<action id="PrevWindowAction" class="com.jetbrains.python.edu.actions.StudyPrevWindowAction" text="Previous Task Window"
description="Navigate to previous task window">
<action id="PrevWindowAction" class="com.jetbrains.python.edu.actions.StudyPrevWindowAction" text="Previous Answer Placeholder"
description="Navigate to the previous answer placeholder">
</action>
<action id="NextWindow" class="com.jetbrains.python.edu.actions.StudyNextWindowAction" text="Next Task Window"
description="Navigate to next task window">
<action id="NextWindow" class="com.jetbrains.python.edu.actions.StudyNextWindowAction" text="Next Answer Placeholder"
description="Navigate to the next answer holder">
</action>
<action id="PreviousTaskAction" class="com.jetbrains.python.edu.actions.StudyPreviousStudyTaskAction" text="Previous Task"
description="Navigate to previous task"/>
@@ -55,8 +54,8 @@
description="Refresh current task"/>
<action id="WatchInputAction" class="com.jetbrains.python.edu.actions.StudyEditInputAction" text="Watch Test Input"
description="Watch test input "/>
<action id="ShowHintAction" class="com.jetbrains.python.edu.actions.StudyShowHintAction" text="Show Hint for Task Window"
description="Show hint for task window"/>
<action id="ShowHintAction" class="com.jetbrains.python.edu.actions.StudyShowHintAction" text="Show Hint for Answer Placeholder"
description="Show hint for answer placeholder"/>
<action id="StudyRunAction" class="com.jetbrains.python.edu.actions.StudyRunAction" text="Run File With Tests"
description="Run your code with tests"/>
<action id="WelcomeScreen.PythonIntro" class="com.jetbrains.python.edu.actions.StudyIntroductionCourseAction" icon="StudyIcons.EducationalProjectType">
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
@@ -188,7 +189,6 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
final VirtualFile taskDir = firstTask.getTaskDir(myProject);
if (taskDir == null) return;
final Map<String, TaskFile> taskFiles = firstTask.getTaskFiles();
VirtualFile activeVirtualFile = null;
for (Map.Entry<String, TaskFile> entry : taskFiles.entrySet()) {
final String name = entry.getKey();
@@ -204,8 +204,16 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
if (activeVirtualFile != null) {
final PsiFile file = PsiManager.getInstance(myProject).findFile(activeVirtualFile);
ProjectView.getInstance(project).select(file, activeVirtualFile, true);
initialized[0] = true;
} else {
String first = StudyUtils.getFirst(taskFiles.keySet());
if (first != null) {
NewVirtualFile firstFile = ((VirtualDirectoryImpl)taskDir).refreshAndFindChild(first);
if (firstFile != null) {
FileEditorManager.getInstance(project).openFile(firstFile, true);
}
}
}
initialized[0] = true;
}
}, ModalityState.current(), new Condition() {
@Override
@@ -117,7 +117,7 @@ class StudyEditorFactoryListener implements EditorFactoryListener {
@Override
public void handle(ReadOnlyFragmentModificationException e) {
HintManager.getInstance().showErrorHint(myEditor, "It's not allowed to delete task windows");
HintManager.getInstance().showErrorHint(myEditor, "It's not allowed to delete answer placeholders");
}
}
}
@@ -33,10 +33,10 @@ public class StudyInstructionPainter extends EditorEmptyTextPainter {
UIUtil.TextPainter painter = new UIUtil.TextPainter().withLineSpacing(1.5f);
painter.appendLine("PyCharm Educational Edition").underlined(new JBColor(Gray._150, Gray._180));
addAction(painter, "Navigate to the next task window", StudyNextWindowAction.ACTION_ID, StudyNextWindowAction.SHORTCUT2, true);
addAction(painter, "Navigate to the next answer placeholder", StudyNextWindowAction.ACTION_ID, StudyNextWindowAction.SHORTCUT2, true);
String shortcut1 = getShortcutText(StudyPrevWindowAction.ACTION_ID, StudyPrevWindowAction.SHORTCUT, false, false);
String shortcut2 = getShortcutText(StudyNextWindowAction.ACTION_ID, StudyNextWindowAction.SHORTCUT, false, false);
String text = "Navigate between task windows with " + shortcut1 +
String text = "Navigate between answer placeholders with " + shortcut1 +
" and " + shortcut2;
painter.appendLine(text).smaller().withBullet();
shortcut1 = getShortcutText(StudyPreviousStudyTaskAction.ACTION_ID, StudyPreviousStudyTaskAction.SHORTCUT, false, false);
@@ -44,7 +44,7 @@ public class StudyInstructionPainter extends EditorEmptyTextPainter {
painter.appendLine("Navigate between tasks with " + shortcut1 + " and " + shortcut2).smaller().withBullet();
addAction(painter, "Reset current task file", StudyRefreshTaskFileAction.ACTION_ID, StudyRefreshTaskFileAction.SHORTCUT, false);
addAction(painter, "Check task", StudyCheckAction.ACTION_ID, StudyCheckAction.SHORTCUT, false);
addAction(painter, "Get hint for the task window", StudyShowHintAction.ACTION_ID, StudyShowHintAction.SHORTCUT, false);
addAction(painter, "Get hint for the answer placeholder", StudyShowHintAction.ACTION_ID, StudyShowHintAction.SHORTCUT, false);
painter.appendLine("To see your progress open the 'Course Description' panel").smaller().withBullet();
painter.draw(g, new PairFunction<Integer, Integer, Couple<Integer>>() {
@Override
@@ -16,7 +16,7 @@ public class StudyNextWindowAction extends StudyWindowNavigationAction {
public static final String SHORTCUT2 = "ctrl pressed ENTER";
public StudyNextWindowAction() {
super("NextWindowAction", "Select next window", AllIcons.Actions.Forward);
super("Navigate to the Next Answer Placeholder", "Navigate to the next answer placeholder", AllIcons.Actions.Forward);
}
@Override
@@ -17,7 +17,7 @@ public class StudyPrevWindowAction extends StudyWindowNavigationAction {
public static final String SHORTCUT = "ctrl shift pressed COMMA";
public StudyPrevWindowAction() {
super("PrevWindowAction", "Select previous window", StudyIcons.Prev);
super("Navigate to the Previous Answer Placeholder", "Navigate to the previous answer placeholder", StudyIcons.Prev);
}
@@ -28,8 +28,8 @@ import java.io.File;
public class StudyShowHintAction extends DumbAwareAction {
public static final String ACTION_ID = "ShowHintAction";
public static final String SHORTCUT = "ctrl pressed 7";
public static final String OUTSIDE_TASK_WINDOW_MESSAGE = "Put caret to the task window to get hint.";
public static final String HINT_NOT_AVAILABLE = "There is no hint for this task window";
public static final String OUTSIDE_TASK_WINDOW_MESSAGE = "Put caret to answer placeholder to get hint";
public static final String HINT_NOT_AVAILABLE = "There is no hint for this answer placeholder";
public StudyShowHintAction() {
super("Show hint", "Show hint", StudyIcons.ShowHint);
@@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.util.Set;
import java.util.Map;
public class StudyDirectoryNode extends PsiDirectoryNode {
private final PsiDirectory myValue;
@@ -144,15 +144,24 @@ public class StudyDirectoryNode extends PsiDirectoryNode {
FileEditorManager.getInstance(myProject).closeFile(openFile);
}
VirtualFile child = null;
Set<String> fileNames = task.getTaskFiles().keySet();
for (String name : fileNames) {
child = taskDir.findChild(name);
if (child != null) {
FileEditorManager.getInstance(myProject).openFile(child, true);
Map<String, TaskFile> taskFiles = task.getTaskFiles();
for (Map.Entry<String, TaskFile> entry: taskFiles.entrySet()) {
VirtualFile file = taskDir.findChild(entry.getKey());
if (file != null) {
FileEditorManager.getInstance(myProject).openFile(file, true);
}
if (!entry.getValue().getTaskWindows().isEmpty()) {
child = file;
}
}
if (child != null) {
ProjectView.getInstance(myProject).select(child, child, false);
FileEditorManager.getInstance(myProject).openFile(child, true);
} else {
VirtualFile[] children = taskDir.getChildren();
if (children.length > 0) {
ProjectView.getInstance(myProject).select(children[0], children[0], false);
}
}
}
}
@@ -1,6 +1,5 @@
import sys
from import_hook import import_hook_manager
backends = {'tk': 'TkAgg',
'gtk': 'GTKAgg',
@@ -57,6 +56,16 @@ def patch_use(interpreter):
setattr(matplotlib, "use", patched_use)
def patch_is_interactive():
""" Patch matplotlib function 'use' """
matplotlib = sys.modules['matplotlib']
def patched_is_interactive():
return matplotlib.rcParams['interactive']
setattr(matplotlib, "real_is_interactive", getattr(matplotlib, "is_interactive"))
setattr(matplotlib, "is_interactive", patched_is_interactive)
def activate_matplotlib(interpreter):
"""Set interactive to True for interactive backends."""
def activate_matplotlib_inner():
@@ -73,13 +82,10 @@ def activate_matplotlib(interpreter):
sys.stdout.write("Backend %s is non-interactive backend. Turning interactive mode off.\n" % backend)
matplotlib.interactive(False)
patch_use(interpreter)
patch_is_interactive()
return activate_matplotlib_inner
def init_matplotlib(interpreter):
import_hook_manager.add_module_name("matplotlib", activate_matplotlib(interpreter))
def flag_calls(func):
"""Wrap a function to detect and flag when it gets called.
@@ -116,17 +122,9 @@ def activate_pylab():
pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
def init_pylab():
import_hook_manager.add_module_name("pylab", activate_pylab)
def activate_pyplot():
pyplot = sys.modules['matplotlib.pyplot']
pyplot.show._needmain = False
# We need to detect at runtime whether show() is called by the user.
# For this, we wrap it into a decorator which adds a 'called' flag.
pyplot.draw_if_interactive = flag_calls(pyplot.draw_if_interactive)
def init_pyplot():
import_hook_manager.add_module_name("pyplot", activate_pyplot)
+5 -4
View File
@@ -171,10 +171,11 @@ def process_exec_queue(interpreter):
set_return_control_callback(return_control)
from pydev_ipython.matplotlibtools import init_matplotlib, init_pylab, init_pyplot
init_matplotlib(interpreter)
init_pylab()
init_pyplot()
from pydev_import_hook import import_hook_manager
from pydev_ipython.matplotlibtools import activate_matplotlib, activate_pylab, activate_pyplot
import_hook_manager.add_module_name("matplotlib", activate_matplotlib(interpreter))
import_hook_manager.add_module_name("pylab", activate_pylab)
import_hook_manager.add_module_name("pyplot", activate_pyplot)
while 1:
# Running the request may have changed the inputhook in use
@@ -20,47 +20,50 @@ import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.QualifiedName;
import com.intellij.util.containers.hash.HashMap;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
import com.jetbrains.python.codeInsight.dataflow.scope.Scope;
import com.jetbrains.python.inspections.quickfix.PyRenameElementQuickFix;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
import com.jetbrains.python.sdk.PythonSdkType;
import com.jetbrains.python.testing.pytest.PyTestUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Map;
import java.util.regex.Pattern;
/**
*
* User : ktisha
*/
public class PyPep8NamingInspection extends PyInspection {
private static final Pattern LOWERCASE_REGEX = Pattern.compile("[_\\p{javaLowerCase}][_\\p{javaLowerCase}0-9]*");
private static final Pattern UPPERCASE_REGEX = Pattern.compile("[_\\p{javaUpperCase}][_\\p{javaUpperCase}0-9]*");
private static final Pattern MIXEDCASE_REGEX = Pattern.compile("_?[\\p{javaUpperCase}][\\p{javaLowerCase}\\p{javaUpperCase}0-9]*");
public boolean ignoreOverriddenFunctions = true;
public boolean ignoreTestFunctions = false;
private static Pattern LOWERCASE_REGEX = Pattern.compile("[_\\p{javaLowerCase}][_\\p{javaLowerCase}0-9]*");
private static Pattern UPPERCASE_REGEX = Pattern.compile("[_\\p{javaUpperCase}][_\\p{javaUpperCase}0-9]*");
private static Pattern MIXEDCASE_REGEX = Pattern.compile("_?[\\p{javaUpperCase}][\\p{javaLowerCase}\\p{javaUpperCase}0-9]*");
public boolean ignoreDescendantsOfStandardClasses = false;
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder,
boolean isOnTheFly,
@NotNull LocalInspectionToolSession session) {
if (ApplicationManager.getApplication().isUnitTestMode())
ignoreTestFunctions = true;
if (ApplicationManager.getApplication().isUnitTestMode()) {
ignoreDescendantsOfStandardClasses = true;
}
return new Visitor(holder, session);
}
public class Visitor extends PyInspectionVisitor {
private final Map<PyFunction, Boolean> myHasSupers = new HashMap<PyFunction, Boolean>();
public Visitor(@NotNull final ProblemsHolder holder, LocalInspectionToolSession session) {
super(holder, session);
}
@@ -95,22 +98,42 @@ public class PyPep8NamingInspection extends PyInspection {
}
@Override
public void visitPyFunction(PyFunction node) {
final PyClass containingClass = node.getContainingClass();
if (hasSupers(node) && ignoreOverriddenFunctions) return;
if(containingClass != null && PyTestUtil.isPyTestClass(containingClass) && ignoreTestFunctions) return;
final String name = node.getName();
public void visitPyFunction(PyFunction function) {
final PyClass containingClass = function.getContainingClass();
if (ignoreOverriddenFunctions && isOverriddenMethod(function)) return;
final String name = function.getName();
if (name == null) return;
if (containingClass != null && name.startsWith("__") && name.endsWith("__")) {
if (containingClass != null && PyUtil.isSpecialName(name)) {
return;
}
if (containingClass != null && ignoreDescendantsOfStandardClasses && isStandardClassDescendant(containingClass)) {
return;
}
if (!LOWERCASE_REGEX.matcher(name).matches()) {
final ASTNode nameNode = node.getNameNode();
final ASTNode nameNode = function.getNameNode();
if (nameNode != null)
registerProblem(nameNode.getPsi(), "Function name should be lowercase", new PyRenameElementQuickFix());
}
}
private boolean isOverriddenMethod(@NotNull PyFunction function) {
return PySuperMethodsSearch.search(function).findFirst() != null;
}
private boolean isStandardClassDescendant(@NotNull final PyClass cls) {
if (PyTestUtil.isPyTestClass(cls)) {
return true;
}
return ContainerUtil.exists(cls.getAncestorClasses(myTypeEvalContext), new Condition<PyClass>() {
@Override
public boolean value(PyClass ancestor) {
final PsiFile ancestorsModule = ancestor.getContainingFile();
final Sdk sdk = PyBuiltinCache.findSdkForFile(ancestorsModule);
return PythonSdkType.isStdLib(ancestorsModule.getVirtualFile(), sdk) && !PyBuiltinCache.getInstance(cls).isBuiltin(ancestor);
}
});
}
@Override
public void visitPyClass(PyClass node) {
final String name = node.getName();
@@ -147,16 +170,6 @@ public class PyPep8NamingInspection extends PyInspection {
registerProblem(node.getAsNameElement(), "CamelCase variable imported as constant", new PyRenameElementQuickFix());
}
}
private boolean hasSupers(@NotNull PyFunction function) {
final Boolean cached = myHasSupers.get(function);
if (cached != null) {
return cached;
}
final boolean result = PySuperMethodsSearch.search(function).findFirst() != null;
myHasSupers.put(function, result);
return result;
}
}
@Nullable
@@ -164,7 +177,7 @@ public class PyPep8NamingInspection extends PyInspection {
public JComponent createOptionsPanel() {
MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this);
panel.addCheckbox("Ignore overridden functions", "ignoreOverriddenFunctions");
panel.addCheckbox("Ignore test functions", "ignoreTestFunctions");
panel.addCheckbox("Ignore descendants of standard classes", "ignoreDescendantsOfStandardClasses");
return panel;
}
}
@@ -16,6 +16,7 @@
package com.jetbrains.python.psi.search;
import com.intellij.injected.editor.VirtualFileWindow;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
@@ -186,6 +187,10 @@ public class PyProjectScopeBuilder extends ProjectScopeBuilderImpl {
file.findChild("xml") != null && file.findChild("email") != null) {
return file;
}
// Mock SDK does not have aforementioned modules
if (ApplicationManager.getApplication().isUnitTestMode() && file.getName().equals("Lib")) {
return file;
}
}
return null;
}
@@ -15,23 +15,26 @@
*/
package com.jetbrains.python.testing.pytest;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyStatement;
import com.jetbrains.python.psi.types.PyClassLikeType;
import com.jetbrains.python.psi.types.TypeEvalContext;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* User: catherine
*/
public class PyTestUtil {
private static final HashSet<String> PYTHON_TEST_QUALIFIED_CLASSES = Sets.newHashSet("unittest.TestCase", "unittest.case.TestCase");
private static final Set<String> PYTHON_TEST_QUALIFIED_CLASSES = ImmutableSet.of("unittest.TestCase", "unittest.case.TestCase");
public static List<PyStatement> getPyTestCasesFromFile(PsiFileSystemItem file) {
List<PyStatement> result = Lists.newArrayList();
@@ -0,0 +1,7 @@
import collections
class MyDict(collections.OrderedDict):
def getLast(self):
if self:
return list(self.values)[-1]
raise ValueError()
@@ -65,6 +65,11 @@ public class PyPep8NamingInspectionTest extends PyTestCase {
doTest();
}
// PY-13537
public void testDescendantOfStandardClass() {
doTest();
}
public void testTest() {
doTest();
}
@@ -16,6 +16,8 @@
package com.intellij.xml.breadcrumbs;
import com.intellij.application.options.editor.WebEditorOptions;
import com.intellij.codeInsight.daemon.impl.tagTreeHighlighting.XmlTagTreeHighlightingUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.lang.Language;
@@ -25,10 +27,14 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorFontType;
import com.intellij.openapi.editor.event.CaretAdapter;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
@@ -52,10 +58,7 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.*;
/**
* @author spleaner
@@ -64,6 +67,7 @@ public class BreadcrumbsXmlWrapper implements BreadcrumbsItemListener<Breadcrumb
private final BreadcrumbsComponent<BreadcrumbsPsiItem> myComponent;
private final Project myProject;
private Editor myEditor;
private Collection<RangeHighlighter> myHighlighed;
private final VirtualFile myFile;
private boolean myUserCaretChange;
private final MergingUpdateQueue myQueue;
@@ -383,6 +387,27 @@ public class BreadcrumbsXmlWrapper implements BreadcrumbsItemListener<Breadcrumb
}
}
@Override
public void itemHovered(@Nullable BreadcrumbsPsiItem item) {
if (myHighlighed != null) {
for (RangeHighlighter highlighter : myHighlighed) {
HighlightManager.getInstance(myProject).removeSegmentHighlighter(myEditor, highlighter);
}
myHighlighed = null;
}
if (item != null) {
final TextRange range = item.getPsiElement().getTextRange();
final TextAttributes attributes = new TextAttributes();
final CrumbPresentation p = item.getPresentation();
final Color color = p != null ? p.getBackgroundColor(false, false, false) : BreadcrumbsComponent.ButtonSettings.DEFAULT_BG_COLOR;
final Color background = EditorColorsManager.getInstance().getGlobalScheme().getColor(EditorColors.CARET_ROW_COLOR);
attributes.setBackgroundColor(XmlTagTreeHighlightingUtil.makeTransparent(color, background, 0.3));
myHighlighed = new ArrayList<RangeHighlighter>(1);
HighlightManager.getInstance(myProject).addRangeHighlight(myEditor, range.getStartOffset(), range.getEndOffset(),
attributes, true, true, myHighlighed);
}
}
@Nullable
public static BreadcrumbsXmlWrapper getBreadcrumbsComponent(@NotNull Editor editor) {
return editor.getUserData(BREADCRUMBS_COMPONENT_KEY);
@@ -121,6 +121,9 @@ public class BreadcrumbsComponent<T extends BreadcrumbsItem> extends JComponent
}
myHovered = crumb;
for (BreadcrumbsItemListener listener : myListeners) {
listener.itemHovered(myHovered != null ? myHovered.myItem : null);
}
repaint();
}
@@ -16,12 +16,12 @@
package com.intellij.xml.breadcrumbs;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author spleaner
*/
public interface BreadcrumbsItemListener<T extends BreadcrumbsItem> {
void itemSelected(@NotNull final T item, final int modifiers);
void itemHovered(@Nullable final T item);
}
@@ -33,7 +33,7 @@ import java.util.Set;
/**
* @author Eugene.Kudelevsky
*/
class XmlTagTreeHighlightingUtil {
public class XmlTagTreeHighlightingUtil {
private XmlTagTreeHighlightingUtil() {
}
@@ -76,7 +76,7 @@ class XmlTagTreeHighlightingUtil {
return false;
}
static Color makeTransparent(@NotNull Color color, @NotNull Color backgroundColor, double transparency) {
public static Color makeTransparent(@NotNull Color color, @NotNull Color backgroundColor, double transparency) {
int r = makeTransparent(transparency, color.getRed(), backgroundColor.getRed());
int g = makeTransparent(transparency, color.getGreen(), backgroundColor.getGreen());
int b = makeTransparent(transparency, color.getBlue(), backgroundColor.getBlue());