mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote branch 'origin/master'
This commit is contained in:
@@ -18,6 +18,7 @@ package com.intellij.debugger.impl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.sun.jdi.VMDisconnectedException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
@@ -65,14 +66,14 @@ public abstract class InvokeThread<E extends PrioritizedTask> {
|
||||
|
||||
public boolean isInterrupted() {
|
||||
assert myRequestFuture != null;
|
||||
return myRequestFuture.isCancelled();
|
||||
return myRequestFuture.isCancelled() || myRequestFuture.isDone();
|
||||
}
|
||||
|
||||
public void join() throws InterruptedException, ExecutionException {
|
||||
assert myRequestFuture != null;
|
||||
try {
|
||||
myRequestFuture.get();
|
||||
}
|
||||
}
|
||||
catch(CancellationException ignored) {
|
||||
}
|
||||
}
|
||||
@@ -101,7 +102,7 @@ public abstract class InvokeThread<E extends PrioritizedTask> {
|
||||
|
||||
public boolean isDone() {
|
||||
assert myRequestFuture != null;
|
||||
return myRequestFuture.isDone();
|
||||
return myRequestFuture.isDone() && ourWorkerRequest.get() == null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +123,7 @@ public abstract class InvokeThread<E extends PrioritizedTask> {
|
||||
workerRequest.setRequestFuture( ApplicationManager.getApplication().executeOnPooledThread(workerRequest) );
|
||||
}
|
||||
|
||||
public void run(WorkerThreadRequest threadRequest) {
|
||||
private void run(@NotNull WorkerThreadRequest threadRequest) {
|
||||
while(true) {
|
||||
try {
|
||||
if(threadRequest.isInterrupted()) {
|
||||
|
||||
@@ -75,6 +75,8 @@ public class DebuggerTreeBase extends DnDAwareTree implements Disposable {
|
||||
}
|
||||
});
|
||||
|
||||
Disposer.register(this, myTipManager);
|
||||
|
||||
UIUtil.setLineStyleAngled(this);
|
||||
setRootVisible(false);
|
||||
setShowsRootHandles(true);
|
||||
@@ -388,7 +390,5 @@ public class DebuggerTreeBase extends DnDAwareTree implements Disposable {
|
||||
}
|
||||
myCurrentTooltip = null;
|
||||
myCurrentTooltipNode = null;
|
||||
Disposer.dispose(myTipManager);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -544,7 +544,7 @@ public class HighlightMethodUtil {
|
||||
PsiMethod method = methodCandidate.getElement();
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
PsiSubstitutor substitutor = methodCandidate.getSubstitutor();
|
||||
@NonNls String ms = "<td><b>" + method.getName() + "</b></td>";
|
||||
@NonNls @Language("HTML") String ms = "<td><b>" + method.getName() + "</b></td>";
|
||||
|
||||
for (int j = 0; j < parameters.length; j++) {
|
||||
PsiParameter parameter = parameters[j];
|
||||
|
||||
@@ -120,7 +120,7 @@ public class AddMethodFix extends LocalQuickFixAndIntentionActionOnPsiElement {
|
||||
}
|
||||
PsiMethod method = (PsiMethod)myClass.add(myMethodPrototype);
|
||||
method = (PsiMethod)method.replace(reformat(project, method));
|
||||
if (editor != null) {
|
||||
if (editor != null && method.getContainingFile() == file) {
|
||||
GenerateMembersUtil.positionCaret(editor, method, true);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -126,7 +126,9 @@ public class CreateConstructorMatchingSuperFix extends BaseIntentionAction {
|
||||
}
|
||||
}
|
||||
|
||||
derived.getNameIdentifier().replace(targetClass.getNameIdentifier());
|
||||
final PsiIdentifier identifier = targetClass.getNameIdentifier();
|
||||
LOG.assertTrue(identifier != null, targetClass);
|
||||
derived.getNameIdentifier().replace(identifier);
|
||||
@NonNls StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("void foo () {\nsuper(");
|
||||
|
||||
|
||||
+14
-3
@@ -55,13 +55,23 @@ import java.util.regex.PatternSyntaxException;
|
||||
public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> implements HintAction, HighPriorityAction {
|
||||
private final T myRef;
|
||||
|
||||
protected ImportClassFixBase(T ref) {
|
||||
protected ImportClassFixBase(@NotNull T ref) {
|
||||
myRef = ref;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return myRef.isValid() && file.getManager().isInProject(file) && !getClassesToImport().isEmpty();
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiFile file) {
|
||||
if (!myRef.isValid()) {
|
||||
return false;
|
||||
}
|
||||
PsiManager manager = file.getManager();
|
||||
if (!manager.isInProject(file)) {
|
||||
return false;
|
||||
}
|
||||
if (getClassesToImport().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -70,6 +80,7 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im
|
||||
|
||||
protected abstract boolean hasTypeParameters(T reference);
|
||||
|
||||
@NotNull
|
||||
public List<PsiClass> getClassesToImport() {
|
||||
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(myRef.getProject());
|
||||
String name = getReferenceName(myRef);
|
||||
|
||||
+2
-4
@@ -36,7 +36,6 @@ public class SideEffectWarningDialog extends DialogWrapper {
|
||||
private final String myBeforeText;
|
||||
private final String myAfterText;
|
||||
private final boolean myCanCopeWithSideEffects;
|
||||
private AbstractAction myMakeStmtAction;
|
||||
private AbstractAction myRemoveAllAction;
|
||||
private AbstractAction myCancelAllAction;
|
||||
public static final int MAKE_STATEMENT = 1;
|
||||
@@ -71,7 +70,7 @@ public class SideEffectWarningDialog extends DialogWrapper {
|
||||
};
|
||||
actions.add(myRemoveAllAction);
|
||||
if (myCanCopeWithSideEffects) {
|
||||
myMakeStmtAction = new AbstractAction() {
|
||||
AbstractAction makeStmtAction = new AbstractAction() {
|
||||
{
|
||||
UIUtil.setActionNameAndMnemonic(QuickFixBundle.message("side.effect.action.transform"), this);
|
||||
}
|
||||
@@ -80,9 +79,8 @@ public class SideEffectWarningDialog extends DialogWrapper {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
close(MAKE_STATEMENT);
|
||||
}
|
||||
|
||||
};
|
||||
actions.add(myMakeStmtAction);
|
||||
actions.add(makeStmtAction);
|
||||
}
|
||||
myCancelAllAction = new AbstractAction() {
|
||||
{
|
||||
|
||||
+5
-9
@@ -132,11 +132,7 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
}
|
||||
|
||||
if (isStringLiteral(token)) {
|
||||
boolean escapeSlashes = true;
|
||||
if (rawText != null && rawText.rawText != null) {
|
||||
//is is assumed that all slashes are escaped in the raw text but some unescaped symbols can present (for example " copied from CharLiteral '"')
|
||||
//so we should escape all needed symbols except slash.
|
||||
escapeSlashes = false;
|
||||
text = rawText.rawText;
|
||||
}
|
||||
|
||||
@@ -144,7 +140,7 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
@NonNls String breaker = getLineBreaker(token);
|
||||
final String[] lines = LineTokenizer.tokenize(text.toCharArray(), false, true);
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
buffer.append(escapeCharCharacters(lines[i], token, escapeSlashes));
|
||||
buffer.append(escapeCharCharacters(lines[i], token));
|
||||
if (i != lines.length - 1 || "\n".equals(breaker) && text.endsWith("\n")) {
|
||||
buffer.append(breaker);
|
||||
}
|
||||
@@ -153,10 +149,10 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
}
|
||||
else if (isCharLiteral(token)) {
|
||||
if (rawText != null && rawText.rawText != null) {
|
||||
return escapeCharCharacters(rawText.rawText, token, false);
|
||||
return escapeCharCharacters(rawText.rawText, token);
|
||||
}
|
||||
else {
|
||||
return escapeCharCharacters(text, token, true);
|
||||
return escapeCharCharacters(text, token);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
@@ -206,9 +202,9 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String escapeCharCharacters(@NotNull String s, @NotNull PsiElement token, boolean escapeSlashes) {
|
||||
protected String escapeCharCharacters(@NotNull String s, @NotNull PsiElement token) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
StringUtil.escapeStringCharacters(s.length(), s, isStringLiteral(token) ? "\"" : "\'",escapeSlashes, buffer);
|
||||
StringUtil.escapeStringCharacters(s.length(), s, isStringLiteral(token) ? "\"" : "\'", buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.file;
|
||||
|
||||
import com.intellij.core.CoreJavaDirectoryService;
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateUtil;
|
||||
@@ -39,14 +40,11 @@ import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
public class JavaDirectoryServiceImpl extends JavaDirectoryService {
|
||||
public class JavaDirectoryServiceImpl extends CoreJavaDirectoryService {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.JavaDirectoryServiceImpl");
|
||||
|
||||
@Override
|
||||
@@ -57,23 +55,6 @@ public class JavaDirectoryServiceImpl extends JavaDirectoryService {
|
||||
return JavaPsiFacade.getInstance(dir.getProject()).findPackage(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass[] getClasses(@NotNull PsiDirectory dir) {
|
||||
LOG.assertTrue(dir.isValid());
|
||||
|
||||
List<PsiClass> classes = null;
|
||||
for (PsiFile file : dir.getFiles()) {
|
||||
if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) {
|
||||
PsiClass[] psiClasses = ((PsiClassOwner)file).getClasses();
|
||||
if (psiClasses.length == 0) continue;
|
||||
if (classes == null) classes = new ArrayList<PsiClass>();
|
||||
ContainerUtil.addAll(classes, psiClasses);
|
||||
}
|
||||
}
|
||||
return classes == null ? PsiClass.EMPTY_ARRAY : classes.toArray(new PsiClass[classes.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass createClass(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
|
||||
@@ -789,7 +789,8 @@ public class ImportHelper{
|
||||
}
|
||||
|
||||
private static void addUnresolvedImportNames(@NotNull final Set<Pair<String, Boolean>> namesToImport, @NotNull PsiJavaFile file) {
|
||||
PsiImportStatementBase[] imports = file.getImportList().getAllImportStatements();
|
||||
final PsiImportList importList = file.getImportList();
|
||||
PsiImportStatementBase[] imports = importList == null ? PsiImportStatementBase.EMPTY_ARRAY : importList.getAllImportStatements();
|
||||
final Map<String, Pair<String, Boolean>> unresolvedNames = new THashMap<String, Pair<String, Boolean>>();
|
||||
@NotNull Set<Pair<String, Boolean>> unresolvedOnDemand = new THashSet<Pair<String, Boolean>>();
|
||||
for (PsiImportStatementBase anImport : imports) {
|
||||
|
||||
@@ -34,6 +34,7 @@ import java.util.Set;
|
||||
public class OptimizeImportsRefactoringHelper implements RefactoringHelper<Set<PsiJavaFile>> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.OptimizeImportsRefactoringHelper");
|
||||
|
||||
@Override
|
||||
public Set<PsiJavaFile> prepareOperation(final UsageInfo[] usages) {
|
||||
Set<PsiJavaFile> javaFiles = new HashSet<PsiJavaFile>();
|
||||
for (UsageInfo usage : usages) {
|
||||
@@ -49,8 +50,10 @@ public class OptimizeImportsRefactoringHelper implements RefactoringHelper<Set<P
|
||||
return javaFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performOperation(final Project project, final Set<PsiJavaFile> javaFiles) {
|
||||
CodeStyleManager.getInstance(project).performActionWithFormatterDisabled(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
}
|
||||
@@ -58,35 +61,42 @@ public class OptimizeImportsRefactoringHelper implements RefactoringHelper<Set<P
|
||||
|
||||
final Set<SmartPsiElementPointer<PsiImportStatementBase>> redundants = new HashSet<SmartPsiElementPointer<PsiImportStatementBase>>();
|
||||
final Runnable findRedundantImports = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project);
|
||||
final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
final SmartPointerManager pointerManager = SmartPointerManager.getInstance(project);
|
||||
int i = 0;
|
||||
final int fileCount = javaFiles.size();
|
||||
for (PsiJavaFile file : javaFiles) {
|
||||
if (file.isValid()) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
if (progressIndicator != null) {
|
||||
progressIndicator.setText2(virtualFile.getPresentableUrl());
|
||||
progressIndicator.setFraction((double)i++/fileCount);
|
||||
}
|
||||
final Collection<PsiImportStatementBase> perFile = styleManager.findRedundantImports(file);
|
||||
if (perFile != null) {
|
||||
for (PsiImportStatementBase redundant : perFile) {
|
||||
redundants.add(pointerManager.createSmartPsiElementPointer(redundant));
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project);
|
||||
final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
final SmartPointerManager pointerManager = SmartPointerManager.getInstance(project);
|
||||
int i = 0;
|
||||
final int fileCount = javaFiles.size();
|
||||
for (PsiJavaFile file : javaFiles) {
|
||||
if (file.isValid()) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
if (progressIndicator != null) {
|
||||
progressIndicator.setText2(virtualFile.getPresentableUrl());
|
||||
progressIndicator.setFraction((double)i++ / fileCount);
|
||||
}
|
||||
final Collection<PsiImportStatementBase> perFile = styleManager.findRedundantImports(file);
|
||||
if (perFile != null) {
|
||||
for (PsiImportStatementBase redundant : perFile) {
|
||||
redundants.add(pointerManager.createSmartPsiElementPointer(redundant));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(findRedundantImports, "Removing redundant imports", false, project)) return;
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (final SmartPsiElementPointer<PsiImportStatementBase> pointer : redundants) {
|
||||
|
||||
+21
-11
@@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.javadoc.PsiDocParamRef;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
|
||||
import com.intellij.psi.javadoc.PsiDocTagValue;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
@@ -114,8 +115,9 @@ public class ConvertToInstanceMethodProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
|
||||
for (final PsiReference ref : ReferencesSearch.search(myTargetParameter, new LocalSearchScope(myMethod), false)) {
|
||||
if (ref.getElement() instanceof PsiReferenceExpression) {
|
||||
result.add(new ParameterUsageInfo((PsiReferenceExpression)ref));
|
||||
final PsiElement element = ref.getElement();
|
||||
if (element instanceof PsiReferenceExpression || element instanceof PsiDocParamRef) {
|
||||
result.add(new ParameterUsageInfo(ref));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,15 +346,23 @@ public class ConvertToInstanceMethodProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
|
||||
private void processParameterUsage(ParameterUsageInfo usage) throws IncorrectOperationException {
|
||||
final PsiJavaCodeReferenceElement referenceExpression = usage.getReferenceExpression();
|
||||
if (referenceExpression.getParent() instanceof PsiReferenceExpression) {
|
||||
// todo: check for correctness
|
||||
referenceExpression.delete();
|
||||
}
|
||||
else {
|
||||
final PsiExpression expression =
|
||||
JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory().createExpressionFromText("this", null);
|
||||
referenceExpression.replace(expression);
|
||||
final PsiReference reference = usage.getReferenceExpression();
|
||||
if (reference instanceof PsiReferenceExpression) {
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)reference;
|
||||
if (referenceExpression.getParent() instanceof PsiReferenceExpression) {
|
||||
// todo: check for correctness
|
||||
referenceExpression.delete();
|
||||
}
|
||||
else {
|
||||
final PsiExpression expression =
|
||||
JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory().createExpressionFromText("this", null);
|
||||
referenceExpression.replace(expression);
|
||||
}
|
||||
} else {
|
||||
final PsiElement element = reference.getElement();
|
||||
if (element instanceof PsiDocParamRef) {
|
||||
element.getParent().delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-7
@@ -15,22 +15,21 @@
|
||||
*/
|
||||
package com.intellij.refactoring.convertToInstanceMethod;
|
||||
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement;
|
||||
import com.intellij.psi.PsiReferenceExpression;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
|
||||
/**
|
||||
* @author dsl
|
||||
*/
|
||||
class ParameterUsageInfo extends UsageInfo {
|
||||
private final PsiReferenceExpression myReferenceExpression;
|
||||
private final PsiReference myReferenceExpression;
|
||||
|
||||
public ParameterUsageInfo(PsiReferenceExpression refereneceElement) {
|
||||
super(refereneceElement);
|
||||
myReferenceExpression = refereneceElement;
|
||||
public ParameterUsageInfo(PsiReference referenceElement) {
|
||||
super(referenceElement);
|
||||
myReferenceExpression = referenceElement;
|
||||
}
|
||||
|
||||
public PsiJavaCodeReferenceElement getReferenceExpression() {
|
||||
public PsiReference getReferenceExpression() {
|
||||
return myReferenceExpression;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-1
@@ -38,8 +38,8 @@ import com.intellij.refactoring.MoveDestination;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.move.MoveCallback;
|
||||
import com.intellij.refactoring.move.MoveHandler;
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.usageView.UsageViewUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -170,6 +170,13 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
MoveFilesOrDirectoriesUtil.checkIfMoveIntoSelf(myDirectory, directory);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
Messages.showErrorDialog(project, e.getMessage(), RefactoringBundle.message("cannot.move"));
|
||||
return;
|
||||
}
|
||||
|
||||
super.doOKAction();
|
||||
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(directory);
|
||||
|
||||
+2
-1
@@ -37,6 +37,7 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class TypeMigrationProcessor extends BaseRefactoringProcessor {
|
||||
@@ -132,7 +133,7 @@ public class TypeMigrationProcessor extends BaseRefactoringProcessor {
|
||||
text = "method \'" + ((PsiMethod)myRoot[0]).getName() + "\' return";
|
||||
}
|
||||
else {
|
||||
text = myRoot.toString();
|
||||
text = Arrays.toString(myRoot);
|
||||
}
|
||||
Content content = UsageViewManager.getInstance(myProject)
|
||||
.addContent("Migrate Type of " +
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.core;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class CoreJavaDirectoryService extends JavaDirectoryService {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.core.CoreJavaDirectoryService");
|
||||
|
||||
@Override
|
||||
public PsiPackage getPackage(@NotNull PsiDirectory dir) {
|
||||
return ServiceManager.getService(dir.getProject(), CoreJavaFileManager.class).getPackage(dir);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass[] getClasses(@NotNull PsiDirectory dir) {
|
||||
LOG.assertTrue(dir.isValid());
|
||||
|
||||
List<PsiClass> classes = null;
|
||||
for (PsiFile file : dir.getFiles()) {
|
||||
if (file instanceof PsiClassOwner && file.getViewProvider().getLanguages().size() == 1) {
|
||||
PsiClass[] psiClasses = ((PsiClassOwner)file).getClasses();
|
||||
if (psiClasses.length == 0) continue;
|
||||
if (classes == null) classes = new ArrayList<PsiClass>();
|
||||
ContainerUtil.addAll(classes, psiClasses);
|
||||
}
|
||||
}
|
||||
return classes == null ? PsiClass.EMPTY_ARRAY : classes.toArray(new PsiClass[classes.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass createClass(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass createClass(@NotNull PsiDirectory dir, @NotNull String name, @NotNull String templateName)
|
||||
throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClass createClass(@NotNull PsiDirectory dir,
|
||||
@NotNull String name,
|
||||
@NotNull String templateName,
|
||||
boolean askForUndefinedVariables) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCreateClass(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass createInterface(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass createEnum(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass createAnnotationType(@NotNull PsiDirectory dir, @NotNull String name) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSourceRoot(@NotNull PsiDirectory dir) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LanguageLevel getLanguageLevel(@NotNull PsiDirectory dir) {
|
||||
return LanguageLevel.HIGHEST;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.core;
|
||||
|
||||
import com.intellij.openapi.roots.PackageIndex;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem;
|
||||
import com.intellij.openapi.vfs.local.CoreLocalFileSystem;
|
||||
@@ -70,6 +71,18 @@ public class CoreJavaFileManager extends PackageIndex implements JavaFileManager
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiPackage getPackage(PsiDirectory dir) {
|
||||
final File ioFile = new File(dir.getVirtualFile().getPath());
|
||||
for (File root : myClasspath) {
|
||||
if (FileUtil.isAncestor(root, ioFile, false)) {
|
||||
final String relativePath = FileUtil.getRelativePath(root.getPath(), ioFile.getPath(), '.');
|
||||
return new PsiPackageImpl(myPsiManager, relativePath);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private VirtualFile findUnderClasspathEntry(File classpathEntry, String relativeName) {
|
||||
if (classpathEntry.isFile()) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.roots.PackageIndex;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.impl.EmptySubstitutorImpl;
|
||||
import com.intellij.psi.impl.JavaPsiFacadeImpl;
|
||||
import com.intellij.psi.impl.JavaPsiImplementationHelper;
|
||||
@@ -60,10 +61,14 @@ public class JavaCoreEnvironment extends CoreEnvironment {
|
||||
|
||||
registerProjectExtensionPoint(PsiElementFinder.EP_NAME, PsiElementFinder.class);
|
||||
registerExtensionPoint(Extensions.getRootArea(), ClsStubBuilderFactory.EP_NAME, ClsStubBuilderFactory.class);
|
||||
registerExtensionPoint(Extensions.getRootArea(), PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
||||
addExtension(ClsStubBuilderFactory.EP_NAME, new DefaultClsStubBuilderFactory());
|
||||
|
||||
myApplication.registerService(PsiPackageImplementationHelper.class, new CorePsiPackageImplementationHelper());
|
||||
|
||||
myFileManager = new CoreJavaFileManager(myPsiManager, getLocalFileSystem(), myJarFileSystem);
|
||||
JavaPsiFacadeImpl javaPsiFacade = new JavaPsiFacadeImpl(myProject, myPsiManager, myFileManager, null);
|
||||
myProject.registerService(CoreJavaFileManager.class, myFileManager);
|
||||
registerComponentInstance(myProject.getPicoContainer(),
|
||||
JavaPsiFacade.class,
|
||||
javaPsiFacade);
|
||||
@@ -72,10 +77,10 @@ public class JavaCoreEnvironment extends CoreEnvironment {
|
||||
myProject.registerService(JavaPsiImplementationHelper.class, new CoreJavaPsiImplementationHelper());
|
||||
myProject.registerService(PsiResolveHelper.class, new PsiResolveHelperImpl(myPsiManager));
|
||||
myProject.registerService(LanguageLevelProjectExtension.class, new CoreLanguageLevelProjectExtension());
|
||||
myProject.registerService(PsiPackageImplementationHelper.class, new CorePsiPackageImplementationHelper());
|
||||
myProject.registerService(PackageIndex.class, myFileManager);
|
||||
|
||||
|
||||
myApplication.registerService(EmptySubstitutor.class, new EmptySubstitutorImpl());
|
||||
myApplication.registerService(JavaDirectoryService.class, new CoreJavaDirectoryService());
|
||||
}
|
||||
|
||||
public void addToClasspath(File path) {
|
||||
|
||||
@@ -299,7 +299,7 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull final GlobalSearchScope scope) {
|
||||
List<PsiClass> list = null;
|
||||
String packageName = psiPackage.getQualifiedName();
|
||||
for (PsiDirectory dir : psiPackage.getDirectories(scope)) {
|
||||
@@ -315,9 +315,18 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
}
|
||||
}
|
||||
}
|
||||
return list == null ? PsiClass.EMPTY_ARRAY : list.toArray(new PsiClass[list.size()]);
|
||||
}
|
||||
if (list == null) {
|
||||
return PsiClass.EMPTY_ARRAY;
|
||||
}
|
||||
ContainerUtil.quickSort(list, new Comparator<PsiClass>() {
|
||||
@Override
|
||||
public int compare(PsiClass o1, PsiClass o2) {
|
||||
return scope.compare(o2.getContainingFile().getVirtualFile(), o1.getContainingFile().getVirtualFile());
|
||||
}
|
||||
});
|
||||
|
||||
return list.toArray(new PsiClass[list.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
class Test {
|
||||
/**
|
||||
* method description
|
||||
* @param a description
|
||||
*/
|
||||
public static void ma<caret>in(A a) {
|
||||
}
|
||||
}
|
||||
|
||||
class A {}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class Test {
|
||||
}
|
||||
|
||||
class A {
|
||||
/**
|
||||
* method description
|
||||
*/
|
||||
public void main() {
|
||||
}
|
||||
}
|
||||
+15
-4
@@ -43,6 +43,8 @@ import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.util.Consumer
|
||||
import com.intellij.openapi.editor.LogicalPosition
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.util.Computable
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -949,9 +951,15 @@ public class Bar {
|
||||
myFixture.completeBasic()
|
||||
}
|
||||
myFixture.checkResult 'class Foo {pr<caret>}'
|
||||
lookup.items.each {
|
||||
lookup.list.cellRenderer.getListCellRendererComponent(lookup.list, it, 0, false, false)
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
void run() {
|
||||
getLookup().items.each {
|
||||
getLookup().list.cellRenderer.getListCellRendererComponent(getLookup().list, it, 0, false, false)
|
||||
}
|
||||
}
|
||||
});
|
||||
assert myFixture.lookupElementStrings.containsAll(['private', 'protected'])
|
||||
}
|
||||
|
||||
@@ -1098,7 +1106,10 @@ class Foo {{
|
||||
<caret>t;
|
||||
t;
|
||||
}}"""
|
||||
def caret = myFixture.editor.offsetToLogicalPosition(myFixture.editor.caretModel.offset)
|
||||
def caret = ApplicationManager.getApplication().runReadAction(new Computable<LogicalPosition>() {
|
||||
public LogicalPosition compute() {
|
||||
return myFixture.editor.offsetToLogicalPosition(myFixture.editor.caretModel.offset)
|
||||
}});
|
||||
edt { myFixture.editor.selectionModel.setBlockSelection(caret, new LogicalPosition(caret.line + 1, caret.column + 1)) }
|
||||
type 'toStr'
|
||||
assert lookup
|
||||
|
||||
+2
@@ -30,6 +30,8 @@ public class ConvertToInstanceMethodTest extends LightRefactoringTestCase {
|
||||
|
||||
public void testInterfaceTypeParameter() throws Exception { doTest(0); }
|
||||
|
||||
public void testJavadocParameter() throws Exception { doTest(0); }
|
||||
|
||||
private void doTest(final int targetParameter) throws Exception {
|
||||
final String filePath = "/refactoring/convertToInstanceMethod/" + getTestName(false) + ".java";
|
||||
configureByFile(filePath);
|
||||
|
||||
@@ -43,11 +43,6 @@ public abstract class IdeaTestCase extends PlatformTestCase {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"})
|
||||
protected IdeaTestCase() {
|
||||
initPlatformPrefix();
|
||||
}
|
||||
|
||||
public final JavaPsiFacadeEx getJavaFacade() {
|
||||
return myJavaFacade;
|
||||
}
|
||||
|
||||
+14
-4
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package com.intellij.testFramework.fixtures.impl;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiModificationTrackerImpl;
|
||||
@@ -51,17 +53,25 @@ public class JavaCodeInsightTestFixtureImpl extends CodeInsightTestFixtureImpl i
|
||||
}
|
||||
|
||||
private PsiClass addClass(@NonNls final String rootPath, @NotNull @NonNls final String classText) {
|
||||
final PsiClass aClass = ((PsiJavaFile)PsiFileFactory.getInstance(getProject()).createFileFromText("a.java", classText)).getClasses()[0];
|
||||
final String qName = aClass.getQualifiedName();
|
||||
final String qName =
|
||||
ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
public String compute() {
|
||||
final PsiClass aClass = ((PsiJavaFile)PsiFileFactory.getInstance(getProject()).createFileFromText("a.java", classText)).getClasses()[0];
|
||||
return aClass.getQualifiedName();
|
||||
}
|
||||
});
|
||||
assert qName != null;
|
||||
|
||||
final PsiFile psiFile = new WriteCommandAction<PsiFile>(getProject()) {
|
||||
@Override
|
||||
protected void run(Result<PsiFile> result) throws Throwable {
|
||||
result.setResult(addFileToProject(rootPath, qName.replace('.', '/') + ".java", classText));
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
return ((PsiJavaFile)psiFile).getClasses()[0];
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
|
||||
public PsiClass compute() {
|
||||
return ((PsiJavaFile)psiFile).getClasses()[0];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+11
@@ -194,6 +194,7 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
|
||||
final Runnable[] resultRunnable = new Runnable[1];
|
||||
Runnable readAction = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!checkFileWritable(file)) return;
|
||||
try{
|
||||
@@ -205,6 +206,7 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
}
|
||||
};
|
||||
Runnable writeAction = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (resultRunnable[0] != null) {
|
||||
resultRunnable[0].run();
|
||||
@@ -261,6 +263,7 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
}
|
||||
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SequentialModalProgressTask progressTask = new SequentialModalProgressTask(myProject, myCommandName);
|
||||
ReformatFilesTask reformatFilesTask = new ReformatFilesTask(tasks);
|
||||
@@ -277,11 +280,13 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
final Runnable[] resultRunnable = new Runnable[1];
|
||||
runLayoutCodeProcess(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
resultRunnable[0] = preprocessFiles(new ArrayList<PsiFile>(Arrays.asList(files)));
|
||||
}
|
||||
},
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (resultRunnable[0] != null){
|
||||
resultRunnable[0].run();
|
||||
@@ -352,10 +357,12 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
|
||||
final Runnable[] resultRunnable = new Runnable[1];
|
||||
runLayoutCodeProcess(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
resultRunnable[0] = preprocessFiles(array);
|
||||
}
|
||||
}, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (resultRunnable[0] != null) {
|
||||
resultRunnable[0].run();
|
||||
@@ -450,12 +457,14 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
final ModalityState modalityState = ModalityState.current();
|
||||
|
||||
final Runnable process = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runReadAction(readAction);
|
||||
}
|
||||
};
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
//DaemonCodeAnalyzer.getInstance(myProject).setUpdateByTimerEnabled(false);
|
||||
@@ -474,8 +483,10 @@ public abstract class AbstractLayoutCodeProcessor {
|
||||
*/
|
||||
|
||||
final Runnable writeRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (globalAction) CommandProcessor.getInstance().markCurrentCommandAsGlobal(myProject);
|
||||
try {
|
||||
|
||||
+4
-11
@@ -31,7 +31,6 @@ import com.intellij.ide.PowerSaveMode;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.components.ProjectComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -696,16 +695,10 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
|
||||
// we'll restart when write action finish
|
||||
return;
|
||||
}
|
||||
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
|
||||
if (documentManager.hasUncommitedDocuments()) {
|
||||
if (ModalityState.current() == ModalityState.NON_MODAL) {
|
||||
((PsiDocumentManagerImpl)documentManager).cancelAndRunWhenAllCommitted("restart daemon when all committed", this);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// when modal dialog is open, DocumentCommitThread is not able to commit in background, so force commit here
|
||||
documentManager.commitAllDocuments();
|
||||
}
|
||||
if (PsiDocumentManager.getInstance(myProject).hasUncommitedDocuments()) {
|
||||
((PsiDocumentManagerImpl)PsiDocumentManager.getInstance(myProject)).cancelAndRunWhenAllCommitted(
|
||||
"restart daemon when all committed", this);
|
||||
return;
|
||||
}
|
||||
|
||||
Map<FileEditor, HighlightingPass[]> passes = new THashMap<FileEditor, HighlightingPass[]>(activeEditors.size());
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class TemporaryRunConfigurationTypeUsagesCollector extends AbstractRunConfigurationTypeUsagesCollector {
|
||||
|
||||
private static final GroupDescriptor GROUP_ID = GroupDescriptor.create("run-configuration-type-temporary");
|
||||
private static final GroupDescriptor GROUP_ID = GroupDescriptor.create("run-configuration-type-temp");
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
|
||||
@@ -358,9 +358,9 @@ public class FindUsagesManager implements JDOMExternalizable {
|
||||
|
||||
private static UsageSearcher createUsageSearcher(final UsageInfoToUsageConverter.TargetElementsDescriptor descriptor,
|
||||
final FindUsagesHandler handler,
|
||||
final FindUsagesOptions options,
|
||||
FindUsagesOptions _options,
|
||||
final PsiFile scopeFile) {
|
||||
|
||||
final FindUsagesOptions options = _options.clone();
|
||||
return new UsageSearcher() {
|
||||
@Override
|
||||
public void generate(@NotNull final Processor<Usage> processor) {
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -55,6 +56,7 @@ import java.util.Map;
|
||||
|
||||
public class DirectoryChooser extends DialogWrapper {
|
||||
@NonNls private static final String FILTER_NON_EXISTING = "filter_non_existing";
|
||||
private static final String DEFAULT_SELECTION = "last_directory_selection";
|
||||
private final DirectoryChooserView myView;
|
||||
private boolean myFilterExisting;
|
||||
private PsiDirectory myDefaultSelection;
|
||||
@@ -106,6 +108,13 @@ public class DirectoryChooser extends DialogWrapper {
|
||||
if (myTabbedPaneWrapper.getSelectedIndex() == 1) {
|
||||
setSelection(myChooseByNamePanel.getChosenElement());
|
||||
}
|
||||
final ItemWrapper item = myView.getSelectedItem();
|
||||
if (item != null) {
|
||||
final PsiDirectory directory = item.getDirectory();
|
||||
if (directory != null) {
|
||||
PropertiesComponent.getInstance(directory.getProject()).setValue(DEFAULT_SELECTION, directory.getVirtualFile().getPath());
|
||||
}
|
||||
}
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
@@ -363,8 +372,11 @@ public class DirectoryChooser extends DialogWrapper {
|
||||
if (myView.getItemsSize() > 0){
|
||||
myView.clearItems();
|
||||
}
|
||||
if (defaultSelection == null && directories.length > 0) {
|
||||
defaultSelection = directories[0];
|
||||
if (defaultSelection == null) {
|
||||
defaultSelection = getDefaultSelection(directories, project);
|
||||
if (defaultSelection == null && directories.length > 0) {
|
||||
defaultSelection = directories[0];
|
||||
}
|
||||
}
|
||||
int selectionIndex = -1;
|
||||
for(int i = 0; i < directories.length; i++){
|
||||
@@ -437,6 +449,19 @@ public class DirectoryChooser extends DialogWrapper {
|
||||
myView.getComponent().repaint();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiDirectory getDefaultSelection(PsiDirectory[] directories, Project project) {
|
||||
final String defaultSelectionPath = PropertiesComponent.getInstance(project).getValue(DEFAULT_SELECTION);
|
||||
if (defaultSelectionPath != null) {
|
||||
final VirtualFile directoryByDefault = LocalFileSystem.getInstance().findFileByPath(defaultSelectionPath);
|
||||
if (directoryByDefault != null) {
|
||||
final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(directoryByDefault);
|
||||
return directory != null && ArrayUtil.find(directories, directory) > -1 ? directory : null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isParent(PsiDirectory directory, PsiDirectory parentCandidate) {
|
||||
while (directory != null) {
|
||||
if (directory.equals(parentCandidate)) return true;
|
||||
|
||||
+2
@@ -36,6 +36,7 @@ import com.intellij.usages.UsageInfoToUsageConverter;
|
||||
import com.intellij.util.Consumer;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -87,6 +88,7 @@ public class DependenciesUsagesPanel extends UsagesPanel {
|
||||
elementsToSearch = searchFor;
|
||||
usages = FindDependencyUtil.findDependencies(myBuilders, searchIn, searchFor);
|
||||
}
|
||||
assert !new HashSet<PsiFile>(elementsToSearch).contains(null);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.intellij.psi.impl;
|
||||
import com.intellij.ide.startup.impl.StartupManagerImpl;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -54,6 +53,7 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.Queue;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -318,7 +318,7 @@ public class DocumentCommitThread implements Runnable, Disposable {
|
||||
}
|
||||
if (success) {
|
||||
assert !ApplicationManager.getApplication().isDispatchThread();
|
||||
ApplicationManager.getApplication().invokeLater(finishRunnable, ModalityState.NON_MODAL); // do not commit while modal progress is running
|
||||
UIUtil.invokeLaterIfNeeded(finishRunnable);
|
||||
log("Invoked later finishRunnable", document, false, success, finishRunnable, indicator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,9 +499,6 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
keyDescriptor.save(out, key);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new IOException("Error saving data for index " + indexId, e);
|
||||
}
|
||||
@@ -517,9 +514,6 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
}
|
||||
return list;
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new IOException("Error reading data for index " + indexId, e);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class RefreshQueue {
|
||||
@@ -34,22 +35,23 @@ public abstract class RefreshQueue {
|
||||
return createSession(async, recursive, finishRunnable, getDefaultModalityState());
|
||||
}
|
||||
|
||||
public abstract RefreshSession createSession(boolean async, boolean recursive, @Nullable Runnable finishRunnable, ModalityState state);
|
||||
public abstract RefreshSession createSession(boolean async, boolean recursive, @Nullable Runnable finishRunnable, @NotNull ModalityState state);
|
||||
|
||||
public final void refresh(boolean async, boolean recursive, @Nullable Runnable finishRunnable, ModalityState state, VirtualFile... files) {
|
||||
public final void refresh(boolean async, boolean recursive, @Nullable Runnable finishRunnable, @NotNull ModalityState state, @NotNull VirtualFile... files) {
|
||||
RefreshSession session = createSession(async, recursive, finishRunnable, state);
|
||||
session.addAllFiles(files);
|
||||
session.launch();
|
||||
}
|
||||
|
||||
public abstract void refreshLocalRoots(boolean async, @Nullable Runnable postAction, ModalityState modalityState);
|
||||
public abstract void refreshLocalRoots(boolean async, @Nullable Runnable postAction, @NotNull ModalityState modalityState);
|
||||
|
||||
public final void refresh(boolean async, boolean recursive, @Nullable Runnable finishRunnable, VirtualFile... files) {
|
||||
public final void refresh(boolean async, boolean recursive, @Nullable Runnable finishRunnable, @NotNull VirtualFile... files) {
|
||||
refresh(async, recursive, finishRunnable, getDefaultModalityState(), files);
|
||||
}
|
||||
|
||||
public abstract void processSingleEvent(VFileEvent event);
|
||||
|
||||
@NotNull
|
||||
protected ModalityState getDefaultModalityState() {
|
||||
return ModalityState.NON_MODAL;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public abstract class RefreshSession {
|
||||
public abstract void addFile(@NotNull VirtualFile file);
|
||||
public abstract void addAllFiles(Collection<VirtualFile> files);
|
||||
|
||||
public void addAllFiles(VirtualFile[] files) {
|
||||
public void addAllFiles(@NotNull VirtualFile[] files) {
|
||||
addAllFiles(Arrays.asList(files));
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,10 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
|
||||
}
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
install();
|
||||
}
|
||||
|
||||
public void install() {
|
||||
IdeaPluginDescriptor[] selection = getPluginTable().getSelectedObjects();
|
||||
|
||||
if (userConfirm(selection)) {
|
||||
@@ -113,14 +117,14 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
|
||||
}
|
||||
catch (IOException e1) {
|
||||
PluginManagerMain.LOG.error(e1);
|
||||
IOExceptionDialog.showErrorDialog(IdeBundle.message("action.download.and.install.plugin"), IdeBundle.message("error.plugin.download.failed"));
|
||||
IOExceptionDialog
|
||||
.showErrorDialog(IdeBundle.message("action.download.and.install.plugin"), IdeBundle.message("error.plugin.download.failed"));
|
||||
}
|
||||
getPluginTable().updateUI();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public PluginTable getPluginTable() {
|
||||
return host.getPluginTable();
|
||||
}
|
||||
|
||||
+19
-1
@@ -16,7 +16,10 @@
|
||||
package com.intellij.ide.plugins;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
|
||||
import com.intellij.openapi.options.ShowSettingsUtil;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
@@ -30,6 +33,8 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
@@ -87,6 +92,19 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
|
||||
return ScrollPaneFactory.createScrollPane(pluginTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installTableActions(final PluginTable pluginTable) {
|
||||
super.installTableActions(pluginTable);
|
||||
pluginTable.addMouseListener(new MouseAdapter() {
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() != 2) return;
|
||||
if (pluginTable.columnAtPoint(e.getPoint()) < 0) return;
|
||||
if (pluginTable.rowAtPoint(e.getPoint()) < 0) return;
|
||||
new ActionInstallPlugin(AvailablePluginsManagerMain.this, installed).install();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
UiNotifyConnector.doWhenFirstShown(getPluginTable(), new Runnable() {
|
||||
|
||||
+2
-1
@@ -32,7 +32,7 @@ public class ModalityStateEx extends ModalityState {
|
||||
this(EMPTY_REFS_ARRAY);
|
||||
}
|
||||
|
||||
public ModalityStateEx(Object[] modalEntities) {
|
||||
public ModalityStateEx(@NotNull Object[] modalEntities) {
|
||||
if (modalEntities.length > 0) {
|
||||
myModalEntities = new WeakReference[modalEntities.length];
|
||||
for (int i = 0; i < modalEntities.length; i++) {
|
||||
@@ -71,6 +71,7 @@ public class ModalityStateEx extends ModalityState {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dominates(@NotNull ModalityState anotherState){
|
||||
if (anotherState == ModalityState.any()) return false;
|
||||
|
||||
|
||||
@@ -192,8 +192,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
private static final int MOUSE_SELECTION_STATE_WORD_SELECTED = 1;
|
||||
private static final int MOUSE_SELECTION_STATE_LINE_SELECTED = 2;
|
||||
|
||||
private final MarkupModelListener myMarkupModelListener;
|
||||
|
||||
private EditorHighlighter myHighlighter;
|
||||
private final TextDrawingCallback myTextDrawingCallback = new MyTextDrawingCallback();
|
||||
|
||||
@@ -306,7 +304,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
myMouseMotionListeners = ContainerUtil.createEmptyCOWList();
|
||||
|
||||
myMarkupModelListener = new MarkupModelListener() {
|
||||
MarkupModelListener markupModelListener = new MarkupModelListener() {
|
||||
@Override
|
||||
public void afterAdded(@NotNull RangeHighlighterEx highlighter) {
|
||||
attributesChanged(highlighter);
|
||||
@@ -341,8 +339,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
};
|
||||
|
||||
((MarkupModelEx)DocumentMarkupModel.forDocument(myDocument, myProject, true)).addMarkupModelListener(myCaretModel, myMarkupModelListener);
|
||||
((MarkupModelEx)getMarkupModel()).addMarkupModelListener(myCaretModel, myMarkupModelListener);
|
||||
((MarkupModelEx)DocumentMarkupModel.forDocument(myDocument, myProject, true)).addMarkupModelListener(myCaretModel, markupModelListener);
|
||||
((MarkupModelEx)getMarkupModel()).addMarkupModelListener(myCaretModel, markupModelListener);
|
||||
|
||||
myDocument.addDocumentListener(myFoldingModel,myCaretModel);
|
||||
myDocument.addDocumentListener(myCaretModel,myCaretModel);
|
||||
|
||||
@@ -247,19 +247,26 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa
|
||||
|
||||
super.stop();
|
||||
|
||||
if (isDialogShowing()) {
|
||||
if (myFocusTrackback != null) {
|
||||
myFocusTrackback.setWillBeSheduledForRestore();
|
||||
}
|
||||
}
|
||||
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean wasShowing = myDialog != null && myDialog.getPanel() != null && myDialog.getPanel().isShowing();
|
||||
boolean wasShowing = isDialogShowing();
|
||||
if (myDialog != null) {
|
||||
myDialog.hide();
|
||||
}
|
||||
|
||||
if (wasShowing) {
|
||||
myFocusTrackback.restoreFocus();
|
||||
} else {
|
||||
myFocusTrackback.consume();
|
||||
if (myFocusTrackback != null) {
|
||||
if (wasShowing) {
|
||||
myFocusTrackback.restoreFocus();
|
||||
} else {
|
||||
myFocusTrackback.consume();
|
||||
}
|
||||
}
|
||||
|
||||
myStoppedAlready = true;
|
||||
@@ -271,6 +278,10 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa
|
||||
SwingUtilities.invokeLater(EmptyRunnable.INSTANCE); // Just to give blocking dispatching a chance to go out.
|
||||
}
|
||||
|
||||
private boolean isDialogShowing() {
|
||||
return myDialog != null && myDialog.getPanel() != null && myDialog.getPanel().isShowing();
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
super.cancel();
|
||||
if (myDialog != null) {
|
||||
|
||||
@@ -121,6 +121,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
MessageBus messageBus = app.getMessageBus();
|
||||
MessageBusConnection connection = messageBus.connect(app);
|
||||
connection.subscribe(StateStorage.STORAGE_TOPIC, new StateStorage.Listener() {
|
||||
@Override
|
||||
public void storageFileChanged(final VirtualFileEvent event, @NotNull final StateStorage storage) {
|
||||
VirtualFile file = event.getFile();
|
||||
LOG.debug("[RELOAD] Storage file changed: " + file.getPath());
|
||||
@@ -133,10 +134,12 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
|
||||
addProjectManagerListener(
|
||||
new ProjectManagerListener() {
|
||||
@Override
|
||||
public void projectOpened(final Project project) {
|
||||
MessageBus messageBus = project.getMessageBus();
|
||||
MessageBusConnection connection = messageBus.connect(project);
|
||||
connection.subscribe(StateStorage.STORAGE_TOPIC, new StateStorage.Listener() {
|
||||
@Override
|
||||
public void storageFileChanged(final VirtualFileEvent event, @NotNull final StateStorage storage) {
|
||||
VirtualFile file = event.getFile();
|
||||
if (!file.isDirectory() && !(event.getRequestor() instanceof StateStorage.SaveSession)) {
|
||||
@@ -151,6 +154,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void projectClosed(Project project) {
|
||||
busPublisher.projectClosed(project);
|
||||
for (ProjectManagerListener listener : getListeners(project)) {
|
||||
@@ -158,6 +162,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCloseProject(Project project) {
|
||||
for (ProjectManagerListener listener : getListeners(project)) {
|
||||
if (!listener.canCloseProject(project)) {
|
||||
@@ -167,6 +172,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void projectClosing(Project project) {
|
||||
busPublisher.projectClosing(project);
|
||||
for (ProjectManagerListener listener : getListeners(project)) {
|
||||
@@ -179,10 +185,12 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
registerExternalProjectFileListener(virtualFileManagerEx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeComponent() {
|
||||
Disposer.dispose(myChangedFilesAlarm);
|
||||
if (myDefaultProject != null) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Disposer.dispose(myDefaultProject);
|
||||
}
|
||||
@@ -193,9 +201,11 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initComponent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Project newProject(final String projectName, String filePath, boolean useDefaultProjectSettings, boolean isDummy) {
|
||||
filePath = canonicalize(filePath);
|
||||
@@ -283,8 +293,10 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
|
||||
private static void scheduleDispose(final ProjectImpl project) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!project.isDisposed()) {
|
||||
Disposer.dispose(project);
|
||||
@@ -295,6 +307,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Project loadProject(String filePath) throws IOException, JDOMException, InvalidDataException {
|
||||
try {
|
||||
@@ -333,6 +346,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
public synchronized boolean isDefaultProjectInitialized() {
|
||||
return myDefaultProject != null;
|
||||
}
|
||||
@Override
|
||||
@NotNull
|
||||
public synchronized Project getDefaultProject() {
|
||||
LOG.assertTrue(!myDefaultProjectWasDisposed, "Default project has been already disposed!");
|
||||
@@ -357,6 +371,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
return myDefaultProjectRootElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Project[] getOpenProjects() {
|
||||
if (myOpenProjectsArrayCache.length != myOpenProjects.size()) {
|
||||
@@ -374,6 +389,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
return myOpenProjectsArrayCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectOpened(Project project) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() && myCurrentTestProject != null) {
|
||||
return project == myCurrentTestProject || myOpenProjects.contains(project);
|
||||
@@ -381,6 +397,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
return myOpenProjects.contains(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean openProject(final Project project) {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
|
||||
@@ -403,6 +420,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManager.getInstance(project);
|
||||
|
||||
boolean ok = myProgressManager.runProcessWithProgressSynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startupManager.runStartupActivities();
|
||||
|
||||
@@ -410,6 +428,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
// only when startCacheUpdate is called from UI thread, we can guarantee that
|
||||
// when the method returns, the application has entered dumb mode
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startupManager.startCacheUpdate();
|
||||
}
|
||||
@@ -418,6 +437,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
startupManager.runPostStartupActivitiesFromExtensions();
|
||||
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startupManager.runPostStartupActivities();
|
||||
}
|
||||
@@ -434,6 +454,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
if (!application.isHeadlessEnvironment() && !application.isUnitTestMode()) {
|
||||
// should be invoked last
|
||||
StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final TrackingPathMacroSubstitutor macroSubstitutor =
|
||||
((ProjectEx)project).getStateStore().getStateStorageManager().getMacroSubstitutor();
|
||||
@@ -451,6 +472,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
myOpenProjectsArrayCache = myOpenProjects.toArray(new Project[myOpenProjects.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project loadAndOpenProject(@NotNull final String filePath) throws IOException {
|
||||
|
||||
final Project project = convertAndLoadProject(filePath);
|
||||
@@ -462,6 +484,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
if (!openProject(project)) {
|
||||
showWelcomeScreenIfNoProjectOpened();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Disposer.dispose(project);
|
||||
}
|
||||
@@ -498,6 +521,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
|
||||
if (!conversionResult.conversionNotNeeded()) {
|
||||
StartupManager.getInstance(project).registerPostStartupActivity(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
conversionResult.postStartupActivity(project);
|
||||
}
|
||||
@@ -519,6 +543,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
final ProjectImpl project = createProject(null, canonicalize(filePath), false, false);
|
||||
try {
|
||||
myProgressManager.runProcessWithProgressSynchronously(new ThrowableComputable<Project, IOException>() {
|
||||
@Override
|
||||
@Nullable
|
||||
public Project compute() throws IOException {
|
||||
doLoadProject(filePath, project);
|
||||
@@ -572,9 +597,11 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
|
||||
private void registerExternalProjectFileListener(VirtualFileManagerEx virtualFileManager) {
|
||||
virtualFileManager.addVirtualFileManagerListener(new VirtualFileManagerListener() {
|
||||
@Override
|
||||
public void beforeRefreshStart(boolean asynchonous) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterRefreshFinish(boolean asynchonous) {
|
||||
scheduleReloadApplicationAndProject();
|
||||
}
|
||||
@@ -618,6 +645,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
final LinkedHashSet<String> components = new LinkedHashSet<String>();
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
reloadOk[0] = ((ApplicationImpl)app).getStateStore().reload(causes, components);
|
||||
@@ -684,6 +712,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
final boolean[] reloadOk = {false};
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
LOG.debug("[RELOAD] Reloading project/components...");
|
||||
@@ -725,14 +754,17 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
Messages.getQuestionIcon()) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFileSavedToBeReloaded(VirtualFile candidate) {
|
||||
return mySavedCopies.containsKey(candidate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void blockReloadingProjectOnExternalChanges() {
|
||||
myReloadBlockCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unblockReloadingProjectOnExternalChanges() {
|
||||
if (myReloadBlockCount.decrementAndGet() == 0) scheduleReloadApplicationAndProject();
|
||||
}
|
||||
@@ -748,6 +780,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
// public void run() {
|
||||
// IdeEventQueue.getInstance().removeIdleListener(this);
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!tryToReloadApplication()) return;
|
||||
askToReloadProjectIfConfigFilesChangedExternally();
|
||||
@@ -759,17 +792,20 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
//}, ModalityState.NON_MODAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentTestProject(@Nullable final Project project) {
|
||||
assert ApplicationManager.getApplication().isUnitTestMode();
|
||||
myCurrentTestProject = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Project getCurrentTestProject() {
|
||||
assert ApplicationManager.getApplication().isUnitTestMode();
|
||||
return myCurrentTestProject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChangedProjectFile(final VirtualFile file, final Project project) {
|
||||
if (file.exists()) {
|
||||
copyToTemp(file);
|
||||
@@ -813,6 +849,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
|
||||
myChangedFilesAlarm.cancelAllRequests();
|
||||
myChangedFilesAlarm.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LOG.debug("[RELOAD] Scheduling reload application & project, myReloadBlockCount = " + myReloadBlockCount);
|
||||
if (myReloadBlockCount.get() == 0) {
|
||||
@@ -855,6 +892,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadProject(@NotNull final Project p) {
|
||||
reloadProjectImpl(p, true, false);
|
||||
}
|
||||
@@ -874,6 +912,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
|
||||
application.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LOG.debug("Reloading project.");
|
||||
ProjectImpl projectImpl = (ProjectImpl)project[0];
|
||||
@@ -894,6 +933,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
|
||||
if (project[0].isDisposed() || ProjectUtil.closeAndDispose(project[0])) {
|
||||
application.runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (final IFile originalFile : original) {
|
||||
restoreCopy(LocalFileSystem.getInstance().refreshAndFindFileByIoFile(originalFile));
|
||||
@@ -915,6 +955,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean closeProject(@NotNull final Project project) {
|
||||
return closeProject(project, true, false);
|
||||
}
|
||||
@@ -940,6 +981,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
fireProjectClosing(project); // somebody can start progress here, do not wrap in write action
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myOpenProjects.remove(project);
|
||||
cacheOpenProjects();
|
||||
@@ -982,6 +1024,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProjectManagerListener(@NotNull ProjectManagerListener listener) {
|
||||
myListeners.add(listener);
|
||||
}
|
||||
@@ -997,11 +1040,13 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProjectManagerListener(@NotNull ProjectManagerListener listener) {
|
||||
boolean removed = myListeners.remove(listener);
|
||||
LOG.assertTrue(removed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProjectManagerListener(@NotNull Project project, @NotNull ProjectManagerListener listener) {
|
||||
List<ProjectManagerListener> listeners = project.getUserData(LISTENERS_IN_PROJECT_KEY);
|
||||
if (listeners == null) {
|
||||
@@ -1010,6 +1055,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProjectManagerListener(@NotNull Project project, @NotNull ProjectManagerListener listener) {
|
||||
List<ProjectManagerListener> listeners = project.getUserData(LISTENERS_IN_PROJECT_KEY);
|
||||
if (listeners != null) {
|
||||
@@ -1051,6 +1097,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canClose(Project project) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("enter: canClose()");
|
||||
@@ -1080,6 +1127,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
Messages.getWarningIcon()) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(Element parentNode) throws WriteExternalException {
|
||||
if (myDefaultProject != null) {
|
||||
myDefaultProject.save();
|
||||
@@ -1098,6 +1146,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
myDefaultProjectRootElement = defaultProjectRootElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readExternal(Element parentNode) throws InvalidDataException {
|
||||
myDefaultProjectRootElement = parentNode.getChild(ELEMENT_DEFAULT_PROJECT);
|
||||
|
||||
@@ -1108,20 +1157,24 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
myDefaultProjectRootElement.detach();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExternalFileName() {
|
||||
return "project.default";
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getComponentName() {
|
||||
return "ProjectManager";
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public File[] getExportFiles() {
|
||||
return new File[]{PathManager.getOptionsFile(this)};
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getPresentableName() {
|
||||
return ProjectBundle.message("project.default.settings");
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.vfs.VfsBundle;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import com.intellij.util.ConcurrencyUtil;
|
||||
import com.intellij.util.io.storage.HeavyProcessLatch;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -41,22 +42,22 @@ public class RefreshQueueImpl extends RefreshQueue {
|
||||
private final ExecutorService myQueue = ConcurrencyUtil.newSingleThreadExecutor("FS Synchronizer");
|
||||
private final ProgressIndicator myRefreshIndicator = new RefreshProgress(VfsBundle.message("file.synchronize.progress"));
|
||||
|
||||
public void execute(final RefreshSessionImpl session) {
|
||||
public void execute(@NotNull RefreshSessionImpl session) {
|
||||
if (session.isAsynchronous()) {
|
||||
ModalityState state = session.getModalityState();
|
||||
queueSession(session, state != null ? state : ModalityState.NON_MODAL);
|
||||
queueSession(session, state);
|
||||
}
|
||||
else {
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
boolean isEDT = app.isDispatchThread();
|
||||
final boolean hasWriteAction = app.isWriteAccessAllowed();
|
||||
if (isEDT || hasWriteAction) {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
boolean isEDT = application.isDispatchThread();
|
||||
if (isEDT) {
|
||||
session.scan();
|
||||
final boolean hasWriteAction = application.isWriteAccessAllowed();
|
||||
session.fireEvents(hasWriteAction);
|
||||
}
|
||||
else {
|
||||
if (((ApplicationEx)app).holdsReadLock()) {
|
||||
LOG.error("Do not call synchronous refresh from inside read action except for event dispatch thread. This will eventually cause deadlock if there are events to fire");
|
||||
if (((ApplicationEx)application).holdsReadLock()) {
|
||||
LOG.error( "Do not call synchronous refresh from inside read action except for event dispatch thread. This will eventually cause deadlock if there are events to fire");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -66,7 +67,7 @@ public class RefreshQueueImpl extends RefreshQueue {
|
||||
}
|
||||
}
|
||||
|
||||
private void queueSession(final RefreshSessionImpl session, final ModalityState modality) {
|
||||
private void queueSession(@NotNull final RefreshSessionImpl session, @NotNull final ModalityState modality) {
|
||||
myQueue.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -96,12 +97,12 @@ public class RefreshQueueImpl extends RefreshQueue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefreshSession createSession(final boolean async, boolean recursively, @Nullable final Runnable finishRunnable, ModalityState state) {
|
||||
public RefreshSession createSession(final boolean async, boolean recursively, @Nullable final Runnable finishRunnable, @NotNull ModalityState state) {
|
||||
return new RefreshSessionImpl(async, recursively, finishRunnable, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshLocalRoots(boolean async, Runnable postAction, ModalityState modalityState) {
|
||||
public void refreshLocalRoots(boolean async, @Nullable Runnable postAction, @NotNull ModalityState modalityState) {
|
||||
RefreshQueue.getInstance().refresh(async, true, postAction, modalityState, ManagingFS.getInstance().getLocalRoots());
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public class RefreshSessionImpl extends RefreshSession {
|
||||
private final Semaphore mySemaphore = new Semaphore();
|
||||
private volatile boolean iHaveEventsToFire;
|
||||
|
||||
private ModalityState myModalityState;
|
||||
private final ModalityState myModalityState;
|
||||
|
||||
public RefreshSessionImpl(final boolean isAsync, final boolean recursively, final Runnable finishRunnable) {
|
||||
this(isAsync, recursively, finishRunnable, ModalityState.NON_MODAL);
|
||||
@@ -65,6 +65,7 @@ public class RefreshSessionImpl extends RefreshSession {
|
||||
myIsRecursive = false;
|
||||
myFinishRunnable = null;
|
||||
myEvents = new ArrayList<VFileEvent>(events);
|
||||
myModalityState = ModalityState.NON_MODAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -167,6 +168,7 @@ public class RefreshSessionImpl extends RefreshSession {
|
||||
return events;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ModalityState getModalityState() {
|
||||
return myModalityState;
|
||||
}
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ class ComboContentLayout extends ContentLayout {
|
||||
|
||||
@Override
|
||||
public void showContentPopup(ListPopup listPopup) {
|
||||
listPopup.setMinimumSize(new Dimension(myComboLabel.getPreferredSize().width, 0));
|
||||
listPopup.setMinimumSize(new Dimension(myComboLabel.getSize().width, 0));
|
||||
listPopup.showUnderneathOf(myComboLabel);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -425,7 +425,7 @@ public class ToolWindowContentUi extends JPanel implements ContentUI, PropertyCh
|
||||
@NotNull
|
||||
@Override
|
||||
public String getTextFor(Content value) {
|
||||
final String displayName = value.getDisplayName();
|
||||
final String displayName = value.getTabName();
|
||||
return displayName != null ? displayName : "";
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class StatusPanel extends JPanel {
|
||||
private boolean myLogMode;
|
||||
private boolean myDirty;
|
||||
private boolean myAfterClick;
|
||||
private final Alarm myLogAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
private Alarm myLogAlarm;
|
||||
private final TextPanel myTextPanel = new TextPanel() {
|
||||
@Override
|
||||
protected String getTextForPreferredSize() {
|
||||
@@ -103,6 +103,17 @@ class StatusPanel extends JPanel {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Alarm getAlarm() {
|
||||
if (myLogAlarm == null || myLogAlarm.isDisposed()) {
|
||||
myLogAlarm = null; //Welcome screen
|
||||
Project project = getActiveProject();
|
||||
if (project != null) {
|
||||
myLogAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, project);
|
||||
}
|
||||
}
|
||||
return myLogAlarm;
|
||||
}
|
||||
|
||||
public void setLogMessage(String text) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
|
||||
@@ -117,26 +128,30 @@ class StatusPanel extends JPanel {
|
||||
final Project project = getActiveProject();
|
||||
final Pair<Notification, Long> statusMessage = EventLog.getStatusMessage(project);
|
||||
myLogMode = logAllowed && StringUtil.isEmpty(nonLogText) && statusMessage != null;
|
||||
myLogAlarm.cancelAllRequests();
|
||||
final Alarm alarm = getAlarm();
|
||||
|
||||
if (myLogMode) {
|
||||
myTextPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
assert statusMessage != null;
|
||||
String text = EventLog.formatForLog(statusMessage.first).status;
|
||||
if (myDirty || System.currentTimeMillis() - statusMessage.second >= DateFormatUtil.MINUTE) {
|
||||
text += " (" + StringUtil.decapitalize(DateFormatUtil.formatPrettyDateTime(statusMessage.second)) + ")";
|
||||
if (alarm != null) {
|
||||
alarm.cancelAllRequests();
|
||||
|
||||
if (myLogMode) {
|
||||
myTextPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
assert statusMessage != null;
|
||||
String text = EventLog.formatForLog(statusMessage.first).status;
|
||||
if (myDirty || System.currentTimeMillis() - statusMessage.second >= DateFormatUtil.MINUTE) {
|
||||
text += " (" + StringUtil.decapitalize(DateFormatUtil.formatPrettyDateTime(statusMessage.second)) + ")";
|
||||
}
|
||||
setStatusText(text);
|
||||
alarm.addRequest(this, 30000);
|
||||
}
|
||||
setStatusText(text);
|
||||
myLogAlarm.addRequest(this, 30000);
|
||||
}
|
||||
}.run();
|
||||
} else {
|
||||
myTextPanel.setCursor(Cursor.getDefaultCursor());
|
||||
myDirty = true;
|
||||
setStatusText(nonLogText);
|
||||
}.run();
|
||||
} else {
|
||||
myTextPanel.setCursor(Cursor.getDefaultCursor());
|
||||
myDirty = true;
|
||||
setStatusText(nonLogText);
|
||||
}
|
||||
}
|
||||
return myLogMode;
|
||||
}
|
||||
@@ -155,15 +170,18 @@ class StatusPanel extends JPanel {
|
||||
}
|
||||
|
||||
public void restoreLogIfNeeded() {
|
||||
myLogAlarm.cancelAllRequests();
|
||||
myLogAlarm.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (StringUtil.isEmpty(myTextPanel.getText())) {
|
||||
updateText(true, "");
|
||||
Alarm alarm = getAlarm();
|
||||
if (alarm != null) {
|
||||
alarm.cancelAllRequests();
|
||||
alarm.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (StringUtil.isEmpty(myTextPanel.getText())) {
|
||||
updateText(true, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 300);
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
|
||||
@@ -307,7 +307,12 @@ public class FocusTrackback {
|
||||
|
||||
if (mustBeLastInStack) {
|
||||
for (int i = index + 1; i < stack.size(); i++) {
|
||||
if (!stack.get(i).isConsumed()) {
|
||||
if (!stack.get(i).isMustBeShown()) {
|
||||
if ((stack.get(i).isSheduledForRestore() || stack.get(i).isWillBeSheduledForRestore()) && !stack.get(i).isConsumed()) {
|
||||
toFocus = null;
|
||||
break;
|
||||
}
|
||||
} else if (!stack.get(i).isConsumed()) {
|
||||
toFocus = null;
|
||||
break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public class ExternalChangesAndRefreshingTest extends IntegrationTestCase {
|
||||
@Override
|
||||
protected void runBareRunnable(Runnable r) throws Throwable {
|
||||
if (getName().equals("testRefreshingAsynchronously")) {
|
||||
// this methods waits for another thread to finish, that leds
|
||||
// this method waits for another thread to finish, that leads
|
||||
// to deadlock in swing-thread. Therefore we have to run this test
|
||||
// outside of swing-thread
|
||||
r.run();
|
||||
|
||||
+7
-2
@@ -30,6 +30,7 @@ import com.intellij.openapi.roots.ContentEntry;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.util.Clock;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.testFramework.PlatformTestCase;
|
||||
@@ -143,8 +144,12 @@ public abstract class IntegrationTestCase extends PlatformTestCase {
|
||||
return getRevisionsFor(f, null);
|
||||
}
|
||||
|
||||
protected List<Revision> getRevisionsFor(VirtualFile f, String pattern) {
|
||||
return LocalHistoryTestCase.collectRevisions(getVcs(), getRootEntry(), f.getPath(), myProject.getLocationHash(), pattern);
|
||||
protected List<Revision> getRevisionsFor(final VirtualFile f, final String pattern) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<List<Revision>>() {
|
||||
public List<Revision> compute() {
|
||||
return LocalHistoryTestCase.collectRevisions(getVcs(), getRootEntry(), f.getPath(), myProject.getLocationHash(), pattern);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected RootEntry getRootEntry() {
|
||||
|
||||
@@ -41,7 +41,6 @@ import com.intellij.openapi.module.ModuleType;
|
||||
import com.intellij.openapi.module.impl.ModuleManagerImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx;
|
||||
import com.intellij.openapi.project.impl.ProjectImpl;
|
||||
import com.intellij.openapi.project.impl.TooManyProjectLeakedException;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
@@ -68,7 +67,6 @@ import com.intellij.psi.impl.PsiDocumentManagerImpl;
|
||||
import com.intellij.psi.impl.PsiManagerEx;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl;
|
||||
import com.intellij.util.PatchedWeakReference;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.indexing.IndexableSetContributor;
|
||||
import com.intellij.util.indexing.IndexedRootsProvider;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -85,6 +83,7 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -127,6 +126,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
|
||||
|
||||
protected void initApplication() throws Exception {
|
||||
boolean firstTime = ourApplication == null;
|
||||
autodetectPlatformPrefix();
|
||||
ourApplication = IdeaTestApplication.getInstance(getApplicationConfigDirPath());
|
||||
ourApplication.setDataProvider(this);
|
||||
|
||||
@@ -135,6 +135,22 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
|
||||
}
|
||||
}
|
||||
|
||||
private static void autodetectPlatformPrefix() {
|
||||
if (ourPlatformPrefixInitialized) {
|
||||
return;
|
||||
}
|
||||
URL resource = PlatformTestCase.class.getClassLoader().getResource("idea/ApplicationInfo.xml");
|
||||
if (resource == null) {
|
||||
resource = PlatformTestCase.class.getClassLoader().getResource("idea/IdeaApplicationInfo.xml");
|
||||
if (resource == null) {
|
||||
System.setProperty("idea.platform.prefix", "PlatformLangXml");
|
||||
}
|
||||
else {
|
||||
System.setProperty("idea.platform.prefix", "Idea");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void cleanPersistedVFSContent() {
|
||||
((PersistentFS)ManagingFS.getInstance()).cleanPersistedContents();
|
||||
}
|
||||
@@ -429,7 +445,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
|
||||
try {
|
||||
LightPlatformTestCase.checkEditorsReleased();
|
||||
}
|
||||
catch (AssertionError error) {
|
||||
catch (Throwable error) {
|
||||
result.add(error);
|
||||
}
|
||||
}
|
||||
@@ -617,7 +633,8 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
|
||||
throw IdeaLogger.ourErrorsOccurred;
|
||||
}
|
||||
|
||||
if (++LEAK_WALKS % 1000 == 0) {
|
||||
/*
|
||||
if (++LEAK_WALKS % 1 == 0) {
|
||||
LeakHunter.checkLeak(ApplicationManager.getApplication(), ProjectImpl.class, new Processor<ProjectImpl>() {
|
||||
@Override
|
||||
public boolean process(ProjectImpl project) {
|
||||
@@ -625,6 +642,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
}
|
||||
private static int LEAK_WALKS;
|
||||
|
||||
|
||||
+6
-1
@@ -36,6 +36,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -236,6 +237,10 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu
|
||||
VfsUtil.saveText(virtualFile[0], fileText);
|
||||
}
|
||||
}.execute();
|
||||
return PsiManager.getInstance(getProject()).findFile(virtualFile[0]);
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
|
||||
public PsiFile compute() {
|
||||
return PsiManager.getInstance(getProject()).findFile(virtualFile[0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -756,12 +756,12 @@ public class StringUtil {
|
||||
return suggestion + "ren";
|
||||
}
|
||||
|
||||
if (endsWithChar(suggestion, 's') || endsWithChar(suggestion, 'x') || suggestion.endsWith("ch")) {
|
||||
if (endsWithIgnoreCase(suggestion, "s") || endsWithIgnoreCase(suggestion, "x") || endsWithIgnoreCase(suggestion, "ch")) {
|
||||
return suggestion + "es";
|
||||
}
|
||||
|
||||
int len = suggestion.length();
|
||||
if (endsWithChar(suggestion, 'y') && len > 1 && !isVowel(suggestion.charAt(len - 2))) {
|
||||
if (endsWithIgnoreCase(suggestion, "y") && len > 1 && !isVowel(toLowerCase(suggestion.charAt(len - 2)))) {
|
||||
return suggestion.substring(0, len - 1) + "ies";
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ public abstract class XBreakpointType<B extends XBreakpoint<P>, P extends XBreak
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated override {@link #getEditorsProvider(XBreakpoint)} instead
|
||||
* @deprecated override {@link #getEditorsProvider(B, com.intellij.openapi.project.Project)} instead
|
||||
*/
|
||||
@Nullable
|
||||
public XDebuggerEditorsProvider getEditorsProvider() {
|
||||
@@ -127,7 +127,7 @@ public abstract class XBreakpointType<B extends XBreakpoint<P>, P extends XBreak
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public XDebuggerEditorsProvider getEditorsProvider(@NotNull B breakpoint) {
|
||||
public XDebuggerEditorsProvider getEditorsProvider(@NotNull B breakpoint, @NotNull Project project) {
|
||||
return getEditorsProvider();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ public class XBreakpointPropertiesPanel<B extends XBreakpoint<?>> {
|
||||
|
||||
mySuspendPolicyPanel.init(project, breakpointManager, breakpoint);
|
||||
|
||||
XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider(breakpoint);
|
||||
XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider(breakpoint, project);
|
||||
|
||||
myBreakpointActionsPanel.init(project, breakpointManager, breakpoint, debuggerEditorsProvider);
|
||||
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
|
||||
mySubPanels.add(mySuspendPolicyPanel);
|
||||
myMasterBreakpointPanel.init(project, breakpointManager, breakpoint);
|
||||
mySubPanels.add(myMasterBreakpointPanel);
|
||||
XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider(breakpoint);
|
||||
XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider(breakpoint, project);
|
||||
|
||||
myActionsPanel.init(project, breakpointManager, breakpoint, debuggerEditorsProvider);
|
||||
mySubPanels.add(myActionsPanel);
|
||||
|
||||
+37
-11
@@ -1,9 +1,25 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.testAssistant;
|
||||
|
||||
import com.intellij.codeHighlighting.Pass;
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.daemon.LineMarkerInfo;
|
||||
import com.intellij.codeInsight.daemon.LineMarkerProvider;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
@@ -22,14 +38,6 @@ import java.util.List;
|
||||
*/
|
||||
public class TestDataLineMarkerProvider implements LineMarkerProvider {
|
||||
public LineMarkerInfo getLineMarkerInfo(PsiElement element) {
|
||||
if (!(element instanceof PsiMethod)) {
|
||||
return null;
|
||||
}
|
||||
final PsiMethod method = (PsiMethod)element;
|
||||
if (isTestMethod(method)) {
|
||||
return new LineMarkerInfo<PsiMethod>(method, method.getTextOffset(), PlatformIcons.TEST_SOURCE_FOLDER, Pass.UPDATE_ALL, null,
|
||||
new TestDataNavigationHandler());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -56,6 +64,20 @@ public class TestDataLineMarkerProvider implements LineMarkerProvider {
|
||||
}
|
||||
|
||||
public void collectSlowLineMarkers(List<PsiElement> elements, Collection<LineMarkerInfo> result) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
return;
|
||||
}
|
||||
for (PsiElement element : elements) {
|
||||
if (!(element instanceof PsiMethod)) {
|
||||
continue;
|
||||
}
|
||||
final PsiMethod method = (PsiMethod)element;
|
||||
if (isTestMethod(method)) {
|
||||
result.add(new LineMarkerInfo<PsiMethod>(
|
||||
method, method.getTextOffset(), PlatformIcons.TEST_SOURCE_FOLDER, Pass.UPDATE_ALL, null, new TestDataNavigationHandler()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -69,13 +91,17 @@ public class TestDataLineMarkerProvider implements LineMarkerProvider {
|
||||
final Object constantValue = evaluationHelper.computeConstantExpression(value, false);
|
||||
if (constantValue instanceof String) {
|
||||
String path = (String) constantValue;
|
||||
if (path.indexOf("$CONTENT_ROOT") >= 0) {
|
||||
if (path.contains("$CONTENT_ROOT")) {
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
final VirtualFile contentRoot = fileIndex.getContentRootForFile(psiClass.getContainingFile().getVirtualFile());
|
||||
final VirtualFile file = psiClass.getContainingFile().getVirtualFile();
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
final VirtualFile contentRoot = fileIndex.getContentRootForFile(file);
|
||||
if (contentRoot == null) return null;
|
||||
path = path.replace("$CONTENT_ROOT", contentRoot.getPath());
|
||||
}
|
||||
if (path.indexOf("$PROJECT_ROOT") >= 0) {
|
||||
if (path.contains("$PROJECT_ROOT")) {
|
||||
final VirtualFile baseDir = project.getBaseDir();
|
||||
if (baseDir == null) {
|
||||
return null;
|
||||
|
||||
@@ -930,9 +930,7 @@ public class InjectionsSettingsUI implements SearchableConfigurable.Parent, NonD
|
||||
|
||||
@Override
|
||||
public boolean equals(final BaseInjection o1, final BaseInjection o2) {
|
||||
if (!o1.sameLanguageParameters(o2)) return false;
|
||||
if (!o1.getInjectionPlaces().equals(o2.getInjectionPlaces())) return false;
|
||||
return true;
|
||||
return o1.sameLanguageParameters(o2) && Arrays.equals(o1.getInjectionPlaces(), o2.getInjectionPlaces());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.search.FileTypeIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
@@ -51,6 +52,8 @@ import org.jetbrains.android.dom.resources.ResourceElement;
|
||||
import org.jetbrains.android.dom.resources.Resources;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.facet.AndroidRootUtil;
|
||||
import org.jetbrains.android.fileTypes.AndroidIdlFileType;
|
||||
import org.jetbrains.android.fileTypes.AndroidRenderscriptFileType;
|
||||
import org.jetbrains.android.resourceManagers.LocalResourceManager;
|
||||
import org.jetbrains.android.sdk.AndroidPlatform;
|
||||
import org.jetbrains.android.util.AndroidUtils;
|
||||
@@ -609,10 +612,15 @@ public class AndroidCompileUtil {
|
||||
|
||||
public static void createGenModulesAndSourceRoots(@NotNull final AndroidFacet facet) {
|
||||
final Module module = facet.getModule();
|
||||
String sourceRootPath;
|
||||
|
||||
String sourceRootPath = AndroidRootUtil.getRenderscriptGenSourceRootPath(module);
|
||||
if (sourceRootPath != null) {
|
||||
createSourceRootIfNotExist(sourceRootPath, module);
|
||||
final GlobalSearchScope moduleScope = facet.getModule().getModuleScope();
|
||||
|
||||
if (FileTypeIndex.getFiles(AndroidRenderscriptFileType.INSTANCE, moduleScope).size() > 0) {
|
||||
sourceRootPath = AndroidRootUtil.getRenderscriptGenSourceRootPath(module);
|
||||
if (sourceRootPath != null) {
|
||||
createSourceRootIfNotExist(sourceRootPath, module);
|
||||
}
|
||||
}
|
||||
|
||||
sourceRootPath = facet.getAptGenSourceRootPath();
|
||||
@@ -620,9 +628,11 @@ public class AndroidCompileUtil {
|
||||
createSourceRootIfNotExist(sourceRootPath, module);
|
||||
}
|
||||
|
||||
sourceRootPath = facet.getAidlGenSourceRootPath();
|
||||
if (sourceRootPath != null) {
|
||||
createSourceRootIfNotExist(sourceRootPath, module);
|
||||
if (FileTypeIndex.getFiles(AndroidIdlFileType.ourFileType, moduleScope).size() > 0) {
|
||||
sourceRootPath = facet.getAidlGenSourceRootPath();
|
||||
if (sourceRootPath != null) {
|
||||
createSourceRootIfNotExist(sourceRootPath, module);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.jetbrains.android.dom;
|
||||
|
||||
import com.intellij.util.xml.ResolvingConverter;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
public @interface AdditionalConverter {
|
||||
Class<? extends ResolvingConverter> value();
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package org.jetbrains.android.dom.converters;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class QuietResourceReferenceConverter extends ResourceReferenceConverter {
|
||||
public QuietResourceReferenceConverter() {
|
||||
setQuiet(true);
|
||||
}
|
||||
}
|
||||
+82
-45
@@ -18,6 +18,7 @@ package org.jetbrains.android.dom.converters;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -28,11 +29,9 @@ import com.intellij.psi.xml.XmlElement;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.PsiNavigateUtil;
|
||||
import com.intellij.util.xml.ConvertContext;
|
||||
import com.intellij.util.xml.CustomReferenceConverter;
|
||||
import com.intellij.util.xml.GenericDomValue;
|
||||
import com.intellij.util.xml.ResolvingConverter;
|
||||
import com.intellij.util.xml.*;
|
||||
import org.jetbrains.android.dom.ResourceType;
|
||||
import org.jetbrains.android.dom.AdditionalConverter;
|
||||
import org.jetbrains.android.dom.resources.Item;
|
||||
import org.jetbrains.android.dom.resources.ResourceElement;
|
||||
import org.jetbrains.android.dom.resources.ResourceValue;
|
||||
@@ -61,6 +60,7 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
private boolean myAdditionalConverterSoft = false;
|
||||
private boolean myWithPrefix = true;
|
||||
private boolean myWithExplicitResourceType = true;
|
||||
private boolean myQuiet = false;
|
||||
|
||||
public ResourceReferenceConverter() {
|
||||
this(new ArrayList<String>());
|
||||
@@ -81,6 +81,10 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
myAdditionalConverterSoft = soft;
|
||||
}
|
||||
|
||||
public void setQuiet(boolean quiet) {
|
||||
myQuiet = quiet;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getPackagePrefix(@Nullable String resourcePackage) {
|
||||
String prefix = myWithPrefix ? "@" : "";
|
||||
@@ -117,32 +121,37 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
if (element == null) return result;
|
||||
String value = getValue(element);
|
||||
assert value != null;
|
||||
String resourcePackage = null;
|
||||
String systemPrefix = getPackagePrefix(SYSTEM_RESOURCE_PACKAGE);
|
||||
if (value.startsWith(systemPrefix)) {
|
||||
resourcePackage = SYSTEM_RESOURCE_PACKAGE;
|
||||
}
|
||||
else {
|
||||
result.add(ResourceValue.literal(systemPrefix));
|
||||
}
|
||||
if (recommendedTypes.size() == 1) {
|
||||
String type = recommendedTypes.iterator().next();
|
||||
boolean explicitResourceType = value.startsWith(getTypePrefix(resourcePackage, type)) || myWithExplicitResourceType;
|
||||
addResourceReferenceValuesWithDeps(facet, type, resourcePackage, result, explicitResourceType);
|
||||
}
|
||||
else {
|
||||
for (String type : ResourceManager.REFERABLE_RESOURCE_TYPES) {
|
||||
String typePrefix = getTypePrefix(resourcePackage, type);
|
||||
if (value.startsWith(typePrefix)) {
|
||||
addResourceReferenceValuesWithDeps(facet, type, resourcePackage, result, true);
|
||||
}
|
||||
else if (recommendedTypes.contains(type)) {
|
||||
result.add(ResourceValue.literal(typePrefix));
|
||||
|
||||
if (!myQuiet || value.startsWith("@")) {
|
||||
String resourcePackage = null;
|
||||
String systemPrefix = getPackagePrefix(SYSTEM_RESOURCE_PACKAGE);
|
||||
if (value.startsWith(systemPrefix)) {
|
||||
resourcePackage = SYSTEM_RESOURCE_PACKAGE;
|
||||
}
|
||||
else {
|
||||
result.add(ResourceValue.literal(systemPrefix));
|
||||
}
|
||||
if (recommendedTypes.size() == 1) {
|
||||
String type = recommendedTypes.iterator().next();
|
||||
boolean explicitResourceType = value.startsWith(getTypePrefix(resourcePackage, type)) || myWithExplicitResourceType;
|
||||
addResourceReferenceValuesWithDeps(facet, type, resourcePackage, result, explicitResourceType);
|
||||
}
|
||||
else {
|
||||
for (String type : ResourceManager.REFERABLE_RESOURCE_TYPES) {
|
||||
String typePrefix = getTypePrefix(resourcePackage, type);
|
||||
if (value.startsWith(typePrefix)) {
|
||||
addResourceReferenceValuesWithDeps(facet, type, resourcePackage, result, true);
|
||||
}
|
||||
else if (recommendedTypes.contains(type)) {
|
||||
result.add(ResourceValue.literal(typePrefix));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myAdditionalConverter != null) {
|
||||
for (String variant : myAdditionalConverter.getVariants(context)) {
|
||||
final ResolvingConverter<String> additionalConverter = getAdditionalConverter(context);
|
||||
|
||||
if (additionalConverter != null) {
|
||||
for (String variant : additionalConverter.getVariants(context)) {
|
||||
result.add(ResourceValue.literal(variant));
|
||||
}
|
||||
}
|
||||
@@ -162,6 +171,9 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
String s = resourceType.value();
|
||||
if (s != null) types.add(s);
|
||||
}
|
||||
if (types.size() == 0) {
|
||||
types.addAll(ResourceManager.REFERABLE_RESOURCE_TYPES);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
@@ -209,8 +221,10 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
public ResourceValue fromString(@Nullable @NonNls String s, ConvertContext context) {
|
||||
if (s == null) return null;
|
||||
ResourceValue parsed = ResourceValue.parse(s, true, myWithPrefix);
|
||||
if ((parsed == null || !parsed.isReference()) && myAdditionalConverter != null) {
|
||||
String value = myAdditionalConverter.fromString(s, context);
|
||||
final ResolvingConverter<String> additionalConverter = getAdditionalConverter(context);
|
||||
|
||||
if ((parsed == null || !parsed.isReference()) && additionalConverter != null) {
|
||||
String value = additionalConverter.fromString(s, context);
|
||||
if (value != null) {
|
||||
return ResourceValue.literal(value);
|
||||
}
|
||||
@@ -224,6 +238,27 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
return parsed;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ResolvingConverter<String> getAdditionalConverter(ConvertContext context) {
|
||||
if (myAdditionalConverter != null) {
|
||||
return myAdditionalConverter;
|
||||
}
|
||||
|
||||
final AdditionalConverter additionalConverterAnnotation =
|
||||
context.getInvocationElement().getAnnotation(AdditionalConverter.class);
|
||||
|
||||
if (additionalConverterAnnotation != null) {
|
||||
final Class<? extends ResolvingConverter> converterClass = additionalConverterAnnotation.value();
|
||||
|
||||
if (converterClass != null) {
|
||||
final ConverterManager converterManager = ServiceManager.getService(ConverterManager.class);
|
||||
//noinspection unchecked
|
||||
return (ResolvingConverter<String>)converterManager.getConverterInstance(converterClass);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toString(@Nullable ResourceValue resourceElement, ConvertContext context) {
|
||||
return resourceElement != null ? resourceElement.toString() : null;
|
||||
}
|
||||
@@ -232,22 +267,24 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
|
||||
public LocalQuickFix[] getQuickFixes(ConvertContext context) {
|
||||
AndroidFacet facet = AndroidFacet.getInstance(context);
|
||||
if (facet != null) {
|
||||
XmlElement element = context.getXmlElement();
|
||||
if (element instanceof XmlAttribute) {
|
||||
String value = ((XmlAttribute)element).getValue();
|
||||
ResourceValue resourceValue = ResourceValue.parse(value, false, myWithPrefix);
|
||||
if (resourceValue != null) {
|
||||
String aPackage = resourceValue.getPackage();
|
||||
String resourceType = resourceValue.getResourceType();
|
||||
if (resourceType == null && myResourceTypes.size() == 1) {
|
||||
resourceType = myResourceTypes.get(0);
|
||||
}
|
||||
final String resourceName = resourceValue.getResourceName();
|
||||
if (aPackage == null && resourceType != null && resourceName != null) {
|
||||
if (value != null &&
|
||||
FIXABLE_RESOURCE_TYPES.contains(resourceType) &&
|
||||
AndroidResourceUtil.isCorrectAndroidResourceName(resourceName)) {
|
||||
return new LocalQuickFix[]{new MyLocalQuickFix(facet, resourceType, resourceName, element.getContainingFile())};
|
||||
final DomElement domElement = context.getInvocationElement();
|
||||
|
||||
if (domElement instanceof GenericDomValue) {
|
||||
final String value = ((GenericDomValue)domElement).getStringValue();
|
||||
|
||||
if (value != null) {
|
||||
ResourceValue resourceValue = ResourceValue.parse(value, false, myWithPrefix);
|
||||
if (resourceValue != null) {
|
||||
String aPackage = resourceValue.getPackage();
|
||||
String resourceType = resourceValue.getResourceType();
|
||||
if (resourceType == null && myResourceTypes.size() == 1) {
|
||||
resourceType = myResourceTypes.get(0);
|
||||
}
|
||||
final String resourceName = resourceValue.getResourceName();
|
||||
if (aPackage == null && resourceType != null && resourceName != null) {
|
||||
if (FIXABLE_RESOURCE_TYPES.contains(resourceType) && AndroidResourceUtil.isCorrectAndroidResourceName(resourceName)) {
|
||||
return new LocalQuickFix[]{new MyLocalQuickFix(facet, resourceType, resourceName, context.getFile())};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.jetbrains.android.dom.resources;
|
||||
|
||||
import com.intellij.util.xml.Convert;
|
||||
import com.intellij.util.xml.GenericDomValue;
|
||||
import org.jetbrains.android.dom.converters.QuietResourceReferenceConverter;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
@Convert(QuietResourceReferenceConverter.class)
|
||||
public interface ArrayElement extends GenericDomValue {
|
||||
}
|
||||
@@ -16,11 +16,14 @@
|
||||
package org.jetbrains.android.dom.resources;
|
||||
|
||||
import com.intellij.util.xml.Convert;
|
||||
import org.jetbrains.android.dom.AdditionalConverter;
|
||||
import org.jetbrains.android.dom.converters.AndroidBooleanValueConverter;
|
||||
import org.jetbrains.android.dom.converters.QuietResourceReferenceConverter;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
@Convert(AndroidBooleanValueConverter.class)
|
||||
@Convert(QuietResourceReferenceConverter.class)
|
||||
@AdditionalConverter(AndroidBooleanValueConverter.class)
|
||||
public interface BoolElement extends ResourceElement {
|
||||
}
|
||||
|
||||
@@ -17,11 +17,14 @@ package org.jetbrains.android.dom.resources;
|
||||
|
||||
import com.intellij.util.xml.Convert;
|
||||
import com.intellij.util.xml.GenericDomValue;
|
||||
import org.jetbrains.android.dom.AdditionalConverter;
|
||||
import org.jetbrains.android.dom.converters.IntegerConverter;
|
||||
import org.jetbrains.android.dom.converters.QuietResourceReferenceConverter;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
@Convert(IntegerConverter.class)
|
||||
@Convert(QuietResourceReferenceConverter.class)
|
||||
@AdditionalConverter(IntegerConverter.class)
|
||||
public interface IntegerArrayItem extends GenericDomValue {
|
||||
}
|
||||
|
||||
@@ -16,11 +16,14 @@
|
||||
package org.jetbrains.android.dom.resources;
|
||||
|
||||
import com.intellij.util.xml.Convert;
|
||||
import org.jetbrains.android.dom.AdditionalConverter;
|
||||
import org.jetbrains.android.dom.converters.IntegerConverter;
|
||||
import org.jetbrains.android.dom.converters.QuietResourceReferenceConverter;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
@Convert(IntegerConverter.class)
|
||||
@Convert(QuietResourceReferenceConverter.class)
|
||||
@AdditionalConverter(IntegerConverter.class)
|
||||
public interface IntegerElement extends ResourceElement {
|
||||
}
|
||||
|
||||
@@ -19,9 +19,10 @@ package org.jetbrains.android.dom.resources;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.xml.Convert;
|
||||
import com.intellij.util.xml.GenericAttributeValue;
|
||||
import org.jetbrains.android.dom.converters.StaticEnumConverter;
|
||||
import org.jetbrains.android.dom.converters.FormatConverter;
|
||||
import org.jetbrains.android.dom.attrs.AttributeFormat;
|
||||
import org.jetbrains.android.dom.converters.FormatConverter;
|
||||
import org.jetbrains.android.dom.converters.QuietResourceReferenceConverter;
|
||||
import org.jetbrains.android.dom.converters.StaticEnumConverter;
|
||||
import org.jetbrains.android.resourceManagers.ResourceManager;
|
||||
|
||||
import java.util.List;
|
||||
@@ -33,6 +34,7 @@ import java.util.List;
|
||||
* Time: 5:40:29 PM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
@Convert(QuietResourceReferenceConverter.class)
|
||||
public interface Item extends ResourceElement {
|
||||
class TypeConverter extends StaticEnumConverter {
|
||||
public TypeConverter() {
|
||||
|
||||
@@ -28,14 +28,14 @@ public interface Resources extends AndroidDomElement {
|
||||
List<StringElement> getStrings();
|
||||
StringElement addString();
|
||||
|
||||
List<ResourceElement> getColors();
|
||||
ResourceElement addColor();
|
||||
List<ScalarResourceElement> getColors();
|
||||
ScalarResourceElement addColor();
|
||||
|
||||
List<ResourceElement> getDrawables();
|
||||
ResourceElement addDrawable();
|
||||
List<ScalarResourceElement> getDrawables();
|
||||
ScalarResourceElement addDrawable();
|
||||
|
||||
List<ResourceElement> getDimens();
|
||||
ResourceElement addDimen();
|
||||
List<ScalarResourceElement> getDimens();
|
||||
ScalarResourceElement addDimen();
|
||||
|
||||
List<Style> getStyles();
|
||||
Style addStyle();
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.jetbrains.android.dom.resources;
|
||||
|
||||
import com.intellij.util.xml.Convert;
|
||||
import org.jetbrains.android.dom.converters.QuietResourceReferenceConverter;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
@Convert(QuietResourceReferenceConverter.class)
|
||||
public interface ScalarResourceElement extends ResourceElement {
|
||||
}
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.jetbrains.android.dom.resources;
|
||||
|
||||
import com.intellij.util.xml.DomElement;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -28,5 +26,5 @@ import java.util.List;
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public interface StringArray extends ResourceElement {
|
||||
List<DomElement> getItems();
|
||||
List<ArrayElement> getItems();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.jetbrains.android.dom.resources;
|
||||
|
||||
import com.intellij.util.xml.Convert;
|
||||
import org.jetbrains.android.dom.converters.QuietResourceReferenceConverter;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Eugene.Kudelevsky
|
||||
@@ -23,5 +26,6 @@ package org.jetbrains.android.dom.resources;
|
||||
* Time: 6:35:12 PM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
@Convert(QuietResourceReferenceConverter.class)
|
||||
public interface StringElement extends ResourceElement, StyledText {
|
||||
}
|
||||
|
||||
@@ -742,6 +742,7 @@ public abstract class AndroidFacetImporterBase extends FacetImporter<AndroidFace
|
||||
@Override
|
||||
public void collectExcludedFolders(MavenProject mavenProject, List<String> result) {
|
||||
result.add(mavenProject.getGeneratedSourcesDirectory(false) + "/combined-resources");
|
||||
result.add(mavenProject.getGeneratedSourcesDirectory(false) + "/combined-assets");
|
||||
result.add(mavenProject.getGeneratedSourcesDirectory(false) + "/extracted-dependencies");
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -272,7 +272,7 @@ public class LocalResourceManager extends ResourceManager {
|
||||
ResourceElement element = addValueResource(type, resources);
|
||||
element.getName().setValue(name);
|
||||
if (value != null) {
|
||||
element.setValue(value);
|
||||
element.setStringValue(value);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
package org.jetbrains.android.sdk;
|
||||
|
||||
import com.android.resources.ResourceType;
|
||||
import com.android.sdklib.IAndroidTarget;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.XmlRecursiveElementVisitor;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.android.dom.attrs.AttributeDefinitions;
|
||||
import org.jetbrains.android.dom.resources.ResourceElement;
|
||||
import org.jetbrains.android.resourceManagers.SystemResourceManager;
|
||||
import org.jetbrains.android.uipreview.RenderServiceFactory;
|
||||
import org.jetbrains.android.uipreview.RenderingException;
|
||||
@@ -17,7 +22,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -75,22 +79,46 @@ public class AndroidTargetData {
|
||||
if (myThemes == null) {
|
||||
myThemes = new HashSet<String>();
|
||||
final SystemResourceManager systemResourceManager = new SystemResourceManager(module, new AndroidPlatform(mySdk, myTarget));
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (module.isDisposed() || module.getProject().isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<ResourceElement> styles = systemResourceManager.getValueResources(ResourceType.STYLE.getName());
|
||||
for (ResourceElement style : styles) {
|
||||
final String styleName = style.getName().getValue();
|
||||
if (styleName != null && (styleName.equals("Theme") || styleName.startsWith("Theme."))) {
|
||||
myThemes.add(styleName);
|
||||
}
|
||||
for (VirtualFile valueResourceDir : systemResourceManager.getResourceSubdirs("values")) {
|
||||
for (final VirtualFile valueResourceFile : valueResourceDir.getChildren()) {
|
||||
if (!valueResourceFile.isDirectory() && valueResourceFile.getFileType().equals(StdFileTypes.XML)) {
|
||||
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Project project = module.getProject();
|
||||
|
||||
if (module.isDisposed() || project.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
final PsiManager psiManager = PsiManager.getInstance(project);
|
||||
final PsiFile psiFile = psiManager.findFile(valueResourceFile);
|
||||
|
||||
if (psiFile instanceof XmlFile) {
|
||||
psiFile.accept(new XmlRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitXmlTag(XmlTag tag) {
|
||||
super.visitXmlTag(tag);
|
||||
|
||||
if ("style".equals(tag.getName())) {
|
||||
final String styleName = tag.getAttributeValue("name");
|
||||
|
||||
if (styleName != null && (styleName.equals("Theme") || styleName.startsWith("Theme."))) {
|
||||
myThemes.add(styleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
psiManager.dropResolveCaches();
|
||||
InjectedLanguageManager.getInstance(project).dropFileCaches(psiFile);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return myThemes;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.android.uipreview;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.VerticalFlowLayout;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
@@ -17,8 +18,10 @@
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class AndroidLayoutPreviewPanel extends JPanel implements Disposable {
|
||||
@@ -35,6 +38,9 @@ public class AndroidLayoutPreviewPanel extends JPanel implements Disposable {
|
||||
|
||||
private double myZoomFactor = 1.0;
|
||||
private boolean myZoomToFit = true;
|
||||
|
||||
private final List<ProgressIndicator> myProgressIndicators = new ArrayList<ProgressIndicator>();
|
||||
private boolean myProgressVisible = false;
|
||||
|
||||
private final JPanel myImagePanel = new JPanel() {
|
||||
@Override
|
||||
@@ -110,16 +116,30 @@ public class AndroidLayoutPreviewPanel extends JPanel implements Disposable {
|
||||
doRevalidate();
|
||||
}
|
||||
|
||||
public void showProgress() {
|
||||
((CardLayout)myProgressIconWrapper.getLayout()).show(myProgressIconWrapper, PROGRESS_ICON_CARD_NAME);
|
||||
myProgressIcon.setVisible(true);
|
||||
myProgressIcon.resume();
|
||||
public synchronized void registerIndicator(@NotNull ProgressIndicator indicator) {
|
||||
synchronized (myProgressIndicators) {
|
||||
myProgressIndicators.add(indicator);
|
||||
|
||||
if (!myProgressVisible) {
|
||||
myProgressVisible = true;
|
||||
((CardLayout)myProgressIconWrapper.getLayout()).show(myProgressIconWrapper, PROGRESS_ICON_CARD_NAME);
|
||||
myProgressIcon.setVisible(true);
|
||||
myProgressIcon.resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void hideProgress() {
|
||||
myProgressIcon.suspend();
|
||||
((CardLayout)myProgressIconWrapper.getLayout()).show(myProgressIconWrapper, EMPTY_CARD_NAME);
|
||||
myProgressIcon.setVisible(false);
|
||||
public void unregisterIndicator(@NotNull ProgressIndicator indicator) {
|
||||
synchronized (myProgressIndicators) {
|
||||
myProgressIndicators.remove(indicator);
|
||||
|
||||
if (myProgressIndicators.size() == 0 && myProgressVisible) {
|
||||
myProgressVisible = false;
|
||||
myProgressIcon.suspend();
|
||||
((CardLayout)myProgressIconWrapper.getLayout()).show(myProgressIconWrapper, EMPTY_CARD_NAME);
|
||||
myProgressIcon.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doRevalidate() {
|
||||
|
||||
+9
-1
@@ -19,6 +19,7 @@ import com.intellij.openapi.actionSystem.ex.CheckboxAction;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
@@ -934,7 +935,14 @@ class AndroidLayoutPreviewToolWindowForm implements Disposable {
|
||||
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
collectFrameworkThemes(themes, facet, finalTargetData, addedThemes);
|
||||
|
||||
ProgressManager.getInstance().runProcess(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
collectFrameworkThemes(themes, facet, finalTargetData, addedThemes);
|
||||
}
|
||||
}, new AndroidPreviewProgressIndicator(AndroidLayoutPreviewToolWindowForm.this, 0));
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
+1
-46
@@ -17,7 +17,6 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
@@ -43,7 +42,6 @@ import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentManager;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.update.MergingUpdateQueue;
|
||||
import com.intellij.util.ui.update.Update;
|
||||
import org.jetbrains.android.dom.layout.LayoutDomFileDescription;
|
||||
@@ -63,8 +61,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -304,7 +300,7 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
|
||||
DumbService.getInstance(myProject).waitForSmartMode();
|
||||
doRender(facet, psiFile);
|
||||
}
|
||||
}, new MyProgressIndicator());
|
||||
}, new AndroidPreviewProgressIndicator(myToolWindowForm, 1000));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -628,45 +624,4 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent {
|
||||
processFileEditorChange(layoutXmlEditor);
|
||||
}
|
||||
}
|
||||
|
||||
private class MyProgressIndicator extends ProgressIndicatorBase {
|
||||
private final Object myLock = new Object();
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
super.start();
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Timer timer = UIUtil.createNamedTimer("Android rendering progress timer", 1000, new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
synchronized (myLock) {
|
||||
if (isRunning() && myToolWindowForm != null) {
|
||||
myToolWindowForm.getPreviewPanel().showProgress();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
timer.setRepeats(false);
|
||||
timer.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
synchronized (myLock) {
|
||||
super.stop();
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myToolWindowForm != null) {
|
||||
myToolWindowForm.getPreviewPanel().hideProgress();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package org.jetbrains.android.uipreview;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
class AndroidPreviewProgressIndicator extends ProgressIndicatorBase {
|
||||
private final Object myLock = new Object();
|
||||
private final int myDelay;
|
||||
private final AndroidLayoutPreviewToolWindowForm myForm;
|
||||
|
||||
AndroidPreviewProgressIndicator(@NotNull AndroidLayoutPreviewToolWindowForm form, int delay) {
|
||||
myDelay = delay;
|
||||
myForm = form;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
super.start();
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Timer timer = UIUtil.createNamedTimer("Android rendering progress timer", myDelay, new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
synchronized (myLock) {
|
||||
if (isRunning() && myForm != null) {
|
||||
myForm.getPreviewPanel().registerIndicator(AndroidPreviewProgressIndicator.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
timer.setRepeats(false);
|
||||
timer.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
synchronized (myLock) {
|
||||
super.stop();
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myForm != null) {
|
||||
myForm.getPreviewPanel().unregisterIndicator(AndroidPreviewProgressIndicator.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/unknownDrawabl<caret>e"
|
||||
/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<drawable name="unknownDrawable"></drawable>
|
||||
</resources>
|
||||
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<drawable name="d1">@drawable/dd<caret>2</drawable>
|
||||
</resources>
|
||||
@@ -0,0 +1,4 @@
|
||||
<resources>
|
||||
<drawable name="d1">@drawable/dd2</drawable>
|
||||
<drawable name="dd2"></drawable>
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="res1">false</bool>
|
||||
<color name="res2">#ffffff</color>
|
||||
<string name="res3">str</string>
|
||||
<integer name="res4">1</integer>
|
||||
|
||||
<string name="s1">@integer/r<caret></string>
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="res1">false</bool>
|
||||
<color name="res2">#ffffff</color>
|
||||
<string name="res3">str</string>
|
||||
<integer name="res4">1</integer>
|
||||
|
||||
<string name="s1">@integer/res4</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="res1">false</bool>
|
||||
<color name="res2">#ffffff</color>
|
||||
<string name="res3">str</string>
|
||||
<integer name="res4">1</integer>
|
||||
|
||||
<string name="s1">@andr<caret></string>
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="res1">false</bool>
|
||||
<color name="res2">#ffffff</color>
|
||||
<string name="res3">str</string>
|
||||
<integer name="res4">1</integer>
|
||||
|
||||
<string name="s1">@android:<caret></string>
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="res1">false</bool>
|
||||
<color name="res2">#ffffff</color>
|
||||
<string name="res3">str</string>
|
||||
<integer name="res4">1</integer>
|
||||
|
||||
<bool name="s1"><caret></bool>
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="res1">false</bool>
|
||||
<color name="res2">#ffffff</color>
|
||||
<string name="res3">str</string>
|
||||
<integer name="res4">1</integer>
|
||||
|
||||
<string name="s1"><caret></bool>
|
||||
</resources>
|
||||
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<integer name="res1">1</integer>
|
||||
<bool name="res2">false</bool>
|
||||
<color name="res3">#ffffff</color>
|
||||
<string name="res4">str</string>
|
||||
|
||||
<string name="s1">@integer/res1</string>
|
||||
<string name="s2">@bool/res2</string>
|
||||
<string name="s3">@color/res3</string>
|
||||
<string name="s4">@string/res4</string>
|
||||
<string name="s5"><error>@string/err</error></string>
|
||||
|
||||
<color name="c1">@integer/res1</color>
|
||||
<color name="c2">@bool/res2</color>
|
||||
<color name="c3">@color/res3</color>
|
||||
<color name="c4">@string/res4</color>
|
||||
<color name="c5"><error>@string/err</error></color>
|
||||
|
||||
<drawable name="drawable1">@integer/res1</drawable>
|
||||
<drawable name="drawable2">@bool/res2</drawable>
|
||||
<drawable name="drawable3">@color/res3</drawable>
|
||||
<drawable name="drawable4">@string/res4</drawable>
|
||||
<drawable name="drawable5"><error>@string/err</error></drawable>
|
||||
|
||||
<dimen name="dimen1">@integer/res1</dimen>
|
||||
<dimen name="dimen2">@bool/res2</dimen>
|
||||
<dimen name="dimen3">@color/res3</dimen>
|
||||
<dimen name="dimen4">@string/res4</dimen>
|
||||
<dimen name="dimen5"><error>@string/err</error></dimen>
|
||||
|
||||
<array name="ar">
|
||||
<item>@integer/res1</item>
|
||||
<item>@bool/res2</item>
|
||||
<item>@color/res3</item>
|
||||
<item>@string/res4</item>
|
||||
<item><error>@string/err</error></item>
|
||||
</array>
|
||||
|
||||
<string-array name="sar">
|
||||
<item>@integer/res1</item>
|
||||
<item>@bool/res2</item>
|
||||
<item>@color/res3</item>
|
||||
<item>@string/res4</item>
|
||||
<item><error>@string/err</error></item>
|
||||
</string-array>
|
||||
|
||||
<bool name="bool1">@integer/res1</bool>
|
||||
<bool name="bool2">@bool/res2</bool>
|
||||
<bool name="bool3">@color/res3</bool>
|
||||
<bool name="bool4">@string/res4</bool>
|
||||
<bool name="bool5"><error>@string/err</error></bool>
|
||||
<bool name="bool6">true</bool>
|
||||
<bool name="bool7"><error>tru</error></bool>
|
||||
|
||||
<integer name="i1">@integer/res1</integer>
|
||||
<integer name="i2">@bool/res2</integer>
|
||||
<integer name="i3">@color/res3</integer>
|
||||
<integer name="i4">@string/res4</integer>
|
||||
<integer name="i5"><error>@string/err</error></integer>
|
||||
<integer name="i6">10</integer>
|
||||
<integer name="i7"><error>aba</error></integer>
|
||||
|
||||
<integer-array name="iar">
|
||||
<item>@integer/res1</item>
|
||||
<item>@bool/res2</item>
|
||||
<item>@color/res3</item>
|
||||
<item>@string/res4</item>
|
||||
<item><error>@string/err</error></item>
|
||||
</integer-array>
|
||||
|
||||
<item name="item1" type="string">@integer/res1</item>
|
||||
<item name="item2" type="string">@bool/res2</item>
|
||||
<item name="item3" type="string">@color/res3</item>
|
||||
<item name="item4" type="string">@string/res4</item>
|
||||
<item name="item5" type="string"><error>@string/err</error></item>
|
||||
|
||||
<item name="iitem1" type="bool">@integer/res1</item>
|
||||
<item name="iitem2" type="bool">@bool/res2</item>
|
||||
<item name="iitem3" type="bool">@color/res3</item>
|
||||
<item name="iitem4" type="bool">@string/res4</item>
|
||||
</resources>
|
||||
@@ -2,11 +2,17 @@ package org.jetbrains.android.dom;
|
||||
|
||||
import com.android.sdklib.SdkConstants;
|
||||
import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -326,6 +332,33 @@ public class AndroidLayoutDomTest extends AndroidDomTest {
|
||||
doTestCompletionVariants(getTestName(false) + ".xml", "@+id/", "@android:", "@id/idd1", "@id/idd2");
|
||||
}
|
||||
|
||||
public void testCreateResourceFromUsage() throws Throwable {
|
||||
final VirtualFile virtualFile = copyFileToProject(getTestName(true) + ".xml");
|
||||
myFixture.configureFromExistingVirtualFile(virtualFile);
|
||||
final List<HighlightInfo> infos = myFixture.doHighlighting();
|
||||
final List<IntentionAction> actions = new ArrayList<IntentionAction>();
|
||||
|
||||
for (HighlightInfo info : infos) {
|
||||
final List<Pair<HighlightInfo.IntentionActionDescriptor, TextRange>> ranges = info.quickFixActionRanges;
|
||||
|
||||
if (ranges != null) {
|
||||
for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : ranges) {
|
||||
actions.add(pair.getFirst().getAction());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(1, actions.size());
|
||||
|
||||
new WriteCommandAction.Simple(getProject()) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
actions.get(0).invoke(getProject(), myFixture.getEditor(), myFixture.getFile());
|
||||
}
|
||||
}.execute();
|
||||
myFixture.checkResultByFile("res/values/drawables.xml", testFolder + '/' + getTestName(true) + "_drawable_after.xml", true);
|
||||
}
|
||||
|
||||
private void copyOnClickClasses() throws IOException {
|
||||
copyFileToProject("OnClick_Class1.java", "src/p1/p2/OnClick_Class1.java");
|
||||
copyFileToProject("OnClick_Class2.java", "src/p1/p2/OnClick_Class2.java");
|
||||
|
||||
@@ -17,12 +17,20 @@
|
||||
package org.jetbrains.android.dom;
|
||||
|
||||
import com.android.sdklib.SdkConstants;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: Eugene.Kudelevsky
|
||||
@@ -137,6 +145,26 @@ public class AndroidValueResourcesTest extends AndroidDomTest {
|
||||
myFixture.testCompletion("res/layout/main.xml", testFolder + "/boolResReference_after.xml");
|
||||
}
|
||||
|
||||
public void testResourceReferenceAsValueHighlighting() throws Throwable {
|
||||
doTestHighlighting();
|
||||
}
|
||||
|
||||
public void testResourceReferenceAsValueCompletion1() throws Throwable {
|
||||
doTestCompletion();
|
||||
}
|
||||
|
||||
public void testResourceReferenceAsValueCompletion2() throws Throwable {
|
||||
doTestCompletion();
|
||||
}
|
||||
|
||||
public void testResourceReferenceAsValueCompletion3() throws Throwable {
|
||||
doTestCompletionVariants(getTestName(true) + ".xml", "true", "false");
|
||||
}
|
||||
|
||||
public void testResourceReferenceAsValueCompletion4() throws Throwable {
|
||||
doTestCompletionVariants(getTestName(true) + ".xml");
|
||||
}
|
||||
|
||||
public void testParentStyleReference() throws Throwable {
|
||||
VirtualFile file = myFixture.copyFileToProject(testFolder + "/psreference.xml", getPathToCopy("psreference.xml"));
|
||||
myFixture.configureFromExistingVirtualFile(file);
|
||||
@@ -153,4 +181,31 @@ public class AndroidValueResourcesTest extends AndroidDomTest {
|
||||
public void testResOverlay() throws Throwable {
|
||||
doTestCompletionVariants("styles1.xml", "@drawable/picture1", "@drawable/picture2", "@drawable/picture3");
|
||||
}
|
||||
|
||||
public void testCreateResourceFromUsage() throws Throwable {
|
||||
final VirtualFile virtualFile = copyFileToProject(getTestName(true) + ".xml", "res/values/drawables.xml");
|
||||
myFixture.configureFromExistingVirtualFile(virtualFile);
|
||||
final List<HighlightInfo> infos = myFixture.doHighlighting();
|
||||
final List<IntentionAction> actions = new ArrayList<IntentionAction>();
|
||||
|
||||
for (HighlightInfo info : infos) {
|
||||
final List<Pair<HighlightInfo.IntentionActionDescriptor, TextRange>> ranges = info.quickFixActionRanges;
|
||||
|
||||
if (ranges != null) {
|
||||
for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : ranges) {
|
||||
actions.add(pair.getFirst().getAction());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(1, actions.size());
|
||||
|
||||
new WriteCommandAction.Simple(getProject()) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
actions.get(0).invoke(getProject(), myFixture.getEditor(), myFixture.getFile());
|
||||
}
|
||||
}.execute();
|
||||
myFixture.checkResultByFile(testFolder + '/' + getTestName(true) + "_after.xml", true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,9 +156,6 @@ public class IdeaJdk extends SdkType implements JavaSdkType {
|
||||
else if (new File(sdkHome, "lib/webide.jar").exists()) {
|
||||
productName = "WebStorm/PhpStorm ";
|
||||
}
|
||||
else if (new File(sdkHome, "lib/webide.jar").exists()) {
|
||||
productName = "WebStorm/PhpStorm ";
|
||||
}
|
||||
else {
|
||||
productName = "IDEA ";
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ public class Git {
|
||||
|
||||
@NotNull
|
||||
public static GitCommandResult clone(@NotNull Project project, @NotNull File parentDirectory, @NotNull String url, @NotNull String clonedDirectoryName) {
|
||||
GitLineHandler handler = new GitLineHandler(project, parentDirectory, GitCommand.CLONE);
|
||||
GitLineHandlerPasswordRequestAware handler = new GitLineHandlerPasswordRequestAware(project, parentDirectory, GitCommand.CLONE);
|
||||
handler.addParameters(url);
|
||||
handler.addParameters(clonedDirectoryName);
|
||||
return run(handler, true);
|
||||
@@ -221,7 +221,7 @@ public class Git {
|
||||
}
|
||||
|
||||
public static GitCommandResult push(@NotNull GitRepository repository, @NotNull GitPushSpec pushSpec, @NotNull GitLineHandlerListener... listeners) {
|
||||
final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.PUSH);
|
||||
final GitLineHandlerPasswordRequestAware h = new GitLineHandlerPasswordRequestAware(repository.getProject(), repository.getRoot(), GitCommand.PUSH);
|
||||
h.setSilent(false);
|
||||
|
||||
for (GitLineHandlerListener listener : listeners) {
|
||||
@@ -274,6 +274,11 @@ public class Git {
|
||||
});
|
||||
|
||||
handler.runInCurrentThread(null);
|
||||
|
||||
if (handler instanceof GitLineHandlerPasswordRequestAware && ((GitLineHandlerPasswordRequestAware)handler).hadAuthRequest()) {
|
||||
errorOutput.add("Authentication failed");
|
||||
}
|
||||
|
||||
final boolean success = !startFailed.get() && errorOutput.isEmpty() && (handler.isIgnoredErrorCode(exitCode.get()) || exitCode.get() == 0);
|
||||
return new GitCommandResult(success, exitCode.get(), errorOutput, output);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public class GitPull extends GitRepositoryAction {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GitHttpAdapter.isHttpUrlWithoutUserCredentials(url)) {
|
||||
if (GitHttpAdapter.shouldUseJGit(url)) {
|
||||
boolean fetchSuccessful = new GitFetcher(project, indicator).fetchRootsAndNotify(gitRoots, "Push failed", false);
|
||||
if (!fetchSuccessful) {
|
||||
return;
|
||||
|
||||
@@ -104,7 +104,7 @@ public class GitCheckoutProvider implements CheckoutProvider {
|
||||
}
|
||||
|
||||
private static boolean doClone(@NotNull Project project, @NotNull String directoryName, @NotNull String parentDirectory, @NotNull String sourceRepositoryURL) {
|
||||
if (GitHttpAdapter.isHttpUrlWithoutUserCredentials(sourceRepositoryURL)) {
|
||||
if (GitHttpAdapter.shouldUseJGit(sourceRepositoryURL)) {
|
||||
GitFetchResult result = GitHttpAdapter.cloneRepository(project, new File(parentDirectory, directoryName), sourceRepositoryURL);
|
||||
GitFetcher.displayFetchResult(project, result, "Clone failed", result.getErrors());
|
||||
return result.isSuccess();
|
||||
|
||||
@@ -19,14 +19,15 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.*;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.ui.EditorComboBox;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import git4idea.commands.*;
|
||||
import git4idea.commands.GitCommand;
|
||||
import git4idea.commands.GitLineHandlerPasswordRequestAware;
|
||||
import git4idea.commands.GitTask;
|
||||
import git4idea.commands.GitTaskResult;
|
||||
import git4idea.i18n.GitBundle;
|
||||
import git4idea.jgit.GitHttpAdapter;
|
||||
import git4idea.remote.GitRememberedInputs;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
@@ -38,7 +39,6 @@ import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@@ -141,7 +141,7 @@ public class GitCloneDialog extends DialogWrapper {
|
||||
|
||||
private void test() {
|
||||
myTestURL = getCurrentUrlText();
|
||||
boolean testResult = GitHttpAdapter.isHttpUrlWithoutUserCredentials(myTestURL) ? testHttp(myTestURL) : testNatively(myTestURL);
|
||||
boolean testResult = test(myTestURL);
|
||||
|
||||
if (testResult) {
|
||||
Messages.showInfoMessage(myTestButton, GitBundle.message("clone.test.success.message", myTestURL),
|
||||
@@ -158,31 +158,13 @@ public class GitCloneDialog extends DialogWrapper {
|
||||
* That way, we have a hack here: if http response asked for a password, then the url is at least valid and existant, and we consider
|
||||
* that the test passed.
|
||||
*/
|
||||
private boolean testHttp(String url) {
|
||||
final AtomicBoolean passwordRequested = new AtomicBoolean();
|
||||
final GitLineHandler handler = new GitLineHandler(myProject, new File("."), GitCommand.LS_REMOTE);
|
||||
handler.addParameters(url, "master");
|
||||
handler.addLineListener(new GitLineHandlerAdapter() {
|
||||
@Override
|
||||
public void onLineAvailable(String line, Key outputType) {
|
||||
String lowerCasedLine = line.toLowerCase();
|
||||
if (lowerCasedLine.contains("password") || lowerCasedLine.contains("login") || lowerCasedLine.contains("username")) {
|
||||
handler.cancel();
|
||||
passwordRequested.set(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
GitTask task = new GitTask(myProject, handler, GitBundle.message("clone.testing", url));
|
||||
GitTaskResult result = task.executeModal();
|
||||
return result.isOK() || passwordRequested.get();
|
||||
}
|
||||
|
||||
private boolean testNatively(String url) {
|
||||
GitSimpleHandler handler = new GitSimpleHandler(myProject, new File("."), GitCommand.LS_REMOTE);
|
||||
private boolean test(String url) {
|
||||
final GitLineHandlerPasswordRequestAware handler = new GitLineHandlerPasswordRequestAware(myProject, new File("."), GitCommand.LS_REMOTE);
|
||||
handler.addParameters(url, "master");
|
||||
GitTask task = new GitTask(myProject, handler, GitBundle.message("clone.testing", url));
|
||||
GitTaskResult result = task.executeModal();
|
||||
return result.isOK();
|
||||
boolean authFailed = handler.hadAuthRequest();
|
||||
return result.isOK() || authFailed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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 git4idea.commands;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* {@link GitLineHandler} that listens to Git output and kills itself if "username" or "password" is queried throughout the prompt.
|
||||
* We can't pass the data to the prompt anyway, so better to kill the process and show an error message, than to hang the task.
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public class GitLineHandlerPasswordRequestAware extends GitLineHandler {
|
||||
|
||||
private boolean myAuthRequest;
|
||||
|
||||
public GitLineHandlerPasswordRequestAware(@NotNull Project project, @NotNull VirtualFile vcsRoot, @NotNull GitCommand command) {
|
||||
super(project, vcsRoot, command);
|
||||
}
|
||||
|
||||
public GitLineHandlerPasswordRequestAware(@NotNull Project project, @NotNull File directory, @NotNull GitCommand clone) {
|
||||
super(project, directory, clone);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTextAvailable(String text, Key outputType) {
|
||||
super.onTextAvailable(text, outputType);
|
||||
if (text.toLowerCase().startsWith("password") || text.toLowerCase().startsWith("username")) {
|
||||
myAuthRequest = true;
|
||||
destroyProcess();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hadAuthRequest() {
|
||||
return myAuthRequest;
|
||||
}
|
||||
}
|
||||
@@ -65,11 +65,11 @@ public final class GitHttpAdapter {
|
||||
|
||||
private static final Pattern HTTP_URL_WITH_USERNAME_AND_PASSWORD = Pattern.compile("http(s?)://([^\\s^@:]+):([^\\s^@:]+)@.*");
|
||||
|
||||
public static boolean isHttpUrlWithoutUserCredentials(@NotNull String url) {
|
||||
// if username & password are specified in the url, give it to the native Git
|
||||
public static boolean shouldUseJGit(@NotNull String url) {
|
||||
if (!url.startsWith("http")) {
|
||||
return false;
|
||||
}
|
||||
// if username & password are specified in the url, give it to the native Git
|
||||
if (HTTP_URL_WITH_USERNAME_AND_PASSWORD.matcher(url).matches()) {
|
||||
return false;
|
||||
}
|
||||
@@ -79,11 +79,11 @@ public final class GitHttpAdapter {
|
||||
return !netrcData.hasAuthDataForUrl(url);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn("Couldn't read netrc file", e);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ public class GitPullDialog extends DialogWrapper {
|
||||
|
||||
@NotNull
|
||||
private Collection<String> getRemoteBranches(@NotNull GitDeprecatedRemote remote) {
|
||||
if (GitHttpAdapter.isHttpUrlWithoutUserCredentials(remote.fetchUrl())) {
|
||||
if (GitHttpAdapter.shouldUseJGit(remote.fetchUrl())) {
|
||||
GitRepository repository = GitRepositoryManager.getInstance(myProject).getRepositoryForRoot(gitRoot());
|
||||
if (repository == null) {
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -332,7 +332,7 @@ public final class GitPusher {
|
||||
return pushNatively(repository, pushSpec);
|
||||
}
|
||||
else {
|
||||
return GitHttpAdapter.isHttpUrlWithoutUserCredentials(remoteUrl) ? GitHttpAdapter.push(repository, null, remoteUrl, null) : pushNatively(repository, pushSpec);
|
||||
return GitHttpAdapter.shouldUseJGit(remoteUrl) ? GitHttpAdapter.push(repository, null, remoteUrl, null) : pushNatively(repository, pushSpec);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -340,7 +340,7 @@ public final class GitPusher {
|
||||
assert remote != null : "Remote can't be null for pushSpec " + pushSpec;
|
||||
String httpUrl = null;
|
||||
for (String pushUrl : remote.getPushUrls()) {
|
||||
if (GitHttpAdapter.isHttpUrlWithoutUserCredentials(pushUrl)) {
|
||||
if (GitHttpAdapter.shouldUseJGit(pushUrl)) {
|
||||
httpUrl = pushUrl;
|
||||
break; // TODO support http and ssh urls in one origin
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import git4idea.GitVcs;
|
||||
import git4idea.commands.*;
|
||||
@@ -67,7 +68,7 @@ public class GitFetcher {
|
||||
if (url == null) {
|
||||
continue;
|
||||
}
|
||||
if (GitHttpAdapter.isHttpUrlWithoutUserCredentials(url)) {
|
||||
if (GitHttpAdapter.shouldUseJGit(url)) {
|
||||
GitFetchResult res = GitHttpAdapter.fetch(repository, remote, url);
|
||||
myErrors.addAll(res.getErrors());
|
||||
if (!res.isSuccess()) {
|
||||
@@ -86,7 +87,7 @@ public class GitFetcher {
|
||||
}
|
||||
|
||||
private boolean fetchNatively(@NotNull VirtualFile root, @NotNull GitRemote remote) {
|
||||
final GitLineHandler h = new GitLineHandler(myProject, root, GitCommand.FETCH);
|
||||
final GitLineHandlerPasswordRequestAware h = new GitLineHandlerPasswordRequestAware(myProject, root, GitCommand.FETCH);
|
||||
h.addParameters(remote.getName());
|
||||
final GitTask fetchTask = new GitTask(myProject, h, "Fetching...");
|
||||
fetchTask.setProgressIndicator(myProgressIndicator);
|
||||
@@ -102,11 +103,15 @@ public class GitFetcher {
|
||||
protected void onCancel() {
|
||||
LOG.info("Cancelled fetch.");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onFailure() {
|
||||
LOG.info("Error fetching: " + h.errors());
|
||||
myErrors.addAll(h.errors());
|
||||
if (!h.hadAuthRequest()) {
|
||||
myErrors.addAll(h.errors());
|
||||
} else {
|
||||
myErrors.add(new VcsException("Authentication failed"));
|
||||
}
|
||||
}
|
||||
});
|
||||
return success.get();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user