diff --git a/.idea/modules.xml b/.idea/modules.xml index 830183138f6a..f31fa8d873f9 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -68,6 +68,8 @@ + + diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java index ec44f00d15bb..d5a3d0e21356 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java @@ -108,7 +108,7 @@ public class BasicExpressionCompletionContributor { } PsiScopesUtil.treeWalkUp(new BaseScopeProcessor() { - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiLocalVariable) { if (!matcher.prefixMatches(((PsiLocalVariable)element).getName())) { return true; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index 2e168b6291ab..791f298c74a0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -389,7 +389,7 @@ public class JavaCompletionUtil { public static PsiType getQualifiedMemberReferenceType(@Nullable PsiType qualifierType, @NotNull final PsiMember member) { final Ref subst = Ref.create(PsiSubstitutor.EMPTY); class MyProcessor extends BaseScopeProcessor implements NameHint, ElementClassHint { - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element == member) { subst.set(state.get(PsiSubstitutor.KEY)); } @@ -407,7 +407,7 @@ public class JavaCompletionUtil { } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { return hintKey == NameHint.KEY || hintKey == ElementClassHint.KEY ? (T)this : null; } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java index bafe000392d2..18cccada0032 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaInheritorsGetter.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.CodeInsightUtil; import com.intellij.codeInsight.ExpectedTypeInfo; import com.intellij.codeInsight.daemon.impl.analysis.HighlightClassUtil; import com.intellij.codeInsight.lookup.*; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -154,14 +155,15 @@ public class JavaInheritorsGetter extends CompletionProvider -1) { + final PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(originalPosition, PsiMethodCallExpression.class); + if (methodCallExpression != null) { + final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(originalPosition, PsiNewExpression.class); + if (newExpression != null && ArrayUtil.find(methodCallExpression.getArgumentList().getExpressions(), newExpression) > -1 || + Comparing.equal(originalPosition.getParent(), methodCallExpression.getArgumentList())) { final JavaResolveResult resolveResult = methodCallExpression.resolveMethodGenerics(); - PsiMethod method = (PsiMethod)resolveResult.getElement(); - return method == null || PsiUtil.getApplicabilityLevel(method, resolveResult.getSubstitutor(), types, PsiUtil.getLanguageLevel(originalPosition)) + final PsiMethod method = (PsiMethod)resolveResult.getElement(); + return method == null || + PsiUtil.getApplicabilityLevel(method, resolveResult.getSubstitutor(), types, PsiUtil.getLanguageLevel(originalPosition)) != MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE; } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/proc/VariablesProcessor.java b/java/java-impl/src/com/intellij/codeInsight/completion/proc/VariablesProcessor.java index 03777100a052..7e11f577e223 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/proc/VariablesProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/proc/VariablesProcessor.java @@ -31,6 +31,7 @@ import com.intellij.psi.ResolveState; import com.intellij.psi.scope.BaseScopeProcessor; import com.intellij.psi.scope.ElementClassHint; import com.intellij.psi.scope.JavaScopeProcessorEvent; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -63,7 +64,7 @@ public class VariablesProcessor } /** Always return true since we wanna get all vars in scope */ - public boolean execute(PsiElement pe, ResolveState state){ + public boolean execute(@NotNull PsiElement pe, ResolveState state){ if(pe instanceof PsiVariable){ final PsiVariable pvar = (PsiVariable)pe; final String pvar_name = pvar.getName(); @@ -90,7 +91,7 @@ public class VariablesProcessor } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if (hintKey == ElementClassHint.KEY) { return (T)this; } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java b/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java index 5723681ecde3..b1fe9212ab69 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java @@ -193,7 +193,7 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme } } - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { //noinspection SuspiciousMethodCalls if (myNonInitializedFields.contains(element)) { return true; @@ -294,7 +294,7 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if (hintKey == ElementClassHint.KEY) { return (T)this; } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java index 08030828a481..d0bc8c86a102 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java @@ -99,7 +99,7 @@ public class RefCountHolder { public static RefCountHolder startUsing(@NotNull PsiFile file) { Pair pair = getInstance(file); HolderReference reference = pair.second; - reference.makeHardReachable(true); + reference.makeHardReachable(true); // make sure RefCountHolder won't be gced during highlighting return pair.first; } @NotNull @@ -127,7 +127,7 @@ public class RefCountHolder { myDclsUsedMap.put(result,Boolean.TRUE); } - public void registerReference(@NotNull PsiJavaReference ref, JavaResolveResult resolveResult) { + public void registerReference(@NotNull PsiJavaReference ref, @NotNull JavaResolveResult resolveResult) { assertIsAnalyzing(); PsiElement refElement = resolveResult.getElement(); PsiFile psiFile = refElement == null ? null : refElement.getContainingFile(); @@ -142,11 +142,11 @@ public class RefCountHolder { } } - private void registerImportStatement(@NotNull PsiReference ref, PsiImportStatementBase importStatement) { + private void registerImportStatement(@NotNull PsiReference ref, @NotNull PsiImportStatementBase importStatement) { myImportStatements.put(ref, importStatement); } - public boolean isRedundant(PsiImportStatementBase importStatement) { + public boolean isRedundant(@NotNull PsiImportStatementBase importStatement) { assertIsRetrieving(); return !myImportStatements.containsValue(importStatement); } @@ -227,7 +227,7 @@ public class RefCountHolder { return true; } - public boolean isReferencedForRead(PsiElement element) { + public boolean isReferencedForRead(@NotNull PsiElement element) { assertIsRetrieving(); LOG.assertTrue(element instanceof PsiVariable); List array = myLocalRefsMap.getKeysByValue(element); @@ -249,7 +249,7 @@ public class RefCountHolder { return false; } - public boolean isReferencedForWrite(PsiElement element) { + public boolean isReferencedForWrite(@NotNull PsiElement element) { assertIsRetrieving(); LOG.assertTrue(element instanceof PsiVariable); List array = myLocalRefsMap.getKeysByValue(element); @@ -271,7 +271,7 @@ public class RefCountHolder { if (!myState.compareAndSet(State.VIRGIN, State.BEING_WRITTEN_BY_GHP)) { return false; } - + boolean finished = false; try { if (dirtyScope != null) { if (dirtyScope.equals(file.getTextRange())) { @@ -283,15 +283,16 @@ public class RefCountHolder { } analyze.run(); + finished = true; } finally { - boolean set = myState.compareAndSet(State.BEING_WRITTEN_BY_GHP, State.READY); + boolean set = myState.compareAndSet(State.BEING_WRITTEN_BY_GHP, finished ? State.READY : State.VIRGIN); assert set : myState.get(); } return true; } - public boolean retrieveUnusedReferencesInfo(Runnable analyze) { + public boolean retrieveUnusedReferencesInfo(@NotNull Runnable analyze) { if (!myState.compareAndSet(State.READY, State.BEING_USED_BY_PHP)) { return false; } @@ -306,10 +307,12 @@ public class RefCountHolder { } private void assertIsAnalyzing() { - assert myState.get() == State.BEING_WRITTEN_BY_GHP : myState.get(); + State state = myState.get(); + assert state == State.BEING_WRITTEN_BY_GHP : state; } private void assertIsRetrieving() { - assert myState.get() == State.BEING_USED_BY_PHP : myState.get(); + State state = myState.get(); + assert state == State.BEING_USED_BY_PHP : state; } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java index d966cb14d7a7..456812925a0d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java @@ -514,7 +514,7 @@ public class CreateFromUsageUtils { final List list = new ArrayList(); VariablesProcessor varproc = new VariablesProcessor("", true, list){ @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if(!(element instanceof PsiField) || JavaPsiFacade.getInstance(element.getProject()).getResolveHelper().isAccessible((PsiField)element, expression, null)) { return super.execute(element, state); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameWrongRefFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameWrongRefFix.java index 44153db1059b..1d0d44cd300f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameWrongRefFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RenameWrongRefFix.java @@ -160,7 +160,7 @@ public class RenameWrongRefFix implements IntentionAction { } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiNamedElement && element instanceof PsiModifierListOwner && myFilterMethods == element instanceof PsiMethod) { diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java index 92f6bcb86ee0..b622a6623050 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java @@ -295,12 +295,7 @@ public class GenerateConstructorHandler extends GenerateMembersHandlerBase { PsiModifierList modifierList = parm.getModifierList(); PsiModifierList newMList = newParam.getModifierList(); if (modifierList != null && newMList != null) { - for (PsiAnnotation annotation : modifierList.getAnnotations()) { - newMList.add(factory.createAnnotationFromText(annotation.getText(), newParam)); - } - for (@PsiModifier.ModifierConstant String m : PsiModifier.MODIFIERS) { - newMList.setModifierProperty(m, parm.hasModifierProperty(m)); - } + newMList.replace(modifierList); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/macro/MacroUtil.java b/java/java-impl/src/com/intellij/codeInsight/template/macro/MacroUtil.java index b67ab09fa72f..6a8912aba347 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/macro/MacroUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/macro/MacroUtil.java @@ -162,7 +162,7 @@ public class MacroUtil { final List list = new ArrayList(); VariablesProcessor varproc = new VariablesProcessor(prefix, true, list) { - public boolean execute(PsiElement pe, ResolveState state) { + public boolean execute(@NotNull PsiElement pe, ResolveState state) { if (pe instanceof PsiVariable) { //exclude variables that are initialized in 'place' final PsiExpression initializer = ((PsiVariable)pe).getInitializer(); diff --git a/java/java-impl/src/com/intellij/ide/structureView/impl/AddAllMembersProcessor.java b/java/java-impl/src/com/intellij/ide/structureView/impl/AddAllMembersProcessor.java index 1ba819f5f14b..68a66cf25407 100644 --- a/java/java-impl/src/com/intellij/ide/structureView/impl/AddAllMembersProcessor.java +++ b/java/java-impl/src/com/intellij/ide/structureView/impl/AddAllMembersProcessor.java @@ -21,6 +21,7 @@ import com.intellij.psi.scope.BaseScopeProcessor; import com.intellij.psi.util.MethodSignature; import com.intellij.psi.util.PsiUtil; import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.Map; @@ -41,7 +42,7 @@ public class AddAllMembersProcessor extends BaseScopeProcessor { myPsiClass = psiClass; } - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { PsiMember member = (PsiMember)element; if (!isInteresting(element)) return true; if (myPsiClass.isInterface() && isObjectMember(element)) return true; diff --git a/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java b/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java index 55001b8d8224..43a05188a6d2 100644 --- a/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java +++ b/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java @@ -247,7 +247,7 @@ public abstract class AbstractQualifiedReference myResults = new LinkedHashSet(); @Override - public boolean execute(final PsiElement element, final ResolveState state) { + public boolean execute(@NotNull final PsiElement element, final ResolveState state) { if (isFound()) return false; process(element); return true; diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java index 4fe0f182794b..20f5f7f57f5b 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/JavaClassReference.java @@ -110,12 +110,12 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer } processorToUse = new PsiScopeProcessor() { @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { return !(element instanceof PsiClass || element instanceof PsiPackage) || processor.execute(element, state); } @Override - public V getHint(Key hintKey) { + public V getHint(@NotNull Key hintKey) { return processor.getHint(hintKey); } diff --git a/java/java-impl/src/com/intellij/psi/scope/processor/VariablesProcessor.java b/java/java-impl/src/com/intellij/psi/scope/processor/VariablesProcessor.java index b82f8ae02123..08ecc5379f0b 100644 --- a/java/java-impl/src/com/intellij/psi/scope/processor/VariablesProcessor.java +++ b/java/java-impl/src/com/intellij/psi/scope/processor/VariablesProcessor.java @@ -24,6 +24,7 @@ import com.intellij.psi.scope.BaseScopeProcessor; import com.intellij.psi.scope.ElementClassHint; import com.intellij.psi.scope.JavaScopeProcessorEvent; import com.intellij.util.SmartList; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -52,7 +53,7 @@ public abstract class VariablesProcessor extends BaseScopeProcessor implements E /** Always return true since we wanna get all vars in scope */ @Override - public boolean execute(PsiElement pe, ResolveState state){ + public boolean execute(@NotNull PsiElement pe, ResolveState state){ if(pe instanceof PsiVariable){ final PsiVariable pvar = (PsiVariable)pe; if(!myStaticSensitiveFlag || !myStaticScopeFlag || pvar.hasModifierProperty(PsiModifier.STATIC)){ @@ -79,7 +80,7 @@ public abstract class VariablesProcessor extends BaseScopeProcessor implements E } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if (hintKey == ElementClassHint.KEY) { return (T)this; } diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java index f52fdbbfc0b0..2d99c94337d0 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -40,6 +40,7 @@ import com.intellij.util.VisibilityUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -512,7 +513,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr return type.isAssignableFrom(varType); } - public boolean execute(PsiElement pe, ResolveState state) { + public boolean execute(@NotNull PsiElement pe, ResolveState state) { super.execute(pe, state); return size() < 2; } diff --git a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java index d0212624665f..aae30f20540f 100644 --- a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java @@ -100,7 +100,19 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase { } } } - return result.isEmpty() ? null : result; + if (result.isEmpty()) { + return null; + } + else { + boolean hasClasses = false; + for (PsiClass[] classes : result.values()) { + if (classes != null) { + hasClasses = true; + break; + } + } + return hasClasses ? result : null; + } } @Nullable diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/WritingAccessProvider.java b/java/java-impl/src/com/intellij/refactoring/util/ClsElementWritingAccessProvider.java similarity index 50% rename from platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/WritingAccessProvider.java rename to java/java-impl/src/com/intellij/refactoring/util/ClsElementWritingAccessProvider.java index 86c23cf1c596..651f433e34f2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/WritingAccessProvider.java +++ b/java/java-impl/src/com/intellij/refactoring/util/ClsElementWritingAccessProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -13,25 +13,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.openapi.vcs.readOnlyHandler; +package com.intellij.refactoring.util; -import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.ide.highlighter.JavaClassFileType; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.WritingAccessProvider; import org.jetbrains.annotations.NotNull; import java.util.Collection; +import java.util.Collections; /** - * @author Dmitry Avdeev + * User: ksafonov */ -public interface WritingAccessProvider { +public class ClsElementWritingAccessProvider extends WritingAccessProvider { - ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.writingAccessProvider"); - - /** - * @param files files to be checked - * @return set of files that cannot be accessed - */ @NotNull - Collection requestWriting(VirtualFile... files); + @Override + public Collection requestWriting(final VirtualFile... files) { + return Collections.emptyList(); + } + + @Override + public boolean isPotentiallyWritable(@NotNull final VirtualFile file) { + // TODO make library class files readonly not by their file type but by location in library roots + return file.getFileType() != JavaClassFileType.INSTANCE; + } } diff --git a/java/java-psi-api/src/com/intellij/psi/HierarchicalMethodSignature.java b/java/java-psi-api/src/com/intellij/psi/HierarchicalMethodSignature.java index 22520b1fa6a9..3c920d38a5e6 100644 --- a/java/java-psi-api/src/com/intellij/psi/HierarchicalMethodSignature.java +++ b/java/java-psi-api/src/com/intellij/psi/HierarchicalMethodSignature.java @@ -27,8 +27,7 @@ import java.util.List; * @since 5.1 */ public abstract class HierarchicalMethodSignature extends MethodSignatureBackedByPsiMethod { - - public HierarchicalMethodSignature(final MethodSignatureBackedByPsiMethod signature) { + public HierarchicalMethodSignature(@NotNull MethodSignatureBackedByPsiMethod signature) { super(signature.getMethod(), signature.getSubstitutor(), signature.isRaw(), signature.getParameterTypes(), signature.getTypeParameters()); } diff --git a/java/java-psi-api/src/com/intellij/psi/JavaRecursiveElementWalkingVisitor.java b/java/java-psi-api/src/com/intellij/psi/JavaRecursiveElementWalkingVisitor.java index a9086633c075..a707a296b0cb 100644 --- a/java/java-psi-api/src/com/intellij/psi/JavaRecursiveElementWalkingVisitor.java +++ b/java/java-psi-api/src/com/intellij/psi/JavaRecursiveElementWalkingVisitor.java @@ -38,7 +38,8 @@ public abstract class JavaRecursiveElementWalkingVisitor extends JavaElementVisi protected void elementFinished(PsiElement element) { } - @Override public void visitReferenceExpression(PsiReferenceExpression expression) { + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { visitExpression(expression); myWalkingState.startedWalking(); // do not traverse from scratch visitReferenceElement(expression); diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethod.java b/java/java-psi-api/src/com/intellij/psi/PsiMethod.java index 83e57127f3f2..3560ec3318f5 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiMethod.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiMethod.java @@ -47,9 +47,11 @@ public interface PsiMethod extends PsiMember, PsiNameIdentifierOwner, PsiModifie /** * Returns the return type of the method. + * * @return the method return type, or null if the method is a constructor. */ - @Nullable PsiType getReturnType(); + @Nullable + PsiType getReturnType(); /** * Returns the type element for the return type of the method. @@ -64,21 +66,24 @@ public interface PsiMethod extends PsiMember, PsiNameIdentifierOwner, PsiModifie * * @return the parameter list instance. */ - @NotNull PsiParameterList getParameterList(); + @NotNull + PsiParameterList getParameterList(); /** * Returns the list of thrown exceptions for the method. * * @return the list of thrown exceptions instance. */ - @NotNull PsiReferenceList getThrowsList(); + @NotNull + PsiReferenceList getThrowsList(); /** * Returns the body of the method. * * @return the method body, or null if the method belongs to a compiled class. */ - @Nullable PsiCodeBlock getBody(); + @Nullable + PsiCodeBlock getBody(); /** * Checks if the method is a constructor. @@ -101,7 +106,8 @@ public interface PsiMethod extends PsiMember, PsiNameIdentifierOwner, PsiModifie * @param substitutor the substitutor. * @return the method signature instance. */ - @NotNull MethodSignature getSignature(@NotNull PsiSubstitutor substitutor); + @NotNull + MethodSignature getSignature(@NotNull PsiSubstitutor substitutor); /** * Returns the name identifier for the method. @@ -109,7 +115,8 @@ public interface PsiMethod extends PsiMember, PsiNameIdentifierOwner, PsiModifie * @return the name identifier instance. */ @Override - @Nullable PsiIdentifier getNameIdentifier(); + @Nullable + PsiIdentifier getNameIdentifier(); /** * Searches the superclasses and base interfaces of the containing class to find @@ -120,7 +127,8 @@ public interface PsiMethod extends PsiMember, PsiNameIdentifierOwner, PsiModifie * * @return the array of super methods, or an empty array if no methods are found. */ - @NotNull PsiMethod[] findSuperMethods(); + @NotNull + PsiMethod[] findSuperMethods(); /** * Searches the superclasses and base interfaces of the containing class to find @@ -131,10 +139,11 @@ public interface PsiMethod extends PsiMember, PsiNameIdentifierOwner, PsiModifie * overridden method is returned. * * @param checkAccess if false, the super methods are searched even if this method - * is private. If true, an empty result list is returned for private methods. + * is private. If true, an empty result list is returned for private methods. * @return the array of super methods, or an empty array if no methods are found. */ - @NotNull PsiMethod[] findSuperMethods(boolean checkAccess); + @NotNull + PsiMethod[] findSuperMethods(boolean checkAccess); /** * Searches the superclasses and base interfaces of the specified class to find @@ -145,7 +154,8 @@ public interface PsiMethod extends PsiMember, PsiNameIdentifierOwner, PsiModifie * @param parentClass the class to search for super methods. * @return the array of super methods, or an empty array if no methods are found. */ - @NotNull PsiMethod[] findSuperMethods(PsiClass parentClass); + @NotNull + PsiMethod[] findSuperMethods(PsiClass parentClass); /** * Searches the superclasses and base interfaces of the containing class to find @@ -155,36 +165,43 @@ public interface PsiMethod extends PsiMember, PsiNameIdentifierOwner, PsiModifie * overrides another method, only the directly overridden method is returned. * * @param checkAccess if false, the super methods are searched even if this method - * is private. If true, an empty result list is returned for private methods. + * is private. If true, an empty result list is returned for private methods. * @return the array of matching method signatures, or an empty array if no methods are found. */ - @NotNull List findSuperMethodSignaturesIncludingStatic(boolean checkAccess); + @NotNull + List findSuperMethodSignaturesIncludingStatic(boolean checkAccess); /** * Returns the method in the deepest base superclass or interface of the containing class which * this method overrides or implements. * * @return the overridden or implemented method, or null if this method does not override - * or implement any other method. + * or implement any other method. * @deprecated use {@link #findDeepestSuperMethods()} instead */ - @Nullable PsiMethod findDeepestSuperMethod(); + @Nullable + PsiMethod findDeepestSuperMethod(); - @NotNull PsiMethod[] findDeepestSuperMethods(); + @NotNull + PsiMethod[] findDeepestSuperMethods(); @Override - @NotNull PsiModifierList getModifierList(); + @NotNull + PsiModifierList getModifierList(); @Override - @NotNull @NonNls + @NotNull + @NonNls String getName(); @Override PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException; - @NotNull HierarchicalMethodSignature getHierarchicalMethodSignature(); + @NotNull + HierarchicalMethodSignature getHierarchicalMethodSignature(); - @Nullable PsiMethodReceiver getMethodReceiver(); + @Nullable + PsiMethodReceiver getMethodReceiver(); @Nullable PsiType getReturnTypeNoResolve(); diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java index 9f5985b54fcc..bfb3bea37651 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java +++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBackedByPsiMethod.java @@ -26,10 +26,10 @@ public class MethodSignatureBackedByPsiMethod extends MethodSignatureBase { private final boolean myIsRaw; protected MethodSignatureBackedByPsiMethod(@NotNull PsiMethod method, - PsiSubstitutor substitutor, + @NotNull PsiSubstitutor substitutor, boolean isRaw, - PsiType[] parameterTypes, - PsiTypeParameter[] methodTypeParameters) { + @NotNull PsiType[] parameterTypes, + @NotNull PsiTypeParameter[] methodTypeParameters) { super(substitutor, parameterTypes, methodTypeParameters); myIsRaw = isRaw; if (!method.isValid()) { @@ -67,11 +67,11 @@ public class MethodSignatureBackedByPsiMethod extends MethodSignatureBase { return myMethod; } - public static MethodSignatureBackedByPsiMethod create(PsiMethod method, PsiSubstitutor substitutor) { + public static MethodSignatureBackedByPsiMethod create(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor) { return create(method, substitutor, PsiUtil.isRawSubstitutor(method, substitutor)); } - public static MethodSignatureBackedByPsiMethod create(PsiMethod method, PsiSubstitutor substitutor, boolean isRaw) { + public static MethodSignatureBackedByPsiMethod create(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor, boolean isRaw) { PsiTypeParameter[] methodTypeParameters = method.getTypeParameters(); final PsiParameter[] parameters = method.getParameterList().getParameters(); PsiType[] parameterTypes = new PsiType[parameters.length]; diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBase.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBase.java index 25c8b6570c6b..f432bc747651 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBase.java +++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureBase.java @@ -27,7 +27,7 @@ public abstract class MethodSignatureBase implements MethodSignature { private final PsiType[] myParameterTypes; protected final PsiTypeParameter[] myTypeParameters; - protected MethodSignatureBase(PsiSubstitutor substitutor, @NotNull PsiType[] parameterTypes, @NotNull PsiTypeParameter[] typeParameters) { + protected MethodSignatureBase(@NotNull PsiSubstitutor substitutor, @NotNull PsiType[] parameterTypes, @NotNull PsiTypeParameter[] typeParameters) { mySubstitutor = substitutor; myParameterTypes = parameterTypes.length == 0 ? PsiType.EMPTY_ARRAY : new PsiType[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java index 9ea434fa27f4..8c436715f9e5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java @@ -233,7 +233,7 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava } @Override - public T getHint(final Key hintKey) { + public T getHint(@NotNull final Key hintKey) { return myDelegate.getHint(hintKey); } @@ -250,7 +250,7 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava } @Override - public boolean execute(final PsiElement element, final ResolveState state) { + public boolean execute(@NotNull final PsiElement element, final ResolveState state) { if (element instanceof PsiModifierListOwner && ((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC)) { if (element instanceof PsiNamedElement && myIsProcessingOnDemand) { final String name = ((PsiNamedElement)element).getName(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java index 83d61fea1827..39815fb6ad30 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ClassResolverProcessor.java @@ -25,6 +25,7 @@ import com.intellij.psi.infos.ClassCandidateInfo; import com.intellij.psi.scope.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.SmartList; +import org.jetbrains.annotations.NotNull; import java.util.Iterator; import java.util.List; @@ -210,7 +211,7 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (!(element instanceof PsiClass)) return true; final PsiClass aClass = (PsiClass)element; final String name = aClass.getName(); @@ -308,7 +309,7 @@ public class ClassResolverProcessor extends BaseScopeProcessor implements NameHi } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if (hintKey == ElementClassHint.KEY || hintKey == NameHint.KEY) { //noinspection unchecked return (T)this; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/StaticImportResolveProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/StaticImportResolveProcessor.java index 316f5a980fc2..f7adb3545e57 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/StaticImportResolveProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/StaticImportResolveProcessor.java @@ -21,6 +21,7 @@ import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.scope.BaseScopeProcessor; import com.intellij.psi.scope.NameHint; import com.intellij.util.SmartList; +import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.ListIterator; @@ -38,7 +39,7 @@ public class StaticImportResolveProcessor extends BaseScopeProcessor implements } @Override - public boolean execute(final PsiElement candidate, final ResolveState state) { + public boolean execute(@NotNull final PsiElement candidate, final ResolveState state) { if (candidate instanceof PsiMember && ((PsiModifierListOwner)candidate).hasModifierProperty(PsiModifier.STATIC)) { if (candidate instanceof PsiField) { if (checkDomination((PsiMember)candidate, myFieldResults)) return true; @@ -90,7 +91,7 @@ public class StaticImportResolveProcessor extends BaseScopeProcessor implements } @Override - public T getHint(final Key hintKey) { + public T getHint(@NotNull final Key hintKey) { if (hintKey == NameHint.KEY) { //noinspection unchecked return (T)this; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java index 8145272ed390..c65b6e65a6df 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java @@ -34,7 +34,7 @@ public class SymbolCollectingProcessor extends BaseScopeProcessor implements Ele private PsiElement myCurrentFileContext = null; @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if (hintKey == ElementClassHint.KEY) { //noinspection unchecked return (T)this; @@ -50,7 +50,7 @@ public class SymbolCollectingProcessor extends BaseScopeProcessor implements Ele } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiNamedElement) { PsiNamedElement named = (PsiNamedElement)element; String name = named.getName(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java index 56c9f20d1dd0..c544598b25c5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java @@ -29,6 +29,7 @@ import com.intellij.psi.scope.conflictResolvers.JavaVariableConflictResolver; import com.intellij.psi.scope.processor.ConflictFilterProcessor; import com.intellij.psi.util.PsiUtil; import com.intellij.util.SmartList; +import org.jetbrains.annotations.NotNull; /** * @author ik, dsl @@ -91,7 +92,7 @@ public class VariableResolverProcessor extends ConflictFilterProcessor implement } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (!(element instanceof PsiField) && (myName == null || PsiUtil.checkName(element, myName, myPlace))) { super.execute(element, state); return myResults.isEmpty(); @@ -101,7 +102,7 @@ public class VariableResolverProcessor extends ConflictFilterProcessor implement } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if (hintKey == ElementClassHint.KEY) { return (T)this; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java index 55adbec6bee5..b03e9a42e3f5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiCodeBlockImpl.java @@ -102,7 +102,7 @@ public class PsiCodeBlockImpl extends LazyParseablePsiElement implements PsiCode final Ref conflict = new Ref(Boolean.FALSE); PsiScopesUtil.walkChildrenScopes(this, new BaseScopeProcessor() { @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiLocalVariable) { final PsiLocalVariable variable = (PsiLocalVariable)element; final String name = variable.getName(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java index 527052d9ced3..6baf38d024f0 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java @@ -51,10 +51,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.util.CharTable; -import com.intellij.util.Function; -import com.intellij.util.IncorrectOperationException; -import com.intellij.util.NullableFunction; +import com.intellij.util.*; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -194,12 +191,13 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple private static JavaResolveResult[] _resolve(boolean incompleteCode, PsiReferenceExpressionImpl expression) { CompositeElement treeParent = expression.getTreeParent(); IElementType parentType = treeParent == null ? null : treeParent.getElementType(); - + expression.resolveAllQualifiers(); final JavaResolveResult[] result = expression.resolve(parentType); if (incompleteCode && parentType != JavaElementType.REFERENCE_EXPRESSION && result.length == 0) { return expression.resolve(JavaElementType.REFERENCE_EXPRESSION); } + return result; } @@ -221,6 +219,38 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple } } + private void resolveAllQualifiers() { + // to avoid SOE + PsiElement qualifier = getQualifier(); + if (qualifier == null) return; + final ResolveCache resolveCache = ResolveCache.getInstance(getProject()); + //resolveCache.resolveWithCaching(this, OurGenericsResolver.INSTANCE, true, incompleteCode) + qualifier.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { + if (!(expression instanceof PsiReferenceExpressionImpl) || resolveCache.isCached(expression, true, false)) { + return; + } + visitElement(expression); + } + + @Override + protected void elementFinished(PsiElement element) { + if (!(element instanceof PsiReferenceExpressionImpl)) return; + PsiReferenceExpressionImpl expression = (PsiReferenceExpressionImpl)element; + //IElementType type = expression.getTreeParent().getElementType(); + //expression.resolve(); + ResolveResult[] results = resolveCache.resolveWithCaching(expression, OurGenericsResolver.INSTANCE, false, false); + //System.out.println("resolveWithCaching "+element); + //if (!resolveCache.isCached(expression, element.isPhysical(), false)) { + // assert resolveCache.isCached(expression, element.isPhysical(), false); + //} + assert results != null; + } + }); + int i = 0; + } + @NotNull private JavaResolveResult[] resolve(IElementType parentType) { if (parentType == JavaElementType.REFERENCE_EXPRESSION) { @@ -414,7 +444,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple private final Set myVarNames = new THashSet(); @Override - public boolean execute(final PsiElement element, final ResolveState state) { + public boolean execute(@NotNull final PsiElement element, final ResolveState state) { if (element instanceof PsiLocalVariable || element instanceof PsiParameter) { myVarNames.add(((PsiVariable) element).getName()); } diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/processor/ConflictFilterProcessor.java b/java/java-psi-impl/src/com/intellij/psi/scope/processor/ConflictFilterProcessor.java index 3d928069cc03..c5b44c8d8563 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/processor/ConflictFilterProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/processor/ConflictFilterProcessor.java @@ -48,7 +48,7 @@ public class ConflictFilterProcessor extends FilterScopeProcessor } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (myCachedResult != null && myCachedResult.length == 1 && myCachedResult[0].isAccessible()) { return false; } @@ -103,7 +103,7 @@ public class ConflictFilterProcessor extends FilterScopeProcessor } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if (hintKey == NameHint.KEY) { //noinspection unchecked return myName != null ? (T)this : null; diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/processor/FilterScopeProcessor.java b/java/java-psi-impl/src/com/intellij/psi/scope/processor/FilterScopeProcessor.java index 3adf67c1aa49..f1eb3ed46853 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/processor/FilterScopeProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/processor/FilterScopeProcessor.java @@ -23,6 +23,7 @@ import com.intellij.psi.filters.ElementFilter; import com.intellij.psi.scope.BaseScopeProcessor; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.util.SmartList; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -66,7 +67,7 @@ public class FilterScopeProcessor extends BaseScopeProcessor { } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (myFilter.isAcceptable(element, myCurrentDeclarationHolder)) { if (myProcessor != null) { return myProcessor.execute(element, state); @@ -82,7 +83,7 @@ public class FilterScopeProcessor extends BaseScopeProcessor { } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if (myProcessor != null) { return myProcessor.getHint(hintKey); } diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodResolverProcessor.java b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodResolverProcessor.java index 76cc89586b86..1917e393c758 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodResolverProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodResolverProcessor.java @@ -21,6 +21,7 @@ import com.intellij.psi.scope.JavaScopeProcessorEvent; import com.intellij.psi.scope.PsiConflictResolver; import com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver; import com.intellij.util.SmartList; +import org.jetbrains.annotations.NotNull; public class MethodResolverProcessor extends MethodCandidatesProcessor { private boolean myStopAcceptingCandidates = false; @@ -51,7 +52,7 @@ public class MethodResolverProcessor extends MethodCandidatesProcessor { } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { return !myStopAcceptingCandidates && super.execute(element, state); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodsProcessor.java b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodsProcessor.java index 919eb89bbec0..ffc49b153981 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodsProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodsProcessor.java @@ -26,6 +26,7 @@ import com.intellij.psi.scope.JavaScopeProcessorEvent; import com.intellij.psi.scope.PsiConflictResolver; import com.intellij.psi.util.PsiUtil; import com.intellij.util.SmartList; +import org.jetbrains.annotations.NotNull; /** * Created by IntelliJ IDEA. @@ -116,7 +117,7 @@ public abstract class MethodsProcessor extends ConflictFilterProcessor implement } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if (hintKey == ElementClassHint.KEY) { return (T)this; } diff --git a/java/java-tests/testData/codeInsight/completion/smartType/DiamondNotCollapsedNotApplicable-out.java b/java/java-tests/testData/codeInsight/completion/smartType/DiamondNotCollapsedNotApplicable-out.java new file mode 100644 index 000000000000..618fd3388c0c --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/DiamondNotCollapsedNotApplicable-out.java @@ -0,0 +1,15 @@ +import java.util.ArrayList; + +public class TestCompletion { + public static void test() { + A> ref = new A<>(); + ref.set(new ArrayList() ); + } +} + +class A { + A() { + } + + void set(V v){} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/DiamondNotCollapsedNotApplicable.java b/java/java-tests/testData/codeInsight/completion/smartType/DiamondNotCollapsedNotApplicable.java new file mode 100644 index 000000000000..3d79a3392a8f --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/DiamondNotCollapsedNotApplicable.java @@ -0,0 +1,15 @@ +import java.util.ArrayList; + +public class TestCompletion { + public static void test() { + A> ref = new A<>(); + ref.set(new ); + } +} + +class A { + A() { + } + + void set(V v){} +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType17CompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType17CompletionTest.java index 96dda9979256..cd531b3b91fa 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType17CompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartType17CompletionTest.java @@ -46,6 +46,10 @@ public class SmartType17CompletionTest extends LightFixtureCompletionTestCase { doTest(); } + public void testDiamondNotCollapsedNotApplicable() throws Exception { + doTest(); + } + public void testDiamondNotCollapsedInCaseOfAnonymousClasses() throws Exception { doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/psi/SrcRepositoryUseTest.java b/java/java-tests/testSrc/com/intellij/psi/SrcRepositoryUseTest.java index 5e4d78facda4..ca3c67108da7 100644 --- a/java/java-tests/testSrc/com/intellij/psi/SrcRepositoryUseTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/SrcRepositoryUseTest.java @@ -29,6 +29,7 @@ import com.intellij.testFramework.PsiTestUtil; import java.io.File; import java.io.IOException; +@SuppressWarnings("ConstantConditions") @PlatformTestCase.WrapInCommand public class SrcRepositoryUseTest extends PsiTestCase{ private static final Logger LOG = Logger.getInstance("#com.intellij.psi.SrcRepositoryUseTest"); @@ -501,8 +502,9 @@ public class SrcRepositoryUseTest extends PsiTestCase{ setupLoadingFilter(); PsiClass aClass = myJavaFacade.findClass("pack.MyClass2", GlobalSearchScope.allScope(myProject)); - - PsiParameterList list = aClass.getMethods()[0].getParameterList(); + assertNotNull(aClass); + PsiMethod[] methods = aClass.getMethods(); + PsiParameterList list = methods[0].getParameterList(); PsiParameter[] parms = list.getParameters(); assertEquals(5, parms.length); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InplaceRenameInvariantTest.groovy b/java/java-tests/testSrc/com/intellij/refactoring/InplaceRenameInvariantTest.groovy index 17c4694f3b9e..a82c77d7f1e0 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/InplaceRenameInvariantTest.groovy +++ b/java/java-tests/testSrc/com/intellij/refactoring/InplaceRenameInvariantTest.groovy @@ -34,7 +34,7 @@ class InplaceRenameInvariantTest extends LightCodeInsightTestCase { } """ - doTestPositionInvariance(text, false) + doTestPositionInvariance(text, false, false) } public void "test middle caret position"() { @@ -44,7 +44,7 @@ class InplaceRenameInvariantTest extends LightCodeInsightTestCase { } """ - doTestPositionInvariance(text, false) + doTestPositionInvariance(text, false, false) } public void "test end caret position"() { @@ -54,7 +54,18 @@ class InplaceRenameInvariantTest extends LightCodeInsightTestCase { } """ - doTestPositionInvariance(text, false) + doTestPositionInvariance(text, false, false) + } + + public void "test end caret position typing"() { + def text = """\ + class Test { + Test myTest; + } + } + """ + + doTestPositionInvariance(text, false, false) } @@ -65,7 +76,7 @@ class InplaceRenameInvariantTest extends LightCodeInsightTestCase { } """ - doTestPositionInvariance(text, true) + doTestPositionInvariance(text, true, false) } public void "test middle caret position preselect"() { @@ -75,7 +86,7 @@ class InplaceRenameInvariantTest extends LightCodeInsightTestCase { } """ - doTestPositionInvariance(text, true) + doTestPositionInvariance(text, true, false) } public void "test end caret position preselect"() { @@ -85,10 +96,10 @@ class InplaceRenameInvariantTest extends LightCodeInsightTestCase { } """ - doTestPositionInvariance(text, true) + doTestPositionInvariance(text, true, false) } - private doTestPositionInvariance(String text, final boolean preselect) { + private doTestPositionInvariance(String text, final boolean preselect, final boolean checkTyping) { configure text TemplateManagerImpl templateManager = (TemplateManagerImpl)TemplateManager.getInstance(project) def oldPreselectSetting = myEditor.settings.preselectRename @@ -104,6 +115,11 @@ class InplaceRenameInvariantTest extends LightCodeInsightTestCase { handler.doRename(element, editor, null); + + if (checkTyping){ + type '1' + offset++ + } assertEquals(offset, myEditor.caretModel.offset) } diff --git a/jps/model-api/jps-model-api.iml b/jps/model-api/jps-model-api.iml new file mode 100644 index 000000000000..4d3f06e41375 --- /dev/null +++ b/jps/model-api/jps-model-api.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/jps/model-api/src/org/jetbrains/jps/model/DummyJpsElementProperties.java b/jps/model-api/src/org/jetbrains/jps/model/DummyJpsElementProperties.java new file mode 100644 index 000000000000..43d44e8a4fac --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/DummyJpsElementProperties.java @@ -0,0 +1,8 @@ +package org.jetbrains.jps.model; + +/** + * @author nik + */ +public class DummyJpsElementProperties extends JpsElementProperties { + public static final DummyJpsElementProperties INSTANCE = new DummyJpsElementProperties(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsCompositeElement.java b/jps/model-api/src/org/jetbrains/jps/model/JpsCompositeElement.java new file mode 100644 index 000000000000..2ed2dfacefb2 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsCompositeElement.java @@ -0,0 +1,11 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface JpsCompositeElement extends JpsParentElement { + @NotNull + JpsElementContainer getContainer(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElement.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElement.java new file mode 100644 index 000000000000..071ea73b35e9 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElement.java @@ -0,0 +1,18 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface JpsElement { + @NotNull + BulkModificationSupport getBulkModificationSupport(); + + interface BulkModificationSupport extends JpsElement { + @NotNull + E createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent); + + void applyChanges(@NotNull E modified); + } +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementCollection.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementCollection.java new file mode 100644 index 000000000000..a95042929058 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementCollection.java @@ -0,0 +1,22 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author nik + */ +public interface JpsElementCollection extends JpsParentElement { + List getElements(); + + @NotNull +

E addChild(@NotNull JpsElementFactoryWithParameter factory, @NotNull P param); + + @NotNull + E addChild(@NotNull JpsElementFactory factory); + + E addChild(E element); + + void removeChild(@NotNull E element); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementContainer.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementContainer.java new file mode 100644 index 000000000000..969b3534fc53 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementContainer.java @@ -0,0 +1,25 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface JpsElementContainer { + + T getChild(@NotNull JpsElementKind kind); + + @NotNull + &JpsElementFactory> + T setChild(@NotNull K kind); + + @NotNull + &JpsElementFactoryWithParameter> + T setChild(@NotNull K kind, @NotNull P param); + + + T setChild(JpsElementKind kind, T child); + + + void removeChild(@NotNull JpsElementKind kind); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactory.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactory.java new file mode 100644 index 000000000000..b06da51b9455 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactory.java @@ -0,0 +1,12 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface JpsElementFactory { + + @NotNull + E create(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactoryWithParameter.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactoryWithParameter.java new file mode 100644 index 000000000000..13e9103789f6 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactoryWithParameter.java @@ -0,0 +1,11 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface JpsElementFactoryWithParameter { + @NotNull + E create(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent, @NotNull P param); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementKind.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementKind.java new file mode 100644 index 000000000000..4e47a07bfc5a --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementKind.java @@ -0,0 +1,15 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class JpsElementKind { + + public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull E element) { + } + + public void fireElementRemoved(@NotNull JpsEventDispatcher dispatcher, @NotNull E element) { + } +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementProperties.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementProperties.java new file mode 100644 index 000000000000..c238f1ce7459 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementProperties.java @@ -0,0 +1,7 @@ +package org.jetbrains.jps.model; + +/** + * @author nik + */ +public abstract class JpsElementProperties { +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementReference.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementReference.java new file mode 100644 index 000000000000..f09bbc71ace3 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementReference.java @@ -0,0 +1,11 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public interface JpsElementReference extends JpsElement { + @Nullable + T resolve(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementType.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementType.java new file mode 100644 index 000000000000..eb4f95707695 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementType.java @@ -0,0 +1,10 @@ +package org.jetbrains.jps.model; + +/** + * @author nik + */ +public abstract class JpsElementType

{ + public abstract P createDefaultProperties(); + + public abstract P createCopy(P properties); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsEventDispatcher.java b/jps/model-api/src/org/jetbrains/jps/model/JpsEventDispatcher.java new file mode 100644 index 000000000000..4c436ffce4c7 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsEventDispatcher.java @@ -0,0 +1,23 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +import java.util.EventListener; + +/** + * @author nik + */ +public interface JpsEventDispatcher { + @NotNull + T getPublisher(Class listenerClass); + + void fireElementRenamed(@NotNull JpsNamedElement element, @NotNull String oldName, @NotNull String newName); + + void fireElementChanged(@NotNull JpsElement element); + + + void fireElementAdded(@NotNull T element, @NotNull JpsElementKind kind); + + + void fireElementRemoved(@NotNull T element, @NotNull JpsElementKind kind); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java b/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java new file mode 100644 index 000000000000..ea535b091670 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java @@ -0,0 +1,15 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryType; + +/** + * @author nik + */ +public interface JpsGlobal extends JpsCompositeElement, JpsReferenceableElement { + @NotNull + JpsLibrary addLibrary(@NotNull JpsLibraryType libraryType, final @NotNull String name); + + +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsModel.java b/jps/model-api/src/org/jetbrains/jps/model/JpsModel.java new file mode 100644 index 000000000000..09780fa1861f --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsModel.java @@ -0,0 +1,19 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface JpsModel { + @NotNull + JpsProject getProject(); + + @NotNull + JpsGlobal getGlobal(); + + @NotNull + JpsModel createModifiableModel(@NotNull JpsEventDispatcher eventDispatcher); + + void commit(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsNamedElement.java b/jps/model-api/src/org/jetbrains/jps/model/JpsNamedElement.java new file mode 100644 index 000000000000..7c7bcc83afba --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsNamedElement.java @@ -0,0 +1,13 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface JpsNamedElement extends JpsElement { + @NotNull + String getName(); + + void setName(@NotNull String name); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsParentElement.java b/jps/model-api/src/org/jetbrains/jps/model/JpsParentElement.java new file mode 100644 index 000000000000..9a28f2bf39b1 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsParentElement.java @@ -0,0 +1,7 @@ +package org.jetbrains.jps.model; + +/** + * @author nik + */ +public interface JpsParentElement extends JpsElement { +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java b/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java new file mode 100644 index 000000000000..0beb26b8a514 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java @@ -0,0 +1,27 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryType; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleType; + +import java.util.List; + +/** + * @author nik + */ +public interface JpsProject extends JpsCompositeElement, JpsReferenceableElement { + + @NotNull + JpsModule addModule(@NotNull JpsModuleType moduleType, @NotNull String name); + + @NotNull + JpsLibrary addLibrary(@NotNull JpsLibraryType libraryType, @NotNull String name); + + @NotNull + List getLibraries(); + + @NotNull + List getModules(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsReferenceableElement.java b/jps/model-api/src/org/jetbrains/jps/model/JpsReferenceableElement.java new file mode 100644 index 000000000000..4df008cce68c --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsReferenceableElement.java @@ -0,0 +1,11 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface JpsReferenceableElement { + @NotNull + JpsElementReference createReference(JpsParentElement parent); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsTypedData.java b/jps/model-api/src/org/jetbrains/jps/model/JpsTypedData.java new file mode 100644 index 000000000000..fee5e2e12a66 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsTypedData.java @@ -0,0 +1,16 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface JpsTypedData

extends JpsElement { + @NotNull + JpsElementType

getType(); + + @NotNull + P getProperties(); + + void setProperties(@NotNull P properties); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsUrlList.java b/jps/model-api/src/org/jetbrains/jps/model/JpsUrlList.java new file mode 100644 index 000000000000..d8040d206771 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsUrlList.java @@ -0,0 +1,17 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author nik + */ +public interface JpsUrlList extends JpsElement { + @NotNull + List getUrls(); + + void addUrl(@NotNull String url); + + void removeUrl(@NotNull String url); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsUrlListChangeListener.java b/jps/model-api/src/org/jetbrains/jps/model/JpsUrlListChangeListener.java new file mode 100644 index 000000000000..0d1450deaaae --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsUrlListChangeListener.java @@ -0,0 +1,12 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface JpsUrlListChangeListener { + void urlAdded(@NotNull T element, @NotNull String url); + + void urlRemoved(@NotNull T element, @NotNull String url); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/SimpleJpsElement.java b/jps/model-api/src/org/jetbrains/jps/model/SimpleJpsElement.java new file mode 100644 index 000000000000..09a565fda058 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/SimpleJpsElement.java @@ -0,0 +1,13 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface SimpleJpsElement

extends JpsElement { + @NotNull + P getProperties(); + + void setProperties(@NotNull P properties); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JavaModuleExtension.java b/jps/model-api/src/org/jetbrains/jps/model/java/JavaModuleExtension.java new file mode 100644 index 000000000000..1ac6c18b42a4 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JavaModuleExtension.java @@ -0,0 +1,21 @@ +package org.jetbrains.jps.model.java; + +import org.jetbrains.jps.model.JpsElement; + +/** + * @author nik + */ +public interface JavaModuleExtension extends JpsElement { + + String getOutputUrl(); + + void setOutputUrl(String outputUrl); + + String getTestOutputUrl(); + + void setTestOutputUrl(String testOutputUrl); + + LanguageLevel getLanguageLevel(); + + void setLanguageLevel(LanguageLevel languageLevel); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootProperties.java b/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootProperties.java new file mode 100644 index 000000000000..716fc48a91e0 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootProperties.java @@ -0,0 +1,22 @@ +package org.jetbrains.jps.model.java; + +import org.jetbrains.jps.model.JpsElementProperties; + +/** + * @author nik + */ +public class JavaSourceRootProperties extends JpsElementProperties { + private final String myPackagePrefix; + + public JavaSourceRootProperties() { + myPackagePrefix = ""; + } + + public JavaSourceRootProperties(String packagePrefix) { + myPackagePrefix = packagePrefix; + } + + public String getPackagePrefix() { + return myPackagePrefix; + } +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootType.java new file mode 100644 index 000000000000..0428014e8c2b --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootType.java @@ -0,0 +1,21 @@ +package org.jetbrains.jps.model.java; + +import org.jetbrains.jps.model.module.JpsModuleSourceRootType; + +/** + * @author nik + */ +public class JavaSourceRootType extends JpsModuleSourceRootType { + public static final JavaSourceRootType SOURCE = new JavaSourceRootType(); + public static final JavaSourceRootType TEST_SOURCE = new JavaSourceRootType(); + + @Override + public JavaSourceRootProperties createDefaultProperties() { + return new JavaSourceRootProperties(); + } + + @Override + public JavaSourceRootProperties createCopy(JavaSourceRootProperties properties) { + return new JavaSourceRootProperties(properties.getPackagePrefix()); + } +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaLibraryType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaLibraryType.java new file mode 100644 index 000000000000..d28bb62867fb --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaLibraryType.java @@ -0,0 +1,21 @@ +package org.jetbrains.jps.model.java; + +import org.jetbrains.jps.model.DummyJpsElementProperties; +import org.jetbrains.jps.model.library.JpsLibraryType; + +/** + * @author nik + */ +public class JpsJavaLibraryType extends JpsLibraryType { + public static final JpsJavaLibraryType INSTANCE = new JpsJavaLibraryType(); + + @Override + public DummyJpsElementProperties createDefaultProperties() { + return DummyJpsElementProperties.INSTANCE; + } + + @Override + public DummyJpsElementProperties createCopy(DummyJpsElementProperties properties) { + return DummyJpsElementProperties.INSTANCE; + } +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleType.java new file mode 100644 index 000000000000..7a9c2b643606 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleType.java @@ -0,0 +1,21 @@ +package org.jetbrains.jps.model.java; + +import org.jetbrains.jps.model.DummyJpsElementProperties; +import org.jetbrains.jps.model.module.JpsModuleType; + +/** + * @author nik + */ +public class JpsJavaModuleType extends JpsModuleType { + public static final JpsJavaModuleType INSTANCE = new JpsJavaModuleType(); + + @Override + public DummyJpsElementProperties createDefaultProperties() { + return DummyJpsElementProperties.INSTANCE; + } + + @Override + public DummyJpsElementProperties createCopy(DummyJpsElementProperties properties) { + return DummyJpsElementProperties.INSTANCE; + } +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaSdkType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaSdkType.java new file mode 100644 index 000000000000..e39872661639 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaSdkType.java @@ -0,0 +1,21 @@ +package org.jetbrains.jps.model.java; + +import org.jetbrains.jps.model.DummyJpsElementProperties; +import org.jetbrains.jps.model.library.JpsSdkType; + +/** + * @author nik + */ +public class JpsJavaSdkType extends JpsSdkType { + public static final JpsJavaSdkType INSTANCE = new JpsJavaSdkType(); + + @Override + public DummyJpsElementProperties createDefaultProperties() { + return DummyJpsElementProperties.INSTANCE; + } + + @Override + public DummyJpsElementProperties createCopy(DummyJpsElementProperties properties) { + return DummyJpsElementProperties.INSTANCE; + } +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/LanguageLevel.java b/jps/model-api/src/org/jetbrains/jps/model/java/LanguageLevel.java new file mode 100644 index 000000000000..5cf1c66de6af --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/LanguageLevel.java @@ -0,0 +1,7 @@ +package org.jetbrains.jps.model.java; + +/** + * @author nik + */ +public enum LanguageLevel { +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java new file mode 100644 index 000000000000..45293113ecfe --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java @@ -0,0 +1,26 @@ +package org.jetbrains.jps.model.library; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsNamedElement; +import org.jetbrains.jps.model.JpsParentElement; +import org.jetbrains.jps.model.JpsReferenceableElement; + +import java.util.List; + +/** + * @author nik + */ +public interface JpsLibrary extends JpsNamedElement, JpsReferenceableElement { + + @NotNull + List getUrls(@NotNull JpsLibraryRootType rootType); + + void addUrl(@NotNull String url, @NotNull JpsLibraryRootType rootType); + + void removeUrl(@NotNull String url, @NotNull JpsLibraryRootType rootType); + + void delete(); + + @NotNull + JpsLibraryReference createReference(JpsParentElement parent); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryListener.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryListener.java new file mode 100644 index 000000000000..050544c1d010 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryListener.java @@ -0,0 +1,13 @@ +package org.jetbrains.jps.model.library; + +import org.jetbrains.annotations.NotNull; + +import java.util.EventListener; + +/** + * @author nik + */ +public interface JpsLibraryListener extends EventListener { + void libraryAdded(@NotNull JpsLibrary library); + void libraryRemoved(@NotNull JpsLibrary library); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryReference.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryReference.java new file mode 100644 index 000000000000..c752520a13fd --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryReference.java @@ -0,0 +1,12 @@ +package org.jetbrains.jps.model.library; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementReference; + +/** + * @author nik + */ +public interface JpsLibraryReference extends JpsElementReference { + @NotNull + String getLibraryName(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRoot.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRoot.java new file mode 100644 index 000000000000..49254236d441 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRoot.java @@ -0,0 +1,18 @@ +package org.jetbrains.jps.model.library; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElement; + +/** + * @author nik + */ +public interface JpsLibraryRoot extends JpsElement { + @NotNull + JpsLibraryRootType getRootType(); + + @NotNull + String getUrl(); + + @NotNull + JpsLibrary getLibrary(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRootListener.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRootListener.java new file mode 100644 index 000000000000..1ef06776865e --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRootListener.java @@ -0,0 +1,13 @@ +package org.jetbrains.jps.model.library; + +import org.jetbrains.annotations.NotNull; + +import java.util.EventListener; + +/** + * @author nik + */ +public interface JpsLibraryRootListener extends EventListener { + void rootAdded(@NotNull JpsLibraryRoot root); + void rootRemoved(@NotNull JpsLibraryRoot root); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRootType.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRootType.java new file mode 100644 index 000000000000..70afc3f5e8ee --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRootType.java @@ -0,0 +1,24 @@ +package org.jetbrains.jps.model.library; + +/** + * @author nik + */ +public class JpsLibraryRootType { + public static final JpsLibraryRootType COMPILED = new JpsLibraryRootType(JpsOrderRootType.COMPILED, false); + public static final JpsLibraryRootType SOURCES = new JpsLibraryRootType(JpsOrderRootType.SOURCES, false); + private final boolean myJarDirectory; + private final JpsOrderRootType myType; + + public JpsLibraryRootType(JpsOrderRootType type, boolean jarDirectory) { + myType = type; + myJarDirectory = jarDirectory; + } + + public boolean isJarDirectory() { + return myJarDirectory; + } + + public JpsOrderRootType getType() { + return myType; + } +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryType.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryType.java new file mode 100644 index 000000000000..e569468d37c1 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryType.java @@ -0,0 +1,10 @@ +package org.jetbrains.jps.model.library; + +import org.jetbrains.jps.model.JpsElementProperties; +import org.jetbrains.jps.model.JpsElementType; + +/** + * @author nik + */ +public abstract class JpsLibraryType

extends JpsElementType

{ +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsOrderRootType.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsOrderRootType.java new file mode 100644 index 000000000000..78f3ff44f0d0 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsOrderRootType.java @@ -0,0 +1,13 @@ +package org.jetbrains.jps.model.library; + +/** + * @author nik + */ +public abstract class JpsOrderRootType { + public static final JpsOrderRootType COMPILED = new JpsOrderRootType() { + }; + public static final JpsOrderRootType SOURCES = new JpsOrderRootType() { + }; + public static final JpsOrderRootType DOCUMENTATION = new JpsOrderRootType() { + }; +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsSdkType.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsSdkType.java new file mode 100644 index 000000000000..33bfd2836b1b --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsSdkType.java @@ -0,0 +1,9 @@ +package org.jetbrains.jps.model.library; + +import org.jetbrains.jps.model.JpsElementProperties; + +/** + * @author nik + */ +public abstract class JpsSdkType

extends JpsLibraryType

{ +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsDependenciesList.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsDependenciesList.java new file mode 100644 index 000000000000..4954e81f6e5b --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsDependenciesList.java @@ -0,0 +1,26 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsSdkType; + +import java.util.List; + +/** + * @author nik + */ +public interface JpsDependenciesList extends JpsElement { + @NotNull + JpsModuleDependency addModuleDependency(@NotNull JpsModule module); + + @NotNull + JpsLibraryDependency addLibraryDependency(@NotNull JpsLibrary libraryElement); + + void addModuleSourceDependency(); + + void addSdkDependency(@NotNull JpsSdkType sdkType); + + @NotNull + List getDependencies(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsDependencyElement.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsDependencyElement.java new file mode 100644 index 000000000000..7f118262731a --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsDependencyElement.java @@ -0,0 +1,10 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.jps.model.JpsElement; + +/** + * @author nik + */ +public interface JpsDependencyElement extends JpsElement { + void remove(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsLibraryDependency.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsLibraryDependency.java new file mode 100644 index 000000000000..d6b9c9773c4f --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsLibraryDependency.java @@ -0,0 +1,12 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.library.JpsLibraryReference; + +/** + * @author nik + */ +public interface JpsLibraryDependency extends JpsDependencyElement { + @NotNull + JpsLibraryReference getLibraryReference(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java new file mode 100644 index 000000000000..4226ad8f7850 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java @@ -0,0 +1,44 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +import java.util.List; + +/** + * @author nik + */ +public interface JpsModule extends JpsNamedElement, JpsReferenceableElement { + @NotNull + JpsUrlList getContentRootsList(); + + @NotNull + JpsUrlList getExcludeRootsList(); + + + @NotNull + List getSourceRoots(); + + @NotNull +

+ JpsModuleSourceRoot addSourceRoot(@NotNull JpsModuleSourceRootType

rootType, @NotNull String url); + + @NotNull +

+ JpsModuleSourceRoot addSourceRoot(@NotNull JpsModuleSourceRootType

rootType, @NotNull String url, @NotNull P properties); + + void removeSourceRoot(@NotNull JpsModuleSourceRootType rootType, @NotNull String url); + + JpsDependenciesList getDependenciesList(); + + @NotNull + JpsElementContainer getContainer(); + + @NotNull + JpsModuleReference createReference(JpsParentElement parent); + + void delete(); + + @NotNull + JpsSdkReferencesTable getSdkReferencesTable(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleContentRootsListener.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleContentRootsListener.java new file mode 100644 index 000000000000..28320c8fe5ef --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleContentRootsListener.java @@ -0,0 +1,9 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.jps.model.JpsUrlListChangeListener; + +/** + * @author nik + */ +public interface JpsModuleContentRootsListener extends JpsUrlListChangeListener { +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleDependency.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleDependency.java new file mode 100644 index 000000000000..88d707794ec4 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleDependency.java @@ -0,0 +1,11 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface JpsModuleDependency extends JpsDependencyElement { + @NotNull + JpsModuleReference getModuleReference(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleExcludeRootsListener.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleExcludeRootsListener.java new file mode 100644 index 000000000000..50b70a795913 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleExcludeRootsListener.java @@ -0,0 +1,9 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.jps.model.JpsUrlListChangeListener; + +/** + * @author nik + */ +public interface JpsModuleExcludeRootsListener extends JpsUrlListChangeListener { +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleListener.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleListener.java new file mode 100644 index 000000000000..73d20ad51fdd --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleListener.java @@ -0,0 +1,14 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.module.JpsModule; + +import java.util.EventListener; + +/** + * @author nik + */ +public interface JpsModuleListener extends EventListener { + void moduleAdded(@NotNull JpsModule module); + void moduleRemoved(@NotNull JpsModule module); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleReference.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleReference.java new file mode 100644 index 000000000000..90a35bf07ec3 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleReference.java @@ -0,0 +1,12 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementReference; + +/** + * @author nik + */ +public interface JpsModuleReference extends JpsElementReference { + @NotNull + String getModuleName(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRoot.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRoot.java new file mode 100644 index 000000000000..36eb82c2c607 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRoot.java @@ -0,0 +1,23 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.JpsElementProperties; + +/** + * @author nik + */ +public interface JpsModuleSourceRoot extends JpsElement { + @NotNull + JpsModuleSourceRootType getRootType(); + + @Nullable +

P getProperties(@NotNull JpsModuleSourceRootType

type); + +

+ void setProperties(JpsModuleSourceRootType

type, P properties); + + @NotNull + String getUrl(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootListener.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootListener.java new file mode 100644 index 000000000000..9b1ef089315a --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootListener.java @@ -0,0 +1,14 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.annotations.NotNull; + +import java.util.EventListener; + +/** + * @author nik + */ +public interface JpsModuleSourceRootListener extends EventListener { + void sourceRootAdded(@NotNull JpsModuleSourceRoot root); + void sourceRootRemoved(@NotNull JpsModuleSourceRoot root); + void sourceRootChanged(@NotNull JpsModuleSourceRoot root); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootType.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootType.java new file mode 100644 index 000000000000..2d5a01706f83 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceRootType.java @@ -0,0 +1,10 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.jps.model.JpsElementProperties; +import org.jetbrains.jps.model.JpsElementType; + +/** + * @author nik + */ +public abstract class JpsModuleSourceRootType

extends JpsElementType

{ +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleType.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleType.java new file mode 100644 index 000000000000..a5e720b73b0a --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleType.java @@ -0,0 +1,11 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.jps.model.JpsElementProperties; +import org.jetbrains.jps.model.JpsElementType; + +/** + * @author nik + */ +public abstract class JpsModuleType

extends JpsElementType

{ + +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsSdkDependency.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsSdkDependency.java new file mode 100644 index 000000000000..934b98c930c7 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsSdkDependency.java @@ -0,0 +1,17 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsSdkType; + +/** + * @author nik + */ +public interface JpsSdkDependency extends JpsDependencyElement { + @NotNull + JpsSdkType getSdkType(); + + @Nullable + JpsLibrary resolveSdk(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsSdkReferencesTable.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsSdkReferencesTable.java new file mode 100644 index 000000000000..cf0a081869a9 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsSdkReferencesTable.java @@ -0,0 +1,18 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsCompositeElement; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.model.library.JpsSdkType; + +/** + * @author nik + */ +public interface JpsSdkReferencesTable extends JpsCompositeElement { + @Nullable + JpsLibraryReference getSdkReference(@NotNull JpsSdkType type); + + void setSdkReference(@NotNull JpsSdkType type, @NotNull JpsLibrary sdk); +} diff --git a/jps/model-impl/jps-model-impl.iml b/jps/model-impl/jps-model-impl.iml new file mode 100644 index 000000000000..4a17b3a41db1 --- /dev/null +++ b/jps/model-impl/jps-model-impl.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsCompositeElementBase.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsCompositeElementBase.java new file mode 100644 index 000000000000..c1b38364d791 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsCompositeElementBase.java @@ -0,0 +1,35 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +/** + * @author nik + */ +public abstract class JpsCompositeElementBase> extends JpsElementBase implements JpsCompositeElement { + protected final JpsElementContainerImpl myContainer; + protected final JpsModel myModel; + + protected JpsCompositeElementBase(JpsModel model, JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(eventDispatcher, parent); + myModel = model; + myContainer = new JpsElementContainerImpl(model, eventDispatcher, this); + } + + protected JpsCompositeElementBase(JpsCompositeElementBase original, JpsModel model, JpsEventDispatcher dispatcher, + JpsParentElement parent) { + super(original, dispatcher, parent); + myModel = model; + myContainer = new JpsElementContainerImpl(original.myContainer, model, dispatcher, this); + } + + public void applyChanges(@NotNull Self element) { + myContainer.applyChanges(element.myContainer); + } + + @Override + @NotNull + public JpsElementContainerImpl getContainer() { + return myContainer; + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementBase.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementBase.java new file mode 100644 index 000000000000..12c982d8f708 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementBase.java @@ -0,0 +1,41 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +/** + * @author nik + */ +public abstract class JpsElementBase> implements JpsElement, JpsElement.BulkModificationSupport { + private JpsEventDispatcher myEventDispatcher; + protected JpsParentElement myParent; + + protected JpsElementBase(JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + myEventDispatcher = eventDispatcher; + myParent = parent; + } + + public JpsElementBase(JpsElementBase original, JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + myEventDispatcher = eventDispatcher; + myParent = parent; + } + + protected JpsEventDispatcher getEventDispatcher() { + return myEventDispatcher; + } + + @NotNull + @Override + public BulkModificationSupport getBulkModificationSupport() { + return this; + } + + @NotNull + public abstract Self createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent); + + public abstract void applyChanges(@NotNull Self modified); + + public JpsParentElement getParent() { + return myParent; + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementCollectionImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementCollectionImpl.java new file mode 100644 index 000000000000..3afa780758c9 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementCollectionImpl.java @@ -0,0 +1,107 @@ +package org.jetbrains.jps.model.impl; + +import com.intellij.util.SmartList; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +import java.util.*; + +/** + * @author nik + */ +public class JpsElementCollectionImpl extends JpsElementBase> implements JpsElementCollection { + private final List myElements; + private final JpsModel myModel; + private final Map myCopyToOriginal; + private final JpsElementKind myKind; + + public JpsElementCollectionImpl(JpsElementKind kind, JpsModel model, JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(eventDispatcher, parent); + myKind = kind; + myModel = model; + myElements = new SmartList(); + myCopyToOriginal = null; + } + + public JpsElementCollectionImpl(JpsElementCollectionImpl original, + JpsModel model, + JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + super(original, eventDispatcher, parent); + myKind = original.myKind; + myModel = model; + myElements = new SmartList(); + myCopyToOriginal = new HashMap(); + for (E e : original.myElements) { + //noinspection unchecked + final E copy = (E)e.getBulkModificationSupport().createCopy(model, eventDispatcher, parent); + myElements.add(copy); + myCopyToOriginal.put(copy, e); + } + } + + @Override + public List getElements() { + return myElements; + } + + @NotNull + @Override + public

E addChild(@NotNull JpsElementFactoryWithParameter factory, @NotNull P param) { + return addChild(factory.create(myModel, getEventDispatcher(), myParent, param)); + } + + @NotNull + @Override + public E addChild(@NotNull JpsElementFactory factory) { + return addChild(factory.create(myModel, getEventDispatcher(), myParent)); + } + + @Override + public E addChild(E element) { + myElements.add(element); + getEventDispatcher().fireElementAdded(element, myKind); + return element; + } + + @Override + public void removeChild(@NotNull E element) { + final boolean removed = myElements.remove(element); + if (removed) { + getEventDispatcher().fireElementRemoved(element, myKind); + } + } + + @NotNull + @Override + public JpsElementCollectionImpl createCopy(@NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + return new JpsElementCollectionImpl(this, model, eventDispatcher, parent); + } + + public void applyChanges(@NotNull JpsElementCollectionImpl modified) { + Set toRemove = new LinkedHashSet(myElements); + List toAdd = new ArrayList(); + final Map copyToOriginal = modified.myCopyToOriginal; + for (E element : modified.myElements) { + final E original = copyToOriginal != null ? copyToOriginal.get(element) : null; + if (original != null) { + //noinspection unchecked + ((BulkModificationSupport)original.getBulkModificationSupport()).applyChanges(element); + toRemove.remove(original); + } + else { + //noinspection unchecked + final E copy = (E)element.getBulkModificationSupport().createCopy(myModel, getEventDispatcher(), myParent); + toAdd.add(copy); + } + } + for (E e : toRemove) { + removeChild(e); + } + for (E e : toAdd) { + addChild(e); + } + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementCollectionKind.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementCollectionKind.java new file mode 100644 index 000000000000..89ec021e072c --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementCollectionKind.java @@ -0,0 +1,24 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +/** + * @author nik + */ +public class JpsElementCollectionKind extends JpsElementKind> + implements JpsElementFactory> { + private final JpsElementKind myElementKind; + + public JpsElementCollectionKind(JpsElementKind elementKind) { + myElementKind = elementKind; + } + + @NotNull + @Override + public JpsElementCollectionImpl create(@NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + return new JpsElementCollectionImpl(myElementKind, model, eventDispatcher, parent); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementContainerImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementContainerImpl.java new file mode 100644 index 000000000000..a231add0dd96 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementContainerImpl.java @@ -0,0 +1,98 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author nik + */ +public class JpsElementContainerImpl implements JpsElementContainer { + private final Map, JpsElement> myElements = new HashMap, JpsElement>(); + private final @NotNull JpsModel myModel; + private final @NotNull JpsEventDispatcher myEventDispatcher; + private final @NotNull JpsParentElement myParent; + + public JpsElementContainerImpl(@NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + myModel = model; + myEventDispatcher = eventDispatcher; + myParent = parent; + } + + public JpsElementContainerImpl(@NotNull JpsElementContainerImpl original, @NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + myModel = model; + myEventDispatcher = eventDispatcher; + myParent = parent; + for (Map.Entry, JpsElement> entry : original.myElements.entrySet()) { + final JpsElementKind kind = entry.getKey(); + myElements.put(kind, entry.getValue().getBulkModificationSupport().createCopy(myModel, myEventDispatcher, myParent)); + } + } + + @Override + public T getChild(@NotNull JpsElementKind kind) { + //noinspection unchecked + return (T)myElements.get(kind); + } + + @NotNull + @Override + public & JpsElementFactoryWithParameter> T setChild(@NotNull K kind, + @NotNull P param) { + final T child = kind.create(myModel, myEventDispatcher, myParent, param); + return setChild(kind, child); + } + + @NotNull + @Override + public & JpsElementFactory> T setChild(@NotNull K kind) { + final T child = kind.create(myModel, myEventDispatcher, myParent); + return setChild(kind, child); + } + + @Override + public T setChild(JpsElementKind kind, T child) { + myElements.put(kind, child); + myEventDispatcher.fireElementAdded(child, kind); + return child; + } + + @Override + public void removeChild(@NotNull JpsElementKind kind) { + //noinspection unchecked + final T removed = (T)myElements.remove(kind); + myEventDispatcher.fireElementRemoved(removed, kind); + } + + public void applyChanges(@NotNull JpsElementContainerImpl modified) { + for (JpsElementKind kind : myElements.keySet()) { + applyChanges(kind, modified); + } + for (JpsElementKind kind : modified.myElements.keySet()) { + if (!myElements.containsKey(kind)) { + applyChanges(kind, modified); + } + } + } + + private void applyChanges(JpsElementKind kind, JpsElementContainerImpl modified) { + final T child = getChild(kind); + final T modifiedChild = modified.getChild(kind); + if (child != null && modifiedChild != null) { + final JpsElement.BulkModificationSupport modificationSupport = child.getBulkModificationSupport(); + //noinspection unchecked + modificationSupport.applyChanges(modifiedChild); + } + else if (modifiedChild == null) { + removeChild(kind); + } + else { + //noinspection unchecked + setChild(kind, (T)modifiedChild.getBulkModificationSupport().createCopy(myModel, myEventDispatcher, myParent)); + } + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsEventDispatcherBase.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsEventDispatcherBase.java new file mode 100644 index 000000000000..07691513f775 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsEventDispatcherBase.java @@ -0,0 +1,40 @@ +package org.jetbrains.jps.model.impl; + +import com.intellij.util.EventDispatcher; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.JpsEventDispatcher; + +import java.util.EventListener; +import java.util.HashMap; +import java.util.Map; + +/** + * @author nik + */ +public abstract class JpsEventDispatcherBase implements JpsEventDispatcher { + private Map, EventDispatcher> myDispatchers = new HashMap, EventDispatcher>(); + + @NotNull + @Override + public T getPublisher(Class listenerClass) { + EventDispatcher dispatcher = myDispatchers.get(listenerClass); + if (dispatcher == null) { + dispatcher = EventDispatcher.create(listenerClass); + myDispatchers.put(listenerClass, dispatcher); + } + //noinspection unchecked + return (T)dispatcher.getMulticaster(); + } + + @Override + public void fireElementAdded(@NotNull T element, @NotNull JpsElementKind kind) { + kind.fireElementAdded(this, element); + } + + @Override + public void fireElementRemoved(@NotNull T element, @NotNull JpsElementKind kind) { + kind.fireElementRemoved(this, element); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalElementReference.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalElementReference.java new file mode 100644 index 000000000000..4e245d5dcf98 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalElementReference.java @@ -0,0 +1,33 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +/** + * @author nik + */ +public class JpsGlobalElementReference extends JpsElementBase implements JpsElementReference { + private final JpsModel myModel; + + public JpsGlobalElementReference(JpsModel model, JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(eventDispatcher, parent); + myModel = model; + } + + @Override + public JpsGlobal resolve() { + return myModel.getGlobal(); + } + + @NotNull + @Override + public JpsGlobalElementReference createCopy(@NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + return new JpsGlobalElementReference(model, eventDispatcher, parent); + } + + @Override + public void applyChanges(@NotNull JpsGlobalElementReference modified) { + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java new file mode 100644 index 000000000000..b6cbe9e08d04 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java @@ -0,0 +1,41 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryType; +import org.jetbrains.jps.model.library.impl.JpsLibraryImpl; +import org.jetbrains.jps.model.library.impl.JpsLibraryKind; + +/** + * @author nik + */ +public class JpsGlobalImpl extends JpsCompositeElementBase implements JpsGlobal { + public JpsGlobalImpl(JpsModel model, JpsEventDispatcher eventDispatcher) { + super(model, eventDispatcher, null); + myContainer.setChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); + } + + public JpsGlobalImpl(JpsGlobalImpl original, JpsModel model, JpsEventDispatcher eventDispatcher) { + super(original, model, eventDispatcher, null); + } + + @NotNull + @Override + public JpsGlobalImpl createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JpsGlobalImpl(this, model, eventDispatcher); + } + + @NotNull + @Override + public JpsLibrary addLibrary(@NotNull JpsLibraryType libraryType, @NotNull final String name) { + final JpsElementCollectionImpl collection = myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); + return collection.addChild(new JpsLibraryImpl(name, libraryType, myModel, getEventDispatcher(), collection)); + } + + @NotNull + @Override + public JpsElementReference createReference(JpsParentElement parent) { + return new JpsGlobalElementReference(myModel, getEventDispatcher(), parent); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsModelImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsModelImpl.java new file mode 100644 index 000000000000..ae6b7f4d1f8c --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsModelImpl.java @@ -0,0 +1,51 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsModel; + +/** + * @author nik + */ +public class JpsModelImpl implements JpsModel { + private JpsProjectImpl myProject; + private JpsGlobalImpl myGlobal; + private JpsModelImpl myOriginalModel; + + public JpsModelImpl(JpsEventDispatcher eventDispatcher) { + myProject = new JpsProjectImpl(this, eventDispatcher); + myGlobal = new JpsGlobalImpl(this, eventDispatcher); + } + + private JpsModelImpl(JpsModelImpl original, JpsEventDispatcher eventDispatcher) { + myOriginalModel = original; + myProject = new JpsProjectImpl(original.myProject, this, eventDispatcher); + myGlobal = new JpsGlobalImpl(original.myGlobal, this, eventDispatcher); + } + + @NotNull + public JpsProjectImpl getProject() { + return myProject; + } + + @NotNull + public JpsGlobalImpl getGlobal() { + return myGlobal; + } + + @NotNull + @Override + public JpsModel createModifiableModel(@NotNull JpsEventDispatcher eventDispatcher) { + return new JpsModelImpl(this, eventDispatcher); + } + + @Override + public void commit() { + myOriginalModel.applyChanges(this); + } + + private void applyChanges(@NotNull JpsModelImpl modifiedCopy) { + myProject.applyChanges(modifiedCopy.myProject); + myGlobal.applyChanges(modifiedCopy.myGlobal); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedCompositeElementBase.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedCompositeElementBase.java new file mode 100644 index 000000000000..e05473c5fab1 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedCompositeElementBase.java @@ -0,0 +1,47 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +/** + * @author nik + */ +public abstract class JpsNamedCompositeElementBase, Parent extends JpsCompositeElementBase> extends + JpsCompositeElementBase + implements JpsNamedElement { + private String myName; + + protected JpsNamedCompositeElementBase(JpsModel model, + JpsEventDispatcher eventDispatcher, + @NotNull String name, JpsParentElement parent) { + super(model, eventDispatcher, parent); + myName = name; + } + + protected JpsNamedCompositeElementBase(JpsNamedCompositeElementBase original, + JpsModel model, + JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(original, model, eventDispatcher, parent); + myName = original.myName; + } + + @NotNull + @Override + public String getName() { + return myName; + } + + public void applyChanges(@NotNull Self modified) { + super.applyChanges(modified); + setName(modified.getName()); + } + + @Override + public void setName(@NotNull String name) { + if (!myName.equals(name)) { + String oldName = myName; + myName = name; + getEventDispatcher().fireElementRenamed(this, oldName, name); + } + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java new file mode 100644 index 000000000000..9e083cf5a66b --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java @@ -0,0 +1,45 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +import java.util.List; + +/** + * @author nik + */ +public abstract class JpsNamedElementReferenceBase> extends JpsCompositeElementBase implements JpsElementReference { + private static final JpsElementKind> PARENT_REFERENCE_KIND = new JpsElementKind>(); + private final JpsElementCollectionKind myCollectionKind; + protected final String myElementName; + + protected JpsNamedElementReferenceBase(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, @NotNull JpsElementCollectionKind kind, @NotNull String elementName, + @NotNull JpsElementReference parentReference, JpsParentElement parent) { + super(model, eventDispatcher, parent); + myCollectionKind = kind; + myElementName = elementName; + myContainer.setChild(PARENT_REFERENCE_KIND, parentReference); + } + + protected JpsNamedElementReferenceBase(JpsNamedElementReferenceBase original, + JpsModel model, JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + super(original, model, eventDispatcher, parent); + myCollectionKind = original.myCollectionKind; + myElementName = original.myElementName; + } + + @Override + public T resolve() { + final JpsCompositeElement parent = myContainer.getChild(PARENT_REFERENCE_KIND).resolve(); + if (parent == null) return null; + + final List elements = parent.getContainer().getChild(myCollectionKind).getElements(); + for (T element : elements) { + if (element.getName().equals(myElementName)) { + return element; + } + } + return null; + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectElementReference.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectElementReference.java new file mode 100644 index 000000000000..1206aca4f6f7 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectElementReference.java @@ -0,0 +1,33 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +/** + * @author nik + */ +public class JpsProjectElementReference extends JpsElementBase implements JpsElementReference { + private final JpsModel myModel; + + public JpsProjectElementReference(JpsModel model, JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(eventDispatcher, parent); + myModel = model; + } + + @Override + public JpsProject resolve() { + return myModel.getProject(); + } + + @NotNull + @Override + public JpsProjectElementReference createCopy(@NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + return new JpsProjectElementReference(model, eventDispatcher, parent); + } + + @Override + public void applyChanges(@NotNull JpsProjectElementReference modified) { + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java new file mode 100644 index 000000000000..006be0cfa53e --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java @@ -0,0 +1,67 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryType; +import org.jetbrains.jps.model.library.impl.JpsLibraryImpl; +import org.jetbrains.jps.model.library.impl.JpsLibraryKind; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleType; +import org.jetbrains.jps.model.module.impl.JpsModuleImpl; +import org.jetbrains.jps.model.module.impl.JpsModuleKind; + +import java.util.List; + +/** + * @author nik + */ +public class JpsProjectImpl extends JpsCompositeElementBase implements JpsProject { + public JpsProjectImpl(JpsModel model, JpsEventDispatcher eventDispatcher) { + super(model, eventDispatcher, null); + myContainer.setChild(JpsModuleKind.MODULE_COLLECTION_KIND); + myContainer.setChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); + } + + public JpsProjectImpl(JpsProjectImpl original, JpsModel model, JpsEventDispatcher eventDispatcher) { + super(original, model, eventDispatcher, null); + } + + @NotNull + @Override + public JpsModule addModule(@NotNull JpsModuleType moduleType, @NotNull final String name) { + final JpsElementCollectionImpl collection = myContainer.getChild(JpsModuleKind.MODULE_COLLECTION_KIND); + return collection.addChild(new JpsModuleImpl(myModel, getEventDispatcher(), moduleType, name, collection)); + } + + @NotNull + @Override + public JpsLibrary addLibrary(@NotNull JpsLibraryType libraryType, @NotNull final String name) { + final JpsElementCollectionImpl collection = myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); + return collection.addChild(new JpsLibraryImpl(name, libraryType, myModel, getEventDispatcher(), collection)); + } + + @NotNull + @Override + public List getLibraries() { + return myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND).getElements(); + } + + @NotNull + @Override + public List getModules() { + return myContainer.getChild(JpsModuleKind.MODULE_COLLECTION_KIND).getElements(); + } + + @NotNull + @Override + public JpsElementReference createReference(JpsParentElement parent) { + return new JpsProjectElementReference(myModel, getEventDispatcher(), parent); + } + + @NotNull + @Override + public JpsProjectImpl createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JpsProjectImpl(this, model, eventDispatcher); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsTypedDataImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsTypedDataImpl.java new file mode 100644 index 000000000000..d09808d00015 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsTypedDataImpl.java @@ -0,0 +1,66 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.*; + +/** + * @author nik + */ +public class JpsTypedDataImpl> extends JpsElementBase> { + private final T myType; + private JpsElementProperties myProperties; + + public JpsTypedDataImpl(T type, JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(eventDispatcher, parent); + myType = type; + myProperties = type.createDefaultProperties(); + } + + public JpsTypedDataImpl(JpsTypedDataImpl original, + JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(original, eventDispatcher, parent); + myType = original.getType(); + final JpsElementType type = original.getType(); + myProperties = createCopy(type, original.myProperties); + } + + @Nullable + public

P getProperties(JpsElementType

type) { + //noinspection unchecked + return myType.equals(type) ? (P)myProperties : null; + } + + private static

P createCopy(final JpsElementType

type, + final JpsElementProperties properties) { + //noinspection unchecked + return type.createCopy((P)properties); + } + + @NotNull + public T getType() { + return myType; + } + + @NotNull + @Override + public JpsTypedDataImpl createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JpsTypedDataImpl(this, eventDispatcher, parent); + } + + @NotNull + public JpsElementProperties getProperties() { + return myProperties; + } + + public void setProperties(@NotNull JpsElementProperties properties) { + if (!myProperties.equals(properties)) { + myProperties = properties; + getEventDispatcher().fireElementChanged(this); + } + } + + public void applyChanges(@NotNull JpsTypedDataImpl data) { + setProperties(data.getProperties()); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsTypedDataKind.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsTypedDataKind.java new file mode 100644 index 000000000000..16805bb40611 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsTypedDataKind.java @@ -0,0 +1,10 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.JpsElementType; + +/** + * @author nik + */ +public class JpsTypedDataKind> extends JpsElementKind> { +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsUrlListImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsUrlListImpl.java new file mode 100644 index 000000000000..5d1ac3ac2ee4 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsUrlListImpl.java @@ -0,0 +1,55 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author nik + */ +public class JpsUrlListImpl extends JpsElementBase implements JpsUrlList { + private List myUrls = new ArrayList(); + + public JpsUrlListImpl(JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(eventDispatcher, parent); + } + + public JpsUrlListImpl(JpsUrlListImpl list, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(list, dispatcher, parent); + myUrls.addAll(list.myUrls); + } + + @NotNull + @Override + public JpsUrlListImpl createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JpsUrlListImpl(this, eventDispatcher, parent); + } + + @NotNull + @Override + public List getUrls() { + return myUrls; + } + + @Override + public void addUrl(@NotNull String url) { + myUrls.add(url); + getEventDispatcher().fireElementChanged(this); + } + + @Override + public void removeUrl(@NotNull String url) { + myUrls.remove(url); + getEventDispatcher().fireElementChanged(this); + } + + public void applyChanges(@NotNull JpsUrlListImpl modified) { + if (!myUrls.equals(modified.myUrls)) { + myUrls.clear(); + myUrls.addAll(modified.myUrls); + getEventDispatcher().fireElementChanged(this); + } + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/SimpleJpsElementImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/SimpleJpsElementImpl.java new file mode 100644 index 000000000000..d60dd07afb8c --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/SimpleJpsElementImpl.java @@ -0,0 +1,45 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; + +/** + * @author nik + */ +public class SimpleJpsElementImpl

extends JpsElementBase> implements SimpleJpsElement

{ + private P myProperties; + + public SimpleJpsElementImpl(JpsEventDispatcher eventDispatcher, P properties, JpsParentElement parent) { + super(eventDispatcher, parent); + myProperties = properties; + } + + public SimpleJpsElementImpl(SimpleJpsElementImpl

original, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(original, dispatcher, parent); + } + + @NotNull + @Override + public P getProperties() { + return myProperties; + } + + @Override + public void setProperties(@NotNull P properties) { + if (!myProperties.equals(properties)) { + myProperties = properties; + getEventDispatcher().fireElementChanged(this); + } + } + + @NotNull + @Override + public SimpleJpsElementImpl

createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new SimpleJpsElementImpl

(this, eventDispatcher, parent); + } + + @Override + public void applyChanges(@NotNull SimpleJpsElementImpl

modified) { + setProperties(modified.getProperties()); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/SimpleJpsElementKind.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/SimpleJpsElementKind.java new file mode 100644 index 000000000000..9e670f918f04 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/SimpleJpsElementKind.java @@ -0,0 +1,11 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.JpsElementProperties; + +/** + * @author nik + */ +public class SimpleJpsElementKind

> extends + JpsElementKind> { +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionImpl.java new file mode 100644 index 000000000000..ff5dce87d4e1 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionImpl.java @@ -0,0 +1,81 @@ +package org.jetbrains.jps.model.java.impl; + +import com.intellij.openapi.util.Comparing; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.JpsParentElement; +import org.jetbrains.jps.model.impl.JpsElementBase; +import org.jetbrains.jps.model.java.JavaModuleExtension; +import org.jetbrains.jps.model.java.LanguageLevel; + +/** + * @author nik + */ +public class JavaModuleExtensionImpl extends JpsElementBase implements JavaModuleExtension { + private String myOutputUrl; + private String myTestOutputUrl; + private LanguageLevel myLanguageLevel; + + public JavaModuleExtensionImpl(JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(eventDispatcher, parent); + } + + public JavaModuleExtensionImpl(JavaModuleExtensionImpl original, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(original, dispatcher, parent); + myOutputUrl = original.myOutputUrl; + myTestOutputUrl = original.myTestOutputUrl; + myLanguageLevel = original.myLanguageLevel; + } + + @NotNull + @Override + public JavaModuleExtensionImpl createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JavaModuleExtensionImpl(this, eventDispatcher, parent); + } + + @Override + public String getOutputUrl() { + return myOutputUrl; + } + + @Override + public void setOutputUrl(String outputUrl) { + if (!Comparing.equal(myOutputUrl, outputUrl)) { + myOutputUrl = outputUrl; + getEventDispatcher().fireElementChanged(this); + } + } + + @Override + public String getTestOutputUrl() { + return myTestOutputUrl; + } + + @Override + public void setTestOutputUrl(String testOutputUrl) { + if (!Comparing.equal(myTestOutputUrl, testOutputUrl)) { + myTestOutputUrl = testOutputUrl; + getEventDispatcher().fireElementChanged(this); + } + } + + @Override + public LanguageLevel getLanguageLevel() { + return myLanguageLevel; + } + + @Override + public void setLanguageLevel(LanguageLevel languageLevel) { + if (!Comparing.equal(myLanguageLevel, languageLevel)) { + myLanguageLevel = languageLevel; + getEventDispatcher().fireElementChanged(this); + } + } + + public void applyChanges(@NotNull JavaModuleExtensionImpl modified) { + setLanguageLevel(modified.myLanguageLevel); + setOutputUrl(modified.myOutputUrl); + setTestOutputUrl(modified.myTestOutputUrl); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionKind.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionKind.java new file mode 100644 index 000000000000..0a62da133950 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionKind.java @@ -0,0 +1,28 @@ +package org.jetbrains.jps.model.java.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.java.JavaModuleExtension; +import org.jetbrains.jps.model.module.JpsModule; + +/** + * @author nik + */ +public class JavaModuleExtensionKind extends JpsElementKind implements JpsElementFactory { + public static final JavaModuleExtensionKind INSTANCE = new JavaModuleExtensionKind(); + + @NotNull + @Override + public JavaModuleExtensionImpl create(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JavaModuleExtensionImpl(eventDispatcher, parent); + } + + @NotNull + public static JavaModuleExtension getExtension(@NotNull JpsModule module) { + JavaModuleExtension child = module.getContainer().getChild(INSTANCE); + if (child == null) { + child = module.getContainer().setChild(INSTANCE); + } + return child; + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java new file mode 100644 index 000000000000..541d81b64667 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java @@ -0,0 +1,87 @@ +package org.jetbrains.jps.model.library.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.impl.*; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.model.library.JpsLibraryRootType; +import org.jetbrains.jps.model.library.JpsLibraryType; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author nik + */ +public class JpsLibraryImpl extends JpsNamedCompositeElementBase implements JpsLibrary { + private static final JpsElementCollectionKind LIBRARY_ROOTS_COLLECTION = new JpsElementCollectionKind(JpsLibraryRootKind.INSTANCE); + private static final JpsTypedDataKind> TYPED_DATA_KIND = new JpsTypedDataKind>(); + + public JpsLibraryImpl(@NotNull String name, @NotNull JpsLibraryType type, @NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, JpsElementCollection parent) { + super(model, eventDispatcher, name, parent); + myContainer.setChild(TYPED_DATA_KIND, new JpsTypedDataImpl>(type, eventDispatcher, this)); + myContainer.setChild(LIBRARY_ROOTS_COLLECTION); + } + + public JpsLibraryImpl(@NotNull JpsLibraryImpl original, JpsModel model, JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(original, model, eventDispatcher, parent); + } + + @NotNull + @Override + public List getUrls(@NotNull JpsLibraryRootType rootType) { + final List urls = new ArrayList(); + for (JpsLibraryRootImpl root : getRootsCollection().getElements()) { + if (root.getRootType().equals(rootType)) { + urls.add(root.getUrl()); + } + } + return urls; + } + + @Override + public void addUrl(@NotNull final String url, @NotNull final JpsLibraryRootType rootType) { + getRootsCollection().addChild(new JpsLibraryRootImpl(getEventDispatcher(), url, rootType, this)); + } + + private JpsElementCollectionImpl getRootsCollection() { + return myContainer.getChild(LIBRARY_ROOTS_COLLECTION); + } + + @Override + public void removeUrl(@NotNull final String url, @NotNull final JpsLibraryRootType rootType) { + final JpsElementCollectionImpl rootsCollection = getRootsCollection(); + for (JpsLibraryRootImpl root : rootsCollection.getElements()) { + if (root.getUrl().equals(url) && root.getRootType().equals(rootType)) { + rootsCollection.removeChild(root); + break; + } + } + } + + @Override + public void delete() { + getParent().removeChild(this); + } + + public JpsElementCollectionImpl getParent() { + //noinspection unchecked + return (JpsElementCollectionImpl)myParent; + } + + @NotNull + @Override + public JpsLibraryImpl createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JpsLibraryImpl(this, model, eventDispatcher, parent); + } + + @NotNull + @Override + public JpsLibraryReference createReference(JpsParentElement parent) { + //noinspection unchecked + final JpsElementReference parentReference = ((JpsReferenceableElement)getParent().getParent()).createReference(parent); + return new JpsLibraryReferenceImpl(myModel, getEventDispatcher(), getName(), parentReference, parent); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryKind.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryKind.java new file mode 100644 index 000000000000..834ada9984fb --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryKind.java @@ -0,0 +1,28 @@ +package org.jetbrains.jps.model.library.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.impl.JpsElementCollectionKind; +import org.jetbrains.jps.model.library.JpsLibraryListener; + +/** + * @author nik + */ +public class JpsLibraryKind extends JpsElementKind { + public static final JpsLibraryKind INSTANCE = new JpsLibraryKind(); + public static final JpsElementCollectionKind LIBRARIES_COLLECTION_KIND = new JpsElementCollectionKind(INSTANCE); + + private JpsLibraryKind() { + } + + @Override + public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibraryImpl element) { + dispatcher.getPublisher(JpsLibraryListener.class).libraryAdded(element); + } + + @Override + public void fireElementRemoved(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibraryImpl element) { + dispatcher.getPublisher(JpsLibraryListener.class).libraryRemoved(element); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryReferenceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryReferenceImpl.java new file mode 100644 index 000000000000..c78e4bdd8c0c --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryReferenceImpl.java @@ -0,0 +1,35 @@ +package org.jetbrains.jps.model.library.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.impl.JpsNamedElementReferenceBase; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryReference; + +/** + * @author nik + */ +public class JpsLibraryReferenceImpl extends JpsNamedElementReferenceBase implements JpsLibraryReference { + public JpsLibraryReferenceImpl(JpsModel model, JpsEventDispatcher eventDispatcher, String elementName, JpsElementReference parentReference, + JpsParentElement parent) { + super(model, eventDispatcher, JpsLibraryKind.LIBRARIES_COLLECTION_KIND, elementName, parentReference, parent); + } + + public JpsLibraryReferenceImpl(JpsLibraryReferenceImpl original, JpsModel model, JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(original, model, eventDispatcher, parent); + } + + @NotNull + @Override + public String getLibraryName() { + return myElementName; + } + + @NotNull + @Override + public JpsLibraryReferenceImpl createCopy(@NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + return new JpsLibraryReferenceImpl(this, model, eventDispatcher, parent); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryRootImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryRootImpl.java new file mode 100644 index 000000000000..6279e3adfa72 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryRootImpl.java @@ -0,0 +1,56 @@ +package org.jetbrains.jps.model.library.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.JpsParentElement; +import org.jetbrains.jps.model.impl.JpsElementBase; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryRoot; +import org.jetbrains.jps.model.library.JpsLibraryRootType; + +/** + * @author nik + */ +public class JpsLibraryRootImpl extends JpsElementBase implements JpsLibraryRoot { + private final String myUrl; + private final JpsLibraryRootType myRootType; + + public JpsLibraryRootImpl(JpsEventDispatcher eventDispatcher, @NotNull String url, @NotNull JpsLibraryRootType rootType, @NotNull JpsParentElement parent) { + super(eventDispatcher, parent); + myUrl = url; + myRootType = rootType; + } + + public JpsLibraryRootImpl(JpsLibraryRootImpl original, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(original, dispatcher, parent); + myUrl = original.myUrl; + myRootType = original.myRootType; + } + + @NotNull + @Override + public JpsLibraryRootType getRootType() { + return myRootType; + } + + @NotNull + public String getUrl() { + return myUrl; + } + + @NotNull + @Override + public JpsLibraryRootImpl createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JpsLibraryRootImpl(this, eventDispatcher, parent); + } + + public void applyChanges(@NotNull JpsLibraryRootImpl modified) { + } + + @Override + @NotNull + public JpsLibrary getLibrary() { + return (JpsLibrary)myParent; + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryRootKind.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryRootKind.java new file mode 100644 index 000000000000..4043b76287ce --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryRootKind.java @@ -0,0 +1,23 @@ +package org.jetbrains.jps.model.library.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.library.JpsLibraryRootListener; + +/** + * @author nik + */ +public class JpsLibraryRootKind extends JpsElementKind { + public static final JpsLibraryRootKind INSTANCE = new JpsLibraryRootKind(); + + @Override + public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibraryRootImpl element) { + dispatcher.getPublisher(JpsLibraryRootListener.class).rootAdded(element); + } + + @Override + public void fireElementRemoved(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibraryRootImpl element) { + dispatcher.getPublisher(JpsLibraryRootListener.class).rootRemoved(element); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesListImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesListImpl.java new file mode 100644 index 000000000000..09a6ec9fe5f1 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesListImpl.java @@ -0,0 +1,74 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.JpsParentElement; +import org.jetbrains.jps.model.impl.JpsCompositeElementBase; +import org.jetbrains.jps.model.impl.JpsElementCollectionKind; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsSdkType; +import org.jetbrains.jps.model.module.*; + +import java.util.List; + +/** + * @author nik + */ +public class JpsDependenciesListImpl extends JpsCompositeElementBase implements JpsDependenciesList { + public static final JpsElementKind> DEPENDENCY_ELEMENT_KIND = new JpsElementKind>(); + public static final JpsElementCollectionKind> DEPENDENCY_COLLECTION_KIND = new JpsElementCollectionKind>(DEPENDENCY_ELEMENT_KIND); + + public JpsDependenciesListImpl(JpsModel model, JpsEventDispatcher eventDispatcher, JpsModuleImpl parent) { + super(model, eventDispatcher, parent); + myContainer.setChild(DEPENDENCY_COLLECTION_KIND); + } + + public JpsDependenciesListImpl(JpsDependenciesListImpl original, JpsModel model, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(original, model, dispatcher, parent); + } + + @Override + @NotNull + public List getDependencies() { + return myContainer.getChild(DEPENDENCY_COLLECTION_KIND).getElements(); + } + + @Override + @NotNull + public JpsModuleDependency addModuleDependency(@NotNull JpsModule module) { + final JpsModuleDependencyImpl dependency = new JpsModuleDependencyImpl(myModel, getEventDispatcher(), module, this); + myContainer.getChild(DEPENDENCY_COLLECTION_KIND).addChild(dependency); + return dependency; + } + + @Override + @NotNull + public JpsLibraryDependency addLibraryDependency(@NotNull JpsLibrary libraryElement) { + JpsLibraryDependencyImpl dependency = new JpsLibraryDependencyImpl(myModel, getEventDispatcher(), libraryElement, this); + myContainer.getChild(DEPENDENCY_COLLECTION_KIND).addChild(dependency); + return dependency; + } + + @Override + public void addModuleSourceDependency() { + myContainer.getChild(DEPENDENCY_COLLECTION_KIND).addChild(new JpsModuleSourceDependency(myModel, getEventDispatcher(), this)); + } + + @Override + public void addSdkDependency(@NotNull JpsSdkType sdkType) { + myContainer.getChild(DEPENDENCY_COLLECTION_KIND).addChild(new JpsSdkDependencyImpl(sdkType, myModel, getEventDispatcher(), this)); + } + + @NotNull + @Override + public JpsDependenciesListImpl createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JpsDependenciesListImpl(this, model, eventDispatcher, parent); + } + + @Override + public JpsModuleImpl getParent() { + return (JpsModuleImpl)super.getParent(); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependencyElementBase.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependencyElementBase.java new file mode 100644 index 000000000000..4be465b91799 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependencyElementBase.java @@ -0,0 +1,25 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.JpsParentElement; +import org.jetbrains.jps.model.impl.JpsCompositeElementBase; +import org.jetbrains.jps.model.module.JpsDependencyElement; + +/** + * @author nik + */ +public abstract class JpsDependencyElementBase> extends JpsCompositeElementBase implements JpsDependencyElement { + protected JpsDependencyElementBase(JpsModel model, JpsEventDispatcher eventDispatcher, JpsDependenciesListImpl parent) { + super(model, eventDispatcher, parent); + } + + protected JpsDependencyElementBase(JpsDependencyElementBase original, JpsModel model, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(original, model, dispatcher, parent); + } + + @Override + public void remove() { + ((JpsDependenciesListImpl)myParent).getContainer().getChild(JpsDependenciesListImpl.DEPENDENCY_COLLECTION_KIND).removeChild(this); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsLibraryDependencyImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsLibraryDependencyImpl.java new file mode 100644 index 000000000000..6470a87414b5 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsLibraryDependencyImpl.java @@ -0,0 +1,37 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.model.module.JpsLibraryDependency; + +/** + * @author nik + */ +public class JpsLibraryDependencyImpl extends JpsDependencyElementBase implements JpsLibraryDependency { + public static final JpsElementKind LIBRARY_REFERENCE_KIND = new JpsElementKind(); + + public JpsLibraryDependencyImpl(JpsModel model, JpsEventDispatcher eventDispatcher, JpsLibrary library, JpsDependenciesListImpl parent) { + super(model, eventDispatcher, parent); + myContainer.setChild(LIBRARY_REFERENCE_KIND, library.createReference(parent)); + } + + public JpsLibraryDependencyImpl(JpsLibraryDependencyImpl original, @NotNull JpsModel model, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(original, model, dispatcher, parent); + } + + @NotNull + @Override + public JpsLibraryReference getLibraryReference() { + return myContainer.getChild(LIBRARY_REFERENCE_KIND); + } + + @NotNull + @Override + public JpsLibraryDependencyImpl createCopy(@NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + return new JpsLibraryDependencyImpl(this, model, eventDispatcher, parent); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleDependencyImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleDependencyImpl.java new file mode 100644 index 000000000000..0931c60e1415 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleDependencyImpl.java @@ -0,0 +1,37 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleDependency; +import org.jetbrains.jps.model.module.JpsModuleReference; + +/** + * @author nik + */ +public class JpsModuleDependencyImpl extends JpsDependencyElementBase implements JpsModuleDependency { + private static final JpsElementKind MODULE_REFERENCE_KIND = new JpsElementKind(); + + public JpsModuleDependencyImpl(JpsModel model, JpsEventDispatcher eventDispatcher, JpsModule module, JpsDependenciesListImpl parent) { + super(model, eventDispatcher, parent); + myContainer.setChild(MODULE_REFERENCE_KIND, module.createReference(this)); + } + + public JpsModuleDependencyImpl(JpsModuleDependencyImpl original, JpsModel model, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(original, model, dispatcher, parent); + } + + @NotNull + @Override + public JpsModuleReference getModuleReference() { + return myContainer.getChild(MODULE_REFERENCE_KIND); + } + + @NotNull + @Override + public JpsModuleDependencyImpl createCopy(@NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + return new JpsModuleDependencyImpl(this, model, eventDispatcher, parent); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java new file mode 100644 index 000000000000..98c53860f232 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java @@ -0,0 +1,108 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.impl.*; +import org.jetbrains.jps.model.module.*; + +import java.util.List; + +/** + * @author nik + */ +public class JpsModuleImpl extends JpsNamedCompositeElementBase implements JpsModule { + private static final JpsTypedDataKind> TYPED_DATA_KIND = new JpsTypedDataKind>(); + private static final JpsElementKind CONTENT_ROOTS_KIND = new JpsElementKind(); + private static final JpsElementKind EXCLUDED_ROOTS_KIND = new JpsElementKind(); + public static final JpsElementKind DEPENDENCIES_LIST_KIND = new JpsElementKind(); + + public JpsModuleImpl(JpsModel model, JpsEventDispatcher eventDispatcher, JpsModuleType type, @NotNull String name, JpsElementCollectionImpl parent) { + super(model, eventDispatcher, name, parent); + myContainer.setChild(TYPED_DATA_KIND, new JpsTypedDataImpl>(type, eventDispatcher, this)); + myContainer.setChild(CONTENT_ROOTS_KIND, new JpsUrlListImpl(eventDispatcher, this)); + myContainer.setChild(EXCLUDED_ROOTS_KIND, new JpsUrlListImpl(eventDispatcher, this)); + myContainer.setChild(DEPENDENCIES_LIST_KIND, new JpsDependenciesListImpl(model, eventDispatcher, this)); + myContainer.setChild(JpsModuleSourceRootKind.ROOT_COLLECTION_KIND); + myContainer.setChild(JpsSdkReferencesTableImpl.KIND, new JpsSdkReferencesTableImpl(model, eventDispatcher, this)); + } + + public JpsModuleImpl(JpsModuleImpl original, JpsEventDispatcher eventDispatcher, JpsModel model, JpsParentElement parent) { + super(original, model, eventDispatcher, parent); + } + + @NotNull + @Override + public JpsModuleImpl createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JpsModuleImpl(this, eventDispatcher, model, parent); + } + + @NotNull + @Override + public JpsUrlList getContentRootsList() { + return myContainer.getChild(CONTENT_ROOTS_KIND); + } + + @NotNull + public JpsUrlList getExcludeRootsList() { + return myContainer.getChild(EXCLUDED_ROOTS_KIND); + } + + @NotNull + @Override + public List getSourceRoots() { + return myContainer.getChild(JpsModuleSourceRootKind.ROOT_COLLECTION_KIND).getElements(); + } + + @NotNull + @Override + public

JpsModuleSourceRoot addSourceRoot(@NotNull JpsModuleSourceRootType

rootType, + @NotNull String url) { + return addSourceRoot(rootType, url, rootType.createDefaultProperties()); + } + + @NotNull + @Override + public

JpsModuleSourceRoot addSourceRoot(@NotNull JpsModuleSourceRootType

rootType, + @NotNull String url, + @NotNull P properties) { + final JpsModuleSourceRootImpl root = new JpsModuleSourceRootImpl(myModel, getEventDispatcher(), url, rootType, this); + myContainer.getChild(JpsModuleSourceRootKind.ROOT_COLLECTION_KIND).addChild(root); + root.setProperties(rootType, properties); + return root; + } + + @Override + public void removeSourceRoot(@NotNull JpsModuleSourceRootType rootType, @NotNull String url) { + final JpsElementCollectionImpl roots = myContainer.getChild(JpsModuleSourceRootKind.ROOT_COLLECTION_KIND); + for (JpsModuleSourceRootImpl root : roots.getElements()) { + if (root.getRootType().equals(rootType) && root.getUrl().equals(url)) { + roots.removeChild(root); + break; + } + } + } + + @NotNull + @Override + public JpsDependenciesList getDependenciesList() { + return myContainer.getChild(DEPENDENCIES_LIST_KIND); + } + + @Override + @NotNull + public JpsSdkReferencesTable getSdkReferencesTable() { + return myContainer.getChild(JpsSdkReferencesTableImpl.KIND); + } + + @Override + public void delete() { + //noinspection unchecked + ((JpsElementCollectionImpl)myParent).removeChild(this); + } + + @NotNull + @Override + public JpsModuleReference createReference(JpsParentElement parent) { + return new JpsModuleReferenceImpl(myModel, getName(), getEventDispatcher(), parent); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleKind.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleKind.java new file mode 100644 index 000000000000..74621d367f0c --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleKind.java @@ -0,0 +1,25 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.impl.JpsElementCollectionKind; +import org.jetbrains.jps.model.module.JpsModuleListener; + +/** + * @author nik + */ +public class JpsModuleKind extends JpsElementKind { + public static final JpsElementKind INSTANCE = new JpsModuleKind(); + public static final JpsElementCollectionKind MODULE_COLLECTION_KIND = new JpsElementCollectionKind(INSTANCE); + + @Override + public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsModuleImpl element) { + dispatcher.getPublisher(JpsModuleListener.class).moduleAdded(element); + } + + @Override + public void fireElementRemoved(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsModuleImpl element) { + dispatcher.getPublisher(JpsModuleListener.class).moduleRemoved(element); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleReferenceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleReferenceImpl.java new file mode 100644 index 000000000000..0d9d6a3607fa --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleReferenceImpl.java @@ -0,0 +1,34 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsCompositeElement; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.JpsParentElement; +import org.jetbrains.jps.model.impl.JpsNamedElementReferenceBase; +import org.jetbrains.jps.model.impl.JpsProjectElementReference; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleReference; + +/** + * @author nik + */ +public class JpsModuleReferenceImpl extends JpsNamedElementReferenceBase implements JpsModuleReference { + public JpsModuleReferenceImpl(JpsModel model, String elementName, JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(model, eventDispatcher, JpsModuleKind.MODULE_COLLECTION_KIND, elementName, new JpsProjectElementReference(model, eventDispatcher, parent), parent); + } + + @NotNull + @Override + public JpsModuleReferenceImpl createCopy(@NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + return new JpsModuleReferenceImpl(model, myElementName, eventDispatcher, parent); + } + + @NotNull + @Override + public String getModuleName() { + return myElementName; + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceDependency.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceDependency.java new file mode 100644 index 000000000000..8d2520fccc15 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceDependency.java @@ -0,0 +1,27 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.JpsParentElement; + +/** + * @author nik + */ +public class JpsModuleSourceDependency extends JpsDependencyElementBase { + public JpsModuleSourceDependency(JpsModel model, JpsEventDispatcher eventDispatcher, JpsDependenciesListImpl parent) { + super(model, eventDispatcher, parent); + } + + public JpsModuleSourceDependency(JpsModuleSourceDependency original, JpsModel model, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(original, model, dispatcher, parent); + } + + @NotNull + @Override + public JpsModuleSourceDependency createCopy(@NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + return new JpsModuleSourceDependency(this, model, eventDispatcher, parent); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootImpl.java new file mode 100644 index 000000000000..61fe889ae060 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootImpl.java @@ -0,0 +1,57 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.impl.JpsCompositeElementBase; +import org.jetbrains.jps.model.impl.JpsTypedDataImpl; +import org.jetbrains.jps.model.impl.JpsTypedDataKind; +import org.jetbrains.jps.model.module.JpsModuleSourceRoot; +import org.jetbrains.jps.model.module.JpsModuleSourceRootType; + +/** + * @author nik + */ +public class JpsModuleSourceRootImpl extends JpsCompositeElementBase implements JpsModuleSourceRoot { + private static final JpsTypedDataKind> TYPED_DATA_KIND = new JpsTypedDataKind>(); + private String myUrl; + + public JpsModuleSourceRootImpl(JpsModel model, JpsEventDispatcher eventDispatcher, + String url, + JpsModuleSourceRootType type, JpsParentElement parent) { + super(model, eventDispatcher, parent); + myContainer.setChild(TYPED_DATA_KIND, new JpsTypedDataImpl>(type, eventDispatcher, this)); + myUrl = url; + } + + public JpsModuleSourceRootImpl(JpsModuleSourceRootImpl original, JpsModel model, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(original, model, dispatcher, parent); + myUrl = original.myUrl; + } + + @Override + public

P getProperties(@NotNull JpsModuleSourceRootType

type) { + return myContainer.getChild(TYPED_DATA_KIND).getProperties(type); + } + + @Override + public

void setProperties(JpsModuleSourceRootType

type, P properties) { + myContainer.getChild(TYPED_DATA_KIND).setProperties(properties); + } + + @NotNull + @Override + public JpsModuleSourceRootType getRootType() { + return myContainer.getChild(TYPED_DATA_KIND).getType(); + } + + @NotNull + public String getUrl() { + return myUrl; + } + + @NotNull + @Override + public JpsModuleSourceRootImpl createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JpsModuleSourceRootImpl(this, model, eventDispatcher, parent); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootKind.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootKind.java new file mode 100644 index 000000000000..70e25abff2dc --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootKind.java @@ -0,0 +1,25 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.impl.JpsElementCollectionKind; +import org.jetbrains.jps.model.module.JpsModuleSourceRootListener; + +/** + * @author nik + */ +public class JpsModuleSourceRootKind extends JpsElementKind { + public static final JpsModuleSourceRootKind INSTANCE = new JpsModuleSourceRootKind(); + public static final JpsElementCollectionKind ROOT_COLLECTION_KIND = new JpsElementCollectionKind(INSTANCE); + + @Override + public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsModuleSourceRootImpl element) { + dispatcher.getPublisher(JpsModuleSourceRootListener.class).sourceRootAdded(element); + } + + @Override + public void fireElementRemoved(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsModuleSourceRootImpl element) { + dispatcher.getPublisher(JpsModuleSourceRootListener.class).sourceRootRemoved(element); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkDependencyImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkDependencyImpl.java new file mode 100644 index 000000000000..c59548818eaf --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkDependencyImpl.java @@ -0,0 +1,50 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.JpsParentElement; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.model.library.JpsSdkType; +import org.jetbrains.jps.model.module.JpsSdkDependency; + +/** + * @author nik + */ +public class JpsSdkDependencyImpl extends JpsDependencyElementBase implements JpsSdkDependency { + private final JpsSdkType mySdkType; + + public JpsSdkDependencyImpl(@NotNull JpsSdkType sdkType, JpsModel model, JpsEventDispatcher eventDispatcher, JpsDependenciesListImpl parent) { + super(model, eventDispatcher, parent); + mySdkType = sdkType; + } + + public JpsSdkDependencyImpl(JpsSdkDependencyImpl original, JpsModel model, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(original, model, dispatcher, parent); + mySdkType = original.mySdkType; + } + + @NotNull + @Override + public JpsSdkDependencyImpl createCopy(@NotNull JpsModel model, @NotNull JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + return new JpsSdkDependencyImpl(this, model, eventDispatcher, parent); + } + + @Override + @NotNull + public JpsSdkType getSdkType() { + return mySdkType; + } + + @Override + public JpsLibrary resolveSdk() { + final JpsLibraryReference reference = getParent().getParent().getSdkReferencesTable().getSdkReference(mySdkType); + return reference != null ? reference.resolve() : null; + } + + @Override + public JpsDependenciesListImpl getParent() { + return (JpsDependenciesListImpl)super.getParent(); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkReferencesTableImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkReferencesTableImpl.java new file mode 100644 index 000000000000..79fe355b9e25 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkReferencesTableImpl.java @@ -0,0 +1,63 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.JpsParentElement; +import org.jetbrains.jps.model.impl.JpsCompositeElementBase; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.model.library.JpsSdkType; +import org.jetbrains.jps.model.module.JpsSdkReferencesTable; + +/** + * @author nik + */ +public class JpsSdkReferencesTableImpl extends JpsCompositeElementBase implements JpsSdkReferencesTable { + public static final JpsElementKind KIND = new JpsElementKind(); + + public JpsSdkReferencesTableImpl(JpsModel model, JpsEventDispatcher eventDispatcher, JpsParentElement parent) { + super(model, eventDispatcher, parent); + } + + public JpsSdkReferencesTableImpl(JpsSdkReferencesTableImpl original, JpsModel model, JpsEventDispatcher dispatcher, JpsParentElement parent) { + super(original, model, dispatcher, parent); + } + + @NotNull + @Override + public JpsSdkReferencesTableImpl createCopy(@NotNull JpsModel model, + @NotNull JpsEventDispatcher eventDispatcher, + JpsParentElement parent) { + return new JpsSdkReferencesTableImpl(this, model, eventDispatcher, parent); + } + + @Override + public void setSdkReference(@NotNull JpsSdkType type, @NotNull JpsLibrary sdk) { + myContainer.setChild(new JpsSdkReferenceKind(type), sdk.createReference(this)); + } + + @Override + public JpsLibraryReference getSdkReference(@NotNull JpsSdkType type) { + return myContainer.getChild(new JpsSdkReferenceKind(type)); + } + + private static class JpsSdkReferenceKind extends JpsElementKind { + private final JpsSdkType myType; + + private JpsSdkReferenceKind(@NotNull JpsSdkType type) { + myType = type; + } + + @Override + public int hashCode() { + return myType.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof JpsSdkReferenceKind && myType.equals(((JpsSdkReferenceKind)obj).myType); + } + } +} diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsJavaExtensionTest.java b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsJavaExtensionTest.java new file mode 100644 index 000000000000..cc6562a97c11 --- /dev/null +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsJavaExtensionTest.java @@ -0,0 +1,16 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.jps.model.java.JpsJavaModuleType; +import org.jetbrains.jps.model.java.impl.JavaModuleExtensionKind; +import org.jetbrains.jps.model.module.JpsModule; + +/** + * @author nik + */ +public class JpsJavaExtensionTest extends JpsModelTestCase { + public void test() { + final JpsModule module = myModel.getProject().addModule(JpsJavaModuleType.INSTANCE, "m"); + JavaModuleExtensionKind.getExtension(module).setOutputUrl("file://path"); + assertEquals("file://path", JavaModuleExtensionKind.getExtension(module).getOutputUrl()); + } +} diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsLibraryTest.java b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsLibraryTest.java new file mode 100644 index 000000000000..f437c6d7e192 --- /dev/null +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsLibraryTest.java @@ -0,0 +1,48 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.jps.model.impl.JpsProjectImpl; +import org.jetbrains.jps.model.java.JpsJavaLibraryType; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.model.library.JpsLibraryRootType; +import org.jetbrains.jps.model.library.impl.JpsLibraryReferenceImpl; + +/** + * @author nik + */ +public class JpsLibraryTest extends JpsModelTestCase { + public void testAddRoot() { + final JpsLibrary library = myModel.getProject().addLibrary(JpsJavaLibraryType.INSTANCE, "a"); + library.addUrl("file://my-url", JpsLibraryRootType.COMPILED); + assertEquals("file://my-url", assertOneElement(library.getUrls(JpsLibraryRootType.COMPILED))); + } + + public void testModifiableCopy() { + myModel.getProject().addLibrary(JpsJavaLibraryType.INSTANCE, "a"); + + final JpsModel modifiableModel = myModel.createModifiableModel(new TestJpsEventDispatcher()); + final JpsLibrary modifiable = assertOneElement(modifiableModel.getProject().getLibraries()); + modifiable.addUrl("file://my-url", JpsLibraryRootType.COMPILED); + modifiableModel.commit(); + + final JpsLibrary library = assertOneElement(myModel.getProject().getLibraries()); + assertEquals("file://my-url", assertOneElement(library.getUrls(JpsLibraryRootType.COMPILED))); + } + + public void testCreateReferenceByLibrary() { + final JpsLibrary library = myModel.getProject().addLibrary(JpsJavaLibraryType.INSTANCE, "l"); + final JpsLibraryReference reference = library.createReference(myModel.getProject()); + assertEquals("l", reference.getLibraryName()); + assertSame(library, reference.resolve()); + } + + public void testCreateReferenceByName() { + final JpsProjectImpl project = myModel.getProject(); + JpsLibraryReference reference = new JpsLibraryReferenceImpl(myModel, myDispatcher, "l", myModel.getProject().createReference(project), project); + assertEquals("l", reference.getLibraryName()); + assertNull(reference.resolve()); + + final JpsLibrary library = myModel.getProject().addLibrary(JpsJavaLibraryType.INSTANCE, "l"); + assertSame(library, reference.resolve()); + } +} diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsModelTestCase.java b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsModelTestCase.java new file mode 100644 index 000000000000..fb3b425b68c2 --- /dev/null +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsModelTestCase.java @@ -0,0 +1,18 @@ +package org.jetbrains.jps.model; + +import com.intellij.testFramework.UsefulTestCase; +import org.jetbrains.jps.model.impl.JpsModelImpl; + +/** + * @author nik + */ +public abstract class JpsModelTestCase extends UsefulTestCase { + protected JpsModelImpl myModel; + protected TestJpsEventDispatcher myDispatcher; + + public void setUp() throws Exception { + super.setUp(); + myDispatcher = new TestJpsEventDispatcher(); + myModel = new JpsModelImpl(myDispatcher); + } +} diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsModuleTest.java b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsModuleTest.java new file mode 100644 index 000000000000..65ccac9ac2b9 --- /dev/null +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsModuleTest.java @@ -0,0 +1,108 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.jps.model.impl.JpsProjectImpl; +import org.jetbrains.jps.model.java.*; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.module.*; +import org.jetbrains.jps.model.module.impl.JpsModuleReferenceImpl; + +import java.util.List; + +/** + * @author nik + */ +public class JpsModuleTest extends JpsModelTestCase { + public void testAddSourceRoot() { + final JpsModule module = myModel.getProject().addModule(JpsJavaModuleType.INSTANCE, "m"); + final JpsModuleSourceRoot sourceRoot = module.addSourceRoot(JavaSourceRootType.SOURCE, "file://url", new JavaSourceRootProperties("com.xxx")); + + assertSameElements(myDispatcher.retrieveAdded(JpsModule.class), module); + assertSameElements(myDispatcher.retrieveAdded(JpsModuleSourceRoot.class), sourceRoot); + + final JpsModuleSourceRoot root = assertOneElement(module.getSourceRoots()); + assertEquals("file://url", root.getUrl()); + final JavaSourceRootProperties properties = root.getProperties(JavaSourceRootType.SOURCE); + assertNotNull(properties); + assertEquals("com.xxx", properties.getPackagePrefix()); + } + + public void testModifiableModel() { + final JpsModule module = myModel.getProject().addModule(JpsJavaModuleType.INSTANCE, "m"); + final JpsModuleSourceRoot root0 = module.addSourceRoot(JavaSourceRootType.SOURCE, "url1"); + myDispatcher.clear(); + + final JpsModel modifiableModel = myModel.createModifiableModel(new TestJpsEventDispatcher()); + final JpsModule modifiableModule = assertOneElement(modifiableModel.getProject().getModules()); + modifiableModule.addSourceRoot(JavaSourceRootType.TEST_SOURCE, "url2"); + modifiableModel.commit(); + + assertEmpty(myDispatcher.retrieveAdded(JpsModule.class)); + assertEmpty(myDispatcher.retrieveRemoved(JpsModule.class)); + + final List roots = module.getSourceRoots(); + assertEquals(2, roots.size()); + assertSame(root0, roots.get(0)); + final JpsModuleSourceRoot root1 = roots.get(1); + assertEquals("url2", root1.getUrl()); + assertOrderedEquals(myDispatcher.retrieveAdded(JpsModuleSourceRoot.class), root1); + assertEmpty(myDispatcher.retrieveChanged(JpsModuleSourceRoot.class)); + } + + public void testAddDependency() { + final JpsModule module = myModel.getProject().addModule(JpsJavaModuleType.INSTANCE, "m"); + final JpsLibrary library = myModel.getProject().addLibrary(JpsJavaLibraryType.INSTANCE, "l"); + final JpsModule dep = myModel.getProject().addModule(JpsJavaModuleType.INSTANCE, "dep"); + module.getDependenciesList().addLibraryDependency(library); + module.getDependenciesList().addModuleDependency(dep); + + final List dependencies = module.getDependenciesList().getDependencies(); + assertEquals(2, dependencies.size()); + assertSame(library, assertInstanceOf(dependencies.get(0), JpsLibraryDependency.class).getLibraryReference().resolve()); + assertSame(dep, assertInstanceOf(dependencies.get(1), JpsModuleDependency.class).getModuleReference().resolve()); + } + + public void testChangeElementInModifiableModel() { + final JpsModule module = myModel.getProject().addModule(JpsJavaModuleType.INSTANCE, "m"); + final JpsModule dep = myModel.getProject().addModule(JpsJavaModuleType.INSTANCE, "dep"); + final JpsLibrary library = myModel.getProject().addLibrary(JpsJavaLibraryType.INSTANCE, "l"); + module.getDependenciesList().addLibraryDependency(library); + myDispatcher.clear(); + + final JpsModel modifiableModel = myModel.createModifiableModel(new TestJpsEventDispatcher()); + final JpsModule m = modifiableModel.getProject().getModules().get(0); + assertEquals("m", m.getName()); + m.getDependenciesList().getDependencies().get(0).remove(); + m.getDependenciesList().addModuleDependency(dep); + modifiableModel.commit(); + assertSame(library, assertOneElement(myDispatcher.retrieveRemoved(JpsLibraryDependency.class)).getLibraryReference().resolve()); + assertSame(dep, assertOneElement(myDispatcher.retrieveAdded(JpsModuleDependency.class)).getModuleReference().resolve()); + assertSame(dep, assertInstanceOf(assertOneElement(module.getDependenciesList().getDependencies()), JpsModuleDependency.class).getModuleReference().resolve()); + } + + public void testCreateReferenceByModule() { + final JpsModule module = myModel.getProject().addModule(JpsJavaModuleType.INSTANCE, "m"); + final JpsModuleReference reference = module.createReference(myModel.getProject()); + assertEquals("m", reference.getModuleName()); + assertSame(module, reference.resolve()); + } + + public void testCreateReferenceByName() { + final JpsProjectImpl project = myModel.getProject(); + final JpsModuleReference reference = new JpsModuleReferenceImpl(myModel, "m", myDispatcher, project); + assertEquals("m", reference.getModuleName()); + assertNull(reference.resolve()); + + final JpsModule module = project.addModule(JpsJavaModuleType.INSTANCE, "m"); + assertSame(module, reference.resolve()); + } + + public void testSdkDependency() { + JpsLibrary sdk = myModel.getGlobal().addLibrary(JpsJavaSdkType.INSTANCE, "sdk"); + final JpsModule module = myModel.getProject().addModule(JpsJavaModuleType.INSTANCE, "m"); + module.getSdkReferencesTable().setSdkReference(JpsJavaSdkType.INSTANCE, sdk); + module.getDependenciesList().addSdkDependency(JpsJavaSdkType.INSTANCE); + + final JpsSdkDependency dependency = assertInstanceOf(assertOneElement(module.getDependenciesList().getDependencies()), JpsSdkDependency.class); + assertSame(sdk, dependency.resolveSdk()); + } +} diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/TestJpsEventDispatcher.java b/jps/model-impl/testSrc/org/jetbrains/jps/model/TestJpsEventDispatcher.java new file mode 100644 index 000000000000..5da03b935dc3 --- /dev/null +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/TestJpsEventDispatcher.java @@ -0,0 +1,70 @@ +package org.jetbrains.jps.model; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.impl.JpsEventDispatcherBase; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author nik + */ +class TestJpsEventDispatcher extends JpsEventDispatcherBase implements JpsEventDispatcher { + private List myAdded = new ArrayList(); + private List myRemoved = new ArrayList(); + private List myChanged = new ArrayList(); + + @Override + public void fireElementAdded(@NotNull T element, @NotNull JpsElementKind kind) { + super.fireElementAdded(element, kind); + myAdded.add(element); + } + + @Override + public void fireElementRemoved(@NotNull T element, @NotNull JpsElementKind kind) { + super.fireElementRemoved(element, kind); + myRemoved.add(element); + } + + @Override + public void fireElementChanged(@NotNull JpsElement element) { + myChanged.add(element); + } + + @Override + public void fireElementRenamed(@NotNull JpsNamedElement element, @NotNull String oldName, @NotNull String newName) { + } + + public List retrieveAdded(Class type) { + return retrieve(type, myAdded); + } + + public List retrieveRemoved(Class type) { + return retrieve(type, myRemoved); + } + + public List retrieveChanged(Class type) { + return retrieve(type, myChanged); + } + + public void clear() { + myAdded.clear(); + myRemoved.clear(); + myChanged.clear(); + } + + + private static List retrieve(Class type, List list) { + final List result = new ArrayList(); + final Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + JpsElement element = iterator.next(); + if (type.isInstance(element)) { + result.add(type.cast(element)); + iterator.remove(); + } + } + return result; + } +} diff --git a/platform/core-api/src/com/intellij/openapi/vfs/WritingAccessProvider.java b/platform/core-api/src/com/intellij/openapi/vfs/WritingAccessProvider.java new file mode 100644 index 000000000000..8be975bfe87f --- /dev/null +++ b/platform/core-api/src/com/intellij/openapi/vfs/WritingAccessProvider.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2012 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.openapi.vfs; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * @author Dmitry Avdeev + */ +public abstract class WritingAccessProvider { + + private static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.writingAccessProvider"); + + /** + * @param files files to be checked + * @return set of files that cannot be accessed + */ + @NotNull + public abstract Collection requestWriting(VirtualFile... files); + + public abstract boolean isPotentiallyWritable(@NotNull VirtualFile file); + + public static WritingAccessProvider[] getProvidersForProject(Project project) { + return project == null || project.isDefault() ? new WritingAccessProvider[0] : Extensions.getExtensions(EP_NAME, project); + } + + public static boolean isPotentiallyWritable(VirtualFile file, Project project) { + WritingAccessProvider[] providers = getProvidersForProject(project); + for (WritingAccessProvider provider : providers) { + if (!provider.isPotentiallyWritable(file)) { + return false; + } + } + return true; + } +} diff --git a/platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java b/platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java index b3627c469d1c..28983a78a911 100644 --- a/platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java +++ b/platform/core-api/src/com/intellij/psi/scope/PsiScopeProcessor.java @@ -18,6 +18,7 @@ package com.intellij.psi.scope; import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; import com.intellij.psi.ResolveState; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public interface PsiScopeProcessor { @@ -30,10 +31,10 @@ public interface PsiScopeProcessor { * @param state current state of resolver. * @return false to stop processing. */ - boolean execute(PsiElement element, ResolveState state); + boolean execute(@NotNull PsiElement element, ResolveState state); @Nullable - T getHint(Key hintKey); + T getHint(@NotNull Key hintKey); void handleEvent(Event event, @Nullable Object associated); } diff --git a/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java b/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java index 50e7b40006d1..5dea7a6b837a 100644 --- a/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java +++ b/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java @@ -330,6 +330,7 @@ public class PsiUtilCore { @NotNull public static PsiElement[] toPsiElementArray(@NotNull Collection collection) { if (collection.isEmpty()) return PsiElement.EMPTY_ARRAY; + //noinspection SSBasedInspection return collection.toArray(new PsiElement[collection.size()]); } diff --git a/platform/core-api/src/com/intellij/ui/IconDeferrer.java b/platform/core-api/src/com/intellij/ui/IconDeferrer.java index 7baa21c2802b..120f5aadaba8 100644 --- a/platform/core-api/src/com/intellij/ui/IconDeferrer.java +++ b/platform/core-api/src/com/intellij/ui/IconDeferrer.java @@ -21,6 +21,7 @@ package com.intellij.ui; import com.intellij.openapi.components.ServiceManager; import com.intellij.util.Function; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -29,5 +30,5 @@ public abstract class IconDeferrer { return ServiceManager.getService(IconDeferrer.class); } - public abstract Icon defer(Icon base, T param, Function f); + public abstract Icon defer(Icon base, T param, @NotNull Function f); } \ No newline at end of file diff --git a/platform/core-api/src/com/intellij/util/IconUtil.java b/platform/core-api/src/com/intellij/util/IconUtil.java index 8319da8072dc..2fcace44a36d 100644 --- a/platform/core-api/src/com/intellij/util/IconUtil.java +++ b/platform/core-api/src/com/intellij/util/IconUtil.java @@ -26,6 +26,7 @@ import com.intellij.openapi.util.Iconable; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.WritingAccessProvider; import com.intellij.ui.IconDeferrer; import com.intellij.ui.LayeredIcon; import com.intellij.ui.RowIcon; @@ -114,7 +115,8 @@ public class IconUtil { icon = patcher.patchIcon(icon, file, flags, project); } - if ((flags & Iconable.ICON_FLAG_READ_STATUS) != 0 && !file.isWritable()) { + if ((flags & Iconable.ICON_FLAG_READ_STATUS) != 0 && + (!file.isWritable() || !WritingAccessProvider.isPotentiallyWritable(file, project))) { icon = new LayeredIcon(icon, PlatformIcons.LOCKED_ICON); } if (file.isSymLink()) { diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java index d473589db14b..f3a3f3655de8 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiManagerImpl.java @@ -142,7 +142,8 @@ public class PsiManagerImpl extends PsiManagerEx { return false; } - public void setAssertOnFileLoadingFilter(VirtualFileFilter filter) { + @TestOnly + public void setAssertOnFileLoadingFilter(@NotNull VirtualFileFilter filter) { // Find something to ensure there's no changed files waiting to be processed in repository indices. myAssertOnFileLoadingFilter = filter; } diff --git a/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java b/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java index daf26e3182b0..3b9b5849faea 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java +++ b/platform/core-impl/src/com/intellij/psi/impl/ResolveScopeManager.java @@ -38,10 +38,12 @@ public abstract class ResolveScopeManager { return ServiceManager.getService(project, ResolveScopeManager.class); } + @NotNull public static GlobalSearchScope getElementUseScope(PsiElement element) { return getInstance(element.getProject()).getUseScope(element); } + @NotNull public static GlobalSearchScope getElementResolveScope(PsiElement element) { return getInstance(element.getProject()).getResolveScope(element); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/resolve/ResolveCache.java b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/ResolveCache.java index 07eb7b7e2b52..d95ebb581b30 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/resolve/ResolveCache.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/ResolveCache.java @@ -149,6 +149,10 @@ public class ResolveCache { return result == null ? ResolveResult.EMPTY_ARRAY : result; } + public boolean isCached(@NotNull T ref, boolean physical, boolean incompleteCode) { + return getCached(ref, myPolyVariantResolveMaps, physical, incompleteCode) != null; + } + public PsiElement resolveWithCaching(@NotNull PsiReference ref, @NotNull Resolver resolver, boolean needToPreventRecursion, diff --git a/platform/core-impl/src/com/intellij/psi/scope/BaseScopeProcessor.java b/platform/core-impl/src/com/intellij/psi/scope/BaseScopeProcessor.java index 4e35c078f27b..889122c2fe63 100644 --- a/platform/core-impl/src/com/intellij/psi/scope/BaseScopeProcessor.java +++ b/platform/core-impl/src/com/intellij/psi/scope/BaseScopeProcessor.java @@ -16,10 +16,11 @@ package com.intellij.psi.scope; import com.intellij.openapi.util.Key; +import org.jetbrains.annotations.NotNull; public abstract class BaseScopeProcessor implements PsiScopeProcessor { @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { return null; } diff --git a/platform/icons/src/general/expandAll.png b/platform/icons/src/general/expandAll.png new file mode 100644 index 000000000000..715ae588da42 Binary files /dev/null and b/platform/icons/src/general/expandAll.png differ diff --git a/platform/icons/src/general/expandAllHover.png b/platform/icons/src/general/expandAllHover.png new file mode 100644 index 000000000000..f4a008fa18b4 Binary files /dev/null and b/platform/icons/src/general/expandAllHover.png differ diff --git a/platform/lang-api/src/com/intellij/refactoring/util/CommonRefactoringUtil.java b/platform/lang-api/src/com/intellij/refactoring/util/CommonRefactoringUtil.java index f7deece87d89..596df393bd7e 100644 --- a/platform/lang-api/src/com/intellij/refactoring/util/CommonRefactoringUtil.java +++ b/platform/lang-api/src/com/intellij/refactoring/util/CommonRefactoringUtil.java @@ -21,10 +21,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.ReadonlyStatusHandler; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.*; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.RefactoringBundle; @@ -147,12 +144,6 @@ public class CommonRefactoringUtil { } } } - else if (element instanceof PsiCompiledElement) { - final PsiFile file = element.getContainingFile(); - if (file != null) { - failed.add(file.getVirtualFile()); - } - } else { PsiFile file = element.getContainingFile(); if (file == null) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/CompletionExtender.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/CompletionExtender.java index 801942040b3b..14d471e082fc 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/CompletionExtender.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/CompletionExtender.java @@ -67,4 +67,9 @@ public class CompletionExtender extends ListExpandableItemsHandler { protected boolean isPaintBorder() { return false; } + + @Override + protected boolean isPopup() { + return false; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 19ff809c8012..5ec61742dc5b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -41,7 +41,6 @@ import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.event.*; -import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; @@ -57,7 +56,10 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.DebugUtil; -import com.intellij.ui.*; +import com.intellij.ui.ExpandableItemsHandler; +import com.intellij.ui.LightweightHint; +import com.intellij.ui.ListScrollingUtil; +import com.intellij.ui.ScreenUtil; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.components.JBList; import com.intellij.ui.components.JBScrollPane; @@ -1407,15 +1409,15 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable if (myElementHint != null && getCurrentItem() != null) { final Rectangle bounds = getCurrentItemBounds(); myElementHint.setSize(myElementHint.getPreferredSize()); - myElementHint.setLocation(new Point(bounds.x + bounds.width - myElementHint.getWidth(), bounds.y)); + myElementHint.setLocation(new Point(bounds.x + bounds.width - myElementHint.getWidth() + myScrollPane.getVerticalScrollBar().getWidth(), bounds.y)); } } } private class LookupHint extends JLabel { - private final Border INACTIVE_BORDER = BorderFactory.createEmptyBorder(4, 4, 4, 4); - private final Border ACTIVE_BORDER = BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.BLACK, 1), BorderFactory.createEmptyBorder(3, 3, 3, 3)); + private final Border INACTIVE_BORDER = BorderFactory.createEmptyBorder(2, 2, 2, 2); + private final Border ACTIVE_BORDER = BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.BLACK, 1), BorderFactory.createEmptyBorder(1, 1, 1, 1)); private LookupHint() { setOpaque(false); setBorder(INACTIVE_BORDER); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java index 7b7fa6568d08..664c700be1f4 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java @@ -96,7 +96,7 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority } public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) { - return myQuickfixClass != null && myQuickfixClass != EmptyIntentionAction.class && !(myTool instanceof UnfairLocalInspectionTool); + return myQuickfixClass != null && myQuickfixClass != EmptyIntentionAction.class && !(myTool.isUnfair()); } public boolean startInWriteAction() { diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java index bc8bb588ff35..f78c9c7e95a9 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarListener.java @@ -21,6 +21,9 @@ import com.intellij.ide.actions.CutAction; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.AnActionListener; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorManagerEvent; +import com.intellij.openapi.fileEditor.FileEditorManagerListener; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootEvent; import com.intellij.openapi.roots.ModuleRootListener; @@ -48,7 +51,7 @@ import java.util.List; * @author Konstantin Bulenkov */ public class NavBarListener extends WolfTheProblemSolver.ProblemListener - implements ActionListener, FocusListener, FileStatusListener, AnActionListener, + implements ActionListener, FocusListener, FileStatusListener, AnActionListener, FileEditorManagerListener, PsiTreeChangeListener, ModuleRootListener, NavBarModelListener, PropertyChangeListener, KeyListener { private static final String LISTENER = "NavBarListener"; private static final String BUS = "NavBarMessageBus"; @@ -70,6 +73,7 @@ public class NavBarListener extends WolfTheProblemSolver.ProblemListener final MessageBusConnection connection = project.getMessageBus().connect(); connection.subscribe(ProjectTopics.PROJECT_ROOTS, listener); connection.subscribe(NavBarModelListener.NAV_BAR, listener); + connection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, listener); panel.putClientProperty(BUS, connection); panel.addKeyListener(listener); } @@ -141,6 +145,7 @@ public class NavBarListener extends WolfTheProblemSolver.ProblemListener // required invokeLater since in current call sequence KeyboardFocusManager is not initialized yet // but future focused component + //noinspection SSBasedInspection SwingUtilities.invokeLater(new Runnable() { public void run() { processFocusLost(e); @@ -290,6 +295,18 @@ public class NavBarListener extends WolfTheProblemSolver.ProblemListener } } + @Override + public void fileOpened(final FileEditorManager manager, final VirtualFile file) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + if (myPanel.hasFocus()) { + manager.openFile(file, true); + } + } + }); + } + //---- Ignored @Override public void keyTyped(KeyEvent e) {} @@ -326,4 +343,10 @@ public class NavBarListener extends WolfTheProblemSolver.ProblemListener @Override public void childRemoved(@NotNull PsiTreeChangeEvent event) {} + + @Override + public void fileClosed(FileEditorManager source, VirtualFile file) {} + + @Override + public void selectionChanged(FileEditorManagerEvent event) {} } diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java index ebaca84492c4..92da1859926a 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -42,6 +42,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ui.configuration.actions.ModuleDeleteProvider; import com.intellij.openapi.ui.Queryable; import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.AsyncResult; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.SystemInfo; @@ -122,8 +123,11 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis } }; + final ActionCallback typeAheadDone = new ActionCallback(); + IdeFocusManager.getInstance(project).typeAheadUntil(typeAheadDone); myUpdateQueue.queueModelUpdateFromFocus(); myUpdateQueue.queueRebuildUi(); + myUpdateQueue.queueTypeAheadDone(typeAheadDone); Disposer.register(project, this); } @@ -139,7 +143,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis return myPresentation; } - public void setContextComponent(Component contextComponent) { + public void setContextComponent(@Nullable Component contextComponent) { myContextComponent = contextComponent; } diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarUpdateQueue.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarUpdateQueue.java index 72670b47f78e..8ea2c4bb9ae8 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarUpdateQueue.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarUpdateQueue.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -20,6 +20,7 @@ import com.intellij.ide.IdeEventQueue; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.AsyncResult; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.IdeFocusManager; @@ -274,6 +275,15 @@ public class NavBarUpdateQueue extends MergingUpdateQueue { super.dispose(); } + public void queueTypeAheadDone(final ActionCallback done) { + queue(new AfterModelUpdate(ID.TYPE_AHEAD_FINISHED) { + @Override + protected void after() { + done.setDone(); + } + }); + } + private abstract class AfterModelUpdate extends Update { private AfterModelUpdate(ID id) { super(id.name(), id.getPriority()); @@ -298,7 +308,8 @@ public class NavBarUpdateQueue extends MergingUpdateQueue { SCROLL_TO_VISIBLE(4), SHOW_HINT(4), REQUEST_FOCUS(4), - NAVIGATE_INSIDE(4); + NAVIGATE_INSIDE(4), + TYPE_AHEAD_FINISHED(5); private final int myPriority; diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java index ea77943d5af9..e03169ec2685 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java @@ -16,9 +16,7 @@ package com.intellij.ide.structureView.newStructureView; -import com.intellij.ide.CopyPasteDelegator; -import com.intellij.ide.DataManager; -import com.intellij.ide.PsiCopyPasteManager; +import com.intellij.ide.*; import com.intellij.ide.structureView.*; import com.intellij.ide.structureView.impl.StructureViewFactoryImpl; import com.intellij.ide.structureView.impl.StructureViewState; @@ -377,8 +375,8 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre public AnAction[] getTitleActions() { return new AnAction[]{ - new ExpandAllAction(getTree()), - new CollapseAllAction(getTree()) + CommonActionsManager.getInstance().createCollapseAllHeaderAction(getTree()), + CommonActionsManager.getInstance().createExpandAllHeaderAction(getTree()), }; } diff --git a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java index 2ec80ddb9818..1236e960cc91 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java +++ b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java @@ -36,9 +36,11 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.ex.MessagesEx; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.WritingAccessProvider; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilBase; +import com.intellij.psi.util.PsiUtilCore; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.safeDelete.SafeDeleteProcessor; import com.intellij.refactoring.util.CommonRefactoringUtil; @@ -286,7 +288,11 @@ public class DeleteHandler { public static boolean shouldEnableDeleteAction(PsiElement[] elements) { if (elements == null || elements.length == 0) return false; for (PsiElement element : elements) { - if (element instanceof PsiCompiledElement) { + VirtualFile virtualFile = PsiUtilCore.getVirtualFile(element); + if (virtualFile == null) { + return false; + } + if (!WritingAccessProvider.isPotentiallyWritable(virtualFile, element.getProject())) { return false; } } diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java index 559044a0bbf0..270c94735c07 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java +++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java @@ -310,6 +310,15 @@ public class FileStructurePopup implements Disposable { @Override public void run() { myTree.repaint(); + if (myFilteringStructure.getRootElement().getChildren().length == 0) { + for (JCheckBox box : myCheckBoxes.values()) { + if (!box.isSelected()) { + box.doClick(); + filter = ""; + break; + } + } + } //if (mySpeedSearch.isPopupActive()) { // mySpeedSearch.refreshSelection(); //} diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/InspectionProjectProfileManager.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/InspectionProjectProfileManager.java index b32e35d1f3ef..9d44932d6a20 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/InspectionProjectProfileManager.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/InspectionProjectProfileManager.java @@ -36,6 +36,7 @@ import com.intellij.packageDependencies.DependencyValidationManager; import com.intellij.profile.DefaultProjectProfileManager; import com.intellij.profile.Profile; import com.intellij.psi.PsiElement; +import com.intellij.util.ui.UIUtil; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -190,6 +191,7 @@ public class InspectionProjectProfileManager extends DefaultProjectProfileManage }; if (app.isUnitTestMode() || app.isHeadlessEnvironment()) { initInspectionProfilesRunnable.run(); + UIUtil.dispatchAllInvocationEvents(); //do not restart daemon in the middle of the test } else { app.executeOnPooledThread(initInspectionProfilesRunnable); } diff --git a/platform/lang-impl/src/com/intellij/psi/scope/DelegatingScopeProcessor.java b/platform/lang-impl/src/com/intellij/psi/scope/DelegatingScopeProcessor.java index 1698e06e5a84..ea5c27501cca 100644 --- a/platform/lang-impl/src/com/intellij/psi/scope/DelegatingScopeProcessor.java +++ b/platform/lang-impl/src/com/intellij/psi/scope/DelegatingScopeProcessor.java @@ -3,6 +3,7 @@ package com.intellij.psi.scope; import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; import com.intellij.psi.ResolveState; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -16,13 +17,13 @@ public abstract class DelegatingScopeProcessor implements PsiScopeProcessor { } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { return myDelegate.execute(element, state); } @Override @Nullable - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { return myDelegate.getHint(hintKey); } diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java index 293ab0095f42..b7e94bc7f93d 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java @@ -716,10 +716,14 @@ public abstract class InplaceRefactoring { final TextResult value = templateState.getVariableValue(PRIMARY_VARIABLE_NAME); myInsertedName = value != null ? value.toString() : null; + TextRange range = templateState.getCurrentVariableRange(); final int currentOffset = myEditor.getCaretModel().getOffset(); + if (range == null && myRenameOffset != null) { + range = new TextRange(myRenameOffset.getStartOffset(), myRenameOffset.getEndOffset()); + } myBeforeRevert = - myRenameOffset != null && myRenameOffset.getEndOffset() >= currentOffset && myRenameOffset.getStartOffset() <= currentOffset - ? myEditor.getDocument().createRangeMarker(myRenameOffset.getStartOffset(), currentOffset) + range != null && range.getEndOffset() >= currentOffset && range.getStartOffset() <= currentOffset + ? myEditor.getDocument().createRangeMarker(range.getStartOffset(), currentOffset) : null; if (myBeforeRevert != null) { myBeforeRevert.setGreedyToRight(true); diff --git a/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java b/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java index fa779821df8f..7624d5bd6827 100644 --- a/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java @@ -30,6 +30,7 @@ import com.intellij.util.Alarm; import com.intellij.util.Function; import com.intellij.util.ui.EmptyIcon; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.plaf.TreeUI; @@ -45,16 +46,16 @@ public class DeferredIconImpl implements DeferredIcon { private volatile boolean myIsScheduled = false; private T myParam; private static final Icon EMPTY_ICON = EmptyIcon.ICON_16; - private boolean myNeedReadAction; + private final boolean myNeedReadAction; private boolean myDone; private IconListener myEvalListener; - public DeferredIconImpl(Icon baseIcon, T param, Function evaluator) { + public DeferredIconImpl(Icon baseIcon, T param, @NotNull Function evaluator) { this(baseIcon, param, true, evaluator); } - public DeferredIconImpl(Icon baseIcon, T param, final boolean needReadAction, Function evaluator) { + public DeferredIconImpl(Icon baseIcon, T param, final boolean needReadAction, @NotNull Function evaluator) { myParam = param; myDelegateIcon = nonNull(baseIcon); myEvaluator = evaluator; @@ -65,6 +66,7 @@ public class DeferredIconImpl implements DeferredIcon { return icon != null ? icon : EMPTY_ICON; } + @Override public void paintIcon(final Component c, final Graphics g, final int x, final int y) { if (!(myDelegateIcon instanceof DeferredIconImpl && ((DeferredIconImpl)myDelegateIcon).myDelegateIcon instanceof DeferredIconImpl)) { myDelegateIcon.paintIcon(c, g, x, y); //SOE protection @@ -116,6 +118,7 @@ public class DeferredIconImpl implements DeferredIcon { } JobUtil.submitToJobThread(Job.DEFAULT_PRIORITY, new Runnable() { + @Override public void run() { int oldWidth = myDelegateIcon.getIconWidth(); final Icon result = evaluate(); @@ -125,6 +128,7 @@ public class DeferredIconImpl implements DeferredIcon { //noinspection SSBasedInspection SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { setDone(result); @@ -177,9 +181,11 @@ public class DeferredIconImpl implements DeferredIcon { myParam = null; } + @Override public Icon evaluate() { final Icon[] evaluated = new Icon[1]; final Runnable runnable = new Runnable() { + @Override public void run() { try { evaluated[0] = nonNull(myEvaluator.fun(myParam)); @@ -226,10 +232,12 @@ public class DeferredIconImpl implements DeferredIcon { } } + @Override public int getIconWidth() { return myDelegateIcon.getIconWidth(); } + @Override public int getIconHeight() { return myDelegateIcon.getIconHeight(); } @@ -245,6 +253,7 @@ public class DeferredIconImpl implements DeferredIcon { public void pushDirtyComponent(final Component c, final Rectangle rec) { myAlarm.cancelAllRequests(); myAlarm.addRequest(new Runnable() { + @Override public void run() { for (RepaintRequest each : myQueue) { Rectangle r = each.getRectangle(); diff --git a/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java b/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java index 58aa34bdc7f7..1be1d296dfc2 100644 --- a/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java @@ -60,7 +60,8 @@ public class IconDeferrerImpl extends IconDeferrer { } } - public Icon defer(final Icon base, final T param, final Function f) { + @Override + public Icon defer(final Icon base, final T param, @NotNull final Function f) { if (myEvaluationIsInProgress.get().booleanValue()) { return f.fun(param); } diff --git a/platform/platform-api/src/com/intellij/ide/CommonActionsManager.java b/platform/platform-api/src/com/intellij/ide/CommonActionsManager.java index 6b08dc23f733..852764a65a26 100644 --- a/platform/platform-api/src/com/intellij/ide/CommonActionsManager.java +++ b/platform/platform-api/src/com/intellij/ide/CommonActionsManager.java @@ -35,10 +35,12 @@ public abstract class CommonActionsManager { @Deprecated public abstract AnAction createExpandAllAction(TreeExpander expander); public abstract AnAction createExpandAllAction(TreeExpander expander, JComponent component); + public abstract AnAction createExpandAllHeaderAction(JTree tree); @Deprecated public abstract AnAction createCollapseAllAction(TreeExpander expander); public abstract AnAction createCollapseAllAction(TreeExpander expander, JComponent component); + public abstract AnAction createCollapseAllHeaderAction(JTree tree); public abstract AnAction createHelpAction(String helpId); @@ -46,7 +48,7 @@ public abstract class CommonActionsManager { * Installs autoscroll capability support to JTree passed. Toggle action returned. * @param project * @return toggle action to be inserted to appropriate toolbar - * @param tree should provide DataContstants.NAVIGATABLE for handler to work on + * @param tree should provide DataConstants.NAVIGATABLE for handler to work on * @param optionProvider get/set API to externalizable property. */ public abstract AnAction installAutoscrollToSourceHandler(Project project, JTree tree, AutoScrollToSourceOptionProvider optionProvider); diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java index 87dde8a28e90..c1f25bc0bc23 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -129,7 +129,7 @@ public abstract class ActionPlaces { FILEVIEW_POPUP, CHECKOUT_POPUP, LVCS_DIRECTORY_HISTORY_POPUP, GUI_DESIGNER_EDITOR_POPUP, GUI_DESIGNER_COMPONENT_TREE_POPUP, GUI_DESIGNER_PROPERTY_INSPECTOR_POPUP, CREATE_EJB_POPUP, CHANGES_VIEW_POPUP, REMOTE_HOST_VIEW_POPUP, REMOTE_HOST_DIALOG_POPUP, TFS_TREE_POPUP, - ACTION_PLACE_VCS_QUICK_LIST_POPUP_ACTION, PHING_EXPLORER_POPUP + ACTION_PLACE_VCS_QUICK_LIST_POPUP_ACTION, PHING_EXPLORER_POPUP, NAVIGATION_BAR }; public static boolean isPopupPlace(@NotNull String place) { diff --git a/platform/platform-api/src/com/intellij/ui/DefaultIconDeferrer.java b/platform/platform-api/src/com/intellij/ui/DefaultIconDeferrer.java index 2bb88da0a17c..adddc1c619f6 100644 --- a/platform/platform-api/src/com/intellij/ui/DefaultIconDeferrer.java +++ b/platform/platform-api/src/com/intellij/ui/DefaultIconDeferrer.java @@ -20,11 +20,12 @@ package com.intellij.ui; import com.intellij.util.Function; +import org.jetbrains.annotations.NotNull; import javax.swing.*; public class DefaultIconDeferrer extends IconDeferrer { - public Icon defer(final Icon base, final T param, final Function f) { + public Icon defer(final Icon base, final T param, @NotNull final Function f) { return f.fun(param); } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/impl/CommonActionsManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/impl/CommonActionsManagerImpl.java index b5d55f683bb0..a48aa7a49421 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/CommonActionsManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/CommonActionsManagerImpl.java @@ -15,6 +15,7 @@ */ package com.intellij.ide.impl; +import com.intellij.icons.AllIcons; import com.intellij.ide.*; import com.intellij.ide.actions.*; import com.intellij.openapi.actionSystem.AnAction; @@ -45,6 +46,14 @@ public class CommonActionsManagerImpl extends CommonActionsManager { return expandAllToolbarAction; } + @Override + public AnAction createExpandAllHeaderAction(JTree tree) { + AnAction action = createExpandAllAction(new DefaultTreeExpander(tree), tree); + action.getTemplatePresentation().setIcon(AllIcons.General.ExpandAll); + action.getTemplatePresentation().setHoveredIcon(AllIcons.General.ExpandAllHover); + return action; + } + public AnAction createCollapseAllAction(TreeExpander expander) { return new CollapseAllToolbarAction(expander); } @@ -55,6 +64,14 @@ public class CommonActionsManagerImpl extends CommonActionsManager { return collapseAllToolbarAction; } + @Override + public AnAction createCollapseAllHeaderAction(JTree tree) { + AnAction action = createCollapseAllAction(new DefaultTreeExpander(tree), tree); + action.getTemplatePresentation().setIcon(AllIcons.General.CollapseAll); + action.getTemplatePresentation().setHoveredIcon(AllIcons.General.CollapseAllHover); + return action; + } + public AnAction createHelpAction(String helpId) { return new ContextHelpAction(helpId); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java index c98519bdc56a..47e911c73f8a 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java @@ -62,7 +62,18 @@ public class InstalledPluginsManagerMain extends PluginManagerMain { @Override public void actionPerformed(ActionEvent e) { final PluginManagerConfigurable configurable = createAvailableConfigurable(); - new SingleConfigurableEditor(myActionsPanel, configurable, ShowSettingsUtilImpl.createDimensionKey(configurable), false).show(); + final SingleConfigurableEditor configurableEditor = + new SingleConfigurableEditor(myActionsPanel, configurable, ShowSettingsUtilImpl.createDimensionKey(configurable), false) { + { + setOKButtonText(CommonBundle.getCloseButtonText()); + } + + @Override + protected Action[] createActions() { + return new Action[]{getOKAction()}; + } + }; + configurableEditor.show(); } }); myActionsPanel.add(button); diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java index 3c445cc106c8..4dee367dfb7d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java @@ -27,6 +27,7 @@ import com.intellij.openapi.editor.markup.TextAttributes; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.awt.*; import java.util.ArrayList; /** @@ -37,6 +38,7 @@ import java.util.ArrayList; class ChangeHighlighterHolder { private static final Logger LOG = Logger.getInstance(ChangeHighlighterHolder.class); + static final int APPLIED_CHANGE_TRANSPARENCY = 30; private Editor myEditor; private final ArrayList myHighlighters = new ArrayList(3); @@ -55,28 +57,41 @@ class ChangeHighlighterHolder { return myEditor.getMarkupModel(); } - private void highlighterCreated(RangeHighlighter highlighter, TextAttributes attrs) { + private void highlighterCreated(RangeHighlighter highlighter, TextAttributes attrs, boolean applied) { if (attrs != null) { - highlighter.setErrorStripeMarkColor(attrs.getErrorStripeColor()); + Color color = attrs.getErrorStripeColor(); + if (applied) { + color = makeColorForApplied(color); + } + highlighter.setErrorStripeMarkColor(color); } myHighlighters.add(highlighter); } + private static Color makeColorForApplied(Color color) { + return new Color(color.getRed(), color.getGreen(), color.getBlue(), APPLIED_CHANGE_TRANSPARENCY); + } + @Nullable - public RangeHighlighter addLineHighlighter(int line, int layer, TextDiffType diffType) { + public RangeHighlighter addLineHighlighter(int line, int layer, TextDiffType diffType, boolean applied) { if (myEditor.getDocument().getTextLength() == 0) return null; RangeHighlighter highlighter = getMarkupModel().addLineHighlighter(line, layer, null); highlighter.setLineSeparatorColor(diffType.getTextBackground(myEditor)); - highlighterCreated(highlighter, diffType.getTextAttributes(myEditor)); + highlighterCreated(highlighter, diffType.getTextAttributes(myEditor), applied); return highlighter; } @Nullable - public RangeHighlighter addRangeHighlighter(int start, int end, int layer, TextDiffType type, HighlighterTargetArea targetArea) { + public RangeHighlighter addRangeHighlighter(int start, + int end, + int layer, + TextDiffType type, + HighlighterTargetArea targetArea, + boolean applied) { if (getMarkupModel().getDocument().getTextLength() == 0) return null; TextAttributes attributes = type.getTextAttributes(myEditor); RangeHighlighter highlighter = getMarkupModel().addRangeHighlighter(start, end, layer, attributes, targetArea); - highlighterCreated(highlighter, attributes); + highlighterCreated(highlighter, attributes, applied); return highlighter; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java index d53490ff22b3..49f2423b8dc6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java @@ -98,7 +98,7 @@ public class ChangeType { int length = text.length(); int start = changeSide.getStart(); int end = start + length; - RangeHighlighter highlighter = markup.addRangeHighlighter(start, end, LAYER, diffType, HighlighterTargetArea.EXACT_RANGE); + RangeHighlighter highlighter = markup.addRangeHighlighter(start, end, LAYER, diffType, HighlighterTargetArea.EXACT_RANGE, myApplied); if (highlighter != null) { highlighter.setLineSeparatorPlacement(SeparatorPlacement.TOP); @@ -111,7 +111,7 @@ public class ChangeType { end--; } - highlighter = markup.addRangeHighlighter(start, end, LAYER, TextDiffType.NONE, HighlighterTargetArea.EXACT_RANGE); + highlighter = markup.addRangeHighlighter(start, end, LAYER, TextDiffType.NONE, HighlighterTargetArea.EXACT_RANGE, myApplied); if (highlighter != null) { highlighter.setLineSeparatorPlacement(SeparatorPlacement.BOTTOM); highlighter.setLineSeparatorColor(separatorColor); @@ -122,8 +122,8 @@ public class ChangeType { } @Nullable - private static RangeHighlighter addLine(ChangeHighlighterHolder markup, int line, TextDiffType type, SeparatorPlacement placement) { - RangeHighlighter highlighter = markup.addLineHighlighter(line, LAYER, type); + private RangeHighlighter addLine(ChangeHighlighterHolder markup, int line, TextDiffType type, SeparatorPlacement placement) { + RangeHighlighter highlighter = markup.addLineHighlighter(line, LAYER, type, myApplied); if (highlighter == null) { return null; } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java index 95164350294f..fbfeb4b0b30a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java @@ -435,6 +435,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl public boolean requestWriting(@NotNull Document document, Project project) { final VirtualFile file = getInstance().getFile(document); if (project != null && file != null && file.isValid()) { + if (file.getFileType().isBinary()) return false; return ReadonlyStatusHandler.ensureFilesWritable(project, file); } if (document.isWritable()) { diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java index 1c1126eea938..0bd8463fc6e8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java @@ -24,6 +24,9 @@ import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.IdeFrame; +import com.intellij.openapi.wm.impl.FocusManagerImpl; import com.intellij.openapi.wm.impl.IdeGlassPaneImpl; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.UIUtil; @@ -123,6 +126,18 @@ public final class IdeMouseEventDispatcher { */ public boolean dispatchMouseEvent(MouseEvent e) { boolean ignore = false; + Component c = e.getComponent(); + + //frame activation by mouse click + if (e.getID() == MOUSE_PRESSED && c instanceof IdeFrame && !c.hasFocus()) { + IdeFocusManager focusManager = IdeFocusManager.getGlobalInstance(); + if (focusManager instanceof FocusManagerImpl) { + Component at = SwingUtilities.getDeepestComponentAt(c, e.getX(), e.getY()); + if (at != null && at.isFocusable()) { + ((FocusManagerImpl)focusManager).setLastFocusedAtDeactivation((IdeFrame)c, at); + } + } + } if (SystemInfo.isLinux && e.isPopupTrigger() && e.getButton() != 3) { // we can do better than silly triggering popup on everything but left click @@ -158,23 +173,21 @@ public final class IdeMouseEventDispatcher { } } - - Component component = e.getComponent(); - if (component == null) { + if (c == null) { throw new IllegalStateException("component cannot be null"); } - component = SwingUtilities.getDeepestComponentAt(component, e.getX(), e.getY()); + c = SwingUtilities.getDeepestComponentAt(c, e.getX(), e.getY()); - if (component instanceof IdeGlassPaneImpl) { - component = ((IdeGlassPaneImpl)component).getTargetComponentFor(e); + if (c instanceof IdeGlassPaneImpl) { + c = ((IdeGlassPaneImpl)c).getTargetComponentFor(e); } - if (component == null) { // do nothing if component doesn't contains specified point + if (c == null) { // do nothing if component doesn't contains specified point return false; } - if (isHorizontalScrolling(component, e)) { - boolean done = doHorizontalScrolling(component, (MouseWheelEvent)e); + if (isHorizontalScrolling(c, e)) { + boolean done = doHorizontalScrolling(c, (MouseWheelEvent)e); if (done) return true; } @@ -186,12 +199,12 @@ public final class IdeMouseEventDispatcher { } final MouseShortcut shortcut = new MouseShortcut(e.getButton(), e.getModifiersEx(), e.getClickCount()); - fillActionsList(component, shortcut, IdeKeyEventDispatcher.isModalContext(component)); + fillActionsList(c, shortcut, IdeKeyEventDispatcher.isModalContext(c)); ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); if (actionManager != null) { AnAction[] actions = myActions.toArray(new AnAction[myActions.size()]); for (AnAction action : actions) { - DataContext dataContext = DataManager.getInstance().getDataContext(component); + DataContext dataContext = DataManager.getInstance().getDataContext(c); Presentation presentation = myPresentationFactory.getPresentation(action); AnActionEvent actionEvent = new AnActionEvent(e, dataContext, ActionPlaces.MAIN_MENU, presentation, ActionManager.getInstance(), @@ -200,9 +213,9 @@ public final class IdeMouseEventDispatcher { if (presentation.isEnabled()) { actionManager.fireBeforeActionPerformed(action, dataContext, actionEvent); - final Component c = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); + final Component context = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); - if (c != null && !c.isShowing()) continue; + if (context != null && !context.isShowing()) continue; action.actionPerformed(actionEvent); e.consume(); diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java index 59d412025a23..c2b4948d7a98 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java @@ -23,12 +23,14 @@ import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.components.StoragePathMacros; -import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.MultiValuesMap; import com.intellij.openapi.vfs.ReadonlyStatusHandler; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.WritingAccessProvider; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -54,7 +56,7 @@ public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements public ReadonlyStatusHandlerImpl(Project project) { myProject = project; - myAccessProviders = project.isDefault() ? new WritingAccessProvider[0] : Extensions.getExtensions(WritingAccessProvider.EP_NAME, project); + myAccessProviders = WritingAccessProvider.getProvidersForProject(myProject); } public State getState() { @@ -80,8 +82,17 @@ public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements } files = VfsUtil.toVirtualFileArray(realFiles); - for (WritingAccessProvider accessProvider : myAccessProviders) { - Collection denied = accessProvider.requestWriting(files); + for (final WritingAccessProvider accessProvider : myAccessProviders) { + Collection denied = ContainerUtil.filter(files, new Condition() { + @Override + public boolean value(final VirtualFile virtualFile) { + return !accessProvider.isPotentiallyWritable(virtualFile); + } + }); + + if (denied.isEmpty()) { + denied = accessProvider.requestWriting(files); + } if (!denied.isEmpty()) { return new OperationStatusImpl(VfsUtil.toVirtualFileArray(denied)); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java index ec63024221e4..df0a0a449e79 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java @@ -83,7 +83,7 @@ class VirtualFilePointerImpl extends TraceableDisposable implements VirtualFileP private void checkDisposed() { if (isDisposed()) { - throwDisposalError("Already disposed: URL=" + getUrlNoUpdate()); + throwDisposalError("Already disposed: URL='" + this+"'"); } } @@ -102,7 +102,7 @@ class VirtualFilePointerImpl extends TraceableDisposable implements VirtualFileP public void dispose() { checkDisposed(); if (myNode.incrementUsageCount(-1) == 0) { - kill(null); + kill("URL when die: "+ toString()); VirtualFilePointerManager pointerManager = VirtualFilePointerManager.getInstance(); if (pointerManager instanceof VirtualFilePointerManagerImpl) { ((VirtualFilePointerManagerImpl)pointerManager).removeNode(myNode, myListener); // remove from the tree diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java index bbdb217f8967..e92039ec2039 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java @@ -275,7 +275,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp if (!left.isEmpty()) { VirtualFilePointerImpl p = left.get(0).leaf; try { - p.throwDisposalError("Not disposed pointer: "+p.getUrlNoUpdate()); + p.throwDisposalError("Not disposed pointer: "+p); } finally { for (FilePointerPartNode pair : left) { @@ -308,7 +308,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp try { for (VirtualFilePointerImpl pointer : pointers) { if (!myStoredPointers.contains(pointer)) { - pointer.throwDisposalError("Virtual pointer hasn't been disposed: "+pointer.getUrlNoUpdate()); + pointer.throwDisposalError("Virtual pointer hasn't been disposed: "+pointer); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index cf7943fff3aa..6983d336869b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -902,6 +902,10 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { return ref != null ? ref.get() : null; } + public void setLastFocusedAtDeactivation(IdeFrame frame, Component c) { + myLastFocusedAtDeactivation.put(frame, new WeakReference(c)); + } + @Override public void toFront(JComponent c) { assertDispatchThread(); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java index 49af843ac29f..5e16df80059c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java @@ -550,11 +550,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable { } private static String getToolTipTextByAction(AnAction action) { - String text = action.getTemplatePresentation().getText(); - final String shortcutForAction = KeymapUtil.getFirstKeyboardShortcutText(action); - if (shortcutForAction.length() > 0) { - text += " " + shortcutForAction; - } + String text = AnAction.createTooltipText(action.getTemplatePresentation().getText(), action); if (action instanceof HideAction) { text += String.format(" (Click with %s to Hide Side)", KeymapUtil.getShortcutText(KeyboardShortcut.fromString("pressed ALT"))); diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java index 95ad1d46b940..22502b46ea00 100644 --- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java +++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java @@ -218,7 +218,7 @@ abstract public class AbstractExpandableItemsHandler - + diff --git a/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml b/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml index 9bf934d49f88..046a54fe4195 100644 --- a/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/VcsExtensionPoints.xml @@ -31,7 +31,7 @@ interface="com.intellij.vcsUtil.VcsSelectionProvider"/> - + - - - - diff --git a/platform/testFramework/src/com/intellij/testFramework/FileTreeAccessFilter.java b/platform/testFramework/src/com/intellij/testFramework/FileTreeAccessFilter.java index 678dbefbbbcb..06155a9004ef 100755 --- a/platform/testFramework/src/com/intellij/testFramework/FileTreeAccessFilter.java +++ b/platform/testFramework/src/com/intellij/testFramework/FileTreeAccessFilter.java @@ -17,11 +17,11 @@ package com.intellij.testFramework; import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileFilter; import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Set; @@ -43,7 +43,7 @@ public class FileTreeAccessFilter implements VirtualFileFilter { return (fileType == StdFileTypes.JAVA || fileType == StdFileTypes.CLASS) && !file.getName().equals("package-info.java"); } - public void allowTreeAccessForFile(VirtualFile file) { + public void allowTreeAccessForFile(@NotNull VirtualFile file) { myAddedClasses.add(file); } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java index 6be249c5717e..0571b0f8ee77 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java @@ -358,7 +358,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { void renameElement(PsiElement element, String newName); - void allowTreeAccessForFile(VirtualFile file); + void allowTreeAccessForFile(@NotNull VirtualFile file); void allowTreeAccessForAllFiles(); diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index dfe811c516db..7e8b2360c90c 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -1487,7 +1487,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig } @Override - public void allowTreeAccessForFile(final VirtualFile file) { + public void allowTreeAccessForFile(@NotNull final VirtualFile file) { myJavaFilesFilter.allowTreeAccessForFile(file); } diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java index b77a5823b58d..6540aa079eaf 100644 --- a/platform/util/src/com/intellij/icons/AllIcons.java +++ b/platform/util/src/com/intellij/icons/AllIcons.java @@ -408,6 +408,8 @@ public class AllIcons { public static final Icon ErrorsInProgress = IconLoader.getIcon("/general/errorsInProgress.png"); public static final Icon ErrorsOK = IconLoader.getIcon("/general/errorsOK.png"); public static final Icon ExclMark = IconLoader.getIcon("/general/exclMark.png"); + public static final Icon ExpandAll = IconLoader.getIcon("/general/expandAll.png"); + public static final Icon ExpandAllHover = IconLoader.getIcon("/general/expandAllHover.png"); public static final Icon ExternalTools = IconLoader.getIcon("/general/externalTools.png"); public static final Icon ExtTools = IconLoader.getIcon("/general/extTools.png"); public static final Icon FileTemplates = IconLoader.getIcon("/general/fileTemplates.png"); @@ -602,11 +604,6 @@ public class AllIcons { } public static final Icon Icon = IconLoader.getIcon("/icon.png"); - public static final Icon Icon_CE = IconLoader.getIcon("/icon_CE.png"); - public static final Icon Icon_CEsmall = IconLoader.getIcon("/icon_CEsmall.png"); - public static final Icon Icon_CEwhite = IconLoader.getIcon("/icon_CEwhite.png"); - public static final Icon Icon_small = IconLoader.getIcon("/icon_small.png"); - public static final Icon Icon_white = IconLoader.getIcon("/icon_white.png"); public static class Icons { @@ -630,6 +627,11 @@ public class AllIcons { } } + public static final Icon Icon_CE = IconLoader.getIcon("/icon_CE.png"); + public static final Icon Icon_CEsmall = IconLoader.getIcon("/icon_CEsmall.png"); + public static final Icon Icon_CEwhite = IconLoader.getIcon("/icon_CEwhite.png"); + public static final Icon Icon_small = IconLoader.getIcon("/icon_small.png"); + public static final Icon Icon_white = IconLoader.getIcon("/icon_white.png"); public static class Ide { public static final Icon DefaultProfile = IconLoader.getIcon("/ide/defaultProfile.png"); @@ -644,9 +646,9 @@ public class AllIcons { } public static final Icon EmptyFatalError = IconLoader.getIcon("/ide/emptyFatalError.png"); - public static final Icon Error_notifications = IconLoader.getIcon("/ide/error_notifications.png"); public static final Icon ErrorPoint = IconLoader.getIcon("/ide/errorPoint.png"); public static final Icon ErrorSign = IconLoader.getIcon("/ide/errorSign.png"); + public static final Icon Error_notifications = IconLoader.getIcon("/ide/error_notifications.png"); public static final Icon FacetDetected = IconLoader.getIcon("/ide/facetDetected.png"); public static final Icon FatalError_read = IconLoader.getIcon("/ide/fatalError-read.png"); public static final Icon FatalError = IconLoader.getIcon("/ide/fatalError.png"); @@ -760,13 +762,13 @@ public class AllIcons { public static final Icon TypeNumeric = IconLoader.getIcon("/javaee/typeNumeric.png"); public static final Icon TypeString = IconLoader.getIcon("/javaee/typeString.png"); public static final Icon UpdateRunningApplication = IconLoader.getIcon("/javaee/updateRunningApplication.png"); - public static final Icon Web_xml = IconLoader.getIcon("/javaee/web_xml.png"); public static final Icon WebModule = IconLoader.getIcon("/javaee/webModule.png"); public static final Icon WebModuleBig = IconLoader.getIcon("/javaee/webModuleBig.png"); public static final Icon WebModuleGroup = IconLoader.getIcon("/javaee/webModuleGroup.png"); public static final Icon WebService = IconLoader.getIcon("/javaee/WebService.png"); public static final Icon WebServiceClient = IconLoader.getIcon("/javaee/WebServiceClient.png"); public static final Icon WebToolWindow = IconLoader.getIcon("/javaee/webToolWindow.png"); + public static final Icon Web_xml = IconLoader.getIcon("/javaee/web_xml.png"); } @@ -862,10 +864,6 @@ public class AllIcons { public static final Icon Artifact = IconLoader.getIcon("/nodes/artifact.png"); public static final Icon Aspect = IconLoader.getIcon("/nodes/aspect.png"); public static final Icon BeaSmall = IconLoader.getIcon("/nodes/beaSmall.png"); - public static final Icon C_plocal = IconLoader.getIcon("/nodes/c_plocal.png"); - public static final Icon C_private = IconLoader.getIcon("/nodes/c_private.png"); - public static final Icon C_protected = IconLoader.getIcon("/nodes/c_protected.png"); - public static final Icon C_public = IconLoader.getIcon("/nodes/c_public.png"); public static final Icon Class = IconLoader.getIcon("/nodes/class.png"); public static final Icon ClassInitializer = IconLoader.getIcon("/nodes/classInitializer.png"); public static final Icon CollapseNode = IconLoader.getIcon("/nodes/collapseNode.png"); @@ -873,6 +871,10 @@ public class AllIcons { public static final Icon CopyOfFolder = IconLoader.getIcon("/nodes/copyOfFolder.png"); public static final Icon Cvs_global = IconLoader.getIcon("/nodes/cvs_global.png"); public static final Icon Cvs_roots = IconLoader.getIcon("/nodes/cvs_roots.png"); + public static final Icon C_plocal = IconLoader.getIcon("/nodes/c_plocal.png"); + public static final Icon C_private = IconLoader.getIcon("/nodes/c_private.png"); + public static final Icon C_protected = IconLoader.getIcon("/nodes/c_protected.png"); + public static final Icon C_public = IconLoader.getIcon("/nodes/c_public.png"); public static final Icon DataColumn = IconLoader.getIcon("/nodes/dataColumn.png"); public static final Icon DataConnection = IconLoader.getIcon("/nodes/dataConnection.png"); public static final Icon DataFkColumn = IconLoader.getIcon("/nodes/dataFkColumn.png"); @@ -1135,8 +1137,8 @@ public class AllIcons { public static final Icon Remote = IconLoader.getIcon("/runConfigurations/remote.png"); public static final Icon RerunFailedTests = IconLoader.getIcon("/runConfigurations/rerunFailedTests.png"); public static final Icon SaveTempConfig = IconLoader.getIcon("/runConfigurations/saveTempConfig.png"); - public static final Icon Scroll_down = IconLoader.getIcon("/runConfigurations/scroll_down.png"); public static final Icon ScrollToStackTrace = IconLoader.getIcon("/runConfigurations/scrollToStackTrace.png"); + public static final Icon Scroll_down = IconLoader.getIcon("/runConfigurations/scroll_down.png"); public static final Icon SelectFirstDefect = IconLoader.getIcon("/runConfigurations/selectFirstDefect.png"); public static final Icon SourceAtException = IconLoader.getIcon("/runConfigurations/sourceAtException.png"); public static final Icon TestError = IconLoader.getIcon("/runConfigurations/testError.png"); diff --git a/platform/util/src/com/intellij/openapi/util/TraceableDisposable.java b/platform/util/src/com/intellij/openapi/util/TraceableDisposable.java index d62ff60d8802..c1c70463ca9b 100644 --- a/platform/util/src/com/intellij/openapi/util/TraceableDisposable.java +++ b/platform/util/src/com/intellij/openapi/util/TraceableDisposable.java @@ -34,9 +34,9 @@ public class TraceableDisposable { CREATE_TRACE = creation; } - public void kill(@Nullable String msg) { + public void kill(@NonNls @Nullable String msg) { if (CREATE_TRACE != null) { - KILL_TRACE = new Throwable(); + KILL_TRACE = new Throwable(msg); } } diff --git a/platform/util/src/com/intellij/util/WalkingState.java b/platform/util/src/com/intellij/util/WalkingState.java index 02af56ff126d..728b31501083 100644 --- a/platform/util/src/com/intellij/util/WalkingState.java +++ b/platform/util/src/com/intellij/util/WalkingState.java @@ -107,6 +107,9 @@ public class WalkingState { stopped = true; } + /** + * process in the in-order fashion + */ public static boolean processAll(@NotNull T root, @NotNull TreeGuide treeGuide, @NotNull final Processor processor) { final boolean[] result = {true}; new WalkingState(treeGuide){ diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictAccessProvider.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictAccessProvider.java index efae427ae26e..acd74d8143cb 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictAccessProvider.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictAccessProvider.java @@ -20,7 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeList; import com.intellij.openapi.vcs.changes.ChangeListManagerImpl; -import com.intellij.openapi.vcs.readOnlyHandler.WritingAccessProvider; +import com.intellij.openapi.vfs.WritingAccessProvider; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; @@ -32,7 +32,7 @@ import java.util.Collections; /** * @author Dmitry Avdeev */ -public class ChangelistConflictAccessProvider implements WritingAccessProvider { +public class ChangelistConflictAccessProvider extends WritingAccessProvider { private final Project myProject; private final ChangeListManagerImpl myManager; @@ -43,6 +43,7 @@ public class ChangelistConflictAccessProvider implements WritingAccessProvider { } @NotNull + @Override public Collection requestWriting(VirtualFile... files) { ChangelistConflictTracker.Options options = myManager.getConflictTracker().getOptions(); if (!options.TRACKING_ENABLED || !options.SHOW_DIALOG) { @@ -78,4 +79,9 @@ public class ChangelistConflictAccessProvider implements WritingAccessProvider { } return denied; } + + @Override + public boolean isPotentiallyWritable(@NotNull final VirtualFile file) { + return true; + } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CovariantCompareToInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CovariantCompareToInspection.java index 244d9d833450..5cddf30e7f9e 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CovariantCompareToInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CovariantCompareToInspection.java @@ -76,42 +76,34 @@ public class CovariantCompareToInspection extends BaseInspection { } final PsiMethod[] methods = aClass.findMethodsByName( HardcodedMethodConstants.COMPARE_TO, false); - for (PsiMethod compareToMethod : methods) { - if (isNonVariantCompareTo(compareToMethod)) { - return; - } - } final Project project = method.getProject(); final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); final GlobalSearchScope scope = method.getResolveScope(); - final PsiClass comparableClass = - psiFacade.findClass(CommonClassNames.JAVA_LANG_COMPARABLE, - scope); + final PsiClass comparableClass = psiFacade.findClass(CommonClassNames.JAVA_LANG_COMPARABLE, scope); + PsiType substitutedTypeParam = null; if (comparableClass != null && comparableClass.getTypeParameters().length == 1) { - final PsiSubstitutor superSubstitutor = - TypeConversionUtil.getClassSubstitutor(comparableClass, - aClass, PsiSubstitutor.EMPTY); + final PsiSubstitutor superSubstitutor = TypeConversionUtil.getClassSubstitutor(comparableClass, aClass, PsiSubstitutor.EMPTY); //null iff aClass is not inheritor of comparableClass if (superSubstitutor != null) { - final PsiType substituted = - superSubstitutor.substitute( - comparableClass.getTypeParameters()[0]); - if (paramType.equals(substituted)) { - return; - } + substitutedTypeParam = superSubstitutor.substitute(comparableClass.getTypeParameters()[0]); + } + } + for (PsiMethod compareToMethod : methods) { + if (isNonVariantCompareTo(compareToMethod, substitutedTypeParam)) { + return; } } registerMethodError(method); } - private static boolean isNonVariantCompareTo(PsiMethod method) { + private static boolean isNonVariantCompareTo(PsiMethod method, PsiType substitutedTypeParam) { final PsiManager manager = method.getManager(); final Project project = method.getProject(); final PsiClassType objectType = PsiType.getJavaLangObject( manager, GlobalSearchScope.allScope(project)); - return MethodUtils.methodMatches(method, null, PsiType.INT, - HardcodedMethodConstants.COMPARE_TO, objectType); + return MethodUtils.methodMatches(method, null, PsiType.INT, HardcodedMethodConstants.COMPARE_TO, objectType) || + (substitutedTypeParam != null && MethodUtils.methodMatches(method, null, PsiType.INT, HardcodedMethodConstants.COMPARE_TO, substitutedTypeParam)); } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CovariantEqualsInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CovariantEqualsInspection.java index 1247f7f02cda..c3f2642996e4 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CovariantEqualsInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CovariantEqualsInspection.java @@ -63,7 +63,7 @@ public class CovariantEqualsInspection extends BaseInspection { return; } final PsiClass aClass = method.getContainingClass(); - if (aClass == null) { + if (aClass == null || aClass.isInterface()) { return; } final PsiMethod[] methods = aClass.getMethods(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InstanceOfUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InstanceOfUtils.java index 68eaa0c19b66..702d84d522ac 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InstanceOfUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InstanceOfUtils.java @@ -113,6 +113,9 @@ public class InstanceOfUtils { } else if (tokenType == JavaTokenType.OROR) { for (PsiExpression operand : expression.getOperands()) { + if (operand instanceof PsiPrefixExpression && ((PsiPrefixExpression)operand).getOperationTokenType() == JavaTokenType.EXCL) { + inElse = true; + } checkExpression(operand); } if (inElse && conflictingInstanceof != null) { @@ -125,8 +128,7 @@ public class InstanceOfUtils { public void visitIfStatement(PsiIfStatement ifStatement) { final PsiStatement branch = ifStatement.getElseBranch(); inElse = branch != null && - PsiTreeUtil.isAncestor(branch, referenceExpression, - true); + PsiTreeUtil.isAncestor(branch, referenceExpression, true); if (inElse) { if (branch instanceof PsiBlockStatement) { final PsiBlockStatement blockStatement = @@ -161,8 +163,7 @@ public class InstanceOfUtils { } @Override - public void visitConditionalExpression( - PsiConditionalExpression expression) { + public void visitConditionalExpression(PsiConditionalExpression expression) { final PsiExpression elseExpression = expression.getElseExpression(); inElse = elseExpression != null && diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/notOr/NotOr.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/notOr/NotOr.java new file mode 100644 index 000000000000..15c0199b3b0d --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/notOr/NotOr.java @@ -0,0 +1,11 @@ +interface I1 {} +interface I2 extends I1{} +interface I3 extends I1 {} + +class PP { + void f(Object o) { + if (o instanceof I1) { + if (!(o instanceof I2) || ((I2)o).getClass() != null){} + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/notOr/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/notOr/expected.xml new file mode 100644 index 000000000000..580a889dbfd6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/castConflictingInstanceof/notOr/expected.xml @@ -0,0 +1,3 @@ + + + diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantCompareTo/simple/Simple.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantCompareTo/simple/Simple.java new file mode 100644 index 000000000000..52fed23d835d --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantCompareTo/simple/Simple.java @@ -0,0 +1,11 @@ +import java.lang.Comparable; + +class Foo implements Comparable { + public int compareTo(Foo o) { + return 0; //To change body of implemented methods use File | Settings | File Templates. + } + + public int compareTo(String o) { + return 0; //To change body of implemented methods use File | Settings | File Templates. + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantCompareTo/simple/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantCompareTo/simple/expected.xml new file mode 100644 index 000000000000..4704d91e891d --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantCompareTo/simple/expected.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantEquals/interf/Interf.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantEquals/interf/Interf.java new file mode 100644 index 000000000000..bc7b5a1e40c0 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantEquals/interf/Interf.java @@ -0,0 +1,3 @@ +interface I { + boolean equals(I i); +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantEquals/interf/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantEquals/interf/expected.xml new file mode 100644 index 000000000000..4704d91e891d --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/covariantEquals/interf/expected.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspectionTest.java index e7593bfa5d39..ff6d488a6fd9 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CastConflictsWithInstanceofInspectionTest.java @@ -38,6 +38,10 @@ public class CastConflictsWithInstanceofInspectionTest extends IGInspectionTestC public void testPolyadic() throws Exception { doTest(); } + + public void testNotOr() throws Exception { + doTest(); + } private void doTest() throws Exception { doTest("com/siyeh/igtest/bugs/castConflictingInstanceof/" + getTestName(true), new CastConflictsWithInstanceofInspection()); diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CovariantCompareToInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CovariantCompareToInspectionTest.java new file mode 100644 index 000000000000..2109c8b1fcf3 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CovariantCompareToInspectionTest.java @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2012 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.siyeh.ig.bugs; + +import com.siyeh.ig.IGInspectionTestCase; + +public class CovariantCompareToInspectionTest extends IGInspectionTestCase { + + public void testSimple() throws Exception { + doTest(); + } + + private void doTest() throws Exception { + doTest("com/siyeh/igtest/bugs/covariantCompareTo/" + getTestName(true), new CovariantCompareToInspection()); + } +} diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CovariantEqualsInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CovariantEqualsInspectionTest.java new file mode 100644 index 000000000000..204c66836339 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/CovariantEqualsInspectionTest.java @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2012 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.siyeh.ig.bugs; + +import com.siyeh.ig.IGInspectionTestCase; + +public class CovariantEqualsInspectionTest extends IGInspectionTestCase { + + public void testInterf() throws Exception { + doTest(); + } + + private void doTest() throws Exception { + doTest("com/siyeh/igtest/bugs/covariantEquals/" + getTestName(true), new CovariantEqualsInspection()); + } +} diff --git a/plugins/IntelliLang/xml-support/resources/xmlInjections-java.xml b/plugins/IntelliLang/xml-support/resources/xmlInjections-java.xml index a3284d2d0cab..9d561eff76ee 100644 --- a/plugins/IntelliLang/xml-support/resources/xmlInjections-java.xml +++ b/plugins/IntelliLang/xml-support/resources/xmlInjections-java.xml @@ -37,7 +37,7 @@ query - + query diff --git a/plugins/git4idea/src/git4idea/actions/GitUnstash.java b/plugins/git4idea/src/git4idea/actions/GitUnstash.java index 0715c8b46e45..2eb28c6caf2a 100644 --- a/plugins/git4idea/src/git4idea/actions/GitUnstash.java +++ b/plugins/git4idea/src/git4idea/actions/GitUnstash.java @@ -20,7 +20,6 @@ import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vfs.VirtualFile; import git4idea.i18n.GitBundle; -import git4idea.repo.GitRepositoryManager; import git4idea.ui.GitUnstashDialog; import org.jetbrains.annotations.NotNull; @@ -50,6 +49,11 @@ public class GitUnstash extends GitRepositoryAction { final List exceptions) throws VcsException { final ChangeListManager changeListManager = ChangeListManager.getInstance(project); if (changeListManager.isFreezedWithNotification("Can not unstash changes now")) return; - GitUnstashDialog.showUnstashDialog(project, gitRoots, defaultRoot, affectedRoots); + GitUnstashDialog.showUnstashDialog(project, gitRoots, defaultRoot); + } + + @Override + protected boolean executeFinalTasksSynchronously() { + return false; } } diff --git a/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java b/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java index 05b8246dd7ab..03cfab25bc84 100644 --- a/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java +++ b/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java @@ -372,12 +372,6 @@ public class GitHandlerUtil { } } } - /** - * Error indicators for the line - */ - @NonNls private static final String[] ERROR_INDICATORS = - {"ERROR:", "error", "FATAL:", "fatal", "Cannot apply", "Could not", "Interactive rebase already started", "refusing to pull", - "cannot rebase:"}; /** * Check if the line is an error line @@ -386,7 +380,7 @@ public class GitHandlerUtil { * @return true if the error line */ protected static boolean isErrorLine(String text) { - for (String prefix : ERROR_INDICATORS) { + for (String prefix : GitImpl.ERROR_INDICATORS) { if (text.startsWith(prefix)) { return true; } diff --git a/plugins/git4idea/src/git4idea/commands/GitImpl.java b/plugins/git4idea/src/git4idea/commands/GitImpl.java index 9f9eeae22688..29d6be84a3cb 100644 --- a/plugins/git4idea/src/git4idea/commands/GitImpl.java +++ b/plugins/git4idea/src/git4idea/commands/GitImpl.java @@ -339,14 +339,14 @@ public class GitImpl implements Git { } } - private GitCommandResult run(@NotNull GitLineHandler handler) { + private static GitCommandResult run(@NotNull GitLineHandler handler) { return run(handler, false); } /** * Runs the given {@link GitLineHandler} in the current thread and returns the {@link GitCommandResult}. */ - private GitCommandResult run(@NotNull GitLineHandler handler, boolean remote) { + private static GitCommandResult run(@NotNull GitLineHandler handler, boolean remote) { handler.setNoSSH(!remote); final List errorOutput = new ArrayList(); @@ -387,7 +387,7 @@ public class GitImpl implements Git { /** * Check if the line looks line an error message */ - private boolean isError(String text) { + private static boolean isError(String text) { for (String indicator : ERROR_INDICATORS) { if (text.startsWith(indicator.toLowerCase())) { return true; @@ -397,8 +397,9 @@ public class GitImpl implements Git { } // could be upper-cased, so should check case-insensitively - private final String[] ERROR_INDICATORS = { - "error", "fatal", "Cannot apply", "Could not", "Interactive rebase already started", "refusing to pull", "cannot rebase:", "conflict" + public static final String[] ERROR_INDICATORS = { + "error", "fatal", "Cannot apply", "Could not", "Interactive rebase already started", "refusing to pull", "cannot rebase:", "conflict", + "unable" }; } diff --git a/plugins/git4idea/src/git4idea/push/GitPusher.java b/plugins/git4idea/src/git4idea/push/GitPusher.java index ebb558aec8fe..b150324b3218 100644 --- a/plugins/git4idea/src/git4idea/push/GitPusher.java +++ b/plugins/git4idea/src/git4idea/push/GitPusher.java @@ -15,6 +15,7 @@ */ package git4idea.push; +import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -45,6 +46,7 @@ import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryManager; import git4idea.settings.GitPushSettings; import git4idea.update.GitUpdateProcess; +import git4idea.update.GitUpdateResult; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -546,12 +548,31 @@ public final class GitPusher { private boolean update(@NotNull Collection rootsToUpdate, @NotNull UpdateMethod updateMethod) { GitUpdateProcess.UpdateMethod um = updateMethod == UpdateMethod.MERGE ? GitUpdateProcess.UpdateMethod.MERGE : GitUpdateProcess.UpdateMethod.REBASE; - boolean updateResult = new GitUpdateProcess(myProject, myProgressIndicator, new HashSet(rootsToUpdate), + GitUpdateResult updateResult = new GitUpdateProcess(myProject, myProgressIndicator, new HashSet(rootsToUpdate), UpdatedFiles.create()).update(um); for (GitRepository repository : rootsToUpdate) { repository.getRoot().refresh(true, true); } - return updateResult; + if (updateResult == GitUpdateResult.SUCCESS) { + return true; + } + else if (updateResult == GitUpdateResult.SUCCESS_WITH_RESOLVED_CONFLICTS || updateResult == GitUpdateResult.INCOMPLETE) { + String title = "Push cancelled"; + String description; + if (updateResult == GitUpdateResult.INCOMPLETE) { + description = "Push has been cancelled, because not all conflicts were resolved during update.
" + + "Resolve the conflicts and invoke push again."; + } + else { + description = "Push has been cancelled, because there were conflicts during update.
" + + "Check that conflicts were resolved correctly, and invoke push again."; + } + new Notification(GitVcs.MINOR_NOTIFICATION.getDisplayId(), title, description, NotificationType.WARNING).notify(myProject); + return false; + } + else { + return false; + } } } diff --git a/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java b/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java index 48bb90ea6839..8a5286351c3d 100644 --- a/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java +++ b/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java @@ -99,7 +99,7 @@ public class GitStashChangesSaver extends GitChangesSaver { @Override protected void showSavedChanges() { - GitUnstashDialog.showUnstashDialog(myProject, new ArrayList(myStashedRoots), myStashedRoots.iterator().next(), new HashSet()); + GitUnstashDialog.showUnstashDialog(myProject, new ArrayList(myStashedRoots), myStashedRoots.iterator().next()); } @Override @@ -216,8 +216,8 @@ public class GitStashChangesSaver extends GitChangesSaver { if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { if (event.getDescription().equals("saver")) { // we don't use #showSavedChanges to specify unmerged root first - GitUnstashDialog.showUnstashDialog(myProject, new ArrayList(myStashedRoots), myStashedRoots.iterator().next(), - new HashSet()); + GitUnstashDialog.showUnstashDialog(myProject, new ArrayList(myStashedRoots), myStashedRoots.iterator().next() + ); } else if (event.getDescription().equals("resolve")) { mergeNoProceed(); } diff --git a/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java b/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java index bf3d7793306b..df7051f224de 100644 --- a/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java +++ b/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java @@ -390,26 +390,10 @@ public class GitUnstashDialog extends DialogWrapper { return myStashList; } - /** - * Show unstash dialog and process its result - * - * @param project the context project - * @param gitRoots the git roots - * @param defaultRoot the default git root - * @param affectedRoots the affected roots - */ - public static void showUnstashDialog(Project project, - List gitRoots, - VirtualFile defaultRoot, - Set affectedRoots) { - GitUnstashDialog d = new GitUnstashDialog(project, gitRoots, defaultRoot); - d.show(); - if (!d.isOK()) { - return; - } - VirtualFile root = d.getGitRoot(); - affectedRoots.add(root); - GitLineHandler h = d.handler(); + @Override + protected void doOKAction() { + VirtualFile root = getGitRoot(); + GitLineHandler h = handler(); final AtomicBoolean conflict = new AtomicBoolean(); h.addLineListener(new GitLineHandlerAdapter() { @@ -423,11 +407,17 @@ public class GitUnstashDialog extends DialogWrapper { root.refresh(true, true); if (conflict.get()) { - boolean conflictsResolved = new UnstashConflictResolver(project, root, d.getSelectedStash()).merge(); + boolean conflictsResolved = new UnstashConflictResolver(myProject, root, getSelectedStash()).merge(); LOG.info("loadRoot " + root + ", conflictsResolved: " + conflictsResolved); } else if (rc != 0) { - GitUIUtil.showOperationErrors(project, h.errors(), h.printableCommandLine()); + GitUIUtil.showOperationErrors(myProject, h.errors(), h.printableCommandLine()); } + super.doOKAction(); + } + + public static void showUnstashDialog(Project project, List gitRoots, VirtualFile defaultRoot) { + new GitUnstashDialog(project, gitRoots, defaultRoot).show(); + // d is not modal=> everything else in doOKAction. } private static class UnstashConflictResolver extends GitConflictResolver { diff --git a/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java b/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java index 1360c937e990..6d4c72597fac 100644 --- a/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java +++ b/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java @@ -113,7 +113,7 @@ public class GitMergeUpdater extends GitUpdater { LOG.info("Conflict detected"); final boolean allMerged = new MyConflictResolver(myProject, myGit, merger, myRoot).merge(); - return allMerged ? GitUpdateResult.SUCCESS : GitUpdateResult.INCOMPLETE; + return allMerged ? GitUpdateResult.SUCCESS_WITH_RESOLVED_CONFLICTS : GitUpdateResult.INCOMPLETE; } else if (error == MergeError.LOCAL_CHANGES) { LOG.info("Local changes would be overwritten by merge"); diff --git a/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java b/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java index 74b7df43e02b..be59067a6cfb 100644 --- a/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java +++ b/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java @@ -105,7 +105,7 @@ public class GitRebaseUpdater extends GitUpdater { if (rebaseConflictDetector.isMergeConflict()) { LOG.info("handleRebaseFailure merge conflict"); final boolean allMerged = new MyConflictResolver(myProject, myGit, myRoot, myRebaser).merge(); - return allMerged ? GitUpdateResult.SUCCESS : GitUpdateResult.INCOMPLETE; + return allMerged ? GitUpdateResult.SUCCESS_WITH_RESOLVED_CONFLICTS : GitUpdateResult.INCOMPLETE; } else if (untrackedWouldBeOverwrittenDetector.wasMessageDetected()) { LOG.info("handleRebaseFailure: untracked files would be overwritten by checkout"); UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, ServiceManager.getService(myProject, PlatformFacade.class), diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java b/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java index 1ef496047022..0fa3515fdf7c 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java @@ -66,7 +66,7 @@ public class GitUpdateEnvironment implements UpdateEnvironment { GitRepositoryManager repositoryManager = getRepositoryManager(myProject); final GitUpdateProcess gitUpdateProcess = new GitUpdateProcess(myProject, progressIndicator, getRepositoriesFromRoots(repositoryManager, roots), updatedFiles); - boolean result = gitUpdateProcess.update(GitUpdateProcess.UpdateMethod.READ_FROM_SETTINGS); + boolean result = gitUpdateProcess.update(GitUpdateProcess.UpdateMethod.READ_FROM_SETTINGS).isSuccess(); return new GitUpdateSession(result); } diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java index 4a7ac4604fbd..0602ce75c7cd 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java @@ -42,6 +42,7 @@ import git4idea.repo.GitBranchTrackInfo; import git4idea.repo.GitRepository; import git4idea.stash.GitChangesSaver; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.HashMap; @@ -67,7 +68,7 @@ public class GitUpdateProcess { private final GitChangesSaver mySaver; private final Map myTrackedBranches = new HashMap(); - private boolean myResult; + private GitUpdateResult myResult; private final Map myUpdaters; private final Collection myRootsToSave; @@ -94,12 +95,7 @@ public class GitUpdateProcess { /** * Checks if update is possible, saves local changes and updates all roots. * In case of error shows notification and returns false. If update completes without errors, returns true. - */ - public boolean update() { - return update(UpdateMethod.READ_FROM_SETTINGS); - } - - /** + * * Perform update on all roots. * 0. Blocks reloading project on external change, saving/syncing on frame deactivation. * 1. Checks if update is possible (rebase/merge in progress, no tracked branches...) and provides merge dialog to solve problems. @@ -110,18 +106,19 @@ public class GitUpdateProcess { * local changes are not restored. * */ - public boolean update(final UpdateMethod updateMethod) { + @NotNull + public GitUpdateResult update(final UpdateMethod updateMethod) { LOG.info("update started|" + updateMethod); String oldText = myProgressIndicator.getText(); myProgressIndicator.setText("Updating..."); // check if update is possible if (checkRebaseInProgress() || isMergeInProgress() || areUnmergedFiles() || !checkTrackedBranchesConfigured()) { - return false; + return GitUpdateResult.NOT_READY; } if (!fetchAndNotify()) { - return false; + return GitUpdateResult.NOT_READY; } GitComplexProcess.Operation updateOperation = new GitComplexProcess.Operation() { @@ -135,7 +132,8 @@ public class GitUpdateProcess { return myResult; } - private boolean updateImpl(UpdateMethod updateMethod, ContinuationContext context) { + @NotNull + private GitUpdateResult updateImpl(UpdateMethod updateMethod, ContinuationContext context) { // define updaters for roots LOG.info("updateImpl: defining updaters..."); try { @@ -158,10 +156,10 @@ public class GitUpdateProcess { } catch (VcsException e) { LOG.info(e); notifyError(myProject, "Git update failed", e.getMessage(), true, e); - return false; + return GitUpdateResult.ERROR; } - if (myUpdaters.isEmpty()) return true; + if (myUpdaters.isEmpty()) return GitUpdateResult.NOTHING_TO_UPDATE; // save local changes if needed (update via merge may perform without saving). LOG.info("updateImpl: identifying if save is needed..."); @@ -182,13 +180,13 @@ public class GitUpdateProcess { notifyError(myProject, "Git update failed", "Tried to save uncommitted changes in " + mySaver.getSaverName() + " before update, but failed with an error.
" + "Update was cancelled.", true, e); - return false; + return GitUpdateResult.ERROR; } // update each root LOG.info("updateImpl: updating..."); boolean incomplete = false; - boolean success = true; + GitUpdateResult compoundResult = null; VirtualFile currentlyUpdatedRoot = null; try { for (Map.Entry entry : myUpdaters.entrySet()) { @@ -199,7 +197,7 @@ public class GitUpdateProcess { if (res == GitUpdateResult.INCOMPLETE) { incomplete = true; } - success &= res.isSuccess(); + compoundResult = joinResults(compoundResult, res); } } catch (VcsException e) { String rootName = (currentlyUpdatedRoot == null) ? "" : currentlyUpdatedRoot.getName(); @@ -207,7 +205,7 @@ public class GitUpdateProcess { notifyImportantError(myProject, "Error updating " + rootName, "Updating " + rootName + " failed with an error: " + e.getLocalizedMessage()); } finally { - if (incomplete || !success) { + if (incomplete || !!compoundResult.isSuccess()) { mySaver.notifyLocalChangesAreNotRestored(); } else { @@ -215,7 +213,15 @@ public class GitUpdateProcess { restoreLocalChanges(context); } } - return success; + return compoundResult; + } + + @NotNull + private static GitUpdateResult joinResults(@Nullable GitUpdateResult compoundResult, GitUpdateResult result) { + if (compoundResult == null) { + return result; + } + return compoundResult.join(result); } private void restoreLocalChanges(ContinuationContext context) { diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateResult.java b/plugins/git4idea/src/git4idea/update/GitUpdateResult.java index 323060120313..215cbb688224 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateResult.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateResult.java @@ -15,19 +15,43 @@ */ package git4idea.update; +import org.jetbrains.annotations.NotNull; + /** * @author Kirill Likhodedov */ public enum GitUpdateResult { - SUCCESS, - /** User cancelled update, everything that has changed was rolled back (git rebase/merge --abort) */ - CANCEL, - /** exception happened during update */ - ERROR, + /** Nothing to update. */ + NOTHING_TO_UPDATE(1), + /** Successful update, without merge conflict resolution during update. */ + SUCCESS(2), + /** Update introduced a merge conflict, that was immediately resolved by user. */ + SUCCESS_WITH_RESOLVED_CONFLICTS(3), /** Update introduced a merge conflict that wasn't immediately resolved. */ - INCOMPLETE; + INCOMPLETE(4), + /** User cancelled update, everything that has changed was rolled back (git rebase/merge --abort) */ + CANCEL(5), + /** An error happened during update */ + ERROR(6), + /** Update is not possible due to a configuration error or because of a failed fetch. */ + NOT_READY(7); + + private final int myPriority; + + GitUpdateResult(int priority) { + myPriority = priority; + } public boolean isSuccess() { - return this == SUCCESS || this == INCOMPLETE; + return this == SUCCESS || this == SUCCESS_WITH_RESOLVED_CONFLICTS || this == INCOMPLETE || this == NOTHING_TO_UPDATE; } + + @NotNull + public GitUpdateResult join(@NotNull GitUpdateResult next) { + if (myPriority >= next.myPriority) { + return this; + } + return next; + } + } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index 0cadee6aa3c9..352f44cf2dd6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -2053,7 +2053,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (myBorderPassed) { return false; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java index 0ff1054751e4..6aaa6ec69382 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java @@ -235,7 +235,7 @@ public class GroovyDslFileIndex extends ScalarIndexExtension { final DelegatingScopeProcessor nameChecker = new DelegatingScopeProcessor(processor) { @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) { return processor.execute(element, state); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyConstructorNamedArgumentProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyConstructorNamedArgumentProvider.java index 1930fc665b11..4b09f3f77b31 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyConstructorNamedArgumentProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyConstructorNamedArgumentProvider.java @@ -151,7 +151,7 @@ public class GroovyConstructorNamedArgumentProvider extends GroovyNamedArgumentP } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiMethod || element instanceof PsiField) { String propertyName; PsiType type; @@ -186,7 +186,7 @@ public class GroovyConstructorNamedArgumentProvider extends GroovyNamedArgumentP } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if ((NameHint.KEY == hintKey && myNameHint != null) || ClassHint.KEY == hintKey || ElementClassHint.KEY == hintKey) { //noinspection unchecked return (T) this; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index 581b6674da9f..2b4ce4c98938 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -115,12 +115,12 @@ public class GroovyCompletionContributor extends CompletionContributor { final PsiManager manager = file.getManager(); PsiScopeProcessor processor = new PsiScopeProcessor() { @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { return !manager.areElementsEquivalent(element, member); } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { return null; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java index 49e7ee2d9e5a..990e30343fdd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java @@ -146,7 +146,7 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile { final String expectedName = ResolveUtil.getNameHint(processor); PsiScopeProcessor importProcessor = !processClasses || expectedName == null ? processor : new DelegatingScopeProcessor(processor) { - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { return isImplicitlyImported(element, expectedName) || super.execute(element, state); } }; @@ -245,7 +245,7 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile { final DelegatingScopeProcessor packageSkipper = new DelegatingScopeProcessor(processor) { @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiPackage) return true; return super.execute(element, state); } @@ -276,7 +276,7 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile { PsiPackage aPackage = facade.findPackage(packageName); if (aPackage != null && !aPackage.processDeclarations(new DelegatingScopeProcessor(processor) { @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiPackage) return true; return super.execute(element, state); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java index 43ba6338da9e..c124cb1c0496 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java @@ -395,7 +395,7 @@ public class CompleteReferenceExpression { } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) return true; PsiNamedElement namedElement = (PsiNamedElement)element; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java index 9f382dae836b..23e962b95722 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GroovyScriptClass.java @@ -400,12 +400,12 @@ public class GroovyScriptClass extends LightElement implements GrMemberOwner, Sy final PsiClass scriptClass = getSuperClass(); //noinspection RedundantIfStatement if (scriptClass != null && !scriptClass.processDeclarations(new BaseScopeProcessor() { - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { return !(element instanceof PsiNamedElement) || ResolveUtil.processElement(processor, (PsiNamedElement)element, state); } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { return processor.getHint(hintKey); } }, state, lastParent, place)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java index 360fdb2c63cd..0a5de49d1973 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java @@ -105,7 +105,7 @@ public class GdkMethodUtil { @NotNull PsiClass categoryClass) { final DelegatingScopeProcessor delegate = new DelegatingScopeProcessor(processor) { @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiMethod) { if (!((PsiMethod)element).hasModifierProperty(PsiModifier.STATIC)) return true; final PsiParameter[] parameters = ((PsiMethod)element).getParameterList().getParameters(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/MixinMemberContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/MixinMemberContributor.java index 65190bb6b41e..de98c0d447a0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/MixinMemberContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/MixinMemberContributor.java @@ -69,7 +69,7 @@ public class MixinMemberContributor extends NonCodeMembersContributor { for (PsiClass mixin : mixins) { if (!mixin.processDeclarations(new DelegatingScopeProcessor(processor) { @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (isCategoryMethod(element, qualifierType, state.get(PsiSubstitutor.KEY))) { return super.execute(GrGdkMethodImpl.createGdkMethod((PsiMethod)element, false), state); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/NonCodeMembersContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/NonCodeMembersContributor.java index 2ec7cca71ecf..8530d0b9c338 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/NonCodeMembersContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/NonCodeMembersContributor.java @@ -116,7 +116,7 @@ public abstract class NonCodeMembersContributor { } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (!wantMore) { return false; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java index d6615c3db993..388ed8909225 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/GrCollectionTypeMembersProvider.java @@ -61,7 +61,7 @@ public class GrCollectionTypeMembersProvider extends NonCodeMembersContributor { } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiField) { final PsiType type = ((PsiField)element).getType(); final String typeText; @@ -79,7 +79,7 @@ public class GrCollectionTypeMembersProvider extends NonCodeMembersContributor { } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if (hintKey == NameHint.KEY) return processor.getHint(hintKey); if (hintKey == ClassHint.KEY || hintKey == ElementClassHint.KEY) return (T)this; return null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/AccessorResolverProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/AccessorResolverProcessor.java index 4a74d3e72cef..b69bd9fada06 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/AccessorResolverProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/AccessorResolverProcessor.java @@ -56,7 +56,7 @@ public class AccessorResolverProcessor extends MethodResolverProcessor { }; } - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (mySearchForGetter) { if (element instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyGetter((PsiMethod)element, myPropertyName)) { return addAccessor((PsiMethod)element, state); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/CompletionProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/CompletionProcessor.java index 699f94697fb7..7b3923a8a906 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/CompletionProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/CompletionProcessor.java @@ -34,7 +34,7 @@ public class CompletionProcessor extends ResolverProcessor { super(name, resolveTargets, place, PsiType.EMPTY_ARRAY); } - public boolean execute(PsiElement element, ResolveState substitutor) { + public boolean execute(@NotNull PsiElement element, ResolveState substitutor) { if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) { return true; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java index 4fa00bd3444b..90b67c467ccd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/MethodResolverProcessor.java @@ -86,7 +86,7 @@ public class MethodResolverProcessor extends ResolverProcessor { } - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (myStopExecuting) { return false; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/PropertyResolverProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/PropertyResolverProcessor.java index 8f82f8bf9280..8fc7d4b9c805 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/PropertyResolverProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/PropertyResolverProcessor.java @@ -36,7 +36,7 @@ public class PropertyResolverProcessor extends ResolverProcessor { } @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof GrReferenceExpression && ((GrReferenceExpression)element).getQualifier() != null) { return true; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/ResolverProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/ResolverProcessor.java index 0870d5a0c9c9..19e46b7fa65b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/ResolverProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/processors/ResolverProcessor.java @@ -68,7 +68,7 @@ public class ResolverProcessor implements PsiScopeProcessor, NameHint, ClassHint myTypeArguments = typeArguments; } - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiLocalVariableImpl) { //todo a better hack return true; // the debugger creates a Java code block context and our expressions to evaluate resolve there } @@ -159,7 +159,7 @@ public class ResolverProcessor implements PsiScopeProcessor, NameHint, ClassHint } @SuppressWarnings({"unchecked"}) - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { if ((NameHint.KEY == hintKey && myName != null) || ClassHint.KEY == hintKey || ElementClassHint.KEY == hintKey) { return (T) this; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java index 480fe28df873..fb1a2d0f04c7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java @@ -39,6 +39,7 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster; @@ -615,7 +616,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc return type.isAssignableFrom(varType); } - public boolean execute(PsiElement pe, ResolveState state) { + public boolean execute(@NotNull PsiElement pe, ResolveState state) { super.execute(pe, state); return size() < 2; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java index ea1c043e5d69..22948deabf3a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java @@ -562,13 +562,13 @@ public class GenerationUtil { final PsiManager manager = PsiManager.getInstance(context.project); return ResolveUtil.processAllDeclarations(declared, new PsiScopeProcessor() { @Override - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (manager.areElementsEquivalent(element, member)) return false; return true; } @Override - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { return null; } diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/JavaI18nUtil.java b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/JavaI18nUtil.java index 9a517c35899f..9e762596374e 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/i18n/JavaI18nUtil.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/i18n/JavaI18nUtil.java @@ -274,7 +274,7 @@ public class JavaI18nUtil extends I18nUtil { private static void addAvailableMethodsOfType(final PsiClassType type, final PsiLiteralExpression context, final Collection result) { PsiScopesUtil.treeWalkUp(new PsiScopeProcessor() { - public boolean execute(PsiElement element, ResolveState state) { + public boolean execute(@NotNull PsiElement element, ResolveState state) { if (element instanceof PsiMethod) { PsiMethod method = (PsiMethod)element; PsiType returnType = method.getReturnType(); @@ -286,7 +286,7 @@ public class JavaI18nUtil extends I18nUtil { return true; } - public T getHint(Key hintKey) { + public T getHint(@NotNull Key hintKey) { return null; } diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java index 925b9dabe92f..23f3889d6bd1 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java @@ -107,8 +107,8 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn final String method = ((TestResultMessage)result).getMethod(); if (method != null) { final PsiMethod[] psiMethods = psiClass.findMethodsByName(method, false); - for (PsiMethod psiMethod : psiMethods) { - psiMethod.navigate(true); + if (psiMethods.length > 0) { + psiMethods[0].navigate(true); return; } } diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 3e6bb2a1f1df..9306ee852f97 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1252,6 +1252,8 @@ implementationClass="com.intellij.psi.impl.JavaRegExpHost"/> + + diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java index a758a7217a71..1c4b2f6f37c7 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/compact/psi/impl/RncNameImpl.java @@ -152,7 +152,7 @@ public class RncNameImpl extends RncElementImpl implements RncName, PsiReference myKind = kind; } - public boolean execute(PsiElement element, ResolveState substitutor) { + public boolean execute(@NotNull PsiElement element, ResolveState substitutor) { final ASTNode node = element.getNode(); if (node == null) return true;