Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2013-08-08 14:05:43 +02:00
58 changed files with 586 additions and 345 deletions
@@ -43,6 +43,7 @@ public class ImageDocumentationProvider extends AbstractDocumentationProvider {
final VirtualFile file = ((PsiFileSystemItem)element).getVirtualFile();
if (file instanceof VirtualFileWithId && !DumbService.isDumb(element.getProject())) {
ImageInfoIndex.processValues(file, new FileBasedIndex.ValueProcessor<ImageInfoIndex.ImageInfo>() {
@Override
public boolean process(VirtualFile file, ImageInfoIndex.ImageInfo value) {
int imageWidth = value.width;
int imageHeight = value.height;
@@ -62,7 +63,7 @@ public class ImageDocumentationProvider extends AbstractDocumentationProvider {
result[0] = String.format("<html><body><img src=\"%s\" width=\"%s\" height=\"%s\"><p>%sx%s, %sbpp</p><body></html>", url, imageWidth,
imageHeight, value.width, value.height, value.bpp);
}
catch (URISyntaxException e) {
catch (URISyntaxException ignored) {
// nothing
}
return true;
@@ -1485,7 +1485,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
return Collections.emptyList();
}
private static List<MethodContract> parseContract(String text) throws ParseException {
public static List<MethodContract> parseContract(String text) throws ParseException {
List<MethodContract> result = ContainerUtil.newArrayList();
for (String clause : StringUtil.replace(text, " ", "").split(";")) {
String arrow = "->";
@@ -1516,7 +1516,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
throw new ParseException("Constraint should be one of: null, !null, true, false, exit, fail, _. Found: " + name);
}
private static class ParseException extends Exception {
public static class ParseException extends Exception {
private ParseException(String message) {
super(message);
}
@@ -48,6 +48,7 @@ import com.intellij.util.ArrayUtilRt;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.SmartList;
import org.jdom.Element;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -98,6 +99,35 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
public void visitClassInitializer(PsiClassInitializer initializer) {
analyzeCodeBlock(initializer.getBody(), holder);
}
@Override
public void visitAnnotation(PsiAnnotation annotation) {
if (!Contract.class.getName().equals(annotation.getQualifiedName())) return;
PsiMethod method = PsiTreeUtil.getParentOfType(annotation, PsiMethod.class);
if (method == null) return;
PsiAnnotationMemberValue value = annotation.findAttributeValue(null);
Object text = JavaPsiFacade.getInstance(annotation.getProject()).getConstantEvaluationHelper().computeConstantExpression(value);
if (!(text instanceof String)) return;
List<MethodContract> contracts;
try {
contracts = ControlFlowAnalyzer.parseContract((String)text);
}
catch (ControlFlowAnalyzer.ParseException e) {
holder.registerProblem(value, e.getMessage());
return;
}
int paramCount = method.getParameterList().getParametersCount();
for (int i = 0; i < contracts.size(); i++) {
MethodContract contract = contracts.get(i);
if (contract.arguments.length != paramCount) {
holder.registerProblem(value, "Method takes " + paramCount + " parameters, while contract clause " + i + " expects " + contract.arguments.length);
return;
}
}
}
};
}
@@ -0,0 +1,25 @@
/*
* Copyright 2000-2013 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.codeInsight.generation;
import com.intellij.codeInsight.MemberImplementorExplorer;
public class MemberImplementorExplorersProviderImpl implements OverrideImplementExploreUtil.MemberImplementorExplorersProvider {
@Override
public MemberImplementorExplorer[] getExplorers() {
return OverrideImplementUtil.getImplementors();
}
}
@@ -3,13 +3,11 @@ package com.intellij.compilerOutputIndex.api.indexer;
import com.intellij.compilerOutputIndex.api.fs.CompilerOutputFilesUtil;
import com.intellij.compilerOutputIndex.api.fs.FileVisitorService;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompileTask;
import com.intellij.openapi.compiler.CompilationStatusAdapter;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
@@ -19,6 +17,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.registry.RegistryValue;
import com.intellij.openapi.util.registry.RegistryValueListener;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Consumer;
import com.intellij.util.indexing.ID;
import com.intellij.util.indexing.IndexInfrastructure;
@@ -111,39 +110,22 @@ public class CompilerOutputIndexer extends AbstractProjectComponent {
catch (IOException e) {
throw new RuntimeException(e);
}
CompilerManager.getInstance(myProject).addAfterTask(new CompileTask() {
CompilerManager.getInstance(myProject).addCompilationStatusListener(new CompilationStatusAdapter() {
@Override
public boolean execute(final CompileContext context) {
if (myEnabled.get() && myInProgress.compareAndSet(false, true)) {
myLock.lock();
public void fileGenerated(final String outputRoot, final String relativePath) {
if (myEnabled.get() && StringUtil.endsWith(relativePath, CompilerOutputFilesUtil.CLASS_FILES_SUFFIX)) {
try {
context.getProgressIndicator().setText("Compiler output indexing in progress");
final Consumer<File> fileConsumer = new Consumer<File>() {
@Override
public void consume(final File file) {
try {
doIndexing(file, context.getProgressIndicator());
}
catch (ProcessCanceledException e0) {
throw e0;
}
catch (RuntimeException e) {
LOG.error(e);
}
}
};
for (final Module module : context.getCompileScope().getAffectedModules()) {
CompilerOutputFilesUtil.iterateModuleClassFiles(module, fileConsumer);
}
doIndexing(new File(outputRoot, relativePath), null);
}
finally {
myLock.unlock();
myInProgress.set(false);
catch (ProcessCanceledException e0) {
throw e0;
}
catch (RuntimeException e) {
LOG.error(e);
}
}
return true;
}
});
}, myProject);
if (needReindex) {
reindexAllProjectInBackground();
}
@@ -233,7 +215,7 @@ public class CompilerOutputIndexer extends AbstractProjectComponent {
}
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
private void doIndexing(@NotNull final File file, @NotNull final ProgressIndicator indicator) {
private void doIndexing(@NotNull final File file, @Nullable final ProgressIndicator indicator) {
final String filePath;
try {
filePath = file.getCanonicalPath();
@@ -267,7 +249,9 @@ public class CompilerOutputIndexer extends AbstractProjectComponent {
}
}
try {
indicator.setText2(filePath);
if (indicator != null) {
indicator.setText2(filePath);
}
final int id = myFileEnumerator.enumerate(filePath);
for (final CompilerOutputBaseIndex index : myIndexes) {
index.update(id, reader);
@@ -125,7 +125,7 @@ public class ClassesTreeStructureProvider implements SelectableTreeStructureProv
return current != null ? current : baseRootFile;
}
private boolean isSelectable(PsiElement element) {
private static boolean isSelectable(PsiElement element) {
if (element instanceof PsiFileSystemItem) return true;
if (element instanceof PsiField || element instanceof PsiClass || element instanceof PsiMethod) {
@@ -84,7 +84,7 @@ public class JavaCodeBlockModificationListener implements PsiTreeChangePreproces
myModificationTracker.incCounter();
}
}
catch (PsiInvalidElementAccessException e) {
catch (PsiInvalidElementAccessException ignored) {
myModificationTracker.incCounter(); // Shall not happen actually, just a pre-release paranoia
}
}
@@ -16,7 +16,7 @@
package com.intellij.psi.impl.source.resolve.reference.impl.providers;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
@@ -87,7 +87,7 @@ public class FilePathReferenceProvider extends PsiReferenceProvider {
systemItems.addAll(getRoots(forModule, true));
}
} else {
systemItems.addAll(getRoots(ModuleUtil.findModuleForPsiElement(getElement()), true));
systemItems.addAll(getRoots(ModuleUtilCore.findModuleForPsiElement(getElement()), true));
}
return systemItems;
}
@@ -144,7 +144,7 @@ public class FilePathReferenceProvider extends PsiReferenceProvider {
if (thisModule == null) return Collections.emptyList();
Set<Module> modules = new com.intellij.util.containers.HashSet<Module>();
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(thisModule);
ModuleUtil.getDependencies(thisModule, modules);
ModuleUtilCore.getDependencies(thisModule, modules);
List<PsiFileSystemItem> result = new ArrayList<PsiFileSystemItem>();
final PsiManager psiManager = PsiManager.getInstance(thisModule.getProject());
if (includingClasses) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2013 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.
@@ -122,8 +122,6 @@ public class PsiClassConverter extends Converter<PsiClass> implements CustomRefe
extendClass);
provider.setOption(JavaClassReferenceProvider.CLASS_KIND, ClassKind.ANNOTATION);
//provider.setOption(JavaClassReferenceProvider.EXTEND_CLASS_NAMES, new String[] {"org.springframework.samples.petclinic.jsr330.Foo"});
//
return provider;
}
}
@@ -1,13 +1,9 @@
package com.intellij.codeInsight;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;
public interface MemberImplementorExplorer {
ExtensionPointName<MemberImplementorExplorer> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.methodImplementor");
@NotNull
PsiMethod[] getMethodsToImplement(PsiClass aClass);
@NotNull PsiMethod[] getMethodsToImplement(PsiClass aClass);
}
@@ -15,6 +15,7 @@
*/
package com.intellij.psi;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.ConcurrentMap;
@@ -33,6 +34,7 @@ public abstract class PsiConstantEvaluationHelper {
* @return the result of the evaluation, or null if the expression is not a constant expression.
*/
@Nullable
@Contract("null -> null")
public Object computeConstantExpression(PsiElement expression) {
return computeConstantExpression(expression, false);
}
@@ -1,8 +1,10 @@
package com.intellij.codeInsight.generation;
import com.intellij.codeInsight.MemberImplementorExplorer;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.NullableLazyValue;
import com.intellij.openapi.util.VolatileNullableLazyValue;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -111,6 +113,17 @@ public class OverrideImplementExploreUtil {
}
}
public interface MemberImplementorExplorersProvider {
MemberImplementorExplorer[] getExplorers();
}
private static final NullableLazyValue<MemberImplementorExplorersProvider> ourExplorersProvider = new VolatileNullableLazyValue<MemberImplementorExplorersProvider>() {
@Override
protected MemberImplementorExplorersProvider compute() {
return ServiceManager.getService(MemberImplementorExplorersProvider.class);
}
};
public static void collectMethodsToImplement(PsiClass aClass,
Map<MethodSignature, PsiMethod> abstracts,
Map<MethodSignature, PsiMethod> finals,
@@ -132,12 +145,16 @@ public class OverrideImplementExploreUtil {
}
}
for (final MemberImplementorExplorer implementor : Extensions.getExtensions(MemberImplementorExplorer.EXTENSION_POINT_NAME)) {
for (final PsiMethod method : implementor.getMethodsToImplement(aClass)) {
MethodSignature signature = MethodSignatureUtil.createMethodSignature(method.getName(), method.getParameterList(),
method.getTypeParameterList(), PsiSubstitutor.EMPTY, method.isConstructor());
CandidateInfo info = new CandidateInfo(method, PsiSubstitutor.EMPTY);
result.put(signature, info);
MemberImplementorExplorersProvider explorersProvider = ourExplorersProvider.getValue();
if (explorersProvider != null) {
for (final MemberImplementorExplorer implementor : explorersProvider.getExplorers()) {
for (final PsiMethod method : implementor.getMethodsToImplement(aClass)) {
MethodSignature signature = MethodSignatureUtil.createMethodSignature(method.getName(), method.getParameterList(),
method.getTypeParameterList(), PsiSubstitutor.EMPTY,
method.isConstructor());
CandidateInfo info = new CandidateInfo(method, PsiSubstitutor.EMPTY);
result.put(signature, info);
}
}
}
}
@@ -101,7 +101,7 @@ public class PsiParameterImpl extends JavaStubPsiElement<PsiParameterStub> imple
@NotNull
private PsiElement getParameterIdentifier() {
PsiJavaToken identifier = PsiTreeUtil.getChildOfAnyType(this, PsiIdentifier.class, PsiKeyword.class);
assert identifier != null : this;
assert identifier != null : getClass() + ":" + getText();
return identifier;
}
@@ -616,19 +616,31 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
final Map<PsiTypeParameter, PsiType> map1 = classSubstitutor1.getSubstitutionMap();
final Map<PsiTypeParameter, PsiType> map2 = classSubstitutor2.getSubstitutionMap();
if (map1.size() == 1 && map2.size() == 1) {
boolean leftAssignable = InheritanceUtil.isInheritorOrSelf(aClass2, aClass1, true);
boolean rightAssignable = InheritanceUtil.isInheritorOrSelf(aClass1, aClass2, true);
final PsiType t1 = map1.values().iterator().next();
final PsiType t2 = map2.values().iterator().next();
boolean raw1 = t1 instanceof PsiClassType && ((PsiClassType)t1).hasParameters();
boolean raw2 = t2 instanceof PsiClassType && ((PsiClassType)t2).hasParameters();
if (!raw1 && raw2) return Specifics.FIRST;
if (raw1 && !raw2) return Specifics.SECOND;
if (!raw1 && raw2) return leftAssignable ? Specifics.FIRST : Specifics.NEITHER;
if (raw1 && !raw2) return rightAssignable ? Specifics.SECOND : Specifics.NEITHER;
final PsiTypeParameter p1 = map1.keySet().iterator().next();
final PsiTypeParameter p2 = map2.keySet().iterator().next();
final Specifics specifics = checkTypeParams(method1, method2, classSubstitutor1, classSubstitutor2, type1, type2, p1, p2);
if (specifics != null) return specifics;
return chooseHigherDimension(t1, t2);
Specifics specifics = checkTypeParams(method1, method2, classSubstitutor1, classSubstitutor2, type1, type2, p1, p2);
if (specifics == null) {
specifics = chooseHigherDimension(t1, t2);
}
if (specifics != null) {
if (specifics == Specifics.FIRST) {
if (leftAssignable && !rightAssignable) return Specifics.NEITHER;
}
else if (specifics == Specifics.SECOND) {
if (rightAssignable && !leftAssignable) return Specifics.NEITHER;
}
}
return specifics;
}
return null;
}
@@ -0,0 +1,11 @@
import java.util.*;
abstract class A {
static <T> void foo(List<T> x) { }
static <T extends List<?>> void foo(Collection<T> x) { }
public static void main(String[] args){
List<List<String>> x = null;
foo<error descr="Ambiguous method call: both 'A.foo(List<List<String>>)' and 'A.foo(Collection<List<String>>)' match">(x)</error>;
foo<error descr="Ambiguous method call: both 'A.foo(List<Object>)' and 'A.foo(Collection<List<?>>)' match">(null)</error>;
}
}
@@ -32,4 +32,10 @@ public class AssertIsNotNull {
}
Object call() {return new Object();}
@Contract(<warning descr="A contract clause must be in form arg1, ..., argN -> return-value">"a"</warning>)
void malformedContract() {}
@Contract(<warning descr="Method takes 2 parameters, while contract clause 0 expects 1">"null -> _"</warning>)
void wrongParameterCount(Object a, boolean b) {}
}
@@ -63,14 +63,19 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase {
}
""")
type('i')
assertContains("iterable", "if", "int")
def les = myFixture.lookupElementStrings
assert 'iterable' in les
assert 'if' in les
assert 'int' in les
type('t')
assertContains "iterable"
assertEquals 'iterable', lookup.currentItem.lookupString
type('er')
assertContains "iterable", "iter"
les = myFixture.lookupElementStrings
assert 'iterable' in les
assert 'iter' in les
assertEquals 'iterable', lookup.currentItem.lookupString
assert lookup.focused
@@ -309,6 +309,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA57289() { doTest5(false); }
public void testIDEA57439() { doTest5(false); }
public void testIDEA57312() { doTest5(false); }
public void testIDEA67865() { doTest5(false); }
public void testJavaUtilCollections_NoVerify() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
@@ -51,7 +51,7 @@ public class IElementType {
};
public static final short FIRST_TOKEN_INDEX = 1;
public static final short MAX_INDEXED_TYPES = 15000;
public static final short MAX_INDEXED_TYPES = 20000;
private static short ourCounter = FIRST_TOKEN_INDEX;
private static IElementType[] ourRegistry = new IElementType[700];
@@ -348,7 +348,8 @@ public class PsiUtilCore {
}
@Nullable
public static VirtualFile getVirtualFile(@Nullable PsiElement element) {
public static VirtualFile getVirtualFile(@Nullable Object object) {
PsiElement element = object instanceof PsiElement ? (PsiElement)object : null;
if (element == null || !element.isValid()) {
return null;
}
@@ -3,7 +3,10 @@ package com.intellij.psi.impl.search;
import com.intellij.openapi.application.QueryExecutorBase;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.meta.PsiMetaData;
import com.intellij.psi.meta.PsiMetaOwner;
import com.intellij.psi.search.SearchScope;
@@ -44,9 +47,7 @@ public class CachesBasedRefSearcher extends QueryExecutorBase<PsiReference, Refe
}
if (StringUtil.isNotEmpty(text)) {
final SearchScope searchScope = p.getEffectiveSearchScope();
assert text != null;
p.getOptimizer().searchWord(text, searchScope, refElement.getLanguage().isCaseSensitive(), refElement);
}
}
}
}
@@ -21,19 +21,22 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.problems.WolfTheProblemSolver;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* A node in the project view tree.
@@ -103,23 +106,21 @@ public abstract class ProjectViewNode <Value> extends AbstractTreeNode<Value> im
public static AbstractTreeNode createTreeNode(Class<? extends AbstractTreeNode> nodeClass,
Project project,
Object value,
ViewSettings settings) throws NoSuchMethodException,
InstantiationException,
IllegalAccessException,
InvocationTargetException {
ViewSettings settings) throws
InstantiationException {
Object[] parameters = new Object[]{project, value, settings};
for (Constructor<? extends AbstractTreeNode> constructor : (Constructor<? extends AbstractTreeNode>[])nodeClass.getConstructors()) {
if (constructor.getParameterTypes().length != 3) continue;
try {
return constructor.newInstance(parameters);
}
catch (InstantiationException e) {
catch (InstantiationException ignored) {
}
catch (IllegalAccessException e) {
catch (IllegalAccessException ignored) {
}
catch (IllegalArgumentException e) {
catch (IllegalArgumentException ignored) {
}
catch (InvocationTargetException e) {
catch (InvocationTargetException ignored) {
}
}
throw new InstantiationException("no constructor found in " + nodeClass);
@@ -142,7 +143,7 @@ public abstract class ProjectViewNode <Value> extends AbstractTreeNode<Value> im
break;
}
if (VfsUtil.isAncestor(eachRoot, file, true)) {
if (VfsUtilCore.isAncestor(eachRoot, file, true)) {
mayContain = true;
break;
}
@@ -193,7 +194,7 @@ public abstract class ProjectViewNode <Value> extends AbstractTreeNode<Value> im
public boolean value(final VirtualFile virtualFile) {
return contains(virtualFile)
// in case of flattened packages, when package node a.b.c contains error file, node a.b might not.
&& (getValue() instanceof PsiElement && Comparing.equal(PsiUtilBase.getVirtualFile((PsiElement)getValue()), virtualFile) ||
&& (getValue() instanceof PsiElement && Comparing.equal(PsiUtilCore.getVirtualFile(getValue()), virtualFile) ||
someChildContainsFile(virtualFile));
}
});
@@ -288,4 +288,15 @@ public class PsiUtilBase extends PsiUtilCore {
final VirtualFile virtualFile = element.getVirtualFile();
return virtualFile != null && virtualFile.is(VFileProperty.SYMLINK);
}
@Nullable
public static VirtualFile asVirtualFile(@Nullable Object element) {
if (element instanceof PsiFileSystemItem) {
PsiFileSystemItem psiFileSystemItem = (PsiFileSystemItem)element;
return psiFileSystemItem.isValid() ? psiFileSystemItem.getVirtualFile() : null;
}
else {
return null;
}
}
}
@@ -70,6 +70,7 @@ public class ImagePreviewComponent extends JPanel implements PreviewHintComponen
setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.black), BorderFactory.createEmptyBorder(5, 5, 5, 5)));
}
@Override
@TestOnly
public boolean isEqualTo(@Nullable PreviewHintComponent other) {
if (!(other instanceof ImagePreviewComponent)) {
@@ -159,7 +160,7 @@ public class ImagePreviewComponent extends JPanel implements PreviewHintComponen
}
}
}
catch (IOException e) {
catch (IOException ignored) {
// nothing
}
}
@@ -21,7 +21,10 @@ import com.intellij.execution.configurations.*;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -276,10 +279,10 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
for (ProgramRunner runner : myConfigurationPerRunnerSettings.keySet()) {
ConfigurationPerRunnerSettings settings = myConfigurationPerRunnerSettings.get(runner);
Element runnerElement = new Element(CONFIGURATION_ELEMENT);
runnerElement.setAttribute(RUNNER_ID, runner.getRunnerId());
if (settings != null) {
settings.writeExternal(runnerElement);
}
runnerElement.setAttribute(RUNNER_ID, runner.getRunnerId());
configurationPerRunnerSettings.add(runnerElement);
}
if (myUnloadedConfigurationPerRunnerSettings != null) {
@@ -31,7 +31,7 @@ import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ArrayUtilRt;
import org.jetbrains.annotations.Nullable;
import java.awt.datatransfer.DataFlavor;
@@ -322,7 +322,7 @@ public class PsiCopyPasteManager {
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return ArrayUtil.find(getTransferDataFlavors(), flavor) != -1;
return ArrayUtilRt.find(getTransferDataFlavors(), flavor) != -1;
}
public PsiElement[] getElements() {
@@ -44,6 +44,7 @@ import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
@@ -59,6 +60,7 @@ import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.*;
import com.intellij.ui.border.CustomLineBorder;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.OnOffButton;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
@@ -222,6 +224,12 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
myAlarm.cancelAllRequests();
myList.setModel(new DefaultListModel());
myClassModel = null;
myFileModel = null;
myActionModel = null;
myClasses = null;
myFiles = null;
myActions = null;
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@@ -373,7 +381,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
String title = getTitle(index, value, index == 0 ? null : list.getModel().getElementAt(index -1));
myTitle.setText(title == null ? "" : title);
myLeftPanel.removeAll();
myLeftPanel.setBackground(Gray._242);
myLeftPanel.setBackground(new JBColor(Gray._242, JBColor.background()));
myMainPanel.removeAll();
myLeftPanel.add(myTitle, BorderLayout.EAST);
myMainPanel.add(myLeftPanel, BorderLayout.WEST);
@@ -501,7 +509,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myLeftWidth += 10;
myTitle.setForeground(Gray._122);
myTitle.setAlignmentY(BOTTOM_ALIGNMENT);
myLeftPanel.setBorder(new CompoundBorder(new CustomLineBorder(Gray._206, 0,0,0,1), new EmptyBorder(0,0,0,5)));
myLeftPanel.setBorder(new CompoundBorder(new CustomLineBorder(new JBColor(Gray._206, Gray._75), 0,0,0,1), new EmptyBorder(0,0,0,5)));
}
private Font getTitleFont() {
@@ -631,10 +639,9 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
for (MatchResult o : classes) {
if (clsCounter > 15) break;
myProgressIndicator.checkCanceled();
Object[] objects = myClassModel.getElementsByName(o.elementName, false, pattern);
Object[] objects = myClassModel.getElementsByName(o.elementName, false, pattern, myProgressIndicator);
for (Object object : objects) {
myProgressIndicator.checkCanceled();
if (!listModel.contains(object)) {
listModel.addElement(object);
clsCounter++;
@@ -650,16 +657,13 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
for (MatchResult o : files) {
if (filesCounter > 15) break;
myProgressIndicator.checkCanceled();
Object[] objects = myFileModel.getElementsByName(o.elementName, false, pattern, myProgressIndicator);
for (Object object : objects) {
myProgressIndicator.checkCanceled();
if (!listModel.contains(object)) {
if (object instanceof PsiFile) {
object = ((PsiFile)object).getVirtualFile();
}
if (object instanceof VirtualFile && !alreadyAddedFiles.contains((VirtualFile)object) && !((VirtualFile)object).isDirectory()) {
myProgressIndicator.checkCanceled();
listModel.addElement(object);
filesCounter++;
}
@@ -767,10 +771,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myRenderer.recalculateWidth();
if (myPopup == null || !myPopup.isVisible()) {
final ActionCallback callback = ListDelegationUtil.installKeyboardDelegation(field.getTextEditor(), myList);
myPopup = JBPopupFactory.getInstance()
.createListPopupBuilder(myList)
.setRequestFocus(false)
.createPopup();
final PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(myList);
myPopup = builder.setRequestFocus(false).createPopup();
Disposer.register(myPopup, new Disposable() {
@Override
public void dispose() {
@@ -793,7 +795,18 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myPopup.cancel();
} else {
final Dimension size = myList.getPreferredSize();
myPopup.setSize(new Dimension(Math.min(600, Math.max(field.getWidth(), size.width + 15)), Math.min(600, size.height + 10)));
Dimension sz = new Dimension(Math.max(field.getWidth(), size.width), size.height);
if (sz.width > 800 || sz.height > 800) {
final int extra = new JBScrollPane().getVerticalScrollBar().getWidth();
sz = new Dimension(Math.min(800, Math.max(field.getWidth(), size.width + extra)), Math.min(800, size.height + extra));
sz.width += 16;
} else {
sz.height++;
sz.height++;
sz.width++;
sz.width++;
}
myPopup.setSize(sz);
final Point screen = field.getLocationOnScreen();
final int x = screen.x + field.getWidth() - myPopup.getSize().width;
@@ -823,7 +836,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
MatchResult result;
for (String name : names) {
myProgressIndicator.checkCanceled();
//myProgressIndicator.checkCanceled();
result = null;
if (model instanceof CustomMatcherModel) {
try {
@@ -117,7 +117,9 @@ public class NavBarUpdateQueue extends MergingUpdateQueue {
void restartRebuild() {
myUserActivityAlarm.cancelAllRequests();
myUserActivityAlarm.addRequest(myUserActivityAlarmRunnable, Registry.intValue("navBar.userActivityMergeTime"));
if (!myUserActivityAlarm.isDisposed()) {
myUserActivityAlarm.addRequest(myUserActivityAlarmRunnable, Registry.intValue("navBar.userActivityMergeTime"));
}
}
private void processUserActivity() {
@@ -32,9 +32,8 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.FocusRequestor;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -68,26 +67,15 @@ public abstract class BaseProjectTreeBuilder extends AbstractTreeBuilder {
if (element instanceof AbstractTreeNode) {
AbstractTreeNode node = (AbstractTreeNode)element;
final Object value = node.getValue();
VirtualFile vFile = null;
if (value instanceof PsiFileSystemItem) {
vFile = ((PsiFileSystemItem)value).getVirtualFile();
}
else if (value instanceof PsiElement) {
PsiFile psiFile = ((PsiElement)value).getContainingFile();
if (psiFile != null) {
vFile = psiFile.getVirtualFile();
}
}
final ActionCallback cb = new ActionCallback();
final VirtualFile finalVFile = vFile;
final ActionCallback callback = new ActionCallback();
final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(value);
final FocusRequestor focusRequestor = IdeFocusManager.getInstance(myProject).getFurtherRequestor();
batch(new Progressive() {
@Override
public void run(@NotNull ProgressIndicator indicator) {
final Ref<Object> target = new Ref<Object>();
_select(value, finalVFile, false, Conditions.<AbstractTreeNode>alwaysTrue(), cb, indicator, target, focusRequestor, false);
cb.doWhenDone(new Runnable() {
_select(value, virtualFile, false, Conditions.<AbstractTreeNode>alwaysTrue(), callback, indicator, target, focusRequestor, false);
callback.doWhenDone(new Runnable() {
@Override
public void run() {
result.setDone(target.get());
@@ -31,12 +31,10 @@ import com.intellij.ui.JBTreeWithHintProvider;
import com.intellij.ui.tabs.FileColorManagerImpl;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.plaf.ColorUIResource;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import java.awt.*;
@@ -85,13 +83,13 @@ public abstract class ProjectViewTree extends JBTreeWithHintProvider {
return super.getToggleClickCount();
}
@Override
public Color getBackground() {
if (!UIUtil.isUnderDarcula()) {
return super.getBackground();
}
return new ColorUIResource(0x414750);
}
//@Override
//public Color getBackground() {
// if (!UIUtil.isUnderDarcula()) {
// return super.getBackground();
// }
// return new ColorUIResource(0x414750);
//}
@Override
public boolean isFileColorsEnabled() {
@@ -104,10 +104,10 @@ SplitPane.highlight=3c3f41
Hyperlink.linkColor=589df6
List.background=45494A
Table.background=45494A
#List.background=45494A
#Table.background=45494A
Tree.background=45494A
#Tree.background=45494A
Tree.collapsedIcon=AllIcons.Mac.Tree_white_right_arrow
Tree.expandedIcon=AllIcons.Mac.Tree_white_down_arrow
@@ -61,7 +61,7 @@ public class DirectoryBasedStorage implements StateStorage, Disposable {
final StateSplitter splitter,
Disposable parentDisposable,
final PicoContainer picoContainer) {
assert dir.indexOf("$") < 0;
assert !dir.contains("$") : dir;
myPathMacroSubstitutor = pathMacroSubstitutor;
myDir = FILE_SYSTEM.createFile(dir);
mySplitter = splitter;
@@ -71,18 +71,18 @@ class ContentTabLabel extends BaseLabel {
@Override
protected Color getActiveFg(boolean selected) {
if (contentManager().getContentCount() > 1 && selected) {
return Gray._255;
}
return super.getActiveFg(selected);
if (contentManager().getContentCount() > 1) {
return selected ? Color.white : UIUtil.isUnderDarcula() ? UIUtil.getLabelForeground() : Color.black;
}
return super.getActiveFg(selected);
}
@Override
protected Color getPassiveFg(boolean selected) {
if (contentManager().getContentCount() > 1 && selected && !UIUtil.isUnderDarcula()) {
return Gray._255;
}
return super.getPassiveFg(selected);
if (contentManager().getContentCount() > 1) {
return selected && !UIUtil.isUnderDarcula() ? Gray._255 : UIUtil.isUnderDarcula()? UIUtil.getLabelDisabledForeground() : Gray._75;
}
return super.getPassiveFg(selected);
}
protected void paintComponent(final Graphics g) {
@@ -21,10 +21,13 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -60,7 +63,9 @@ public class UsageTargetUtil {
public static UsageTarget[] findUsageTargets(PsiElement psiElement) {
List<UsageTarget> result = new ArrayList<UsageTarget>();
for (UsageTargetProvider provider : Extensions.getExtensions(EP_NAME)) {
UsageTargetProvider[] providers = Extensions.getExtensions(EP_NAME);
Project project = psiElement.getProject();
for (UsageTargetProvider provider : DumbService.getInstance(project).filterByDumbAwareness(Arrays.asList(providers))) {
UsageTarget[] targets = provider.getTargets(psiElement);
if (targets != null) Collections.addAll(result, targets);
}
@@ -74,7 +74,7 @@ public abstract class XLineBreakpointType<P extends XBreakpointProperties> exten
return fileLineDisplayText(breakpoint.getPresentableFilePath(), breakpoint.getLine());
}
private String fileLineDisplayText(String path, int line) {
private static String fileLineDisplayText(String path, int line) {
return XDebuggerBundle.message("xbreakpoint.default.display.text", line + 1, path);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2013 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.
@@ -19,12 +19,8 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
/**
* @author nik
*/
class RemoveBreakpointGutterIconAction<P extends XBreakpointProperties> extends AnAction {
class RemoveBreakpointGutterIconAction extends AnAction {
private XBreakpointBase<?,?,?> myBreakpoint;
RemoveBreakpointGutterIconAction(XBreakpointBase<?, ?, ?> breakpoint) {
@@ -35,4 +31,4 @@ class RemoveBreakpointGutterIconAction<P extends XBreakpointProperties> extends
public void actionPerformed(final AnActionEvent e) {
XDebuggerUtil.getInstance().removeBreakpoint(myBreakpoint.getProject(), myBreakpoint);
}
}
}
@@ -345,7 +345,7 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
}
@Override
public int compareTo(Self self) {
public int compareTo(@NotNull Self self) {
return myType.getBreakpointComparator().compare((Self)this, self);
}
@@ -71,7 +71,7 @@ public class GithubCreatePullRequestAction extends DumbAwareAction {
return;
}
if (StringUtil.isEmptyOrSpaces(GithubSettings.getInstance().getLogin())) {
if (!GithubSettings.getInstance().isAuthConfigured()) {
setVisibleEnabled(e, false, false);
return;
}
@@ -23,7 +23,6 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ThrowableConvertor;
@@ -42,7 +41,9 @@ import git4idea.util.GitPreservingProcess;
import icons.GithubIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.api.*;
import org.jetbrains.plugins.github.api.GithubApiUtil;
import org.jetbrains.plugins.github.api.GithubFullPath;
import org.jetbrains.plugins.github.api.GithubRepoDetailed;
import java.io.IOException;
import java.util.Collections;
@@ -71,7 +72,7 @@ public class GithubRebaseAction extends DumbAwareAction {
return;
}
if (StringUtil.isEmptyOrSpaces(GithubSettings.getInstance().getLogin())) {
if (!GithubSettings.getInstance().isAuthConfigured()) {
setVisibleEnabled(e, false, false);
return;
}
@@ -115,6 +116,7 @@ public class GithubRebaseAction extends DumbAwareAction {
new Task.Backgroundable(project, "Rebasing GitHub fork...") {
@Override
public void run(@NotNull ProgressIndicator indicator) {
gitRepository.update();
String upstreamRemoteUrl = GithubUtil.findUpstreamRemote(gitRepository);
if (upstreamRemoteUrl == null) {
@@ -23,9 +23,11 @@ import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.api.GithubApiUtil;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import static org.jetbrains.plugins.github.GithubAuthData.AuthType;
@@ -52,15 +54,15 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S
}
public static class State {
public String LOGIN = "";
public String HOST = GithubApiUtil.DEFAULT_GITHUB_HOST;
public AuthType AUTH_TYPE = AuthType.ANONYMOUS;
@Nullable public String LOGIN = null;
@NotNull public String HOST = GithubApiUtil.DEFAULT_GITHUB_HOST;
@NotNull public AuthType AUTH_TYPE = AuthType.ANONYMOUS;
public boolean ANONYMOUS_GIST = false;
public boolean OPEN_IN_BROWSER_GIST = true;
public boolean PRIVATE_GIST = true;
public boolean SAVE_PASSWORD = true;
public Collection<String> TRUSTED_HOSTS = new ArrayList<String>();
public String CREATE_PULL_REQUEST_DEFAULT_BRANCH = "";
@NotNull public Collection<String> TRUSTED_HOSTS = new ArrayList<String>();
@NotNull public String CREATE_PULL_REQUEST_DEFAULT_BRANCH = "";
}
public static GithubSettings getInstance() {
@@ -72,8 +74,7 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S
return myState.HOST;
}
// TODO return null if no login instead of empty string
@NotNull
@Nullable
public String getLogin() {
return StringUtil.notNullize(myState.LOGIN);
}
@@ -83,11 +84,15 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S
return myState.AUTH_TYPE;
}
public boolean isAuthConfigured() {
return !myState.AUTH_TYPE.equals(AuthType.ANONYMOUS);
}
private void setHost(@NotNull String host) {
myState.HOST = StringUtil.notNullize(host, GithubApiUtil.DEFAULT_GITHUB_HOST);
}
private void setLogin(@NotNull String login) {
private void setLogin(@Nullable String login) {
myState.LOGIN = login;
}
@@ -203,13 +208,16 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S
switch (auth.getAuthType()) {
case BASIC:
assert auth.getBasicAuth() != null;
setLogin(auth.getBasicAuth().getLogin());
setPassword(auth.getBasicAuth().getPassword(), rememberPassword);
break;
case TOKEN:
assert auth.getTokenAuth() != null;
setLogin(null);
setPassword(auth.getTokenAuth().getToken(), rememberPassword);
break;
case ANONYMOUS:
setLogin(null);
setPassword("", rememberPassword);
break;
default:
@@ -217,9 +225,8 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S
}
}
public void setCredentials(@NotNull String host, @NotNull String login, @NotNull GithubAuthData auth, boolean rememberPassword) {
public void setCredentials(@NotNull String host, @NotNull GithubAuthData auth, boolean rememberPassword) {
setHost(host);
setLogin(login);
setAuthData(auth, rememberPassword);
}
}
@@ -35,7 +35,8 @@ import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.api.*;
import org.jetbrains.plugins.github.api.GithubApiUtil;
import org.jetbrains.plugins.github.api.GithubUserDetailed;
import org.jetbrains.plugins.github.ui.GithubBasicLoginDialog;
import org.jetbrains.plugins.github.ui.GithubLoginDialog;
@@ -109,12 +110,15 @@ public class GithubUtil {
}
@NotNull
public static <T> T runWithValidBasicAuth(@Nullable Project project,
@NotNull ProgressIndicator indicator,
@NotNull ThrowableConvertor<GithubAuthData, T, IOException> task) throws IOException {
public static <T> T runWithValidBasicAuthForHost(@Nullable Project project,
@NotNull ProgressIndicator indicator,
@NotNull String host,
@NotNull ThrowableConvertor<GithubAuthData, T, IOException> task) throws IOException {
GithubSettings settings = GithubSettings.getInstance();
GithubAuthData auth;
if (GithubSettings.getInstance().getAuthType() == GithubAuthData.AuthType.BASIC) {
auth = GithubSettings.getInstance().getAuthData();
if (settings.getAuthType() == GithubAuthData.AuthType.BASIC &&
StringUtil.equalsIgnoreCase(GithubUrlUtil.getApiUrl(host), GithubUrlUtil.getApiUrl(settings.getHost()))) {
auth = settings.getAuthData();
}
else {
auth = GithubAuthData.createAnonymous();
@@ -126,7 +130,7 @@ public class GithubUtil {
return task.convert(auth);
}
catch (GithubAuthenticationException e) {
auth = getValidBasicAuthData(project, indicator);
auth = getValidBasicAuthDataForHost(project, indicator, host);
if (auth == null) {
throw new GithubAuthenticationCanceledException("Can't get valid credentials");
}
@@ -134,7 +138,7 @@ public class GithubUtil {
}
catch (IOException e) {
if (checkSSLCertificate(e, auth.getHost(), indicator)) {
return runWithValidBasicAuth(project, indicator, task);
return runWithValidBasicAuthForHost(project, indicator, host, task);
}
throw e;
}
@@ -177,8 +181,11 @@ public class GithubUtil {
* @return null if user canceled login dialog. Valid GithubAuthData otherwise.
*/
@Nullable
public static GithubAuthData getValidBasicAuthData(@Nullable Project project, @NotNull ProgressIndicator indicator) {
public static GithubAuthData getValidBasicAuthDataForHost(@Nullable Project project,
@NotNull ProgressIndicator indicator,
@NotNull String host) {
final GithubLoginDialog dialog = new GithubBasicLoginDialog(project);
dialog.lockHost(host);
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
@@ -232,12 +239,7 @@ public class GithubUtil {
throw new GithubAuthenticationException("Anonymous connection not allowed");
}
try {
return testConnection(auth);
}
catch (JsonException e) {
throw new GithubAuthenticationException("Can't get user info", e);
}
return testConnection(auth);
}
@NotNull
@@ -19,9 +19,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author Aleksey Pivovarov
*/
/**
*
* All fields of the raw type are nullable by the nature of GSon parser;
* but some of them are required, so we want them to be @NotNull in the actual data class,
* otherwise there is an error in JSon data received from the server
@@ -43,6 +43,7 @@ public class GithubApiUtil {
public static final String DEFAULT_GITHUB_HOST = "github.com";
private static final int CONNECTION_TIMEOUT = 5000;
private static final String PER_PAGE = "per_page=100";
private static final Logger LOG = GithubUtil.LOG;
private static final Header ACCEPT_HTML_BODY_MARKUP = new Header("Accept", "application/vnd.github.v3.html+json");
@@ -207,10 +208,9 @@ public class GithubApiUtil {
case HttpStatus.SC_UNAUTHORIZED:
case HttpStatus.SC_PAYMENT_REQUIRED:
case HttpStatus.SC_FORBIDDEN:
case HttpStatus.SC_NOT_FOUND:
throw new GithubAuthenticationException("Request response: " + getErrorMessage(method));
default:
throw new HttpException(code + ": " + getErrorMessage(method));
throw new GithubStatusCodeException(code + ": " + getErrorMessage(method), code);
}
}
@@ -375,7 +375,7 @@ public class GithubApiUtil {
public static Collection<String> getTokenScopes(@NotNull GithubAuthData auth) throws IOException {
HttpMethod method = null;
try {
method = doREST(auth, "", null, null, HttpVerb.HEAD);
method = doREST(auth, "/user", null, null, HttpVerb.HEAD);
checkStatusCode(method);
@@ -409,6 +409,16 @@ public class GithubApiUtil {
return response.getToken();
}
@NotNull
public static String getReadOnlyToken(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo, @Nullable String note)
throws IOException {
GithubRepo repository = getDetailedRepoInfo(auth, user, repo);
List<String> scopes = repository.isPrivate() ? Collections.singletonList("repo") : Collections.<String>emptyList();
return getScopedToken(auth, scopes, note);
}
@NotNull
public static GithubUser getCurrentUser(@NotNull GithubAuthData auth) throws IOException {
JsonElement result = getRequest(auth, "/user");
@@ -433,7 +443,7 @@ public class GithubApiUtil {
@NotNull
private static List<GithubRepo> doGetAvailableRepos(@NotNull GithubAuthData auth, @Nullable String user) throws IOException {
String path = user == null ? "/user/repos" : "/users/" + user + "/repos?per_page=100";
String path = user == null ? "/user/repos" : "/users/" + user + "/repos?" + PER_PAGE;
PagedRequest<GithubRepo> request = new PagedRequest<GithubRepo>(path, GithubRepo.class, GithubRepoRaw[].class);
@@ -509,10 +519,10 @@ public class GithubApiUtil {
@Nullable String assigned) throws IOException {
String path;
if (StringUtil.isEmptyOrSpaces(assigned)) {
path = "/repos/" + user + "/" + repo + "/issues?per_page=100";
path = "/repos/" + user + "/" + repo + "/issues?" + PER_PAGE;
}
else {
path = "/repos/" + user + "/" + repo + "/issues?assignee=" + assigned + "&per_page=100";
path = "/repos/" + user + "/" + repo + "/issues?assignee=" + assigned + "&" + PER_PAGE;
}
PagedRequest<GithubIssue> request = new PagedRequest<GithubIssue>(path, GithubIssue.class, GithubIssueRaw[].class);
@@ -549,7 +559,7 @@ public class GithubApiUtil {
@NotNull
public static List<GithubIssueComment> getIssueComments(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo, long id)
throws IOException {
String path = "/repos/" + user + "/" + repo + "/issues/" + id + "/comments?per_page=100";
String path = "/repos/" + user + "/" + repo + "/issues/" + id + "/comments?" + PER_PAGE;
PagedRequest<GithubIssueComment> request =
new PagedRequest<GithubIssueComment>(path, GithubIssueComment.class, GithubIssueCommentRaw[].class, ACCEPT_HTML_BODY_MARKUP);
@@ -579,7 +589,7 @@ public class GithubApiUtil {
@NotNull
public static List<GithubPullRequest> getPullRequests(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo)
throws IOException {
String path = "/repos/" + user + "/" + repo + "/pulls?per_page=100";
String path = "/repos/" + user + "/" + repo + "/pulls?" + PER_PAGE;
PagedRequest<GithubPullRequest> request =
new PagedRequest<GithubPullRequest>(path, GithubPullRequest.class, GithubPullRequestRaw[].class, ACCEPT_HTML_BODY_MARKUP);
@@ -589,7 +599,7 @@ public class GithubApiUtil {
@NotNull
public static PagedRequest<GithubPullRequest> getPullRequests(@NotNull String user, @NotNull String repo) {
String path = "/repos/" + user + "/" + repo + "/pulls?per_page=100";
String path = "/repos/" + user + "/" + repo + "/pulls?" + PER_PAGE;
return new PagedRequest<GithubPullRequest>(path, GithubPullRequest.class, GithubPullRequestRaw[].class, ACCEPT_HTML_BODY_MARKUP);
}
@@ -597,7 +607,7 @@ public class GithubApiUtil {
@NotNull
public static List<GithubCommit> getPullRequestCommits(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo, long id)
throws IOException {
String path = "/repos/" + user + "/" + repo + "/pulls/" + id + "/commits?per_page=100";
String path = "/repos/" + user + "/" + repo + "/pulls/" + id + "/commits?" + PER_PAGE;
PagedRequest<GithubCommit> request = new PagedRequest<GithubCommit>(path, GithubCommit.class, GithubCommitRaw[].class);
@@ -607,7 +617,7 @@ public class GithubApiUtil {
@NotNull
public static List<GithubFile> getPullRequestFiles(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo, long id)
throws IOException {
String path = "/repos/" + user + "/" + repo + "/pulls/" + id + "/files?per_page=100";
String path = "/repos/" + user + "/" + repo + "/pulls/" + id + "/files?" + PER_PAGE;
PagedRequest<GithubFile> request = new PagedRequest<GithubFile>(path, GithubFile.class, GithubFileRaw[].class);
@@ -617,7 +627,7 @@ public class GithubApiUtil {
@NotNull
public static List<GithubBranch> getRepoBranches(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo)
throws IOException {
String path = "/repos/" + user + "/" + repo + "/branches?per_page=100";
String path = "/repos/" + user + "/" + repo + "/branches?" + PER_PAGE;
PagedRequest<GithubBranch> request = new PagedRequest<GithubBranch>(path, GithubBranch.class, GithubBranchRaw[].class);
@@ -629,7 +639,7 @@ public class GithubApiUtil {
@NotNull String user,
@NotNull String repo,
@NotNull String forkUser) throws IOException {
String path = "/repos/" + user + "/" + repo + "/forks?per_page=100";
String path = "/repos/" + user + "/" + repo + "/forks?" + PER_PAGE;
PagedRequest<GithubRepo> request = new PagedRequest<GithubRepo>(path, GithubRepo.class, GithubRepoRaw[].class);
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2013 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.github.api;
import java.io.IOException;
/**
* @author Aleksey Pivovarov
*/
public class GithubStatusCodeException extends IOException {
private final int myStatusCode;
public GithubStatusCodeException(String message, int statusCode) {
super(message);
myStatusCode = statusCode;
}
public int getStatusCode() {
return myStatusCode;
}
}
@@ -13,16 +13,19 @@ import com.intellij.util.ThrowableConvertor;
import com.intellij.util.ui.FormBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.*;
import org.jetbrains.plugins.github.GithubAuthData;
import org.jetbrains.plugins.github.GithubAuthenticationCanceledException;
import org.jetbrains.plugins.github.GithubNotifications;
import org.jetbrains.plugins.github.GithubUtil;
import org.jetbrains.plugins.github.api.GithubApiUtil;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
/**
* @author Dennis.Ushakov
@@ -34,7 +37,7 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor
private JButton myTokenButton;
private JBLabel myRepoAuthorLabel;
private JBLabel myRepoLabel;
private JCheckBox myPrivateRepo;
private JBLabel myTokenLabel;
public GithubRepositoryEditor(final Project project, final GithubRepository repository, Consumer<GithubRepository> changeListener) {
super(project, repository, changeListener);
@@ -42,11 +45,32 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor
myUsernameLabel.setVisible(false);
myPasswordText.setVisible(false);
myPasswordLabel.setVisible(false);
myUseHttpAuthenticationCheckBox.setVisible(false);
myToken.setText(repository.getToken());
myRepoAuthor.setText(repository.getRepoAuthor());
myRepoName.setText(repository.getRepoName());
myPrivateRepo.setSelected(false);
DocumentListener buttonUpdater = new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
updateTokenButton();
}
@Override
public void removeUpdate(DocumentEvent e) {
updateTokenButton();
}
@Override
public void changedUpdate(DocumentEvent e) {
updateTokenButton();
}
};
myRepoAuthor.getDocument().addDocumentListener(buttonUpdater);
myRepoName.getDocument().addDocumentListener(buttonUpdater);
myURLText.getDocument().addDocumentListener(buttonUpdater);
setAnchor(myRepoAuthorLabel);
}
@@ -56,7 +80,7 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor
protected JComponent createCustomPanel() {
myUrlLabel.setText("Host:");
myRepoAuthorLabel = new JBLabel("Repository author:", SwingConstants.RIGHT);
myRepoAuthorLabel = new JBLabel("Repository Owner:", SwingConstants.RIGHT);
myRepoAuthor = new JTextField();
installListener(myRepoAuthor);
@@ -64,9 +88,10 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor
myRepoName = new JTextField();
installListener(myRepoName);
myTokenLabel = new JBLabel("API Token:", SwingConstants.RIGHT);
myToken = new JTextField();
installListener(myToken);
myTokenButton = new JButton("API token");
myTokenButton = new JButton("Create API token");
myTokenButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
generateToken();
@@ -74,70 +99,39 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor
}
});
myPrivateRepo = new JCheckBox("Private repository");
installListener(myPrivateRepo);
JPanel myTokenPanel = new JPanel();
myTokenPanel.setLayout(new BorderLayout(5, 5));
myTokenPanel.add(myToken, BorderLayout.CENTER);
myTokenPanel.add(myTokenButton, BorderLayout.EAST);
return FormBuilder.createFormBuilder().setAlignLabelOnRight(true).addLabeledComponent(myTokenButton, myToken)
.addLabeledComponent(myRepoAuthorLabel, myRepoAuthor).addLabeledComponent(myRepoLabel, myRepoName)
.addComponentToRightColumn(myPrivateRepo).getPanel();
return FormBuilder.createFormBuilder().setAlignLabelOnRight(true).addLabeledComponent(myRepoAuthorLabel, myRepoAuthor)
.addLabeledComponent(myRepoLabel, myRepoName).addLabeledComponent(myTokenLabel, myTokenPanel).getPanel();
}
@Override
public void apply() {
myRepository.setRepoName(myRepoName.getText().trim());
myRepository.setRepoAuthor(myRepoAuthor.getText().trim());
myRepository.setToken(myToken.getText().trim());
myUseHttpAuthenticationCheckBox.setSelected(!StringUtil.isEmpty(myUserNameText.getText()));
myRepository.setRepoName(getRepoName());
myRepository.setRepoAuthor(getRepoAuthor());
myRepository.setToken(getToken());
super.apply();
}
@Override
protected void afterTestConnection(final boolean connectionSuccessful) {
if (connectionSuccessful) {
final Ref<Collection<String>> scopesRef = new Ref<Collection<String>>();
final Ref<IOException> exceptionRef = new Ref<IOException>();
ProgressManager.getInstance().run(new Task.Modal(myProject, "Access to GitHub", true) {
public void run(@NotNull ProgressIndicator indicator) {
try {
scopesRef
.set(GithubApiUtil.getTokenScopes(GithubAuthData.createTokenAuth(myURLText.getText().trim(), myToken.getText().trim())));
}
catch (IOException e) {
exceptionRef.set(e);
}
}
});
if (!exceptionRef.isNull()) {
GithubNotifications.showErrorDialog(myProject, "Can't check token scopes", exceptionRef.get());
return;
}
Collection<String> scopes = scopesRef.get();
if (myPrivateRepo.isSelected()) {
scopes.remove("repo");
}
if (scopes.isEmpty()) {
return;
}
GithubNotifications
.showWarningDialog(myProject, "Unneeded token scopes detected", "Unneeded scopes: " + StringUtil.join(scopes, ", "));
}
}
private void generateToken() {
final Ref<String> tokenRef = new Ref<String>();
final Ref<IOException> exceptionRef = new Ref<IOException>();
final Collection<String> scopes = myPrivateRepo.isSelected() ? Collections.singleton("repo") : Collections.<String>emptyList();
ProgressManager.getInstance().run(new Task.Modal(myProject, "Access to GitHub", true) {
public void run(@NotNull ProgressIndicator indicator) {
try {
tokenRef.set(GithubUtil.runWithValidBasicAuth(myProject, indicator, new ThrowableConvertor<GithubAuthData, String, IOException>() {
@Nullable
@Override
public String convert(GithubAuthData auth) throws IOException {
return GithubApiUtil.getScopedToken(auth, scopes, "Intellij tasks plugin");
}
}));
tokenRef.set(GithubUtil.runWithValidBasicAuthForHost(myProject, indicator, getHost(),
new ThrowableConvertor<GithubAuthData, String, IOException>() {
@NotNull
@Override
public String convert(GithubAuthData auth) throws IOException {
return GithubApiUtil
.getReadOnlyToken(auth, getRepoAuthor(), getRepoName(),
"Intellij tasks plugin");
}
}));
}
catch (IOException e) {
exceptionRef.set(e);
@@ -159,5 +153,37 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor
super.setAnchor(anchor);
myRepoAuthorLabel.setAnchor(anchor);
myRepoLabel.setAnchor(anchor);
myTokenLabel.setAnchor(anchor);
}
private void updateTokenButton() {
if (StringUtil.isEmptyOrSpaces(getHost()) ||
StringUtil.isEmptyOrSpaces(getRepoAuthor()) ||
StringUtil.isEmptyOrSpaces(getRepoName())) {
myTokenButton.setEnabled(false);
}
else {
myTokenButton.setEnabled(true);
}
}
@NotNull
private String getHost() {
return myURLText.getText().trim();
}
@NotNull
private String getRepoAuthor() {
return myRepoAuthor.getText().trim();
}
@NotNull
private String getRepoName() {
return myRepoName.getText().trim();
}
@NotNull
private String getToken() {
return myToken.getText().trim();
}
}
@@ -34,8 +34,7 @@ public class GithubBasicLoginDialog extends GithubLoginDialog {
protected void saveCredentials(GithubAuthData auth) {
final GithubSettings settings = GithubSettings.getInstance();
if (settings.getAuthType() != GithubAuthData.AuthType.TOKEN) {
settings
.setCredentials(myGithubLoginPanel.getHost(), myGithubLoginPanel.getLogin(), auth, myGithubLoginPanel.isSavePasswordSelected());
settings.setCredentials(myGithubLoginPanel.getHost(), auth, myGithubLoginPanel.isSavePasswordSelected());
}
}
}
@@ -6,10 +6,8 @@ import com.intellij.openapi.ui.DialogWrapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.GithubAuthData;
import org.jetbrains.plugins.github.GithubAuthenticationException;
import org.jetbrains.plugins.github.GithubSettings;
import org.jetbrains.plugins.github.GithubUtil;
import org.jetbrains.plugins.github.api.GithubUserDetailed;
import javax.swing.*;
import java.io.IOException;
@@ -70,12 +68,7 @@ public class GithubLoginDialog extends DialogWrapper {
protected void doOKAction() {
final GithubAuthData auth = myGithubLoginPanel.getAuthData();
try {
GithubUserDetailed user = GithubUtil.checkAuthData(auth);
if (!myGithubLoginPanel.getLogin().equalsIgnoreCase(user.getLogin())) {
myGithubLoginPanel.setLogin(user.getLogin());
setErrorText("Login doesn't match credentials. Fixed");
return;
}
GithubUtil.checkAuthData(auth);
saveCredentials(auth);
if (mySettings.isSavePasswordMakesSense()) {
@@ -91,7 +84,7 @@ public class GithubLoginDialog extends DialogWrapper {
protected void saveCredentials(GithubAuthData auth) {
final GithubSettings settings = GithubSettings.getInstance();
settings.setCredentials(myGithubLoginPanel.getHost(), myGithubLoginPanel.getLogin(), auth, myGithubLoginPanel.isSavePasswordSelected());
settings.setCredentials(myGithubLoginPanel.getHost(), auth, myGithubLoginPanel.isSavePasswordSelected());
}
public void clearErrors() {
@@ -102,4 +95,8 @@ public class GithubLoginDialog extends DialogWrapper {
public GithubAuthData getAuthData() {
return myGithubLoginPanel.getAuthData();
}
public void lockHost(String host) {
myGithubLoginPanel.lockHost(host);
}
}
@@ -3,29 +3,13 @@
<grid id="27dc6" binding="myPane" layout-manager="GridLayoutManager" row-count="6" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="168"/>
<xy x="20" y="20" width="500" height="174"/>
</constraints>
<properties>
<focusable value="false"/>
</properties>
<border type="none"/>
<children>
<component id="e76ec" class="javax.swing.JTextField" binding="myLoginTextField">
<constraints>
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="c0234" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Login:"/>
</properties>
</component>
<component id="28ddd" class="javax.swing.JTextPane" binding="mySignupTextField">
<constraints>
<grid row="4" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
@@ -71,7 +55,7 @@
</component>
<component id="f851a" class="javax.swing.JComboBox" binding="myAuthTypeComboBox">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<model/>
@@ -80,7 +64,7 @@
</component>
<component id="b466f" class="javax.swing.JCheckBox" binding="mySavePasswordCheckBox">
<constraints>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
<preferred-size width="120" height="-1"/>
</grid>
</constraints>
@@ -91,7 +75,7 @@
</component>
<component id="325bb" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Auth type:"/>
@@ -105,6 +89,22 @@
<text value="Password:"/>
</properties>
</component>
<component id="e76ec" class="javax.swing.JTextField" binding="myLoginTextField">
<constraints>
<grid row="2" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="c0234" class="javax.swing.JLabel" binding="myLoginLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Login:"/>
</properties>
</component>
</children>
</grid>
</form>
@@ -21,6 +21,7 @@ import com.intellij.ui.HyperlinkAdapter;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.table.ComponentsListFocusTraversalPolicy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.GithubAuthData;
import org.jetbrains.plugins.github.GithubUtil;
@@ -31,7 +32,7 @@ import javax.swing.event.HyperlinkEvent;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
/**
@@ -47,6 +48,7 @@ public class GithubLoginPanel {
private JCheckBox mySavePasswordCheckBox;
private JComboBox myAuthTypeComboBox;
private JLabel myPasswordLabel;
private JLabel myLoginLabel;
private final static String AUTH_PASSWORD = "Password";
private final static String AUTH_TOKEN = "Token";
@@ -79,8 +81,21 @@ public class GithubLoginPanel {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
String item = e.getItem().toString();
myPasswordLabel.setText(item + ":");
mySavePasswordCheckBox.setText("Save " + item.toLowerCase());
if (AUTH_PASSWORD.equals(item)) {
myPasswordLabel.setText("Password:");
mySavePasswordCheckBox.setText("Save password");
myLoginLabel.setVisible(true);
myLoginTextField.setVisible(true);
}
if (AUTH_TOKEN.equals(item)) {
myPasswordLabel.setText("Token:");
mySavePasswordCheckBox.setText("Save token");
myLoginLabel.setVisible(false);
myLoginTextField.setVisible(false);
}
if (dialog.isShowing()) {
dialog.pack();
}
}
}
});
@@ -103,7 +118,7 @@ public class GithubLoginPanel {
myHostTextField.setText(host);
}
public void setLogin(@NotNull String login) {
public void setLogin(@Nullable String login) {
myLoginTextField.setText(login);
}
@@ -125,6 +140,11 @@ public class GithubLoginPanel {
myAuthTypeComboBox.setEnabled(false);
}
public void lockHost(@NotNull String host) {
setHost(host);
myHostTextField.setEnabled(false);
}
public void setSavePasswordSelected(boolean savePassword) {
mySavePasswordCheckBox.setSelected(savePassword);
}
@@ -46,7 +46,7 @@ public class GithubSettingsConfigurable implements SearchableConfigurable, VcsCo
public void apply() throws ConfigurationException {
if (mySettingsPane != null) {
mySettings.setCredentials(mySettingsPane.getHost(), mySettingsPane.getLogin(), mySettingsPane.getAuthData(), true);
mySettings.setCredentials(mySettingsPane.getHost(), mySettingsPane.getAuthData(), true);
mySettingsPane.resetCredentialsModification();
}
}
@@ -16,7 +16,7 @@
</constraints>
<properties/>
</component>
<component id="c0234" class="javax.swing.JLabel">
<component id="c0234" class="javax.swing.JLabel" binding="myLoginLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
@@ -22,8 +22,11 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.HyperlinkAdapter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.github.*;
import org.jetbrains.plugins.github.api.GithubUserDetailed;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.GithubAuthData;
import org.jetbrains.plugins.github.GithubAuthenticationException;
import org.jetbrains.plugins.github.GithubSettings;
import org.jetbrains.plugins.github.GithubUtil;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
@@ -53,6 +56,7 @@ public class GithubSettingsPanel {
private JButton myTestButton;
private JTextField myHostTextField;
private JComboBox myAuthTypeComboBox;
private JLabel myLoginLabel;
private boolean myCredentialsModified;
@@ -71,18 +75,11 @@ public class GithubSettingsPanel {
myAuthTypeComboBox.addItem(AUTH_PASSWORD);
myAuthTypeComboBox.addItem(AUTH_TOKEN);
reset();
myTestButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
GithubUserDetailed user = GithubUtil.checkAuthData(getAuthData());
if (!getLogin().equalsIgnoreCase(user.getLogin())) {
setLogin(user.getLogin());
Messages.showInfoMessage(myPane, "Login doesn't match credentials. Fixed", "Success");
return;
}
GithubUtil.checkAuthData(getAuthData());
Messages.showInfoMessage(myPane, "Connection successful", "Success");
}
catch (GithubAuthenticationException ex) {
@@ -116,24 +113,21 @@ public class GithubSettingsPanel {
@Override
public void insertUpdate(DocumentEvent e) {
if (!myCredentialsModified) {
setPassword("");
myCredentialsModified = true;
erasePassword();
}
}
@Override
public void removeUpdate(DocumentEvent e) {
if (!myCredentialsModified) {
setPassword("");
myCredentialsModified = true;
erasePassword();
}
}
@Override
public void changedUpdate(DocumentEvent e) {
if (!myCredentialsModified) {
setPassword("");
myCredentialsModified = true;
erasePassword();
}
}
};
@@ -145,8 +139,7 @@ public class GithubSettingsPanel {
@Override
public void focusGained(FocusEvent e) {
if (!myCredentialsModified && !getPassword().isEmpty()) {
setPassword("");
myCredentialsModified = true;
erasePassword();
}
}
@@ -158,10 +151,28 @@ public class GithubSettingsPanel {
myAuthTypeComboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
setPassword("");
myCredentialsModified = true;
if (e.getStateChange() == ItemEvent.SELECTED) {
String item = e.getItem().toString();
if (AUTH_PASSWORD.equals(item)) {
myLoginLabel.setVisible(true);
myLoginTextField.setVisible(true);
}
if (AUTH_TOKEN.equals(item)) {
myLoginLabel.setVisible(false);
myLoginTextField.setVisible(false);
}
myPane.validate();
erasePassword();
}
}
});
reset();
}
private void erasePassword() {
setPassword("");
myCredentialsModified = true;
}
public JComponent getPanel() {
@@ -182,7 +193,7 @@ public class GithubSettingsPanel {
myHostTextField.setText(host);
}
public void setLogin(@NotNull final String login) {
public void setLogin(@Nullable final String login) {
myLoginTextField.setText(login);
}
@@ -232,18 +243,15 @@ public class GithubSettingsPanel {
}
public void reset() {
String login = mySettings.getLogin();
setHost(mySettings.getHost());
setLogin(login);
setPassword(login.isEmpty() ? "" : DEFAULT_PASSWORD_TEXT);
setLogin(mySettings.getLogin());
setPassword(mySettings.isAuthConfigured() ? DEFAULT_PASSWORD_TEXT : "");
setAuthType(mySettings.getAuthType());
resetCredentialsModification();
}
public boolean isModified() {
return !Comparing.equal(mySettings.getHost(), getHost()) ||
!Comparing.equal(mySettings.getLogin(), getLogin()) ||
myCredentialsModified;
return !Comparing.equal(mySettings.getHost(), getHost()) || myCredentialsModified;
}
public void resetCredentialsModification() {
@@ -173,7 +173,7 @@ public abstract class GithubTest extends UsefulTestCase {
myAuth = GithubAuthData.createBasicAuth(host, login1, password);
myGitHubSettings = GithubSettings.getInstance();
myGitHubSettings.setCredentials(myHost, myLogin1, myAuth, false);
myGitHubSettings.setCredentials(myHost, myAuth, false);
myDialogManager = (TestDialogManager)ServiceManager.getService(DialogManager.class);
myNotificator = (TestNotificator)ServiceManager.getService(myProject, Notificator.class);
@@ -10,7 +10,7 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.problems.WolfTheProblemSolver;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -59,6 +59,7 @@ public abstract class AbstractMvcPsiNodeDescriptor extends AbstractPsiBasedNode<
return super.contains(file);
}
@Override
@Nullable
protected PsiElement extractPsiFromValue() {
final NodeId nodeId = getValue();
@@ -86,15 +87,10 @@ public abstract class AbstractMvcPsiNodeDescriptor extends AbstractPsiBasedNode<
if (!isValid()) {
return null;
}
final PsiElement psiElement = extractPsiFromValue();
assert psiElement != null;
if (psiElement instanceof PsiFileSystemItem) {
return ((PsiFileSystemItem)psiElement).getVirtualFile();
}
return psiElement.getContainingFile().getVirtualFile();
return PsiUtilCore.getVirtualFile(extractPsiFromValue());
}
@Override
protected void updateImpl(final PresentationData data) {
final PsiElement psiElement = extractPsiFromValue();
if (psiElement instanceof NavigationItem) {
@@ -110,14 +106,17 @@ public abstract class AbstractMvcPsiNodeDescriptor extends AbstractPsiBasedNode<
return myWeight;
}
@Override
protected boolean hasProblemFileBeneath() {
return WolfTheProblemSolver.getInstance(getProject()).hasProblemFilesBeneath(new Condition<VirtualFile>() {
@Override
public boolean value(final VirtualFile virtualFile) {
return contains(virtualFile);
}
});
}
@Override
public boolean isValid() {
final PsiElement psiElement = extractPsiFromValue();
return psiElement != null && psiElement.isValid();
@@ -34,11 +34,11 @@ import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.actions.ModuleDeleteProvider;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
@@ -169,19 +169,23 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id
toolWindow.setTitleActions(new AnAction[]{new ScrollFromSourceAction(), collapseAction});
}
@Override
public String getTitle() {
throw new UnsupportedOperationException();
}
@Override
public Icon getIcon() {
return myDescriptor.getFramework().getIcon();
}
@Override
@NotNull
public String getId() {
return myId;
}
@Override
public int getWeight() {
throw new UnsupportedOperationException();
}
@@ -191,6 +195,7 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id
throw new UnsupportedOperationException();
}
@Override
public SelectInTarget createSelectInTarget() {
throw new UnsupportedOperationException();
}
@@ -199,12 +204,14 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id
@Override
protected BaseProjectTreeBuilder createBuilder(final DefaultTreeModel treeModel) {
return new ProjectTreeBuilder(myProject, myTree, treeModel, null, (ProjectAbstractTreeStructureBase)myTreeStructure) {
@Override
protected AbstractTreeUpdater createUpdater() {
return createTreeUpdater(this);
}
};
}
@Override
protected ProjectAbstractTreeStructureBase createStructure() {
final Project project = myProject;
final String id = getId();
@@ -215,28 +222,33 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id
return myViewState.hideEmptyMiddlePackages;
}
@Override
protected AbstractTreeNode createRoot(final Project project, ViewSettings settings) {
return new MvcProjectNode(project, this, myDescriptor);
}
};
}
@Override
protected ProjectViewTree createTree(final DefaultTreeModel treeModel) {
return new ProjectViewTree(myProject, treeModel) {
public String toString() {
return myDescriptor.getFramework().getDisplayName() + " " + super.toString();
}
@Override
public DefaultMutableTreeNode getSelectedNode() {
return MvcProjectViewPane.this.getSelectedNode();
}
};
}
@Override
protected AbstractTreeUpdater createTreeUpdater(final AbstractTreeBuilder treeBuilder) {
return new AbstractTreeUpdater(treeBuilder);
}
@Override
@Nullable
protected PsiElement getPSIElement(@Nullable final Object element) {
// E.g is used by Project View's DataProvider
@@ -305,20 +317,23 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id
return content == null ? null : (MvcProjectViewPane)content.getDisposer();
}
@Override
public void selectElement(PsiElement element) {
PsiFileSystemItem psiFile;
if (!(element instanceof PsiFileSystemItem)) {
psiFile = element.getContainingFile();
}
else {
if (element instanceof PsiFileSystemItem) {
psiFile = (PsiFileSystemItem)element;
}
if (psiFile == null) return;
else {
psiFile = element.getContainingFile();
if (psiFile == null) {
return;
}
}
VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile == null) return;
if (virtualFile == null) {
return;
}
selectFile(virtualFile, false);
@@ -337,10 +352,12 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id
}
}
@Override
public PsiDirectory[] getDirectories() {
return getSelectedDirectories();
}
@Override
public PsiDirectory getOrChooseDirectory() {
return DirectoryChooserUtil.getOrChooseDirectory(this);
}
@@ -360,7 +377,7 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id
return null;
}
final Module module = ModuleUtil.findModuleForFile(file, project);
final Module module = ModuleUtilCore.findModuleForFile(file, project);
if (module == null || !framework.hasSupport(module)) {
return null;
}
@@ -386,7 +403,7 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id
if (descriptor instanceof AbstractFolderNode) {
final AbstractFolderNode folderNode = (AbstractFolderNode)descriptor;
final VirtualFile dir = folderNode.getVirtualFile();
if (dir != null && VfsUtil.isAncestor(dir, file, false)) {
if (dir != null && VfsUtilCore.isAncestor(dir, file, false)) {
cur = folderNode;
result.add(folderNode);
if (dir.equals(file)) {
@@ -506,6 +523,7 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id
return myViewState.hideEmptyMiddlePackages;
}
@Override
public void setSelected(AnActionEvent event, boolean flag) {
myViewState.hideEmptyMiddlePackages = flag;
TreeUtil.collapseAll(myTree, 1);
@@ -1,11 +1,16 @@
<html>
<body>
<font face="verdana" size="-1">This inspection reports those conditions in the specified inspection scope that are
always <b><font color="#000080">true</font></b> or <b><font color="#000080">false</font></b>,
as well as points out where a <b><font color="#000080">RuntimeException</font></b> may be thrown,
based on data flow analysis of the code.<br>
This inspection also reports Nullable/NotNull contract violations.
Annotations to support the contract can be configured (by default @Nullable/@NotNull annotations from annotations.jar will be used)
</font>
This inspection analyzes method control and data flow to report possible conditions that are always <b>true</b> or <b>false</b>,
expressions whose value is statically proven to be constant, and situations that can lead to nullability contract violations.<p/>
Variables, method parameters and return values marked as <code>@Nullable</code> or <code>@NotNull</code> are treated as nullable (or not-null, respectively)
and used during the analysis to check nullability contracts, e.g. report possible <code>NullPointerException</code> errors.<p/>
More complex contracts can be defined using <code>@Contract</code> annotation, for example:<p/>
<code>@Contract("_, null -> null")</code> &mdash; method returns null if its second argument is null<br/>
<code>@Contract("_, null -> null; _, !null -> !null")</code> &mdash; method returns null if its second argument is null and not-null otherwise<br/>
<code>@Contract("true -> fail")</code> &mdash; a typical <code>assertFalse</code> method which throws an exception if <code>true</code> is passed to it<br/>
<p/>
The inspection can be configured to use custom <code>@Nullable</code>/<code>@NotNull</code> annotations (by default the ones from annotations.jar will be used)
</body>
</html>
+3
View File
@@ -399,6 +399,9 @@
<applicationService serviceInterface="com.intellij.refactoring.JavaRefactoringSettings"
serviceImplementation="com.intellij.refactoring.JavaRefactoringSettings"/>
<applicationService serviceInterface="com.intellij.codeInsight.generation.OverrideImplementExploreUtil$MemberImplementorExplorersProvider"
serviceImplementation="com.intellij.codeInsight.generation.MemberImplementorExplorersProviderImpl"/>
<projectService serviceInterface="com.intellij.refactoring.RefactoringManager"
serviceImplementation="com.intellij.refactoring.RefactoringManager"/>
<projectService serviceInterface="com.intellij.refactoring.listeners.JavaRefactoringListenerManager"
@@ -44,6 +44,7 @@ public class FileReferenceUtil {
final FileReference[] references = set.getAllReferences();
return ContainerUtil.map2Array(references, PsiReference.class, new NotNullFunction<FileReference, PsiReference>() {
@Override
@NotNull
public PsiReference fun(FileReference fileReference) {
return new MyFileReference(fileReference, cond, soft);
@@ -66,6 +67,7 @@ public class FileReferenceUtil {
myType = type;
}
@Override
public boolean value(PsiFile file) {
return file.getFileType() == myType;
}
@@ -78,6 +80,7 @@ public class FileReferenceUtil {
myPattern = pattern;
}
@Override
public boolean value(PsiFile o) {
return myPattern.accepts(o);
}
@@ -113,6 +116,7 @@ public class FileReferenceUtil {
protected ResolveResult[] innerResolve() {
final ResolveResult[] results = super.innerResolve();
return ContainerUtil.findAll(results, new Condition<ResolveResult>() {
@Override
public boolean value(ResolveResult resolveResult) {
final PsiElement e = resolveResult.getElement();
return match(e, myCond);
@@ -125,6 +129,7 @@ public class FileReferenceUtil {
public Object[] getVariants() {
final Object[] variants = super.getVariants();
return ContainerUtil.findAll(variants, new Condition<Object>() {
@Override
public boolean value(Object o) {
/*if (o instanceof CandidateInfo) {
o = ((CandidateInfo)o).getElement();