diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateAssignFieldsFromParametersAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BindFieldsFromParametersAction.java similarity index 68% rename from java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateAssignFieldsFromParametersAction.java rename to java/java-impl/src/com/intellij/codeInsight/intention/impl/BindFieldsFromParametersAction.java index 859ac737ece9..6ca6edcba548 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateAssignFieldsFromParametersAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BindFieldsFromParametersAction.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.generation.ClassMember; import com.intellij.codeInsight.generation.MemberChooserObject; import com.intellij.codeInsight.generation.PsiMethodMember; +import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.ide.util.MemberChooser; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.application.ApplicationManager; @@ -48,7 +49,7 @@ import java.util.*; /** * @author Danila Ponomarenko */ -public class CreateAssignFieldsFromParametersAction extends BaseIntentionAction { +public class BindFieldsFromParametersAction extends BaseIntentionAction implements HighPriorityAction { private static final Logger LOG = Logger.getInstance(CreateFieldFromParameterAction.class); private static final Key, Boolean>> PARAMS = Key.create("FIELDS_FROM_PARAMS"); @@ -75,7 +76,7 @@ public class CreateAssignFieldsFromParametersAction extends BaseIntentionAction LOG.assertTrue(psiParameter != null); } - setText(CodeInsightBundle.message("intention.create.assign.fields.from.parameters.text", method.isConstructor() ? "Constructor" : "Method")); + setText(CodeInsightBundle.message("intention.bind.fields.from.parameters.text", method.isConstructor() ? "Constructor" : "Method")); } return isAvailable(psiParameter); } @@ -150,7 +151,7 @@ public class CreateAssignFieldsFromParametersAction extends BaseIntentionAction @Override @NotNull public String getFamilyName() { - return CodeInsightBundle.message("intention.create.assign.fields.from.parameters.family"); + return CodeInsightBundle.message("intention.bind.fields.from.parameters.family"); } @Override @@ -163,62 +164,94 @@ public class CreateAssignFieldsFromParametersAction extends BaseIntentionAction if (!CodeInsightUtilBase.prepareFileForWrite(file)) return; final PsiMethod method = myParameter != null ? (PsiMethod)myParameter.getDeclarationScope() : PsiTreeUtil.getParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), PsiMethod.class); LOG.assertTrue(method != null); - final Collection> unboundedParams; - synchronized (LOCK) { - unboundedParams = getUnboundedParams(method); - if (unboundedParams.isEmpty()) return; - if (myParameter == null) { - myParameter = unboundedParams.iterator().next().getElement(); - } - } - if (unboundedParams.size() > 1 && isInteractive) { - ClassMember[] members = new ClassMember[unboundedParams.size()]; - ClassMember selection = null; - int i = 0; - for (SmartPsiElementPointer pointer : unboundedParams) { - final PsiParameter parameter = pointer.getElement(); - final ParameterClassMember classMember = new ParameterClassMember(parameter); - members[i++] = classMember; - if (parameter == myParameter) { - selection = classMember; - } - } - final PsiParameterList parameterList = method.getParameterList(); - Arrays.sort(members, new Comparator() { - @Override - public int compare(ClassMember o1, ClassMember o2) { - return parameterList.getParameterIndex(((ParameterClassMember)o1).getParameter()) - - parameterList.getParameterIndex(((ParameterClassMember)o2).getParameter()); - } - }); - final MemberChooser chooser = new MemberChooser(members, false, true, project); - if (selection != null) { - chooser.selectElements(new ClassMember[]{selection}); - } - chooser.setTitle("Choose " + (method.isConstructor() ? "Constructor" : "Method") + " Parameters"); - chooser.setCopyJavadocVisible(false); - chooser.show(); - if (chooser.getExitCode() != DialogWrapper.OK_EXIT_CODE) return; - final List selectedElements = chooser.getSelectedElements(); - if (selectedElements == null) return; - - final HashSet usedNames = new HashSet(); - for (ClassMember selectedElement : selectedElements) { - processParameter(project, ((ParameterClassMember)selectedElement).getParameter(), usedNames); - } - } - else { - processParameter(project, myParameter); - } - synchronized (LOCK) { - unboundedParams.clear(); + final HashSet usedNames = new HashSet(); + for (PsiParameter selected : selectParameters(project, method, copyUnboundedParamsAndClearOriginal(method), isInteractive)) { + processParameter(project, selected, usedNames); } } - private static void processParameter(final Project project, - final PsiParameter myParameter) { - processParameter(project, myParameter, new HashSet()); + @NotNull + private static Iterable selectParameters(@NotNull Project project, + @NotNull PsiMethod method, + @NotNull Collection> unboundedParams, + boolean isInteractive) { + if (unboundedParams.size() < 2 || !isInteractive) { + return revealPointers(unboundedParams); + } + + final ParameterClassMember[] members = sortByParameterIndex(toClassMemberArray(unboundedParams), method); + + final MemberChooser chooser = showChooser(project, method, members); + + final List selectedElements = chooser.getSelectedElements(); + if (chooser.getExitCode() != DialogWrapper.OK_EXIT_CODE || selectedElements == null) { + return Collections.emptyList(); + } + + return revealParameterClassMembers(selectedElements); + } + + @NotNull + private static MemberChooser showChooser(@NotNull Project project, + @NotNull PsiMethod method, + @NotNull ParameterClassMember[] members) { + final MemberChooser chooser = new MemberChooser(members, false, true, project); + chooser.selectElements(members); + chooser.setTitle("Choose " + (method.isConstructor() ? "Constructor" : "Method") + " Parameters"); + chooser.show(); + return chooser; + } + + @NotNull + private static ParameterClassMember[] sortByParameterIndex(@NotNull ParameterClassMember[] members, @NotNull PsiMethod method) { + final PsiParameterList parameterList = method.getParameterList(); + Arrays.sort(members, new Comparator() { + @Override + public int compare(ParameterClassMember o1, ParameterClassMember o2) { + return parameterList.getParameterIndex(o1.getParameter()) - + parameterList.getParameterIndex(o2.getParameter()); + } + }); + return members; + } + + @NotNull + private static List revealPointers(@NotNull Iterable> pointers) { + final List result = new ArrayList(); + for (SmartPsiElementPointer pointer : pointers) { + result.add(pointer.getElement()); + } + return result; + } + + @NotNull + private static List revealParameterClassMembers(@NotNull Iterable parameterClassMembers) { + final List result = new ArrayList(); + for (ParameterClassMember parameterClassMember : parameterClassMembers) { + result.add(parameterClassMember.getParameter()); + } + return result; + } + + @NotNull + private static ParameterClassMember[] toClassMemberArray(@NotNull Collection> unboundedParams) { + final ParameterClassMember[] result = new ParameterClassMember[unboundedParams.size()]; + int i = 0; + for (SmartPsiElementPointer pointer : unboundedParams) { + result[i++] = new ParameterClassMember(pointer.getElement()); + } + return result; + } + + @NotNull + private static Collection> copyUnboundedParamsAndClearOriginal(@NotNull PsiMethod method) { + synchronized (LOCK) { + final Collection> unboundedParams = getUnboundedParams(method); + final Collection> result = new ArrayList>(unboundedParams); + unboundedParams.clear(); + return result; + } } private static void processParameter(final Project project, diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterCaretOnMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterCaretOnMethod.java new file mode 100644 index 000000000000..4f063b655e00 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterCaretOnMethod.java @@ -0,0 +1,12 @@ +// "Bind Method Parameters to Fields" "true" + +class A{ + private int myP1; + private int myP2; + + void method(int p1, int p2){ + myP1 = p1; + myP2 = p2; + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterNotNull.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterNotNull.java new file mode 100644 index 000000000000..1bc8122c7c4a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterNotNull.java @@ -0,0 +1,18 @@ +// "Bind Constructor Parameters to Fields" "true" + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class TestBefore { + + @NotNull + private final String myName; + @NotNull + private final String myName2; + + public TestBefore(@NotNull String name, @NotNull String name2) { + super(); + myName = name; + myName2 = name2; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterNullable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterNullable.java new file mode 100644 index 000000000000..7d457f162b57 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterNullable.java @@ -0,0 +1,18 @@ +// "Bind Constructor Parameters to Fields" "true" + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class TestBefore { + + @Nullable + private final String myName; + @Nullable + private final String myName2; + + public TestBefore(@Nullable String name, @Nullable String name2) { + super(); + myName = name; + myName2 = name2; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterSimple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterSimple.java new file mode 100644 index 000000000000..829746789fed --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterSimple.java @@ -0,0 +1,16 @@ +// "Bind Constructor Parameters to Fields" "true" + +class Bar { + + private int myi1; + private int myi2; + private final int myI1; + private final int myI2; + private final String myI3; + + Bar(int i1, int i2, String i3) { + myI1 = i1; + myI2 = i2; + myI3 = i3; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterSimpleTypeParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterSimpleTypeParameter.java new file mode 100644 index 000000000000..ce5ccf1d7927 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterSimpleTypeParameter.java @@ -0,0 +1,12 @@ +// "Bind Method Parameters to Fields" "true" + +class A{ + private Object myP1; + private Object myP2; + + void f(T p1, T p2){ + myP1 = p1; + myP2 = p2; + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterTypeParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterTypeParameter.java new file mode 100644 index 000000000000..35fb95437d97 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/afterTypeParameter.java @@ -0,0 +1,12 @@ +// "Bind Method Parameters to Fields" "true" + +class A{ + private String myP1; + private String myP2; + + void f(T p1, T p2){ + myP1 = p1; + myP2 = p2; + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethod.java new file mode 100644 index 000000000000..70c7d1c401e7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethod.java @@ -0,0 +1,7 @@ +// "Bind Method Parameters to Fields" "true" + +class A{ + void method(int p1, int p2){ + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethodWithOnlyAssignedParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethodWithOnlyAssignedParams.java new file mode 100644 index 000000000000..6cb3b5cb6a3e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethodWithOnlyAssignedParams.java @@ -0,0 +1,10 @@ +// "Bind Method Parameters to Fields" "false" + +class A{ + private final String myP1; + + void f(String p1){ + myP1 = p1; + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethodWithTwoAssignedParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethodWithTwoAssignedParams.java new file mode 100644 index 000000000000..133a7aad7cea --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethodWithTwoAssignedParams.java @@ -0,0 +1,12 @@ +// "Bind Method Parameters to Fields" "false" + +class A{ + private final String myP1; + private final String myP2; + + void f(String p1, String p2){ + myP1 = p1; + myP2 = p2; + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethodWithoutParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethodWithoutParams.java new file mode 100644 index 000000000000..604baee2ddb9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeCaretOnMethodWithoutParams.java @@ -0,0 +1,7 @@ +// "Bind Method Parameters to Fields" "false" + +class A{ + void f(){ + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeNotNull.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeNotNull.java new file mode 100644 index 000000000000..304dab951c88 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeNotNull.java @@ -0,0 +1,11 @@ +// "Bind Constructor Parameters to Fields" "true" + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class TestBefore { + + public TestBefore(@NotNull String name, @NotNull String name2) { + super(); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeNullable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeNullable.java new file mode 100644 index 000000000000..8fb83042fbf5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeNullable.java @@ -0,0 +1,11 @@ +// "Bind Constructor Parameters to Fields" "true" + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class TestBefore { + + public TestBefore(@Nullable String name, @Nullable String name2) { + super(); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeSimple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeSimple.java new file mode 100644 index 000000000000..6f64007a938f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeSimple.java @@ -0,0 +1,10 @@ +// "Bind Constructor Parameters to Fields" "true" + +class Bar { + + private int myi1; + private int myi2; + + Bar(int i1, int i2, String i3) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeSimpleTypeParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeSimpleTypeParameter.java new file mode 100644 index 000000000000..939901410f34 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeSimpleTypeParameter.java @@ -0,0 +1,7 @@ +// "Bind Method Parameters to Fields" "true" + +class A{ + void f(T p1, T p2){ + } +} + diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeTypeParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeTypeParameter.java new file mode 100644 index 000000000000..28e7b25a75d6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters/beforeTypeParameter.java @@ -0,0 +1,7 @@ +// "Bind Method Parameters to Fields" "true" + +class A{ + void f(T p1, T p2){ + } +} + diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateAssignFieldsFromParametersTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/BindFieldsFromParametersTest.java similarity index 88% rename from java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateAssignFieldsFromParametersTest.java rename to java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/BindFieldsFromParametersTest.java index 9205e0250353..2b0bed041fe3 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateAssignFieldsFromParametersTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/BindFieldsFromParametersTest.java @@ -22,7 +22,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager; /** * @author Danila Ponomarenko */ -public class CreateAssignFieldsFromParametersTest extends LightIntentionActionTestCase { +public class BindFieldsFromParametersTest extends LightIntentionActionTestCase { @Override protected void setUp() throws Exception { super.setUp(); @@ -41,6 +41,6 @@ public class CreateAssignFieldsFromParametersTest extends LightIntentionActionTe @Override protected String getBasePath() { - return "/codeInsight/daemonCodeAnalyzer/quickFix/createAssignFieldsFromParameters"; + return "/codeInsight/daemonCodeAnalyzer/quickFix/bindFieldsFromParameters"; } } diff --git a/java/java-tests/testSrc/com/intellij/roots/OrderEntriesTest.java b/java/java-tests/testSrc/com/intellij/roots/OrderEntriesTest.java index c2bffba57dda..e2ff28a82912 100644 --- a/java/java-tests/testSrc/com/intellij/roots/OrderEntriesTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/OrderEntriesTest.java @@ -83,7 +83,6 @@ public class OrderEntriesTest extends ModuleRootManagerTestCase { } private void assertOrderFiles(final OrderRootType type, VirtualFile... files) { - assertOrderedEquals(ModuleRootManager.getInstance(myModule).getFiles(type), files); assertRoots(collectByOrderEnumerator(type), files); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsCompositeElement.java b/jps/model-api/src/org/jetbrains/jps/model/JpsCompositeElement.java index 2ed2dfacefb2..ec6a8894c47e 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsCompositeElement.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsCompositeElement.java @@ -5,7 +5,7 @@ import org.jetbrains.annotations.NotNull; /** * @author nik */ -public interface JpsCompositeElement extends JpsParentElement { +public interface JpsCompositeElement extends JpsElement { @NotNull JpsElementContainer getContainer(); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementCollection.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementCollection.java index 4da1ab422c3b..841a8ace72f1 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsElementCollection.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementCollection.java @@ -7,7 +7,7 @@ import java.util.List; /** * @author nik */ -public interface JpsElementCollection extends JpsParentElement { +public interface JpsElementCollection extends JpsElement { List getElements(); @NotNull diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java b/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java index ea535b091670..b602f1363de1 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsGlobal.java @@ -2,6 +2,7 @@ package org.jetbrains.jps.model; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryCollection; import org.jetbrains.jps.model.library.JpsLibraryType; /** @@ -11,5 +12,6 @@ public interface JpsGlobal extends JpsCompositeElement, JpsReferenceableElement< @NotNull JpsLibrary addLibrary(@NotNull JpsLibraryType libraryType, final @NotNull String name); - + @NotNull + JpsLibraryCollection getLibraryCollection(); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsParentElement.java b/jps/model-api/src/org/jetbrains/jps/model/JpsParentElement.java deleted file mode 100644 index 9a28f2bf39b1..000000000000 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsParentElement.java +++ /dev/null @@ -1,7 +0,0 @@ -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 index 9855a4b3d5d8..5c093dee34d0 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java @@ -2,6 +2,7 @@ package org.jetbrains.jps.model; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryCollection; import org.jetbrains.jps.model.library.JpsLibraryType; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleType; @@ -16,16 +17,15 @@ public interface JpsProject extends JpsCompositeElement, JpsReferenceableElement @NotNull JpsModule addModule(@NotNull JpsModuleType moduleType, @NotNull String name); + void addModule(@NotNull JpsModule module); + + @NotNull + List getModules(); + + @NotNull JpsLibrary addLibrary(@NotNull JpsLibraryType libraryType, @NotNull String name); @NotNull - List getLibraries(); - - @NotNull - List getModules(); - - void addModule(JpsModule module); - - void addLibrary(JpsLibrary library); + JpsLibraryCollection getLibraryCollection(); } 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 index 1d79c0bcc107..4c94fca2439a 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibrary.java @@ -12,11 +12,13 @@ import java.util.List; public interface JpsLibrary extends JpsNamedElement, JpsReferenceableElement { @NotNull - List getUrls(@NotNull JpsLibraryRootType rootType); + List getRoots(@NotNull JpsOrderRootType rootType); - void addUrl(@NotNull String url, @NotNull JpsLibraryRootType rootType); + void addRoot(@NotNull String url, @NotNull JpsOrderRootType rootType); - void removeUrl(@NotNull String url, @NotNull JpsLibraryRootType rootType); + void addRoot(@NotNull String url, @NotNull JpsOrderRootType rootType, @NotNull JpsLibraryRoot.InclusionOptions options); + + void removeUrl(@NotNull String url, @NotNull JpsOrderRootType rootType); void delete(); diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryCollection.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryCollection.java new file mode 100644 index 000000000000..3f1dfc0c84ef --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryCollection.java @@ -0,0 +1,18 @@ +package org.jetbrains.jps.model.library; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author nik + */ +public interface JpsLibraryCollection { + @NotNull + JpsLibrary addLibrary(@NotNull JpsLibraryType libraryType, @NotNull String name); + + @NotNull + List getLibraries(); + + void addLibrary(@NotNull JpsLibrary library); +} 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 index 49254236d441..6654ecfa99a9 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRoot.java +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRoot.java @@ -8,11 +8,16 @@ import org.jetbrains.jps.model.JpsElement; */ public interface JpsLibraryRoot extends JpsElement { @NotNull - JpsLibraryRootType getRootType(); + JpsOrderRootType getRootType(); @NotNull String getUrl(); + @NotNull + InclusionOptions getInclusionOptions(); + @NotNull JpsLibrary getLibrary(); + + enum InclusionOptions {ROOT_ITSELF, ARCHIVES_UNDER_ROOT, ARCHIVES_UNDER_ROOT_RECURSIVELY} } 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 deleted file mode 100644 index 707344331440..000000000000 --- a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRootType.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.jetbrains.jps.model.library; - -/** - * @author nik - */ -public class JpsLibraryRootType { - public static final JpsLibraryRootType COMPILED = new JpsLibraryRootType(JpsOrderRootType.COMPILED, false, false); - public static final JpsLibraryRootType SOURCES = new JpsLibraryRootType(JpsOrderRootType.SOURCES, false, false); - private final boolean myJarDirectory; - private final boolean myRecursive; - private final JpsOrderRootType myType; - - public JpsLibraryRootType(JpsOrderRootType type, boolean jarDirectory, boolean recursive) { - myJarDirectory = jarDirectory; - myRecursive = recursive; - myType = type; - } - - public boolean isJarDirectory() { - return myJarDirectory; - } - - public JpsOrderRootType getType() { - return myType; - } - - public boolean isRecursive() { - return myRecursive; - } -} 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 index 88aa5b375f8e..03fb7ff6878e 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java @@ -3,6 +3,7 @@ package org.jetbrains.jps.model.module; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.*; import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryCollection; import org.jetbrains.jps.model.library.JpsLibraryType; import java.util.List; @@ -42,11 +43,13 @@ public interface JpsModule extends JpsNamedElement, JpsReferenceableElement type, @NotNull String name); - @NotNull - JpsLibrary addModuleLibrary(@NotNull JpsLibrary library); + void addModuleLibrary(@NotNull JpsLibrary library); - void delete(); + @NotNull + JpsLibraryCollection getLibraryCollection(); @NotNull JpsSdkReferencesTable getSdkReferencesTable(); + + void delete(); } 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 index f48ad0d0f365..9cf7dbdf0730 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java @@ -1,30 +1,42 @@ package org.jetbrains.jps.model.impl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.JpsElementReference; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsGlobal; +import org.jetbrains.jps.model.JpsModel; import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryCollection; import org.jetbrains.jps.model.library.JpsLibraryType; -import org.jetbrains.jps.model.library.impl.JpsLibraryImpl; +import org.jetbrains.jps.model.library.impl.JpsLibraryCollectionImpl; import org.jetbrains.jps.model.library.impl.JpsLibraryKind; /** * @author nik */ public class JpsGlobalImpl extends JpsRootElementBase implements JpsGlobal { + private final JpsLibraryCollectionImpl myLibraryCollection; + public JpsGlobalImpl(JpsModel model, JpsEventDispatcher eventDispatcher) { super(model, eventDispatcher); - myContainer.setChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); + myLibraryCollection = new JpsLibraryCollectionImpl(myContainer.setChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND)); } public JpsGlobalImpl(JpsGlobalImpl original, JpsModel model, JpsEventDispatcher eventDispatcher) { super(original, model, eventDispatcher); + myLibraryCollection = new JpsLibraryCollectionImpl(myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND)); } @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)); + return myLibraryCollection.addLibrary(libraryType, name); + } + + @NotNull + @Override + public JpsLibraryCollection getLibraryCollection() { + return myLibraryCollection; } @NotNull 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 index e70099f276da..d1f835eb914e 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java @@ -1,10 +1,14 @@ package org.jetbrains.jps.model.impl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.JpsElementReference; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.JpsProject; import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryCollection; import org.jetbrains.jps.model.library.JpsLibraryType; -import org.jetbrains.jps.model.library.impl.JpsLibraryImpl; +import org.jetbrains.jps.model.library.impl.JpsLibraryCollectionImpl; import org.jetbrains.jps.model.library.impl.JpsLibraryKind; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleType; @@ -19,16 +23,18 @@ import java.util.List; public class JpsProjectImpl extends JpsRootElementBase implements JpsProject { private static final JpsElementCollectionKind> EXTERNAL_REFERENCES_COLLECTION_KIND = new JpsElementCollectionKind>(new JpsElementKindBase>("external reference")); + private final JpsLibraryCollection myLibraryCollection; public JpsProjectImpl(JpsModel model, JpsEventDispatcher eventDispatcher) { super(model, eventDispatcher); myContainer.setChild(JpsModuleKind.MODULE_COLLECTION_KIND); - myContainer.setChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); myContainer.setChild(EXTERNAL_REFERENCES_COLLECTION_KIND); + myLibraryCollection = new JpsLibraryCollectionImpl(myContainer.setChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND)); } public JpsProjectImpl(JpsProjectImpl original, JpsModel model, JpsEventDispatcher eventDispatcher) { super(original, model, eventDispatcher); + myLibraryCollection = new JpsLibraryCollectionImpl(myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND)); } public void addExternalReference(@NotNull JpsElementReference reference) { @@ -45,30 +51,24 @@ public class JpsProjectImpl extends JpsRootElementBase implement @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)); + return myLibraryCollection.addLibrary(libraryType, name); } @NotNull @Override - public List getLibraries() { - return myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND).getElements(); - } - - @NotNull - @Override - public List getModules() { + public List getModules() { return myContainer.getChild(JpsModuleKind.MODULE_COLLECTION_KIND).getElements(); } @Override - public void addModule(JpsModule module) { + public void addModule(@NotNull JpsModule module) { myContainer.getChild(JpsModuleKind.MODULE_COLLECTION_KIND).addChild(module); } + @NotNull @Override - public void addLibrary(JpsLibrary library) { - myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND).addChild(library); + public JpsLibraryCollection getLibraryCollection() { + return myLibraryCollection; } @NotNull diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryCollectionImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryCollectionImpl.java new file mode 100644 index 000000000000..8fba7b9e49bd --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryCollectionImpl.java @@ -0,0 +1,37 @@ +package org.jetbrains.jps.model.library.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementCollection; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryCollection; +import org.jetbrains.jps.model.library.JpsLibraryType; + +import java.util.List; + +/** + * @author nik + */ +public class JpsLibraryCollectionImpl implements JpsLibraryCollection { + private final JpsElementCollection myCollection; + + public JpsLibraryCollectionImpl(JpsElementCollection collection) { + myCollection = collection; + } + + @NotNull + @Override + public JpsLibrary addLibrary(@NotNull JpsLibraryType libraryType, @NotNull String name) { + return myCollection.addChild(new JpsLibraryImpl(name, libraryType)); + } + + @NotNull + @Override + public List getLibraries() { + return myCollection.getElements(); + } + + @Override + public void addLibrary(@NotNull JpsLibrary library) { + myCollection.addChild(library); + } +} 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 index beb49333b109..995d25cef8a6 100644 --- 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 @@ -3,20 +3,16 @@ 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 org.jetbrains.jps.model.library.*; -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 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) { @@ -31,29 +27,29 @@ public class JpsLibraryImpl extends JpsNamedCompositeElementBase 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; + public List getRoots(@NotNull JpsOrderRootType rootType) { + return getRootsCollection().getElements(); } @Override - public void addUrl(@NotNull final String url, @NotNull final JpsLibraryRootType rootType) { - getRootsCollection().addChild(new JpsLibraryRootImpl(url, rootType)); + public void addRoot(@NotNull String url, @NotNull JpsOrderRootType rootType) { + addRoot(url, rootType, JpsLibraryRoot.InclusionOptions.ROOT_ITSELF); } - private JpsElementCollectionImpl getRootsCollection() { + @Override + public void addRoot(@NotNull final String url, @NotNull final JpsOrderRootType rootType, + @NotNull JpsLibraryRoot.InclusionOptions options) { + getRootsCollection().addChild(new JpsLibraryRootImpl(url, rootType, options)); + } + + 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()) { + public void removeUrl(@NotNull final String url, @NotNull final JpsOrderRootType rootType) { + final JpsElementCollection rootsCollection = getRootsCollection(); + for (JpsLibraryRoot root : rootsCollection.getElements()) { if (root.getUrl().equals(url) && root.getRootType().equals(rootType)) { rootsCollection.removeChild(root); break; 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 index 33dc41361b98..215968d9efc3 100644 --- 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 @@ -4,29 +4,31 @@ import org.jetbrains.annotations.NotNull; 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; +import org.jetbrains.jps.model.library.JpsOrderRootType; /** * @author nik */ public class JpsLibraryRootImpl extends JpsElementBase implements JpsLibraryRoot { private final String myUrl; - private final JpsLibraryRootType myRootType; + private final JpsOrderRootType myRootType; + private final InclusionOptions myOptions; - public JpsLibraryRootImpl(@NotNull String url, - @NotNull JpsLibraryRootType rootType) { + public JpsLibraryRootImpl(@NotNull String url, @NotNull JpsOrderRootType rootType, @NotNull InclusionOptions options) { myUrl = url; myRootType = rootType; + myOptions = options; } public JpsLibraryRootImpl(JpsLibraryRootImpl original) { myUrl = original.myUrl; myRootType = original.myRootType; + myOptions = original.myOptions; } @NotNull @Override - public JpsLibraryRootType getRootType() { + public JpsOrderRootType getRootType() { return myRootType; } @@ -35,6 +37,12 @@ public class JpsLibraryRootImpl extends JpsElementBase imple return myUrl; } + @NotNull + @Override + public InclusionOptions getInclusionOptions() { + return myOptions; + } + @NotNull @Override public JpsLibraryRootImpl createCopy() { 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 index f01d8cc843c6..27822254b0df 100644 --- 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 @@ -1,14 +1,15 @@ package org.jetbrains.jps.model.library.impl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.impl.JpsElementKindBase; import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.impl.JpsElementKindBase; +import org.jetbrains.jps.model.library.JpsLibraryRoot; import org.jetbrains.jps.model.library.JpsLibraryRootListener; /** * @author nik */ -public class JpsLibraryRootKind extends JpsElementKindBase { +public class JpsLibraryRootKind extends JpsElementKindBase { public static final JpsLibraryRootKind INSTANCE = new JpsLibraryRootKind(); public JpsLibraryRootKind() { @@ -16,12 +17,12 @@ public class JpsLibraryRootKind extends JpsElementKindBase { } @Override - public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibraryRootImpl element) { + public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibraryRoot element) { dispatcher.getPublisher(JpsLibraryRootListener.class).rootAdded(element); } @Override - public void fireElementRemoved(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibraryRootImpl element) { + public void fireElementRemoved(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibraryRoot element) { dispatcher.getPublisher(JpsLibraryRootListener.class).rootRemoved(element); } } 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 index adb148b5da3d..97f6e96bdfaf 100644 --- 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 @@ -1,11 +1,14 @@ package org.jetbrains.jps.model.module.impl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.JpsElementProperties; +import org.jetbrains.jps.model.JpsUrlList; import org.jetbrains.jps.model.impl.*; import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryCollection; import org.jetbrains.jps.model.library.JpsLibraryType; -import org.jetbrains.jps.model.library.impl.JpsLibraryImpl; +import org.jetbrains.jps.model.library.impl.JpsLibraryCollectionImpl; import org.jetbrains.jps.model.library.impl.JpsLibraryKind; import org.jetbrains.jps.model.module.*; @@ -18,8 +21,8 @@ public class JpsModuleImpl extends JpsNamedCompositeElementBase> TYPED_DATA_KIND = new JpsTypedDataKind>(); private static final JpsUrlListKind CONTENT_ROOTS_KIND = new JpsUrlListKind("content roots"); private static final JpsUrlListKind EXCLUDED_ROOTS_KIND = new JpsUrlListKind("excluded roots"); - public static final JpsElementKind DEPENDENCIES_LIST_KIND = - new JpsElementKindBase("dependencies"); + public static final JpsElementKind DEPENDENCIES_LIST_KIND = new JpsElementKindBase("dependencies"); + private final JpsLibraryCollection myLibraryCollection; public JpsModuleImpl(JpsModuleType type, @NotNull String name) { @@ -28,13 +31,14 @@ public class JpsModuleImpl extends JpsNamedCompositeElementBase type, @NotNull String name) { - return addModuleLibrary(new JpsLibraryImpl(name, type)); + return myLibraryCollection.addLibrary(type, name); + } + + @Override + public void addModuleLibrary(final @NotNull JpsLibrary library) { + myLibraryCollection.addLibrary(library); } @NotNull @Override - public JpsLibrary addModuleLibrary(final @NotNull JpsLibrary library) { - return myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND).addChild(library); + public JpsLibraryCollection getLibraryCollection() { + return myLibraryCollection; } } diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsLibraryTest.java b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsLibraryTest.java index 7410eec8f26e..e279eb1d114a 100644 --- a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsLibraryTest.java +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsLibraryTest.java @@ -1,9 +1,7 @@ package org.jetbrains.jps.model; 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.*; /** * @author nik @@ -11,20 +9,20 @@ import org.jetbrains.jps.model.library.JpsLibraryRootType; 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))); + library.addRoot("file://my-url", JpsOrderRootType.COMPILED); + assertEquals("file://my-url", assertOneElement(library.getRoots(JpsOrderRootType.COMPILED)).getUrl()); } 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); + final JpsLibrary modifiable = assertOneElement(modifiableModel.getProject().getLibraryCollection().getLibraries()); + modifiable.addRoot("file://my-url", JpsOrderRootType.COMPILED); modifiableModel.commit(); - final JpsLibrary library = assertOneElement(myModel.getProject().getLibraries()); - assertEquals("file://my-url", assertOneElement(library.getUrls(JpsLibraryRootType.COMPILED))); + final JpsLibrary library = assertOneElement(myModel.getProject().getLibraryCollection().getLibraries()); + assertEquals("file://my-url", assertOneElement(library.getRoots(JpsOrderRootType.COMPILED)).getUrl()); } public void testCreateReferenceByLibrary() { diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryTableLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryTableLoader.java index ee53d55a93a9..a6e4b81e40f6 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryTableLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryTableLoader.java @@ -5,10 +5,7 @@ import com.intellij.util.containers.MultiMap; import org.jdom.Element; import org.jetbrains.jps.model.JpsElementFactory; import org.jetbrains.jps.model.java.JpsJavaLibraryType; -import org.jetbrains.jps.model.library.JpsLibrary; -import org.jetbrains.jps.model.library.JpsLibraryRootType; -import org.jetbrains.jps.model.library.JpsLibraryType; -import org.jetbrains.jps.model.library.JpsOrderRootType; +import org.jetbrains.jps.model.library.*; import org.jetbrains.jps.service.JpsServiceManager; import java.util.HashMap; @@ -55,9 +52,15 @@ public class JpsLibraryTableLoader { final JpsOrderRootType rootType = getRootType(rootTypeId); for (Element rootElement : JDOMUtil.getChildren(rootsElement, "root")) { String url = rootElement.getAttributeValue("url"); - final boolean jarDirectory = jarDirectories.get(rootType).contains(url); - final boolean recursive = recursiveJarDirectories.get(rootType).contains(url); - library.addUrl(url, new JpsLibraryRootType(rootType, jarDirectory, recursive)); + JpsLibraryRoot.InclusionOptions options; + if (jarDirectories.get(rootType).contains(url)) { + final boolean recursive = recursiveJarDirectories.get(rootType).contains(url); + options = recursive ? JpsLibraryRoot.InclusionOptions.ARCHIVES_UNDER_ROOT_RECURSIVELY : JpsLibraryRoot.InclusionOptions.ARCHIVES_UNDER_ROOT; + } + else { + options = JpsLibraryRoot.InclusionOptions.ROOT_ITSELF; + } + library.addRoot(url, rootType, options); } } } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java index 9e68ed669178..45751864903d 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java @@ -103,7 +103,7 @@ public class JpsProjectLoader { final ArrayList libraries = new ArrayList(); JpsLibraryTableLoader.loadLibraries(libraryTableElement, libraries); for (JpsLibrary library : libraries) { - myProject.addLibrary(library); + myProject.getLibraryCollection().addLibrary(library); } } diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsModuleSerializationTest.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsModuleSerializationTest.java index 20087a1e0326..bb7a5a0970b4 100644 --- a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsModuleSerializationTest.java +++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsModuleSerializationTest.java @@ -15,7 +15,7 @@ public class JpsModuleSerializationTest extends JpsModelTestCase { loadProject("iprProject/iprProject.ipr"); final JpsModule module = assertOneElement(myModel.getProject().getModules()); assertEquals("iprProject", module.getName()); - final JpsLibrary library = assertOneElement(myModel.getProject().getLibraries()); + final JpsLibrary library = assertOneElement(myModel.getProject().getLibraryCollection().getLibraries()); assertEquals("junit", library.getName()); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java index a19b2ba3c060..e288ef1a57c2 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java @@ -124,7 +124,9 @@ public class EnterHandler extends BaseEnterHandler { throw new AssertionError("Wrong caret offset change by " + delegate); } - if (result == EnterHandlerDelegate.Result.Stop) return; + if (result == EnterHandlerDelegate.Result.Stop) { + return; + } if (result != EnterHandlerDelegate.Result.Continue) { if (result == EnterHandlerDelegate.Result.DefaultForceIndent) { forceIndent = true; diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties index 499bdaaebf18..b6b201ca3882 100644 --- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties +++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties @@ -192,8 +192,8 @@ intention.assign.field.from.parameter.text=Assign Parameter to Field ''{0}'' intention.assign.field.from.parameter.family=Assign Parameter to Field intention.create.field.from.parameter.text=Create Field for Parameter ''{0}'' intention.create.field.from.parameter.family=Create Field for Parameter -intention.create.assign.fields.from.parameters.text=Create/Assign Fields from {0} Parameters -intention.create.assign.fields.from.parameters.family=Create/Assign Fields from Parameters +intention.bind.fields.from.parameters.text=Bind {0} Parameters to Fields +intention.bind.fields.from.parameters.family=Bind Parameters to Fields intention.implement.abstract.method.searching.for.descendants.progress=Searching For Descendants... intention.implement.abstract.method.error.no.classes.message=There are no classes found where this method can be implemented intention.implement.abstract.method.error.no.classes.title=No Classes Found @@ -205,6 +205,8 @@ intention.extract.if.condition.family=Extract If Condition intention.underscores.in.literals.family=Underscores in numeric literals intention.remove.literal.underscores=Remove underscores from literal intention.insert.literal.underscores=Insert underscores into literal +intention.replace.cast.with.var.text=Replace '{0}' with '{1}' +intention.replace.cast.with.var.family=Replace cast with variable intention.create.test=Create Test diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java index 2277d4f19954..87e0c9dbce80 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ModifiableRootModel.java @@ -151,23 +151,12 @@ public interface ModifiableRootModel extends ModuleRootModel { */ void inheritSdk(); - /** - * @deprecated see {@link ModuleRootManager#getFiles(OrderRootType)} for replacement - */ - @NotNull VirtualFile[] getOrderedRoots(OrderRootType type); - - void setExplodedDirectory(VirtualFile file); void setExplodedDirectory(String url); boolean isChanged(); - /** - * @deprecated see {@link ModuleRootManager#getUrls(OrderRootType)} for replacement - */ - @NotNull String[] getOrderedRootUrls(OrderRootType type); - boolean isExcludeExplodedDirectory(); void setExcludeExplodedDirectory(boolean excludeExplodedDir); diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootManager.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootManager.java index 6acc55da8169..deb9134da0c0 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootManager.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleRootManager.java @@ -16,7 +16,6 @@ package com.intellij.openapi.roots; import com.intellij.openapi.module.Module; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; /** @@ -35,34 +34,6 @@ public abstract class ModuleRootManager implements ModuleRootModel { return module.getComponent(ModuleRootManager.class); } - /** - * Returns the list of roots of the specified type for the current module and all modules it depends on. - * - * @param type the type of roots requested. - * @return the list of roots. - * - * @deprecated - *
    - *
  • to get {@link OrderRootType#CLASSES} use OrderEnumerator.orderEntries(module).getAllLibrariesAndSdkClassesRoots() - *
  • to get {@link OrderRootType#SOURCES} use OrderEnumerator.orderEntries(module).getAllSourceRoots() - */ - @NotNull - public abstract VirtualFile[] getFiles(OrderRootType type); - - /** - * Returns the list of URLs of roots of the specified type for the current module and all modules it depends on. - * - * @param type the type of roots requested. - * @return the list of root URLs. - - * @deprecated - *
      - *
    • to get {@link OrderRootType#CLASSES} use OrderEnumerator.orderEntries(module).withoutModuleSourceEntries().recursively().exportedOnly().classes().getUrls() - *
    • to get {@link OrderRootType#SOURCES} use OrderEnumerator.orderEntries(module).recursively().exportedOnly().sources().getUrls() - */ - @NotNull - public abstract String[] getUrls(OrderRootType type); - /** * Returns the file index for the current module. * diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java index 2f6b4204bbff..8da7c492019a 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectRootManager.java @@ -51,11 +51,6 @@ public abstract class ProjectRootManager implements ModificationTracker { @NotNull public abstract ProjectFileIndex getFileIndex(); - /** - * @deprecated use {@link #orderEntries()} - */ - public abstract VirtualFile[] getFilesFromAllModules(OrderRootType type); - /** * Creates new enumerator instance to process dependencies of all modules in the project. Only first level dependencies of * modules are processed so {@link OrderEnumerator#recursively()} option is ignored and {@link OrderEnumerator#withoutDepModules()} option is forced diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java index 431ff368eea0..71ff5f7bf1a3 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java @@ -168,16 +168,6 @@ public class ModuleRootManagerImpl extends ModuleRootManager implements ModuleCo return myRootModel.isSdkInherited(); } - @NotNull - public VirtualFile[] getFiles(OrderRootType type) { - return getCachingEnumeratorForType(type, myModule, false).getRoots(); - } - - @NotNull - public String[] getUrls(OrderRootType type) { - return getCachingEnumeratorForType(type, myModule, false).getUrls(); - } - void commitModel(RootModelImpl rootModel) { ApplicationManager.getApplication().assertWriteAccessAllowed(); LOG.assertTrue(rootModel.myModuleRootManager == this); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java index 7bcb2d0f215e..0271361b07c3 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java @@ -176,16 +176,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj return VfsUtilCore.toVirtualFileArray(result); } - @Override - public VirtualFile[] getFilesFromAllModules(OrderRootType type) { - final List result = new ArrayList(); - for (Module module : getModuleManager().getSortedModules()) { - final VirtualFile[] files = ModuleRootManager.getInstance(module).getFiles(type); - ContainerUtil.addAll(result, files); - } - return VfsUtilCore.toVirtualFileArray(result); - } - @NotNull @Override public OrderEnumerator orderEntries() { diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java index c50c7949a17c..b32f7201af8f 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java @@ -247,28 +247,6 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel return myOrderRootPointerContainers.get(orderRootType); } - @Override - @NotNull - public VirtualFile[] getOrderedRoots(OrderRootType type) { - final ArrayList result = new ArrayList(); - - for (OrderEntry orderEntry : getOrderEntries()) { - ContainerUtil.addAll(result, orderEntry.getFiles(type)); - } - return ContainerUtil.toArray(result, new VirtualFile[result.size()]); - } - - @Override - @NotNull - public String[] getOrderedRootUrls(OrderRootType type) { - final ArrayList result = new ArrayList(); - - for (OrderEntry orderEntry : getOrderEntries()) { - ContainerUtil.addAll(result, orderEntry.getUrls(type)); - } - return ContainerUtil.toArray(result, new String[result.size()]); - } - @Override @NotNull public OrderEntry[] getOrderEntries() { diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/library/JpsLibraryDelegate.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/library/JpsLibraryDelegate.java new file mode 100644 index 000000000000..eb95c0e11eaa --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/library/JpsLibraryDelegate.java @@ -0,0 +1,209 @@ +/* + * 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.project.model.impl.library; + +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.RootProvider; +import com.intellij.openapi.roots.impl.RootModelImpl; +import com.intellij.openapi.roots.impl.RootProviderBaseImpl; +import com.intellij.openapi.roots.impl.libraries.JarDirectories; +import com.intellij.openapi.roots.impl.libraries.LibraryEx; +import com.intellij.openapi.roots.impl.libraries.LibraryImpl; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryProperties; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.PersistentLibraryKind; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer; +import com.intellij.util.ArrayUtil; +import com.intellij.util.SmartList; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryRoot; +import org.jetbrains.jps.model.library.JpsOrderRootType; + +import java.util.*; + +/** + * @author nik + */ +public class JpsLibraryDelegate implements LibraryEx { + private JpsLibrary myJpsLibrary; + private JpsLibraryTableImpl myLibraryTable; + private Map myRoots; + private RootProviderBaseImpl myRootProvider = new MyRootProvider(); + + public JpsLibraryDelegate(JpsLibrary library, JpsLibraryTableImpl table) { + myJpsLibrary = library; + myLibraryTable = table; + myRoots = new HashMap(); + } + + @Override + public String getName() { + return myJpsLibrary.getName(); + } + + @Override + public PersistentLibraryKind getKind() { + return null; + } + + @Override + public LibraryProperties getProperties() { + return null; + } + + @NotNull + @Override + public String[] getUrls(@NotNull OrderRootType rootType) { + final VirtualFilePointerContainer container = myRoots.get(rootType); + if (container == null) return ArrayUtil.EMPTY_STRING_ARRAY; + return container.getUrls(); + } + + @NotNull + @Override + public VirtualFile[] getFiles(@NotNull OrderRootType rootType) { + final VirtualFilePointerContainer container = myRoots.get(rootType); + if (container == null) return VirtualFile.EMPTY_ARRAY; + final List expanded = new ArrayList(); + for (JpsLibraryRoot root : myJpsLibrary.getRoots(getJpsRootType(rootType))) { + final VirtualFilePointer pointer = container.findByUrl(root.getUrl()); + if (pointer == null) continue; + VirtualFile file = pointer.getFile(); + if (file == null) continue; + + if (file.isDirectory() && root.getInclusionOptions() != JpsLibraryRoot.InclusionOptions.ROOT_ITSELF) { + LibraryImpl.collectJarFiles(file, expanded, root.getInclusionOptions() == JpsLibraryRoot.InclusionOptions.ARCHIVES_UNDER_ROOT_RECURSIVELY); + continue; + } + expanded.add(file); + } + return VfsUtilCore.toVirtualFileArray(expanded); + } + + @Override + public List getInvalidRootUrls(OrderRootType type) { + final VirtualFilePointerContainer container = myRoots.get(type); + if (container == null) return Collections.emptyList(); + final List pointers = container.getList(); + List invalidPaths = null; + for (VirtualFilePointer pointer : pointers) { + if (!pointer.isValid()) { + if (invalidPaths == null) { + invalidPaths = new SmartList(); + } + invalidPaths.add(pointer.getUrl()); + } + } + return invalidPaths == null ? Collections.emptyList() : invalidPaths; + } + + @Override + public boolean isDisposed() { + return false; + } + + @Override + public LibraryTable getTable() { + return myLibraryTable; + } + + @NotNull + @Override + public RootProvider getRootProvider() { + return myRootProvider; + } + + @Override + public void dispose() { + } + + @Override + public Library cloneLibrary(RootModelImpl rootModel) { + throw new UnsupportedOperationException("'cloneLibrary' not implemented in " + getClass().getName()); + } + + @NotNull + @Override + public ModifiableModel getModifiableModel() { + throw new UnsupportedOperationException("'getModifiableModel' not implemented in " + getClass().getName()); + } + + @Override + public void readExternal(Element element) throws InvalidDataException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeExternal(Element element) throws WriteExternalException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isJarDirectory(@NotNull String url) { + return isJarDirectory(url, JarDirectories.DEFAULT_JAR_DIRECTORY_TYPE); + } + + @Override + public boolean isJarDirectory(@NotNull String url, @NotNull OrderRootType rootType) { + for (JpsLibraryRoot root : myJpsLibrary.getRoots(getJpsRootType(rootType))) { + if (url.equals(root.getUrl()) && root.getInclusionOptions() != JpsLibraryRoot.InclusionOptions.ROOT_ITSELF) { + return true; + } + } + return false; + } + + @Override + public boolean isValid(@NotNull String url, @NotNull OrderRootType rootType) { + final VirtualFilePointerContainer container = myRoots.get(rootType); + if (container == null) return false; + final VirtualFilePointer fp = container.findByUrl(url); + return fp != null && fp.isValid(); + } + + private static JpsOrderRootType getJpsRootType(OrderRootType type) { + if (type == OrderRootType.CLASSES) return JpsOrderRootType.COMPILED; + if (type == OrderRootType.SOURCES) return JpsOrderRootType.SOURCES; + if (type == OrderRootType.DOCUMENTATION) return JpsOrderRootType.DOCUMENTATION; + return JpsOrderRootType.COMPILED; + } + + private class MyRootProvider extends RootProviderBaseImpl { + @NotNull + @Override + public String[] getUrls(@NotNull OrderRootType rootType) { + Set originalUrls = new LinkedHashSet(Arrays.asList(JpsLibraryDelegate.this.getUrls(rootType))); + for (VirtualFile file : getFiles(rootType)) { // Add those expanded with jar directories. + originalUrls.add(file.getUrl()); + } + return ArrayUtil.toStringArray(originalUrls); + } + + @NotNull + @Override + public VirtualFile[] getFiles(@NotNull OrderRootType rootType) { + return JpsLibraryDelegate.this.getFiles(rootType); + } + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/library/JpsLibraryTableImpl.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/library/JpsLibraryTableImpl.java new file mode 100644 index 000000000000..2819a876ee75 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/library/JpsLibraryTableImpl.java @@ -0,0 +1,189 @@ +/* + * 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.project.model.impl.library; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.roots.impl.libraries.LibraryTableBase; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.roots.libraries.LibraryTablePresentation; +import com.intellij.openapi.roots.libraries.PersistentLibraryKind; +import com.intellij.openapi.util.Disposer; +import com.intellij.util.EventDispatcher; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryCollection; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * @author nik + */ +public class JpsLibraryTableImpl implements LibraryTable, Disposable { + private JpsLibrariesModel myModel; + private final EventDispatcher myDispatcher = EventDispatcher.create(Listener.class); + private String myTableLevel; + private LibraryTablePresentation myPresentation; + + public JpsLibraryTableImpl(JpsLibraryCollection libraryCollection, String level) { + myTableLevel = level; + myModel = new JpsLibrariesModel(libraryCollection); + } + + @NotNull + @Override + public Library[] getLibraries() { + return myModel.getLibraries(); + } + + @NotNull + @Override + public Iterator getLibraryIterator() { + return myModel.getLibraryIterator(); + } + + @Override + public Library getLibraryByName(@NotNull String name) { + return myModel.getLibraryByName(name); + } + + @Override + public void addListener(Listener listener) { + myDispatcher.addListener(listener); + } + + @Override + public void addListener(Listener listener, Disposable parentDisposable) { + myDispatcher.addListener(listener, parentDisposable); + } + + @Override + public void removeListener(Listener listener) { + myDispatcher.removeListener(listener); + } + + @Override + public Library createLibrary() { + return createLibrary(null); + } + + @Override + public Library createLibrary(@NonNls String name) { + final ModifiableModel model = getModifiableModel(); + final Library library = model.createLibrary(name); + model.commit(); + return library; + } + + @Override + public void removeLibrary(@NotNull Library library) { + final ModifiableModel model = getModifiableModel(); + model.removeLibrary(library); + model.commit(); + } + + @Override + public void dispose() { + for (Library library : getLibraries()) { + Disposer.dispose(library); + } + } + + @Override + public ModifiableModel getModifiableModel() { + return new JpsLibrariesModel(myModel.myJpsLibraries); + } + + @Override + public boolean isEditable() { + return true; + } + + @Override + public String getTableLevel() { + return myTableLevel; + } + + @Override + public LibraryTablePresentation getPresentation() { + return myPresentation; + } + + private class JpsLibrariesModel implements LibraryTableBase.ModifiableModelEx { + private JpsLibraryCollection myJpsLibraries; + private List myLibraries; + + private JpsLibrariesModel(JpsLibraryCollection libraryCollection) { + myLibraries = new ArrayList(); + myJpsLibraries = libraryCollection; + for (JpsLibrary library : libraryCollection.getLibraries()) { + myLibraries.add(new JpsLibraryDelegate(library, JpsLibraryTableImpl.this)); + } + } + + @Override + public Library createLibrary(String name) { + return createLibrary(name, null); + } + + @Override + public Library createLibrary(String name, @Nullable PersistentLibraryKind type) { + throw new UnsupportedOperationException("'createLibrary' not implemented in " + getClass().getName()); + } + + @NotNull + @Override + public Iterator getLibraryIterator() { + return Collections.unmodifiableList(myLibraries).iterator(); + } + + @Override + public void removeLibrary(@NotNull Library library) { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public Library[] getLibraries() { + return myLibraries.toArray(new Library[myLibraries.size()]); + } + + @Override + public Library getLibraryByName(@NotNull String name) { + for (JpsLibraryDelegate library : myLibraries) { + if (name.equals(library.getName())) { + return library; + } + } + return null; + } + + @Override + public void commit() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isChanged() { + return false; + } + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java index 38343a8bb911..db1f6462eabc 100644 --- a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java @@ -31,6 +31,8 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; import com.intellij.project.model.impl.module.JpsRootModel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.java.JavaSourceRootProperties; +import org.jetbrains.jps.model.java.JavaSourceRootType; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleSourceRoot; @@ -130,47 +132,80 @@ public class JpsContentEntry implements ContentEntry, Disposable { @Override public SourceFolder addSourceFolder(@NotNull VirtualFile file, boolean isTestSource) { - throw new UnsupportedOperationException("'addSourceFolder' not implemented in " + getClass().getName()); + return addSourceFolder(file, isTestSource, ""); } @Override public SourceFolder addSourceFolder(@NotNull VirtualFile file, boolean isTestSource, @NotNull String packagePrefix) { - throw new UnsupportedOperationException("'addSourceFolder' not implemented in " + getClass().getName()); + return addSourceFolder(file.getUrl(), isTestSource, packagePrefix); + } + + private SourceFolder addSourceFolder(final String url, boolean isTestSource, String packagePrefix) { + final JavaSourceRootType rootType = isTestSource ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE; + final JpsModuleSourceRoot sourceRoot = myModule.addSourceRoot(rootType, url, new JavaSourceRootProperties(packagePrefix)); + final JpsSourceFolder sourceFolder = new JpsSourceFolder(sourceRoot, this); + mySourceFolders.add(sourceFolder); + return sourceFolder; } @Override public SourceFolder addSourceFolder(@NotNull String url, boolean isTestSource) { - throw new UnsupportedOperationException("'addSourceFolder' not implemented in " + getClass().getName()); + return addSourceFolder(url, isTestSource, ""); } @Override public void removeSourceFolder(@NotNull SourceFolder sourceFolder) { - throw new UnsupportedOperationException(); + final JpsSourceFolder folder = (JpsSourceFolder)sourceFolder; + mySourceFolders.remove(folder); + myModule.removeSourceRoot(folder.getSourceRoot().getRootType(), folder.getSourceRoot().getUrl()); + Disposer.dispose(folder); } @Override public void clearSourceFolders() { - throw new UnsupportedOperationException(); + List toRemove = new ArrayList(); + for (JpsSourceFolder folder : mySourceFolders) { + toRemove.add(folder.getSourceRoot()); + Disposer.dispose(folder); + } + mySourceFolders.clear(); + for (JpsModuleSourceRoot root : toRemove) { + myModule.removeSourceRoot(root.getRootType(), root.getUrl()); + } } @Override public ExcludeFolder addExcludeFolder(@NotNull VirtualFile file) { - throw new UnsupportedOperationException("'addExcludeFolder' not implemented in " + getClass().getName()); + return addExcludeFolder(file.getUrl()); } @Override public ExcludeFolder addExcludeFolder(@NotNull String url) { - throw new UnsupportedOperationException("'addExcludeFolder' not implemented in " + getClass().getName()); + final JpsExcludeFolder folder = new JpsExcludeFolder(url, this); + myModule.getExcludeRootsList().addUrl(url); + myExcludeFolders.add(folder); + return folder; } @Override public void removeExcludeFolder(@NotNull ExcludeFolder excludeFolder) { - throw new UnsupportedOperationException(); + JpsExcludeFolder folder = (JpsExcludeFolder)excludeFolder; + myExcludeFolders.remove(folder); + myModule.getExcludeRootsList().removeUrl(folder.getUrl()); + Disposer.dispose(folder); } @Override public void clearExcludeFolders() { - throw new UnsupportedOperationException(); + List toRemove = new ArrayList(); + for (JpsExcludeFolder folder : myExcludeFolders) { + toRemove.add(folder.getUrl()); + Disposer.dispose(folder); + } + myExcludeFolders.clear(); + for (String url : toRemove) { + myModule.getExcludeRootsList().removeUrl(url); + } } @Override diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java index 219b0f8bdd12..41127ac8b250 100644 --- a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java @@ -32,6 +32,10 @@ public class JpsSourceFolder extends JpsContentFolderBase implements SourceFolde mySourceRoot = sourceRoot; } + public JpsModuleSourceRoot getSourceRoot() { + return mySourceRoot; + } + @Override public boolean isTestSource() { return mySourceRoot.getRootType() == JavaSourceRootType.TEST_SOURCE; diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsExportableOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsExportableOrderEntry.java index 693899a33517..d04b8c19bab1 100644 --- a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsExportableOrderEntry.java +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsExportableOrderEntry.java @@ -56,7 +56,7 @@ public abstract class JpsExportableOrderEntry ex @Override public void setScope(@NotNull DependencyScope scope) { - JpsJavaExtensionService.getInstance().getOrCreateDependencyExtension(myDependencyElement) - .setScope(JpsJavaDependencyScope.valueOf(scope.name())); + final JpsJavaDependencyExtension extension = JpsJavaExtensionService.getInstance().getOrCreateDependencyExtension(myDependencyElement); + extension.setScope(JpsJavaDependencyScope.valueOf(scope.name())); } } diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleOrderEntry.java index 3617589faf25..48b5bca5fa40 100644 --- a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleOrderEntry.java +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleOrderEntry.java @@ -18,10 +18,13 @@ package com.intellij.project.model.impl.module.dependencies; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.ModuleOrderEntry; import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.OrderRootsEnumerator; import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.roots.impl.ModuleRootManagerImpl; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.project.model.JpsModelManager; import com.intellij.project.model.impl.module.JpsRootModel; +import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.module.JpsModule; @@ -53,15 +56,23 @@ public class JpsModuleOrderEntry extends JpsExportableOrderEntry { } }; + final LocalFileSystem lfs = LocalFileSystem.getInstance(); + for (FilePath filePath : directlyAffected) { + lfs.refreshAndFindFileByIoFile(filePath.getIOFile()); + } final RefreshSession session = RefreshQueue.getInstance().createSession(false, true, new Runnable() { public void run() { if (project.isDisposed()) return; @@ -401,6 +406,7 @@ public class PatchApplier { final VcsDirtyScopeManager vcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(project); // will schedule update vcsDirtyScopeManager.filePathsDirty(directlyAffected, null); + vcsDirtyScopeManager.filesDirty(indirectlyAffected, null); scheduleProjectFilesReload.run(); if (context != null) { context.ping(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java index 3230c13d601e..a4f9e24599fa 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java @@ -686,7 +686,6 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, Advan final TreePath path = getPathForLocation(e.getPoint().x, e.getPoint().y); if (path != null) { setSelectionPath(path); - e.consume(); } } } diff --git a/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java b/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java index 227d9075738b..c40f66ff5189 100644 --- a/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java +++ b/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java @@ -131,7 +131,7 @@ public class CreateXmlResourceDialog extends DialogWrapper { myModuleCombo.setRenderer(new ModuleListCellRendererWrapper(myModuleCombo.getRenderer())); } - final String defaultResFileName = AndroidResourceUtil.getDefaultResourceFileName(resourceType.getName()); + final String defaultResFileName = AndroidResourceUtil.getDefaultResourceFileName(resourceType); if (defaultResFileName != null) { myFileNameField.setText(defaultResFileName); } @@ -393,7 +393,18 @@ public class CreateXmlResourceDialog extends DialogWrapper { @Override public JComponent getPreferredFocusedComponent() { - return myNameField.getText().length() == 0 ? myNameField : myValueField; + if (myNameField.getText().length() == 0) { + return myNameField; + } + else if (myValueField.isVisible()) { + return myValueField; + } + else if (myModuleCombo.isVisible()) { + return myModuleCombo; + } + else { + return myFileNameField; + } } @Override diff --git a/plugins/android/src/org/jetbrains/android/compiler/ResourceNamesValidityState.java b/plugins/android/src/org/jetbrains/android/compiler/ResourceNamesValidityState.java index 3cd624e19740..1be06afcae31 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/ResourceNamesValidityState.java +++ b/plugins/android/src/org/jetbrains/android/compiler/ResourceNamesValidityState.java @@ -11,6 +11,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileFilter; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.HashMap; +import org.jetbrains.android.dom.resources.DeclareStyleable; import org.jetbrains.android.dom.resources.ResourceElement; import org.jetbrains.android.dom.resources.Resources; import org.jetbrains.android.facet.AndroidFacet; @@ -58,10 +59,19 @@ public class ResourceNamesValidityState implements ValidityState { final VirtualFile file = pair.getSecond(); for (final ResourceType resType : AndroidResourceUtil.VALUE_RESOURCE_TYPES) { - addValueResources(file, resType, AndroidResourceUtil.getValueResourcesFromElement(resType.getName(), resources), myResources); + addValueResources(file, resType, AndroidResourceUtil.getValueResourcesFromElement(resType.getName(), resources), myResources, ""); + } + addValueResources(file, ResourceType.ATTR, resources.getAttrs(), myResources, ""); + final List styleables = resources.getDeclareStyleables(); + addValueResources(file, ResourceType.DECLARE_STYLEABLE, styleables, myResources, ""); + + for (DeclareStyleable styleable : styleables) { + final String styleableName = styleable.getName().getValue(); + + if (styleableName != null) { + addValueResources(file, ResourceType.DECLARE_STYLEABLE, styleable.getAttrs(), myResources, styleableName + '_'); + } } - addValueResources(file, ResourceType.ATTR, resources.getAttrs(), myResources); - addValueResources(file, ResourceType.DECLARE_STYLEABLE, resources.getDeclareStyleables(), myResources); } for (final VirtualFile subdir : manager.getResourceSubdirs(null)) { @@ -94,7 +104,8 @@ public class ResourceNamesValidityState implements ValidityState { private static void addValueResources(VirtualFile file, ResourceType resType, Collection resourceElements, - Map result) { + Map result, + String namePrefix) { for (ResourceElement element : resourceElements) { final String name = element.getName().getValue(); @@ -104,7 +115,7 @@ public class ResourceNamesValidityState implements ValidityState { data = new ResourceFileData(); result.put(file.getPath(), data); } - data.addValueResource(new ResourceEntry(resType.getName(), name)); + data.addValueResource(new ResourceEntry(resType.getName(), namePrefix + name)); } } } diff --git a/plugins/android/src/org/jetbrains/android/dom/resources/Resources.java b/plugins/android/src/org/jetbrains/android/dom/resources/Resources.java index a3a8c069ae2d..520470f61b82 100644 --- a/plugins/android/src/org/jetbrains/android/dom/resources/Resources.java +++ b/plugins/android/src/org/jetbrains/android/dom/resources/Resources.java @@ -56,7 +56,10 @@ public interface Resources extends AndroidDomElement { StringArray addStringArray(); List getDeclareStyleables(); + DeclareStyleable addDeclareStyleable(); + List getAttrs(); + Attr addAttr(); List getItems(); Item addItem(); diff --git a/plugins/android/src/org/jetbrains/android/inspections/AndroidQuickFixProvider.java b/plugins/android/src/org/jetbrains/android/inspections/AndroidQuickFixProvider.java index 39ec81858ca8..5ec1a6699031 100644 --- a/plugins/android/src/org/jetbrains/android/inspections/AndroidQuickFixProvider.java +++ b/plugins/android/src/org/jetbrains/android/inspections/AndroidQuickFixProvider.java @@ -51,13 +51,9 @@ public class AndroidQuickFixProvider extends UnresolvedReferenceQuickFixProvider final String resClassName = pair.getFirst(); final String resFieldName = pair.getSecond(); - final ResourceType resourceType = ResourceType.getEnum(resClassName); - if (resourceType == ResourceType.STYLEABLE || resourceType == ResourceType.ATTR) { - // todo: support - return; - } + ResourceType resourceType = ResourceType.getEnum(resClassName); - if (AndroidResourceUtil.VALUE_RESOURCE_TYPES.contains(resourceType)) { + if (AndroidResourceUtil.ALL_VALUE_RESOURCE_TYPES.contains(resourceType)) { registrar .register(new CreateValueResourceQuickFix(facet, resourceType, resFieldName, contextFile, true)); } diff --git a/plugins/android/src/org/jetbrains/android/inspections/CreateValueResourceQuickFix.java b/plugins/android/src/org/jetbrains/android/inspections/CreateValueResourceQuickFix.java index dd9bfdba0952..9c55d7b4f1cb 100644 --- a/plugins/android/src/org/jetbrains/android/inspections/CreateValueResourceQuickFix.java +++ b/plugins/android/src/org/jetbrains/android/inspections/CreateValueResourceQuickFix.java @@ -49,7 +49,7 @@ public class CreateValueResourceQuickFix implements LocalQuickFix, IntentionActi @NotNull public String getName() { return AndroidBundle.message("create.value.resource.quickfix.name", myResourceName, - AndroidResourceUtil.getDefaultResourceFileName(myResourceType.getName())); + AndroidResourceUtil.getDefaultResourceFileName(myResourceType)); } @NotNull @@ -75,7 +75,7 @@ public class CreateValueResourceQuickFix implements LocalQuickFix, IntentionActi protected boolean doInvoke() { if (ApplicationManager.getApplication().isUnitTestMode()) { - final String fileName = AndroidResourceUtil.getDefaultResourceFileName(myResourceType.getName()); + final String fileName = AndroidResourceUtil.getDefaultResourceFileName(myResourceType); assert fileName != null; if (!AndroidResourceUtil.createValueResource(myFacet.getModule(), myResourceName, myResourceType, fileName, @@ -84,8 +84,10 @@ public class CreateValueResourceQuickFix implements LocalQuickFix, IntentionActi } } else { - final CreateXmlResourceDialog dialog = new CreateXmlResourceDialog(myFacet.getModule(), myResourceType, myResourceName, null, - myChooseName); + final String value = myResourceType == ResourceType.STYLEABLE || + myResourceType == ResourceType.ATTR ? "\n" : null; + final CreateXmlResourceDialog dialog = + new CreateXmlResourceDialog(myFacet.getModule(), myResourceType, myResourceName, value, myChooseName); dialog.setTitle("New " + StringUtil.capitalize(myResourceType.getDisplayName()) + " Value Resource"); dialog.show(); diff --git a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java index 35179b26b783..294eb2c69281 100644 --- a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java +++ b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java @@ -427,7 +427,7 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { final String normalizedAppName = AndroidResourceUtil.normalizeXmlResourceValue(myApplicationName.replace("\\", "\\\\")); if (appNameResElement == null) { - final String fileName = AndroidResourceUtil.getDefaultResourceFileName(ResourceType.STRING.getName()); + final String fileName = AndroidResourceUtil.getDefaultResourceFileName(ResourceType.STRING); assert fileName != null; AndroidResourceUtil.createValueResource(facet.getModule(), appNameResource, ResourceType.STRING, fileName, Collections .singletonList(AndroidConstants.FD_RES_VALUES), normalizedAppName); diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java index b6044ccc2d7c..c554b63945f6 100644 --- a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java +++ b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java @@ -99,11 +99,6 @@ public class AndroidResourceUtil { ALL_VALUE_RESOURCE_TYPES.add(ResourceType.STYLEABLE); } - public static boolean isValueResourceType(@NotNull String resTypeName) { - final ResourceType type = ResourceType.getEnum(resTypeName); - return type != null && VALUE_RESOURCE_TYPES.contains(type); - } - @NotNull public static PsiField[] findResourceFields(@NotNull AndroidFacet facet, @NotNull String resClassName, @@ -384,38 +379,36 @@ public class AndroidResourceUtil { } @NotNull - public static ResourceElement addValueResource(@NotNull final String type, @NotNull final Resources resources) { - if (type.equals("string")) { - return resources.addString(); + public static ResourceElement addValueResource(@NotNull final ResourceType resType, @NotNull final Resources resources) { + switch (resType) { + case STRING: + return resources.addString(); + case DIMEN: + return resources.addDimen(); + case COLOR: + return resources.addColor(); + case DRAWABLE: + return resources.addDrawable(); + case STYLE: + return resources.addStyle(); + case ARRAY: + // todo: choose among string-array, integer-array and array + return resources.addStringArray(); + case INTEGER: + return resources.addInteger(); + case BOOL: + return resources.addBool(); + case ID: + final Item item = resources.addItem(); + item.getType().setValue("id"); + return item; + case ATTR: + return resources.addAttr(); + case STYLEABLE: + return resources.addDeclareStyleable(); + default: + throw new IllegalArgumentException("Incorrect resource type"); } - else if (type.equals("dimen")) { - return resources.addDimen(); - } - else if (type.equals("color")) { - return resources.addColor(); - } - else if (type.equals("drawable")) { - return resources.addDrawable(); - } - else if (type.equals("style")) { - return resources.addStyle(); - } - else if (type.equals("array")) { - // todo: choose among string-array, integer-array and array - return resources.addStringArray(); - } - else if (type.equals("integer")) { - return resources.addInteger(); - } - else if (type.equals("bool")) { - return resources.addBool(); - } - else if (type.equals("id")) { - Item item = resources.addItem(); - item.getType().setValue("id"); - return item; - } - throw new IllegalArgumentException("Incorrect resource type"); } @NotNull @@ -443,8 +436,15 @@ public class AndroidResourceUtil { } @Nullable - public static String getDefaultResourceFileName(@NotNull String resourceType) { - return isValueResourceType(resourceType) ? resourceType + "s.xml" : null; + public static String getDefaultResourceFileName(@NotNull ResourceType type) { + if (VALUE_RESOURCE_TYPES.contains(type)) { + return type.getName() + "s.xml"; + } + if (ResourceType.ATTR == type || + ResourceType.STYLEABLE == type) { + return "attrs.xml"; + } + return null; } @NotNull @@ -667,12 +667,17 @@ public class AndroidResourceUtil { @Override public void run() { for (Resources resources : resourcesElements) { - final ResourceElement element = addValueResource(resourceType.getName(), resources); + final ResourceElement element = addValueResource(resourceType, resources); element.getName().setValue(resourceName); if (value.length() > 0) { element.setStringValue(value); } + else if (resourceType == ResourceType.STYLEABLE || + resourceType == ResourceType.STYLE) { + element.setStringValue("value"); + element.getXmlTag().getValue().setText(""); + } } } }); diff --git a/plugins/git4idea/src/git4idea/status/GitChangeProvider.java b/plugins/git4idea/src/git4idea/status/GitChangeProvider.java index 58d834217064..4a5194e96896 100644 --- a/plugins/git4idea/src/git4idea/status/GitChangeProvider.java +++ b/plugins/git4idea/src/git4idea/status/GitChangeProvider.java @@ -71,10 +71,12 @@ public class GitChangeProvider implements ChangeProvider { } final Collection affected = dirtyScope.getAffectedContentRootsWithCheck(); - if (dirtyScope.getAffectedContentRoots().size() != affected.size()) { + final Collection affectedContentRoots = dirtyScope.getAffectedContentRoots(); + if (affectedContentRoots.size() != affected.size()) { final Set set = new HashSet(affected); - set.removeAll(dirtyScope.getAffectedContentRoots()); + set.removeAll(affectedContentRoots); for (VirtualFile file : set) { + debug("adding git root for check: " + file.getPath()); ((VcsModifiableDirtyScope) dirtyScope).addDirtyDirRecursively(new FilePathImpl(file)); } } @@ -84,13 +86,16 @@ public class GitChangeProvider implements ChangeProvider { final MyNonChangedHolder holder = new MyNonChangedHolder(myProject, dirtyScope.getDirtyFilesNoExpand(), addGate, myFileDocumentManager, myVcsManager); for (VirtualFile root : roots) { + debug("checking root: " + root.getPath()); GitChangesCollector collector = isNewGitChangeProviderAvailable() ? GitNewChangesCollector.collect(myProject, myGit, myChangeListManager, myVcsManager, vcs, dirtyScope, root) : GitOldChangesCollector.collect(myProject, myChangeListManager, myVcsManager, vcs, dirtyScope, root); - holder.changed(collector.getChanges()); - for (Change file : collector.getChanges()) { + final Collection changes = collector.getChanges(); + holder.changed(changes); + for (Change file : changes) { + debug("process change: " + ChangesUtil.getFilePath(file).getPath()); builder.processChange(file, GitVcs.getKey()); } for (VirtualFile f : collector.getUnversionedFiles()) { @@ -101,6 +106,7 @@ public class GitChangeProvider implements ChangeProvider { } } catch (VcsException e) { + PROFILE_LOG.info(e); // most probably the error happened because git is not configured vcs.getExecutableValidator().showNotificationOrThrow(e); } diff --git a/plugins/git4idea/tests/git4idea/test/GitMockProjectRootManager.groovy b/plugins/git4idea/tests/git4idea/test/GitMockProjectRootManager.groovy index f88dbf85c1ce..edcd0b9e5960 100644 --- a/plugins/git4idea/tests/git4idea/test/GitMockProjectRootManager.groovy +++ b/plugins/git4idea/tests/git4idea/test/GitMockProjectRootManager.groovy @@ -45,10 +45,6 @@ class GitMockProjectRootManager extends ProjectRootManager { - @Override - VirtualFile[] getFilesFromAllModules(OrderRootType type) { - throw new UnsupportedOperationException() - } @Override OrderEnumerator orderEntries() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/GrSplitDeclarationIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/GrSplitDeclarationIntention.java index bb2bc80e091f..4f9f22dabd46 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/GrSplitDeclarationIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/GrSplitDeclarationIntention.java @@ -28,6 +28,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; /** @@ -49,11 +50,11 @@ public class GrSplitDeclarationIntention extends Intention { element.getParent().addAfter(assignment, element); } } - else if (variables.length>1) { + else if (variables.length > 1) { String modifiers = ((GrVariableDeclaration)element).getModifierList().getText(); GrStatement[] sts = new GrStatement[variables.length]; for (int i = 0; i < variables.length; i++) { - sts[i] = GroovyPsiElementFactory.getInstance(project).createStatementFromText(modifiers + " " + variables[i].getText()); + sts[i] = createVarDeclaration(project, variables[i], modifiers); } element = GroovyRefactoringUtil.addBlockIntoParent(element); @@ -61,10 +62,27 @@ public class GrSplitDeclarationIntention extends Intention { for (int i = sts.length - 1; i >= 0; i--) { element.getParent().addAfter(sts[i], element); } + + element.delete(); } } } + private static GrStatement createVarDeclaration(Project project, GrVariable variable, String modifiers) { + StringBuilder builder = new StringBuilder(); + builder.append(modifiers).append(' '); + GrTypeElement typeElement = variable.getTypeElementGroovy(); + if (typeElement != null) { + builder.append(typeElement.getText()).append(' '); + } + builder.append(variable.getName()); + GrExpression initializer = variable.getInitializerGroovy(); + if (initializer != null) { + builder.append('=').append(initializer.getText()); + } + return GroovyPsiElementFactory.getInstance(project).createStatementFromText(builder.toString()); + } + private String myText = ""; @NotNull diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java index d09837265ff3..f0e48cffa806 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/actions/GroovyEnterHandler.java @@ -298,14 +298,11 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { TextRange literalRange = stringElement.getTextRange(); //the case of print '\' - if (fileText.charAt(caretOffset) == '\'' && caretOffset > 0 && fileText.charAt(caretOffset - 1) == '\\') { - convertEndToMultiline(caretOffset, document, fileText, '\''); - } - else { + if (!isSlashBeforeCaret(caretOffset, fileText)) { convertEndToMultiline(literalRange.getEndOffset(), document, fileText, '\''); + document.insertString(literalRange.getStartOffset(), "''"); + editor.getCaretModel().moveToOffset(caretOffset + 2); } - document.insertString(literalRange.getStartOffset(), "''"); - editor.getCaretModel().moveToOffset(caretOffset + 2); EditorModificationUtil.insertStringAtCaret(editor, "\n"); } else { @@ -331,15 +328,11 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { boolean rightFromDollar = exprSibling instanceof GrExpression && exprSibling.getTextRange().getStartOffset() == caretOffset; if (rightFromDollar) caretOffset--; TextRange parentRange = parent.getTextRange(); - //the case of print '\' - if (fileText.charAt(caretOffset) == '\"' && caretOffset > 0 && fileText.charAt(caretOffset - 1) == '\\') { - convertEndToMultiline(caretOffset, document, fileText, '"'); - } - else { + if (rightFromDollar || !isSlashBeforeCaret(caretOffset, fileText)) { convertEndToMultiline(parent.getTextRange().getEndOffset(), document, fileText, '"'); + document.insertString(parentRange.getStartOffset(), "\"\""); + editor.getCaretModel().moveToOffset(caretOffset + 2); } - document.insertString(parentRange.getStartOffset(), "\"\""); - editor.getCaretModel().moveToOffset(caretOffset + 2); EditorModificationUtil.insertStringAtCaret(editor, "\n"); if (rightFromDollar) { editor.getCaretModel().moveCaretRelatively(1, 0, false, false, true); @@ -378,6 +371,10 @@ public class GroovyEnterHandler extends EnterHandlerDelegateAdapter { return false; } + private static boolean isSlashBeforeCaret(int caretOffset, String fileText) { + return caretOffset > 0 && fileText.charAt(caretOffset - 1) == '\\'; + } + private static void insertLineFeedInString(Editor editor, DataContext dataContext, EditorActionHandler originalHandler, diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java index e33b7c2684c0..fc7041dc1a03 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/expectedTypes/GroovyExpectedTypesProvider.java @@ -30,6 +30,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; @@ -44,9 +45,11 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; +import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; @@ -151,13 +154,42 @@ public class GroovyExpectedTypesProvider { public void visitVariable(GrVariable variable) { if (myExpression.equals(variable.getInitializerGroovy())) { - PsiType type = variable.getDeclaredType(); - if (type != null) { - myResult = new TypeConstraint[]{new SubtypeConstraint(type, type)}; + PsiType type = variable.getType(); + myResult = new TypeConstraint[]{new SubtypeConstraint(type, type)}; + } + } + + @Override + public void visitNamedArgument(GrNamedArgument argument) { + PsiElement pparent = argument.getParent().getParent(); + if (pparent instanceof GrCall && resolvesToDefaultConstructor(((GrCall)pparent))) { + GrArgumentLabel label = argument.getLabel(); + if (label != null) { + PsiElement resolved = label.resolve(); + if (resolved instanceof PsiField) { + PsiType type = ((PsiField)resolved).getType(); + myResult = new TypeConstraint[]{new SubtypeConstraint(type, type)}; + } + else if (resolved instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertySetter((PsiMethod)resolved)) { + PsiType type = ((PsiMethod)resolved).getParameterList().getParameters()[0].getType(); + myResult = new TypeConstraint[]{new SubtypeConstraint(type,type)}; + } } } } + private static boolean resolvesToDefaultConstructor(GrCall call) { + PsiMethod method = call.resolveMethod(); + if (method != null && method.isConstructor() && method.getParameterList().getParametersCount() == 0) return true; + + if (call instanceof GrConstructorCall) { + PsiElement resolved = PsiImplUtil.extractUniqueResult(((GrConstructorCall)call).multiResolveClass()).getElement(); + if (resolved instanceof PsiClass) return true; + } + + return false; + } + public void visitMethodCallExpression(GrMethodCallExpression methodCall) { final GrExpression invokedExpression = methodCall.getInvokedExpression(); if (myExpression.equals(invokedExpression)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java index be3e52cc63b4..2e56f8cba5fb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java @@ -366,7 +366,8 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImpl imported = new ArrayList(); final PsiType[] args = reference.getTypeArguments(); for (int i = 0; i < results.length; i++) { @@ -390,6 +391,7 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImplDeclaration - com.intellij.codeInsight.intention.impl.CreateAssignFieldsFromParametersAction + com.intellij.codeInsight.intention.impl.BindFieldsFromParametersAction Declaration @@ -710,6 +710,13 @@ Other + + + + + + + com.intellij.codeInspection.concurrencyAnnotations.JCiPOrderEntryFix