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:
@@ -257,10 +257,13 @@ public class AppletConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
|
||||
throw new RuntimeConfigurationWarning(ExecutionBundle.message("html.file.not.specified.error.message"));
|
||||
}
|
||||
try {
|
||||
new URL(HTML_FILE_NAME);
|
||||
new URL(getHtmlURL().getUrl());
|
||||
}
|
||||
catch (CantRunException ex) {
|
||||
checkUrlIsValid(ex);
|
||||
}
|
||||
catch (MalformedURLException ex) {
|
||||
throw new RuntimeConfigurationWarning("URL " + HTML_FILE_NAME + " is not valid: " + ex.getLocalizedMessage());
|
||||
checkUrlIsValid(ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -268,6 +271,10 @@ public class AppletConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
|
||||
}
|
||||
}
|
||||
|
||||
private void checkUrlIsValid(Exception ex) throws RuntimeConfigurationWarning {
|
||||
throw new RuntimeConfigurationWarning("URL " + HTML_FILE_NAME + " is not valid: " + ex.getLocalizedMessage());
|
||||
}
|
||||
|
||||
public AppletParameter[] getAppletParameters() {
|
||||
return myAppletParameters;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
package com.intellij.ide.impl;
|
||||
|
||||
import com.intellij.ide.GeneralSettings;
|
||||
import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
|
||||
import com.intellij.ide.util.projectWizard.ProjectBuilder;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -209,7 +210,7 @@ public class NewProjectUtil {
|
||||
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
|
||||
if (openProjects.length > 0) {
|
||||
int exitCode = ProjectUtil.confirmOpenNewProject(true);
|
||||
if (exitCode == 0) { // this window option
|
||||
if (exitCode == GeneralSettings.OPEN_PROJECT_SAME_WINDOW) {
|
||||
ProjectUtil.closeAndDispose(projectToClose != null ? projectToClose : openProjects[openProjects.length - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
+26
-9
@@ -47,6 +47,7 @@ import java.util.Set;
|
||||
*/
|
||||
public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.GenerateDelegateHandler");
|
||||
private boolean myToCopyJavaDoc = false;
|
||||
|
||||
@Override
|
||||
public boolean isValidFor(Editor editor, PsiFile file) {
|
||||
@@ -101,7 +102,7 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
return false;
|
||||
}
|
||||
|
||||
private static PsiGenerationInfo<PsiMethod> generateDelegatePrototype(PsiMethodMember methodCandidate, PsiElement target) throws IncorrectOperationException {
|
||||
private PsiGenerationInfo<PsiMethod> generateDelegatePrototype(PsiMethodMember methodCandidate, PsiElement target) throws IncorrectOperationException {
|
||||
PsiMethod method = GenerateMembersUtil.substituteGenericMethod(methodCandidate.getElement(), methodCandidate.getSubstitutor());
|
||||
clearMethod(method);
|
||||
|
||||
@@ -184,7 +185,7 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
return new PsiGenerationInfo<PsiMethod>(method);
|
||||
}
|
||||
|
||||
private static void clearMethod(PsiMethod method) throws IncorrectOperationException {
|
||||
private void clearMethod(PsiMethod method) throws IncorrectOperationException {
|
||||
LOG.assertTrue(!method.isPhysical());
|
||||
PsiCodeBlock codeBlock = JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createCodeBlock();
|
||||
if (method.getBody() != null) {
|
||||
@@ -194,9 +195,11 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
method.add(codeBlock);
|
||||
}
|
||||
|
||||
final PsiDocComment docComment = method.getDocComment();
|
||||
if (docComment != null) {
|
||||
docComment.delete();
|
||||
if (!myToCopyJavaDoc) {
|
||||
final PsiDocComment docComment = method.getDocComment();
|
||||
if (docComment != null) {
|
||||
docComment.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +211,7 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiMethodMember[] chooseMethods(PsiElement target, PsiFile file, Editor editor, Project project) {
|
||||
private PsiMethodMember[] chooseMethods(PsiElement target, PsiFile file, Editor editor, Project project) {
|
||||
PsiClassType.ClassResolveResult resolveResult = null;
|
||||
|
||||
if (target instanceof PsiField) {
|
||||
@@ -232,6 +235,8 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
|
||||
final PsiMethod[] allMethods = targetClass.getAllMethods();
|
||||
final Set<MethodSignature> signatures = new HashSet<MethodSignature>();
|
||||
final Set<MethodSignature> existingSignatures = new HashSet<MethodSignature>(aClass.getVisibleSignatures());
|
||||
final Set<PsiMethodMember> selection = new HashSet<PsiMethodMember>();
|
||||
Map<PsiClass, PsiSubstitutor> superSubstitutors = new HashMap<PsiClass, PsiSubstitutor>();
|
||||
JavaPsiFacade facade = JavaPsiFacade.getInstance(target.getProject());
|
||||
for (PsiMethod method : allMethods) {
|
||||
@@ -248,7 +253,11 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
if (!signatures.contains(signature)) {
|
||||
signatures.add(signature);
|
||||
if (facade.getResolveHelper().isAccessible(method, target, aClass)) {
|
||||
methodInstances.add(new PsiMethodMember(method, methodSubstitutor));
|
||||
final PsiMethodMember methodMember = new PsiMethodMember(method, methodSubstitutor);
|
||||
methodInstances.add(methodMember);
|
||||
if (!existingSignatures.contains(signature)) {
|
||||
selection.add(methodMember);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -257,21 +266,29 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
MemberChooser<PsiElementClassMember> chooser = new MemberChooser<PsiElementClassMember>(methodInstances.toArray(new PsiMethodMember[methodInstances.size()]), false, true, project);
|
||||
chooser.setTitle(CodeInsightBundle.message("generate.delegate.method.chooser.title"));
|
||||
chooser.setCopyJavadocVisible(false);
|
||||
chooser.setCopyJavadocVisible(true);
|
||||
if (!selection.isEmpty()) {
|
||||
chooser.selectElements(selection.toArray(new ClassMember[selection.size()]));
|
||||
}
|
||||
chooser.show();
|
||||
|
||||
if (chooser.getExitCode() != MemberChooser.OK_EXIT_CODE) return null;
|
||||
|
||||
myToCopyJavaDoc = chooser.isCopyJavadoc();
|
||||
final List<PsiElementClassMember> list = chooser.getSelectedElements();
|
||||
result = list.toArray(new PsiMethodMember[list.size()]);
|
||||
}
|
||||
else {
|
||||
result = new PsiMethodMember[] {methodInstances.get(0)};
|
||||
result = methodInstances.isEmpty() ? new PsiMethodMember[0] : new PsiMethodMember[] {methodInstances.get(0)};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setToCopyJavaDoc(boolean toCopyJavaDoc) {
|
||||
myToCopyJavaDoc = toCopyJavaDoc;
|
||||
}
|
||||
|
||||
public static boolean isApplicable(PsiFile file, Editor editor) {
|
||||
ClassMember[] targetElements = getTargetElements(file, editor);
|
||||
return targetElements != null && targetElements.length > 0;
|
||||
|
||||
@@ -27,13 +27,17 @@ import com.intellij.openapi.util.NotNullLazyKey;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.AnyPsiChangeListener;
|
||||
import com.intellij.psi.impl.DebugUtil;
|
||||
import com.intellij.psi.impl.PsiManagerEx;
|
||||
import com.intellij.psi.impl.PsiManagerImpl;
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType;
|
||||
import com.intellij.psi.impl.source.tree.TreeElement;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ConcurrencyUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ConcurrentWeakHashMap;
|
||||
import com.intellij.util.containers.WeakHashMap;
|
||||
import com.intellij.util.containers.WeakList;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -53,6 +57,9 @@ public class JavaResolveCache {
|
||||
|
||||
private final ConcurrentMap<PsiExpression, PsiType> myCalculatedTypes = new ConcurrentWeakHashMap<PsiExpression, PsiType>();
|
||||
private final ConcurrentMap<PsiElement, PsiType> myCachedReferencesInPsiTypes = new ConcurrentWeakHashMap<PsiElement, PsiType>();
|
||||
// e.g. given FileOutputStream os, os2;
|
||||
// PsiJavaCodeReferenceElement("FileOutputStream") -> [ PsiReferenceExpression("os"), PsiReferenceExpression("os2") ]
|
||||
private final Map<PsiElement, WeakList<PsiElement>> myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere = new WeakHashMap<PsiElement, WeakList<PsiElement>>();
|
||||
|
||||
private final Map<PsiVariable,Object> myVarToConstValueMapPhysical;
|
||||
private final Map<PsiVariable,Object> myVarToConstValueMapNonPhysical;
|
||||
@@ -78,6 +85,7 @@ public class JavaResolveCache {
|
||||
private void clearCaches(boolean isPhysical) {
|
||||
myCalculatedTypes.clear();
|
||||
myCachedReferencesInPsiTypes.clear();
|
||||
myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.clear();
|
||||
if (isPhysical) {
|
||||
myVarToConstValueMapPhysical.clear();
|
||||
}
|
||||
@@ -96,8 +104,15 @@ public class JavaResolveCache {
|
||||
if (type == null) {
|
||||
type = TypeConversionUtil.NULL_TYPE;
|
||||
}
|
||||
type = ConcurrencyUtil.cacheOrGet(myCalculatedTypes, expr, type);
|
||||
PsiType stored = ConcurrencyUtil.cacheOrGet(myCalculatedTypes, expr, type);
|
||||
|
||||
if (stored == type && DebugUtil.DO_EXPENSIVE_CHECKS) {
|
||||
registerDiagnosticsHooks(expr, type);
|
||||
}
|
||||
|
||||
type = stored;
|
||||
}
|
||||
|
||||
if (!type.isValid()) {
|
||||
if (expr.isValid()) {
|
||||
PsiJavaCodeReferenceElement refInside = type instanceof PsiClassReferenceType ? ((PsiClassReferenceType)type).getReference() : null;
|
||||
@@ -109,44 +124,86 @@ public class JavaResolveCache {
|
||||
}
|
||||
}
|
||||
|
||||
if (DebugUtil.DO_EXPENSIVE_CHECKS) {
|
||||
if (type instanceof PsiClassReferenceType) {
|
||||
PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType)type).getReference();
|
||||
ConcurrencyUtil.cacheOrGet(myCachedReferencesInPsiTypes, reference, type);
|
||||
DebugUtil.trackInvalidation(reference, "Reference inside PsiClassReferenceType was invalidated", new Processor<PsiElement>() {
|
||||
@Override
|
||||
public boolean process(PsiElement element) {
|
||||
PsiType cached = myCalculatedTypes.get(element);
|
||||
if (cached != null) {
|
||||
LOG.error(element + " (inside ref) is invalid and yet it is still cached: " + cached);
|
||||
}
|
||||
PsiType cachedRef = myCachedReferencesInPsiTypes.get(element);
|
||||
if (cachedRef != null) {
|
||||
LOG.error(element + " (inside ref) is invalid and yet it is still cached in ref cache: " + cachedRef);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return type == TypeConversionUtil.NULL_TYPE ? null : type;
|
||||
}
|
||||
|
||||
private <T extends PsiExpression> void registerDiagnosticsHooks(T expr, PsiType type) {
|
||||
if (type instanceof PsiClassReferenceType) {
|
||||
PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType)type).getReference();
|
||||
ConcurrencyUtil.cacheOrGet(myCachedReferencesInPsiTypes, reference, type);
|
||||
synchronized (myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere) {
|
||||
WeakList<PsiElement> refsTo = myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.get(reference);
|
||||
if (refsTo==null) {
|
||||
refsTo = new WeakList<PsiElement>();
|
||||
myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.put(reference, refsTo);
|
||||
}
|
||||
refsTo.add(expr);
|
||||
}
|
||||
DebugUtil.trackInvalidation(expr, "Expression invalidated", new Processor<PsiElement>() {
|
||||
final PsiFile dummyHolder = reference.getContainingFile();
|
||||
if (dummyHolder != null && !dummyHolder.isPhysical()) {
|
||||
PsiElement physicalContext = dummyHolder.getContext();
|
||||
PsiFile physicalFile;
|
||||
if (physicalContext != null &&
|
||||
(physicalFile = physicalContext.getContainingFile()) != null &&
|
||||
physicalFile.getVirtualFile() != null &&
|
||||
!((PsiManagerEx)PsiManager.getInstance(dummyHolder.getProject())).isAssertOnFileLoading(physicalFile.getVirtualFile())) {
|
||||
DebugUtil.trackInvalidation(physicalContext, "dummy holder was invalidated", new Processor<PsiElement>() {
|
||||
@Override
|
||||
public boolean process(PsiElement element) {
|
||||
DebugUtil.onInvalidated((TreeElement)dummyHolder.getNode());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
DebugUtil.trackInvalidation(reference, "Reference inside PsiClassReferenceType was invalidated", new Processor<PsiElement>() {
|
||||
@Override
|
||||
public boolean process(PsiElement element) {
|
||||
PsiType cached = myCalculatedTypes.get(element);
|
||||
if (cached != null) {
|
||||
LOG.error(element + " is invalid and yet it is still cached: " + cached);
|
||||
LOG.error(element + " (inside ref) is invalid and yet it is still cached: " + cached);
|
||||
}
|
||||
|
||||
PsiType cachedRef = myCachedReferencesInPsiTypes.get(element);
|
||||
if (cachedRef != null) {
|
||||
LOG.error(element + " is invalid and yet it is still cached (inside PsiType): " + cachedRef);
|
||||
LOG.error(element + " (inside ref) is invalid and yet it is still cached in ref cache: " + cachedRef);
|
||||
}
|
||||
|
||||
|
||||
synchronized (myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere) {
|
||||
WeakList<PsiElement> refsTo = myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.get(element);
|
||||
if (refsTo != null) {
|
||||
for (PsiElement ref : refsTo) {
|
||||
PsiType cachedT = myCalculatedTypes.get(ref);
|
||||
if (cachedT != null && !cachedT.isValid()) {
|
||||
LOG.error("During invalidation of " + element + " ("+element.getClass()+")"+
|
||||
" cached type " + cachedT + " of the ref "+ref+" ("+ref.getClass()+")"+
|
||||
" became invalid and yet it is still cached"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
DebugUtil.trackInvalidation(expr, "Expression invalidated", new Processor<PsiElement>() {
|
||||
@Override
|
||||
public boolean process(PsiElement element) {
|
||||
PsiType cached = myCalculatedTypes.get(element);
|
||||
if (cached != null) {
|
||||
LOG.error(element + " is invalid and yet it is still cached: " + cached);
|
||||
}
|
||||
|
||||
return type == TypeConversionUtil.NULL_TYPE ? null : type;
|
||||
PsiType cachedRef = myCachedReferencesInPsiTypes.get(element);
|
||||
if (cachedRef != null) {
|
||||
LOG.error(element + " is invalid and yet it is still cached (inside PsiType): " + cachedRef);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+6
-1
@@ -65,7 +65,12 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testException1() throws Exception { doTest(); }
|
||||
public void testException2() throws Exception { doTest(); }
|
||||
public void testException3() throws Exception { doTest(); }
|
||||
public void testException4() throws Exception { doTest(); }
|
||||
public void testException4() throws Exception {
|
||||
final JavaDocLocalInspection javaDocLocalInspection = new JavaDocLocalInspection();
|
||||
javaDocLocalInspection.METHOD_OPTIONS.ACCESS_JAVADOC_REQUIRED_FOR = "package";
|
||||
enableInspectionTool(javaDocLocalInspection);
|
||||
doTest();
|
||||
}
|
||||
public void testMultipleThrows() throws Exception { doTest(); }
|
||||
public void testInheritJavaDoc() throws Exception {doTestWithLangLevel(LanguageLevel.JDK_1_3);}
|
||||
public void testLink0() throws Exception { doTest(); }
|
||||
|
||||
+2
@@ -19,6 +19,8 @@ public class JavadocInspectionQuickFixTest extends LightQuickFix15TestCase {
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
final JavaDocLocalInspection javaDocLocalInspection = new JavaDocLocalInspection();
|
||||
javaDocLocalInspection.TOP_LEVEL_CLASS_OPTIONS.REQUIRED_TAGS = "param";
|
||||
javaDocLocalInspection.TOP_LEVEL_CLASS_OPTIONS.ACCESS_JAVADOC_REQUIRED_FOR = "package";
|
||||
javaDocLocalInspection.METHOD_OPTIONS.ACCESS_JAVADOC_REQUIRED_FOR = "package";
|
||||
return new LocalInspectionTool[]{javaDocLocalInspection};
|
||||
}
|
||||
|
||||
|
||||
@@ -490,7 +490,7 @@ public class DebugUtil {
|
||||
}
|
||||
|
||||
public static void onInvalidated(@NotNull TreeElement treeElement) {
|
||||
treeElement.acceptTree(new RecursiveTreeElementWalkingVisitor() {
|
||||
treeElement.acceptTree(new RecursiveTreeElementWalkingVisitor(false) {
|
||||
@Override
|
||||
protected void visitNode(TreeElement element) {
|
||||
List<Pair<Object, Processor<PsiElement>>> callbacks = element.getUserData(TRACK_INVALIDATION_KEY);
|
||||
@@ -501,6 +501,7 @@ public class DebugUtil {
|
||||
if (psi != null) callback.process(psi);
|
||||
}
|
||||
}
|
||||
super.visitNode(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ public class ExternalToolPassFactory extends AbstractProjectComponent implements
|
||||
@Override
|
||||
@Nullable
|
||||
public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) {
|
||||
TextRange textRange = FileStatusMap.getDirtyTextRange(editor, Pass.EXTERNAL_TOOLS);
|
||||
TextRange textRange = file.getTextRange();
|
||||
if (textRange == null || !externalAnnotatorsDefined(file)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class GeneralSettings implements NamedJDOMExternalizable, ExportableAppli
|
||||
private String myLastProjectLocation;
|
||||
private boolean mySearchInBackground;
|
||||
private boolean myConfirmExit = true;
|
||||
private int myConfirmOpenNewProject = -1;
|
||||
private int myConfirmOpenNewProject = OPEN_PROJECT_ASK;
|
||||
@NonNls private static final String ELEMENT_OPTION = "option";
|
||||
@NonNls private static final String ATTRIBUTE_NAME = "name";
|
||||
@NonNls private static final String ATTRIBUTE_VALUE = "value";
|
||||
@@ -74,7 +74,7 @@ public class GeneralSettings implements NamedJDOMExternalizable, ExportableAppli
|
||||
@NonNls private static final String OPTION_USE_CYCLIC_BUFFER = "useCyclicBuffer";
|
||||
@NonNls private static final String OPTION_SEARCH_IN_BACKGROUND = "searchInBackground";
|
||||
@NonNls private static final String OPTION_CONFIRM_EXIT = "confirmExit";
|
||||
@NonNls private static final String OPTION_CONFIRM_OPEN_NEW_PROJECT = "confirmOpenNewProject";
|
||||
@NonNls private static final String OPTION_CONFIRM_OPEN_NEW_PROJECT = "confirmOpenNewProject2";
|
||||
@NonNls private static final String OPTION_CYCLIC_BUFFER_SIZE = "cyclicBufferSize";
|
||||
@NonNls private static final String OPTION_LAST_PROJECT_LOCATION = "lastProjectLocation";
|
||||
@Deprecated
|
||||
@@ -331,7 +331,7 @@ public class GeneralSettings implements NamedJDOMExternalizable, ExportableAppli
|
||||
myConfirmOpenNewProject = Integer.valueOf(value).intValue();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
myConfirmOpenNewProject = -1;
|
||||
myConfirmOpenNewProject = OPEN_PROJECT_ASK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,9 +477,9 @@ public class GeneralSettings implements NamedJDOMExternalizable, ExportableAppli
|
||||
/**
|
||||
* @return
|
||||
* <ul>
|
||||
* <li>0 if new project should be opened in new window
|
||||
* <li>1 if new project should be opened in same window
|
||||
* <li>-1 if a confirmation dialog should be shown
|
||||
* <li>{@link GeneralSettings#OPEN_PROJECT_NEW_WINDOW} if new project should be opened in new window
|
||||
* <li>{@link GeneralSettings#OPEN_PROJECT_SAME_WINDOW} if new project should be opened in same window
|
||||
* <li>{@link GeneralSettings#OPEN_PROJECT_ASK} if a confirmation dialog should be shown
|
||||
* </ul>
|
||||
*/
|
||||
public int getConfirmOpenNewProject() {
|
||||
|
||||
@@ -67,7 +67,7 @@ public class GeneralSettingsConfigurable extends CompositeConfigurable<Searchabl
|
||||
settings.setInactiveTimeout(newInactiveTimeout);
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
||||
|
||||
@@ -85,13 +85,14 @@ public class GeneralSettingsConfigurable extends CompositeConfigurable<Searchabl
|
||||
|
||||
int openProjectOption = settings.getConfirmOpenNewProject();
|
||||
|
||||
isModified |= (myComponent.myConfirmFrameToOpenCheckBox.isSelected() && openProjectOption >= 0) || (!myComponent.myConfirmFrameToOpenCheckBox.isSelected() == openProjectOption < 0);
|
||||
boolean savedOptionIsAsk = openProjectOption == GeneralSettings.OPEN_PROJECT_ASK;
|
||||
isModified |= myComponent.myConfirmFrameToOpenCheckBox.isSelected() != savedOptionIsAsk;
|
||||
|
||||
int inactiveTimeout = -1;
|
||||
try {
|
||||
inactiveTimeout = Integer.parseInt(myComponent.myTfInactiveTimeout.getText());
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
||||
isModified |= inactiveTimeout > 0 && settings.getInactiveTimeout() != inactiveTimeout;
|
||||
@@ -141,7 +142,7 @@ public class GeneralSettingsConfigurable extends CompositeConfigurable<Searchabl
|
||||
myComponent.myTfInactiveTimeout.setText(Integer.toString(settings.getInactiveTimeout()));
|
||||
myComponent.myTfInactiveTimeout.setEditable(settings.isAutoSaveIfInactive());
|
||||
myComponent.myConfirmExit.setSelected(settings.isConfirmExit());
|
||||
myComponent.myConfirmFrameToOpenCheckBox.setSelected(settings.getConfirmOpenNewProject() < 0);
|
||||
myComponent.myConfirmFrameToOpenCheckBox.setSelected(settings.getConfirmOpenNewProject() == GeneralSettings.OPEN_PROJECT_ASK);
|
||||
}
|
||||
|
||||
public void disposeUIResources() {
|
||||
|
||||
+3
-1
@@ -25,7 +25,9 @@ public class ProjectNewWindowDoNotAskOption implements DialogWrapper.DoNotAskOpt
|
||||
}
|
||||
|
||||
public void setToBeShown(boolean value, int exitCode) {
|
||||
GeneralSettings.getInstance().setConfirmOpenNewProject(value || exitCode == 2 ? -1 : exitCode);
|
||||
int confirmOpenNewProject = value || exitCode == 2 ? GeneralSettings.OPEN_PROJECT_ASK :
|
||||
exitCode == 0 ? GeneralSettings.OPEN_PROJECT_SAME_WINDOW : GeneralSettings.OPEN_PROJECT_NEW_WINDOW ;
|
||||
GeneralSettings.getInstance().setConfirmOpenNewProject(confirmOpenNewProject);
|
||||
}
|
||||
|
||||
public boolean canBeHidden() {
|
||||
|
||||
@@ -161,10 +161,10 @@ public class ProjectUtil {
|
||||
|
||||
if (!forceOpenInNewFrame && openProjects.length > 0) {
|
||||
int exitCode = confirmOpenNewProject(false);
|
||||
if (exitCode == 0) { // this window option
|
||||
if (exitCode == GeneralSettings.OPEN_PROJECT_SAME_WINDOW) {
|
||||
if (!closeAndDispose(projectToClose != null ? projectToClose : openProjects[openProjects.length - 1])) return null;
|
||||
}
|
||||
else if (exitCode != 1) { // not in a new window
|
||||
else if (exitCode != GeneralSettings.OPEN_PROJECT_NEW_WINDOW) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -192,30 +192,33 @@ public class ProjectUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 0 - this window
|
||||
* 1 - new window
|
||||
* 2 - cancel
|
||||
* @return {@link com.intellij.ide.GeneralSettings#OPEN_PROJECT_SAME_WINDOW}
|
||||
* {@link com.intellij.ide.GeneralSettings#OPEN_PROJECT_NEW_WINDOW}
|
||||
* {@link com.intellij.openapi.ui.Messages#CANCEL} - if user canceled the dialog
|
||||
* @param isNewProject
|
||||
*/
|
||||
public static int confirmOpenNewProject(boolean isNewProject) {
|
||||
final GeneralSettings settings = GeneralSettings.getInstance();
|
||||
if (settings.getConfirmOpenNewProject() == GeneralSettings.OPEN_PROJECT_ASK) {
|
||||
int confirmOpenNewProject = settings.getConfirmOpenNewProject();
|
||||
if (confirmOpenNewProject == GeneralSettings.OPEN_PROJECT_ASK) {
|
||||
if (isNewProject) {
|
||||
return Messages.showYesNoDialog(IdeBundle.message("prompt.open.project.in.new.frame"),
|
||||
IdeBundle.message("title.new.project"),
|
||||
IdeBundle.message("button.existingframe"),
|
||||
IdeBundle.message("button.newframe"),
|
||||
Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
int exitCode = Messages.showYesNoDialog(IdeBundle.message("prompt.open.project.in.new.frame"),
|
||||
IdeBundle.message("title.new.project"),
|
||||
IdeBundle.message("button.existingframe"),
|
||||
IdeBundle.message("button.newframe"),
|
||||
Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
return exitCode == 0 ? GeneralSettings.OPEN_PROJECT_SAME_WINDOW : GeneralSettings.OPEN_PROJECT_NEW_WINDOW;
|
||||
}
|
||||
else {
|
||||
return Messages.showYesNoCancelDialog(IdeBundle.message("prompt.open.project.in.new.frame"),
|
||||
IdeBundle.message("title.open.project"),
|
||||
IdeBundle.message("button.existingframe"), IdeBundle.message("button.newframe"),
|
||||
CommonBundle.getCancelButtonText(), Messages.getQuestionIcon(),
|
||||
new ProjectNewWindowDoNotAskOption());
|
||||
int exitCode = Messages.showYesNoCancelDialog(IdeBundle.message("prompt.open.project.in.new.frame"),
|
||||
IdeBundle.message("title.open.project"),
|
||||
IdeBundle.message("button.existingframe"), IdeBundle.message("button.newframe"),
|
||||
CommonBundle.getCancelButtonText(), Messages.getQuestionIcon(),
|
||||
new ProjectNewWindowDoNotAskOption());
|
||||
return exitCode == 0 ? GeneralSettings.OPEN_PROJECT_SAME_WINDOW : exitCode == 1 ? GeneralSettings.OPEN_PROJECT_NEW_WINDOW : Messages.CANCEL;
|
||||
}
|
||||
}
|
||||
return settings.getConfirmOpenNewProject();
|
||||
return confirmOpenNewProject;
|
||||
}
|
||||
|
||||
private static boolean isSameProject(String path, Project p) {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package com.intellij.platform;
|
||||
|
||||
import com.intellij.conversion.ConversionResult;
|
||||
|
||||
import com.intellij.ide.GeneralSettings;
|
||||
import com.intellij.ide.impl.ProjectUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
@@ -125,10 +127,10 @@ public class PlatformProjectOpenProcessor extends ProjectOpenProcessor {
|
||||
}
|
||||
else {
|
||||
int exitCode = ProjectUtil.confirmOpenNewProject(false);
|
||||
if (exitCode == 0) { // this window option
|
||||
if (exitCode == GeneralSettings.OPEN_PROJECT_SAME_WINDOW) {
|
||||
if (!ProjectUtil.closeAndDispose(projectToClose)) return null;
|
||||
}
|
||||
else if (exitCode != 1) { // not in a new window
|
||||
else if (exitCode != GeneralSettings.OPEN_PROJECT_NEW_WINDOW) { // not in a new window
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.usages;
|
||||
|
||||
import com.intellij.injected.editor.DocumentWindow;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -29,6 +30,7 @@ import com.intellij.openapi.fileTypes.PlainSyntaxHighlighter;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Segment;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -96,7 +98,7 @@ public class ChunkExtractor {
|
||||
};
|
||||
|
||||
public static TextChunk[] extractChunks(@NotNull PsiFile file, UsageInfo2UsageAdapter usageAdapter) {
|
||||
return ourExtractors.get().getValue().get(file).extractChunks(usageAdapter);
|
||||
return ourExtractors.get().getValue().get(file).extractChunks(usageAdapter, file);
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +126,7 @@ public class ChunkExtractor {
|
||||
return minStart == Integer.MAX_VALUE ? -1 : minStart;
|
||||
}
|
||||
|
||||
private TextChunk[] extractChunks(UsageInfo2UsageAdapter usageInfo2UsageAdapter) {
|
||||
private TextChunk[] extractChunks(@NotNull UsageInfo2UsageAdapter usageInfo2UsageAdapter, @NotNull PsiFile file) {
|
||||
int absoluteStartOffset = usageInfo2UsageAdapter.getNavigationOffset();
|
||||
if (absoluteStartOffset == -1) return TextChunk.EMPTY_ARRAY;
|
||||
|
||||
@@ -150,6 +152,14 @@ public class ChunkExtractor {
|
||||
lineStartOffset = Math.max(lineStartOffset, absoluteStartOffset - OFFSET_BEFORE_TO_SHOW_WHEN_LONG_LINE);
|
||||
lineEndOffset = Math.min(lineEndOffset, absoluteStartOffset + OFFSET_AFTER_TO_SHOW_WHEN_LONG_LINE);
|
||||
}
|
||||
if (myDocument instanceof DocumentWindow) {
|
||||
List<TextRange> editable = InjectedLanguageManager.getInstance(file.getProject())
|
||||
.intersectWithAllEditableFragments(file, new TextRange(lineStartOffset, lineEndOffset));
|
||||
for (TextRange range : editable) {
|
||||
createTextChunks(usageInfo2UsageAdapter, chars, range.getStartOffset(), range.getEndOffset(), result);
|
||||
}
|
||||
return result.toArray(new TextChunk[result.size()]);
|
||||
}
|
||||
return createTextChunks(usageInfo2UsageAdapter, chars, lineStartOffset, lineEndOffset, result);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.util.pico;
|
||||
|
||||
import com.intellij.util.ReflectionCache;
|
||||
import com.intellij.util.containers.ConcurrentHashMap;
|
||||
import com.intellij.util.containers.FList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.picocontainer.*;
|
||||
@@ -24,7 +25,6 @@ import org.picocontainer.defaults.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class DefaultPicoContainer implements MutablePicoContainer, Serializable {
|
||||
@@ -34,11 +34,11 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable
|
||||
private final Set<PicoContainer> children = new HashSet<PicoContainer>();
|
||||
|
||||
private final Map<Object, ComponentAdapter> componentKeyToAdapterCache = new ConcurrentHashMap<Object, ComponentAdapter>();
|
||||
private final AtomicReference<LinkedHashSet<ComponentAdapter>> componentAdapters = new AtomicReference<LinkedHashSet<ComponentAdapter>>(new LinkedHashSet<ComponentAdapter>());
|
||||
private final LinkedHashSetWrapper<ComponentAdapter> componentAdapters = new LinkedHashSetWrapper<ComponentAdapter>();
|
||||
// Keeps track of instantiation order.
|
||||
private final AtomicReference<LinkedHashSet<ComponentAdapter>> orderedComponentAdapters = new AtomicReference<LinkedHashSet<ComponentAdapter>>(new LinkedHashSet<ComponentAdapter>());
|
||||
private final LinkedHashSetWrapper<ComponentAdapter> orderedComponentAdapters = new LinkedHashSetWrapper<ComponentAdapter>();
|
||||
private final Map<String, ComponentAdapter> classNameToAdapter = new ConcurrentHashMap<String, ComponentAdapter>();
|
||||
private final CopyOnWriteArrayList<ComponentAdapter> nonAssignableComponentAdapters = new CopyOnWriteArrayList<ComponentAdapter>();
|
||||
private final AtomicReference<FList<ComponentAdapter>> nonAssignableComponentAdapters = new AtomicReference<FList<ComponentAdapter>>(FList.<ComponentAdapter>emptyList());
|
||||
|
||||
public DefaultPicoContainer(@NotNull ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) {
|
||||
this.componentAdapterFactory = componentAdapterFactory;
|
||||
@@ -50,7 +50,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable
|
||||
}
|
||||
|
||||
public Collection<ComponentAdapter> getComponentAdapters() {
|
||||
return Collections.unmodifiableCollection(componentAdapters.get());
|
||||
return componentAdapters.getImmutableSet();
|
||||
}
|
||||
|
||||
public Map<String, ComponentAdapter> getAssignablesCache() {
|
||||
@@ -59,7 +59,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable
|
||||
|
||||
|
||||
public Collection<ComponentAdapter> getNonAssignableAdapters() {
|
||||
return nonAssignableComponentAdapters;
|
||||
return nonAssignableComponentAdapters.get().getReversedList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -141,51 +141,34 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable
|
||||
classNameToAdapter.put(classKey, componentAdapter);
|
||||
}
|
||||
else {
|
||||
nonAssignableComponentAdapters.add(componentAdapter);
|
||||
do {
|
||||
FList<ComponentAdapter> oldList = nonAssignableComponentAdapters.get();
|
||||
FList<ComponentAdapter> newList = oldList.prepend(componentAdapter);
|
||||
if (nonAssignableComponentAdapters.compareAndSet(oldList, newList)) {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
addElement(componentAdapters, componentAdapter);
|
||||
componentAdapters.add(componentAdapter);
|
||||
|
||||
componentKeyToAdapterCache.put(componentKey, componentAdapter);
|
||||
return componentAdapter;
|
||||
}
|
||||
|
||||
private static <T> void addElement(AtomicReference<LinkedHashSet<T>> collectionHolder, T element) {
|
||||
do {
|
||||
LinkedHashSet<T> oldCollection = collectionHolder.get();
|
||||
if (oldCollection.contains(element)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LinkedHashSet<T> newCollection = new LinkedHashSet<T>(oldCollection);
|
||||
newCollection.add(element);
|
||||
|
||||
if (collectionHolder.compareAndSet(oldCollection, newCollection)) break;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
private static <T> void removeElement(AtomicReference<LinkedHashSet<T>> collectionHolder, T element) {
|
||||
do {
|
||||
LinkedHashSet<T> oldCollection = collectionHolder.get();
|
||||
|
||||
LinkedHashSet<T> newCollection = new LinkedHashSet<T>(oldCollection);
|
||||
newCollection.remove(element);
|
||||
|
||||
if (collectionHolder.compareAndSet(oldCollection, newCollection)) break;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
public ComponentAdapter unregisterComponent(Object componentKey) {
|
||||
ComponentAdapter adapter = componentKeyToAdapterCache.remove(componentKey);
|
||||
|
||||
removeElement(componentAdapters, adapter);
|
||||
removeElement(orderedComponentAdapters, adapter);
|
||||
componentAdapters.remove(adapter);
|
||||
orderedComponentAdapters.remove(adapter);
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
private void addOrderedComponentAdapter(ComponentAdapter componentAdapter) {
|
||||
addElement(orderedComponentAdapters, componentAdapter);
|
||||
if (!orderedComponentAdapters.contains(componentAdapter)) {
|
||||
orderedComponentAdapters.add(componentAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
public List getComponentInstances() throws PicoException {
|
||||
@@ -198,7 +181,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable
|
||||
}
|
||||
|
||||
Map<ComponentAdapter, Object> adapterToInstanceMap = new HashMap<ComponentAdapter, Object>();
|
||||
for (final ComponentAdapter componentAdapter : componentAdapters.get()) {
|
||||
for (final ComponentAdapter componentAdapter : componentAdapters.getImmutableSet()) {
|
||||
if (ReflectionCache.isAssignable(componentType, componentAdapter.getComponentImplementation())) {
|
||||
Object componentInstance = getInstance(componentAdapter);
|
||||
adapterToInstanceMap.put(componentAdapter, componentInstance);
|
||||
@@ -210,7 +193,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable
|
||||
}
|
||||
|
||||
List<Object> result = new ArrayList<Object>();
|
||||
for (ComponentAdapter componentAdapter : orderedComponentAdapters.get()) {
|
||||
for (ComponentAdapter componentAdapter : orderedComponentAdapters.getImmutableSet()) {
|
||||
final Object componentInstance = adapterToInstanceMap.get(componentAdapter);
|
||||
if (componentInstance != null) {
|
||||
// may be null in the case of the "implicit" adapter
|
||||
@@ -240,7 +223,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable
|
||||
|
||||
@Nullable
|
||||
private Object getInstance(ComponentAdapter componentAdapter) {
|
||||
final boolean isLocal = componentAdapters.get().contains(componentAdapter);
|
||||
final boolean isLocal = componentAdapters.contains(componentAdapter);
|
||||
|
||||
if (isLocal) {
|
||||
return getLocalInstance(componentAdapter);
|
||||
@@ -359,4 +342,50 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable
|
||||
public PicoContainer getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
private static class LinkedHashSetWrapper<T> {
|
||||
|
||||
private volatile Set<T> immutableSet;
|
||||
|
||||
private final LinkedHashSet<T> synchronizedSet = new LinkedHashSet<T>();
|
||||
|
||||
private final ConcurrentHashMap<T, T> concurrentSet = new ConcurrentHashMap<T, T>();
|
||||
|
||||
public boolean contains(@Nullable T element) {
|
||||
return element != null && concurrentSet.containsKey(element);
|
||||
}
|
||||
|
||||
public void add(@NotNull T element) {
|
||||
synchronized (synchronizedSet) {
|
||||
immutableSet = null;
|
||||
synchronizedSet.add(element);
|
||||
concurrentSet.put(element, element);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(@Nullable T element) {
|
||||
if (element == null) return;
|
||||
synchronized (synchronizedSet) {
|
||||
immutableSet = null;
|
||||
synchronizedSet.remove(element);
|
||||
concurrentSet.remove(element);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<T> getImmutableSet() {
|
||||
Set<T> res = immutableSet;
|
||||
if (res == null) {
|
||||
synchronized (synchronizedSet) {
|
||||
res = immutableSet;
|
||||
if (res == null) {
|
||||
res = Collections.unmodifiableSet((Set<T>)synchronizedSet.clone());
|
||||
immutableSet = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-2
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class SpringLoadedPositionManager implements PositionManager {
|
||||
|
||||
private static final Pattern GENERATED_CLASS_NAME = Pattern.compile(".*\\$\\$[A-Za-z0-9]{8}");
|
||||
private static final Pattern GENERATED_CLASS_NAME = Pattern.compile("\\$\\$[A-Za-z0-9]{8}");
|
||||
|
||||
private final DebugProcess myDebugProcess;
|
||||
|
||||
@@ -158,6 +158,16 @@ public class SpringLoadedPositionManager implements PositionManager {
|
||||
return myDebugProcess.getRequestsManager().createClassPrepareRequest(requestor, className + "*");
|
||||
}
|
||||
|
||||
private static boolean isSpringLoadedGeneratedClass(ReferenceType ownerClass, ReferenceType aClass) {
|
||||
String name = aClass.name();
|
||||
String ownerClassName = ownerClass.name();
|
||||
|
||||
// return name == ownerClassName + "$$" + /[A-Za-z0-9]{8}/
|
||||
return name.length() == ownerClassName.length() + 2 + 8
|
||||
&& name.startsWith(ownerClassName)
|
||||
&& GENERATED_CLASS_NAME.matcher(name.substring(ownerClassName.length())).matches();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static List<ReferenceType> findNested(ReferenceType fromClass, SourcePosition classPosition) {
|
||||
if (!fromClass.isPrepared()) return null;
|
||||
@@ -169,7 +179,7 @@ public class SpringLoadedPositionManager implements PositionManager {
|
||||
for (ReferenceType nested : nestedTypes) {
|
||||
if (!nested.isPrepared()) continue;
|
||||
|
||||
if (GENERATED_CLASS_NAME.matcher(nested.name()).matches()) {
|
||||
if (isSpringLoadedGeneratedClass(fromClass, nested)) {
|
||||
if (springLoadedGeneratedClasses.size() > 0 && !springLoadedGeneratedClasses.get(0).name().equals(nested.name())) {
|
||||
springLoadedGeneratedClasses.clear(); // Only latest generated classes should be used.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user