mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -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;
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
|
||||
+30
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+25
@@ -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();
|
||||
}
|
||||
}
|
||||
+16
-32
@@ -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);
|
||||
|
||||
+1
-1
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -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);
|
||||
}
|
||||
|
||||
+24
-7
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+17
-5
@@ -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;
|
||||
}
|
||||
|
||||
+11
@@ -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) {}
|
||||
}
|
||||
|
||||
+7
-2
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+8
-8
@@ -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);
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+3
-7
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+7
-8
@@ -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();
|
||||
|
||||
+30
-12
@@ -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> — method returns null if its second argument is null<br/>
|
||||
<code>@Contract("_, null -> null; _, !null -> !null")</code> — method returns null if its second argument is null and not-null otherwise<br/>
|
||||
<code>@Contract("true -> fail")</code> — 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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user