Snapshot of commit d5ec1d5018ed24f1b4f32b1d09df6dbd7e2fc425
from branch master of git://git.jetbrains.org/idea/community.git
diff --git a/java/openapi/openapi.iml b/java/openapi/openapi.iml
new file mode 100644
index 0000000..0f0db7c
--- /dev/null
+++ b/java/openapi/openapi.iml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="util" exported="" />
+ <orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
+ <orderEntry type="library" name="JDOM" level="project" />
+ <orderEntry type="module" module-name="forms_rt" />
+ <orderEntry type="library" name="Trove4j" level="project" />
+ <orderEntry type="module" module-name="extensions" exported="" />
+ <orderEntry type="module" module-name="icons" />
+ <orderEntry type="library" exported="" name="NanoXML" level="project" />
+ <orderEntry type="library" exported="" name="microba" level="project" />
+ <orderEntry type="library" name="jgoodies-forms" level="project" />
+ <orderEntry type="module" module-name="xml-openapi" exported="" />
+ <orderEntry type="module" module-name="platform-api" exported="" />
+ <orderEntry type="module" module-name="lang-api" exported="" />
+ <orderEntry type="module" module-name="vcs-api" exported="" />
+ <orderEntry type="library" name="XmlRPC" level="project" />
+ <orderEntry type="module" module-name="dom-openapi" />
+ <orderEntry type="module" module-name="resources-en" exported="" />
+ <orderEntry type="module" module-name="java-psi-api" exported="" />
+ <orderEntry type="module" module-name="java-indexing-api" exported="" />
+ </component>
+ <component name="copyright">
+ <option name="body" value="/* * Copyright (c) $today.year Your Corporation. All Rights Reserved. */" />
+ <option name="location" value="1" />
+ <option name="remove" value="true" />
+ </component>
+</module>
+
diff --git a/java/openapi/src/com/intellij/codeInsight/AttachSourcesProvider.java b/java/openapi/src/com/intellij/codeInsight/AttachSourcesProvider.java
new file mode 100644
index 0000000..2bfdbb1
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/AttachSourcesProvider.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.openapi.roots.LibraryOrderEntry;
+import com.intellij.openapi.util.ActionCallback;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.List;
+
+public interface AttachSourcesProvider {
+ @NotNull
+ Collection<AttachSourcesAction> getActions(List<LibraryOrderEntry> orderEntries, PsiFile psiFile);
+
+ interface AttachSourcesAction {
+ String getName();
+ String getBusyText();
+ ActionCallback perform(List<LibraryOrderEntry> orderEntriesContainingFile);
+ }
+
+ /**
+ * This marker interface means what this action will be shown only if it is single action.
+ */
+ interface LightAttachSourcesAction extends AttachSourcesAction {
+
+ }
+
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/ClassUtil.java b/java/openapi/src/com/intellij/codeInsight/ClassUtil.java
new file mode 100644
index 0000000..eb41a67
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/ClassUtil.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexey
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.psi.*;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Set;
+
+public class ClassUtil {
+ private ClassUtil() { }
+
+ @Nullable
+ public static PsiMethod getAnyAbstractMethod(@NotNull PsiClass aClass) {
+ PsiMethod methodToImplement = getAnyMethodToImplement(aClass);
+ if (methodToImplement != null) {
+ return methodToImplement;
+ }
+ PsiMethod[] methods = aClass.getMethods();
+ for (PsiMethod method : methods) {
+ if (method.hasModifierProperty(PsiModifier.ABSTRACT)) return method;
+ }
+
+ return null;
+ }
+
+ @Nullable
+ public static PsiMethod getAnyMethodToImplement(@NotNull PsiClass aClass) {
+ Set<PsiMethod> alreadyImplemented = new THashSet<PsiMethod>();
+ for (HierarchicalMethodSignature signatureHierarchical : aClass.getVisibleSignatures()) {
+ for (PsiMethod superS : signatureHierarchical.getMethod().findSuperMethods()) {
+ add(superS, alreadyImplemented);
+ }
+ }
+ PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(aClass.getProject()).getResolveHelper();
+ for (HierarchicalMethodSignature signatureHierarchical : aClass.getVisibleSignatures()) {
+ PsiMethod method = signatureHierarchical.getMethod();
+ PsiClass containingClass = method.getContainingClass();
+ if (containingClass == null) {
+ continue;
+ }
+ if (!aClass.equals(containingClass)
+ && method.hasModifierProperty(PsiModifier.ABSTRACT)
+ && !method.hasModifierProperty(PsiModifier.STATIC)
+ && !method.hasModifierProperty(PsiModifier.PRIVATE)
+ && !alreadyImplemented.contains(method)) {
+ return method;
+ }
+ final List<HierarchicalMethodSignature> superSignatures = signatureHierarchical.getSuperSignatures();
+ for (HierarchicalMethodSignature superSignatureHierarchical : superSignatures) {
+ final PsiMethod superMethod = superSignatureHierarchical.getMethod();
+ if (superMethod.hasModifierProperty(PsiModifier.ABSTRACT) && !resolveHelper.isAccessible(superMethod, method, null)) {
+ return superMethod;
+ }
+ }
+ }
+
+ return checkPackageLocalInSuperClass(aClass);
+ }
+
+ @Nullable
+ private static PsiMethod checkPackageLocalInSuperClass(@NotNull PsiClass aClass) {
+ // super class can have package local abstract methods not accessible for overriding
+ PsiClass superClass = aClass.getSuperClass();
+ if (superClass == null) return null;
+ if (CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) return null;
+ if (JavaPsiFacade.getInstance(aClass.getProject()).arePackagesTheSame(aClass, superClass)) return null;
+
+ for (HierarchicalMethodSignature methodSignature : superClass.getVisibleSignatures()) {
+ PsiMethod method = methodSignature.getMethod();
+ if (method.hasModifierProperty(PsiModifier.ABSTRACT) && method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) return method;
+ }
+ return null;
+ }
+
+ private static boolean add(PsiMethod method, Set<PsiMethod> alreadyImplemented) {
+ boolean already = alreadyImplemented.add(method);
+ if (!already) return already;
+
+ for (PsiMethod superSig : method.findSuperMethods()) {
+ already &= add(superSig, alreadyImplemented);
+ }
+ return already;
+ }
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java b/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java
new file mode 100644
index 0000000..b440e4c
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.util.IncorrectOperationException;
+
+/**
+ * @author ven
+ */
+public class CodeInsightServicesUtil {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.CodeInsightServicesUtil");
+
+ private static final IElementType[] ourTokenMap = {
+ JavaTokenType.EQEQ, JavaTokenType.NE,
+ JavaTokenType.LT, JavaTokenType.GE,
+ JavaTokenType.LE, JavaTokenType.GT,
+ JavaTokenType.OROR, JavaTokenType.ANDAND
+ };
+
+ public static PsiExpression invertCondition(PsiExpression booleanExpression) throws IncorrectOperationException {
+ PsiElementFactory factory = JavaPsiFacade.getInstance(booleanExpression.getProject()).getElementFactory();
+
+ if (booleanExpression instanceof PsiPolyadicExpression) {
+ PsiPolyadicExpression expression = (PsiPolyadicExpression)booleanExpression;
+ IElementType operationSign = expression.getOperationTokenType();
+ for (int i = 0; i < ourTokenMap.length; i++) {
+ IElementType tokenType = ourTokenMap[i];
+ if (operationSign == tokenType) {
+ expression = (PsiPolyadicExpression)expression.copy();
+ PsiExpression[] operands = expression.getOperands();
+ for (int o = 0; o < operands.length; o++) {
+ PsiExpression op = operands[o];
+ if (o != 0) {
+ expression.getTokenBeforeOperand(op).replace(createOperationToken(factory, ourTokenMap[i + (i % 2 == 0 ? 1 : -1)]));
+ }
+ if (tokenType == JavaTokenType.OROR || tokenType == JavaTokenType.ANDAND) {
+ op.replace(invertCondition(op));
+ }
+ }
+ return expression;
+ }
+ }
+ }
+ else if (booleanExpression instanceof PsiPrefixExpression) {
+ PsiPrefixExpression expression = (PsiPrefixExpression)booleanExpression;
+ if (expression.getOperationTokenType() == JavaTokenType.EXCL) {
+ PsiExpression operand = expression.getOperand();
+ if (operand instanceof PsiParenthesizedExpression) {
+ operand = ((PsiParenthesizedExpression)operand).getExpression();
+ }
+ return operand;
+ }
+ }
+ else if (booleanExpression instanceof PsiLiteralExpression) {
+ return booleanExpression.getText().equals("true") ?
+ factory.createExpressionFromText("false", null) :
+ factory.createExpressionFromText("true", null);
+ }
+
+ if (booleanExpression instanceof PsiParenthesizedExpression) {
+ PsiExpression operand = ((PsiParenthesizedExpression)booleanExpression).getExpression();
+ operand.replace(invertCondition(operand));
+ return booleanExpression;
+ }
+
+ PsiPrefixExpression result = (PsiPrefixExpression)factory.createExpressionFromText("!(a)", null);
+ if (!(booleanExpression instanceof PsiPolyadicExpression)) {
+ result.getOperand().replace(booleanExpression);
+ }
+ else {
+ PsiParenthesizedExpression e = (PsiParenthesizedExpression)result.getOperand();
+ e.getExpression().replace(booleanExpression);
+ }
+
+ return result;
+ }
+
+ private static PsiElement createOperationToken(PsiElementFactory factory, IElementType tokenType) throws IncorrectOperationException {
+ final String s;
+ if (tokenType == JavaTokenType.EQEQ) {
+ s = "==";
+ }
+ else if (tokenType == JavaTokenType.NE) {
+ s = "!=";
+ }
+ else if (tokenType == JavaTokenType.LT) {
+ s = "<";
+ }
+ else if (tokenType == JavaTokenType.LE) {
+ s = "<=";
+ }
+ else if (tokenType == JavaTokenType.GT) {
+ s = ">";
+ }
+ else if (tokenType == JavaTokenType.GE) {
+ s = ">=";
+ }
+ else if (tokenType == JavaTokenType.ANDAND) {
+ s = "&&";
+ }
+ else if (tokenType == JavaTokenType.OROR) {
+ s = "||";
+ }
+ else {
+ LOG.error("Unknown token type");
+ s = "==";
+ }
+
+ PsiBinaryExpression expression = (PsiBinaryExpression)factory.createExpressionFromText("a" + s + "b", null);
+ return expression.getOperationSign();
+ }
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/ContainerProvider.java b/java/openapi/src/com/intellij/codeInsight/ContainerProvider.java
new file mode 100644
index 0000000..63f1a42
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/ContainerProvider.java
@@ -0,0 +1,31 @@
+/*
+ * 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.codeInsight;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Max Medvedev
+ */
+public interface ContainerProvider {
+ ExtensionPointName<ContainerProvider> EP_NAME = ExtensionPointName.create("com.intellij.codeInsight.containerProvider");
+
+ @Nullable
+ PsiElement getContainer(@NotNull PsiElement item);
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/MethodImplementor.java b/java/openapi/src/com/intellij/codeInsight/MethodImplementor.java
new file mode 100644
index 0000000..903c868
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/MethodImplementor.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.codeInsight.generation.GenerationInfo;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+ */
+public interface MethodImplementor extends MemberImplementorExplorer {
+ ExtensionPointName<MethodImplementor> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.methodImplementor");
+
+ @NotNull
+ PsiMethod[] createImplementationPrototypes(final PsiClass inClass, PsiMethod method) throws IncorrectOperationException;
+
+ boolean isBodyGenerated();
+
+ @Nullable
+ GenerationInfo createGenerationInfo(PsiMethod method, boolean mergeIfExists);
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/NullableNotNullDialog.java b/java/openapi/src/com/intellij/codeInsight/NullableNotNullDialog.java
new file mode 100644
index 0000000..a091f39
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/NullableNotNullDialog.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.ClassFilter;
+import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.TreeClassChooserFactory;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Splitter;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.ui.*;
+import com.intellij.ui.components.JBList;
+import com.intellij.util.ui.EmptyIcon;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.awt.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * User: anna
+ * Date: 1/25/11
+ */
+public class NullableNotNullDialog extends DialogWrapper {
+
+ private final Project myProject;
+ private AnnotationsPanel myNullablePanel;
+ private AnnotationsPanel myNotNullPanel;
+
+ public NullableNotNullDialog(Project project) {
+ super(project, true);
+ myProject = project;
+ init();
+ setTitle("Nullable/NotNull configuration");
+ }
+
+
+ @Override
+ protected JComponent createCenterPanel() {
+ final NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject);
+ final Splitter splitter = new Splitter(true);
+ myNullablePanel =
+ new AnnotationsPanel("Nullable", manager.getDefaultNullable(), manager.getNullables(), NullableNotNullManager.DEFAULT_NULLABLES);
+ splitter.setFirstComponent(myNullablePanel.getComponent());
+ myNotNullPanel =
+ new AnnotationsPanel("NotNull", manager.getDefaultNotNull(), manager.getNotNulls(), NullableNotNullManager.DEFAULT_NOT_NULLS);
+ splitter.setSecondComponent(myNotNullPanel.getComponent());
+ splitter.setHonorComponentsMinimumSize(true);
+ splitter.setPreferredSize(new Dimension(300, 400));
+ return splitter;
+ }
+
+ @Override
+ protected void doOKAction() {
+ final NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject);
+
+ manager.setNotNulls(myNotNullPanel.getAnnotations());
+ manager.setDefaultNotNull(myNotNullPanel.getDefaultAnnotation());
+
+ manager.setNullables(myNullablePanel.getAnnotations());
+ manager.setDefaultNullable(myNullablePanel.getDefaultAnnotation());
+
+ super.doOKAction();
+ }
+
+ private class AnnotationsPanel {
+ private String myDefaultAnnotation;
+ private final Set<String> myDefaultAnnotations;
+ private final JBList myList;
+ private final JPanel myComponent;
+
+ private AnnotationsPanel(final String name, final String defaultAnnotation,
+ final Collection<String> annotations, final String[] defaultAnnotations) {
+ myDefaultAnnotation = defaultAnnotation;
+ myDefaultAnnotations = new HashSet(Arrays.asList(defaultAnnotations));
+ myList = new JBList(annotations);
+ myList.setCellRenderer(new ColoredListCellRenderer() {
+ @Override
+ protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
+ append((String)value, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ if (value.equals(myDefaultAnnotation)) {
+ setIcon(AllIcons.Diff.CurrentLine);
+ } else {
+ setIcon(EmptyIcon.ICON_16);
+ }
+ //if (myDefaultAnnotations.contains(value)) {
+ // append(" (built in)", SimpleTextAttributes.GRAY_ATTRIBUTES);
+ //}
+ }
+ });
+
+ final AnActionButton selectButton =
+ new AnActionButton("Select annotation used for code generation", AllIcons.Actions.Checked) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final String selectedValue = (String)myList.getSelectedValue();
+ if (selectedValue == null) return;
+ myDefaultAnnotation = selectedValue;
+ final DefaultListModel model = (DefaultListModel)myList.getModel();
+
+ // to show the new default value in the ui
+ model.setElementAt(myList.getSelectedValue(), myList.getSelectedIndex());
+ }
+
+ @Override
+ public void updateButton(AnActionEvent e) {
+ final String selectedValue = (String)myList.getSelectedValue();
+ final boolean enabled = selectedValue != null && !selectedValue.equals(myDefaultAnnotation);
+ if (!enabled) {
+ e.getPresentation().setEnabled(enabled);
+ }
+ }
+ };
+
+ final ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myList).disableUpDownActions()
+ .setAddAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton anActionButton) {
+ chooseAnnotation(name, myList);
+ }
+ })
+ .setRemoveAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton anActionButton) {
+ final String selectedValue = (String)myList.getSelectedValue();
+ if (selectedValue == null) return;
+ if (myDefaultAnnotation.equals(selectedValue)) myDefaultAnnotation = (String)myList.getModel().getElementAt(0);
+
+ ((DefaultListModel)myList.getModel()).removeElement(selectedValue);
+ }
+ })
+ .addExtraAction(selectButton);
+ final JPanel panel = toolbarDecorator.createPanel();
+ myComponent = new JPanel(new BorderLayout());
+ myComponent.setBorder(IdeBorderFactory.createTitledBorder(name + " annotations", false, new Insets(10, 0, 0, 0)));
+ myComponent.add(panel);
+ final AnActionButton removeButton = ToolbarDecorator.findRemoveButton(myComponent);
+ myList.addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ if (e.getValueIsAdjusting()) return;
+ final String selectedValue = (String)myList.getSelectedValue();
+ if (myDefaultAnnotations.contains(selectedValue)) {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ removeButton.setEnabled(false);
+ }
+ });
+ }
+ }
+ });
+ myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ myList.setSelectedValue(myDefaultAnnotation, true);
+ }
+
+ private void chooseAnnotation(String title, JBList list) {
+ final TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject)
+ .createNoInnerClassesScopeChooser("Choose " + title + " annotation", GlobalSearchScope.allScope(myProject), new ClassFilter() {
+ @Override
+ public boolean isAccepted(PsiClass aClass) {
+ return aClass.isAnnotationType();
+ }
+ }, null);
+ chooser.showDialog();
+ final PsiClass selected = chooser.getSelected();
+ if (selected == null) {
+ return;
+ }
+ final String qualifiedName = selected.getQualifiedName();
+ final DefaultListModel model = (DefaultListModel)list.getModel();
+ final int index = model.indexOf(qualifiedName);
+ if (index < 0) {
+ model.addElement(qualifiedName);
+ } else {
+ myList.setSelectedIndex(index);
+ }
+ }
+
+ public JComponent getComponent() {
+ return myComponent;
+ }
+
+ public String getDefaultAnnotation() {
+ return myDefaultAnnotation;
+ }
+
+ public String[] getAnnotations() {
+ final ListModel model = myList.getModel();
+ final int size = model.getSize();
+ final String[] result = new String[size];
+ for (int i = 0; i < size; i++) {
+ result[i] = (String)model.getElementAt(i);
+ }
+ return result;
+ }
+ }
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java b/java/openapi/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java
new file mode 100644
index 0000000..04426ec
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java
@@ -0,0 +1,27 @@
+/*
+ * 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.codeInsight;
+
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.components.StoragePathMacros;
+
+@State(
+ name = "NullableNotNullManager",
+ storages = {@Storage( file = StoragePathMacros.PROJECT_FILE)}
+)
+public class NullableNotNullManagerImpl extends NullableNotNullManager {
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/completion/util/MethodParenthesesHandler.java b/java/openapi/src/com/intellij/codeInsight/completion/util/MethodParenthesesHandler.java
new file mode 100644
index 0000000..e1f83cb
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/completion/util/MethodParenthesesHandler.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.completion.util;
+
+import com.intellij.codeInsight.completion.InsertionContext;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+
+/**
+ * @author peter
+ */
+public class MethodParenthesesHandler extends ParenthesesInsertHandler<LookupElement> {
+ private final PsiMethod myMethod;
+ private final boolean myOverloadsMatter;
+
+ public MethodParenthesesHandler(final PsiMethod method, boolean overloadsMatter) {
+ myMethod = method;
+ myOverloadsMatter = overloadsMatter;
+ }
+
+ @Override
+ protected boolean placeCaretInsideParentheses(final InsertionContext context, final LookupElement item) {
+ return hasParams(item, context.getElements(), myOverloadsMatter, myMethod);
+ }
+
+ public static boolean hasParams(LookupElement item, LookupElement[] allItems, final boolean overloadsMatter, final PsiMethod method) {
+ boolean hasParams = method.getParameterList().getParametersCount() > 0;
+ if (overloadsMatter){
+ hasParams |= hasOverloads(allItems, method);
+ }
+ return hasParams;
+ }
+
+ private static boolean hasOverloads(LookupElement[] allItems, final PsiMethod method) {
+ String name = method.getName();
+ for (LookupElement another : allItems) {
+ final PsiElement element = another.getPsiElement();
+ if (method != element && element instanceof PsiMethod && ((PsiMethod)element).getName().equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/completion/util/PsiTypeCanonicalLookupElement.java b/java/openapi/src/com/intellij/codeInsight/completion/util/PsiTypeCanonicalLookupElement.java
new file mode 100644
index 0000000..2ff5f44
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/completion/util/PsiTypeCanonicalLookupElement.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.completion.util;
+
+import com.intellij.codeInsight.completion.InsertionContext;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementPresentation;
+import com.intellij.openapi.util.Iconable;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiPrimitiveType;
+import com.intellij.psi.PsiType;
+import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.PlatformIcons;
+import com.intellij.util.ui.EmptyIcon;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * @author peter
+ */
+public class PsiTypeCanonicalLookupElement extends LookupElement {
+ private static final Icon EMPTY_ICON = new EmptyIcon(PlatformIcons.CLASS_ICON.getIconWidth() * 2, PlatformIcons.CLASS_ICON.getIconHeight());
+
+ private final PsiType myType;
+ private final String myPresentableText;
+
+ public PsiTypeCanonicalLookupElement(@NotNull final PsiType type) {
+ myType = type;
+ myPresentableText = myType.getPresentableText();
+ }
+
+ @NotNull
+ @Override
+ public Object getObject() {
+ final PsiClass psiClass = getPsiClass();
+ if (psiClass != null) {
+ return psiClass;
+ }
+ return super.getObject();
+ }
+
+ @Nullable
+ public PsiClass getPsiClass() {
+ return PsiUtil.resolveClassInType(myType);
+ }
+
+ @Override
+ public boolean isValid() {
+ return myType.isValid() && super.isValid();
+ }
+
+ public PsiType getPsiType() {
+ return myType;
+ }
+
+ @Override
+ @NotNull
+ public String getLookupString() {
+ return myPresentableText;
+ }
+
+ @Override
+ public void handleInsert(InsertionContext context) {
+ context.getEditor().getDocument().replaceString(context.getStartOffset(), context.getStartOffset() + getLookupString().length(), getPsiType().getCanonicalText());
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (!(o instanceof PsiTypeCanonicalLookupElement)) return false;
+
+ final PsiTypeCanonicalLookupElement that = (PsiTypeCanonicalLookupElement)o;
+
+ if (!myType.equals(that.myType)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return myType.hashCode();
+ }
+
+ @Override
+ public void renderElement(LookupElementPresentation presentation) {
+ final PsiClass psiClass = getPsiClass();
+ if (psiClass != null) {
+ presentation.setIcon(presentation.isReal() ? psiClass.getIcon(Iconable.ICON_FLAG_VISIBILITY) : EMPTY_ICON);
+ presentation.setTailText(" (" + PsiFormatUtil.getPackageDisplayName(psiClass) + ")", true);
+ }
+ final PsiType type = getPsiType();
+ presentation.setItemText(type.getPresentableText());
+ presentation.setItemTextBold(type instanceof PsiPrimitiveType);
+ }
+
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/completion/util/SimpleMethodCallLookupElement.java b/java/openapi/src/com/intellij/codeInsight/completion/util/SimpleMethodCallLookupElement.java
new file mode 100644
index 0000000..1ebda15
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/completion/util/SimpleMethodCallLookupElement.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.completion.util;
+
+import com.intellij.codeInsight.completion.InsertionContext;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementPresentation;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiSubstitutor;
+import com.intellij.psi.PsiType;
+import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.openapi.util.Iconable;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class SimpleMethodCallLookupElement extends LookupElement {
+ private final PsiMethod myMethod;
+
+ public SimpleMethodCallLookupElement(final PsiMethod method) {
+ myMethod = method;
+ }
+
+ @Override
+ @NotNull
+ public String getLookupString() {
+ return myMethod.getName();
+ }
+
+ @Override
+ public void handleInsert(InsertionContext context) {
+ new MethodParenthesesHandler(myMethod, true).handleInsert(context, this);
+ }
+
+ public PsiMethod getMethod() {
+ return myMethod;
+ }
+
+ @Override
+ public void renderElement(LookupElementPresentation presentation) {
+ presentation.setIcon(myMethod.getIcon(Iconable.ICON_FLAG_VISIBILITY));
+ presentation.setItemText(myMethod.getName());
+ presentation.setTailText(PsiFormatUtil.formatMethod(myMethod,
+ PsiSubstitutor.EMPTY,
+ PsiFormatUtil.SHOW_PARAMETERS,
+ PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE));
+ final PsiType returnType = myMethod.getReturnType();
+ if (returnType != null) {
+ presentation.setTypeText(returnType.getCanonicalText());
+ }
+ }
+
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/daemon/GroupNames.java b/java/openapi/src/com/intellij/codeInsight/daemon/GroupNames.java
new file mode 100644
index 0000000..20bd1b1
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/daemon/GroupNames.java
@@ -0,0 +1,71 @@
+/*
+ * 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.codeInsight.daemon;
+
+import com.intellij.codeInspection.InspectionsBundle;
+
+/**
+ * @author anna
+ * Date: Jun 22, 2005
+ */
+public interface GroupNames {
+ String ABSTRACTION_GROUP_NAME = InspectionsBundle.message("group.names.abstraction.issues");
+ String ASSIGNMENT_GROUP_NAME = InspectionsBundle.message("group.names.assignment.issues");
+ String BUGS_GROUP_NAME = InspectionsBundle.message("group.names.probable.bugs");
+ String BITWISE_GROUP_NAME = InspectionsBundle.message("group.names.bitwise.operation.issues");
+ String CLASS_LAYOUT_GROUP_NAME = InspectionsBundle.message("group.names.class.structure");
+ String CLASS_METRICS_GROUP_NAME = InspectionsBundle.message("group.names.class.metrics");
+ String COMPILER_ISSUES = InspectionsBundle.message("group.names.compiler.issues");
+ String CONFUSING_GROUP_NAME = InspectionsBundle.message("group.names.potentially.confusing.code.constructs");
+ String ENCAPSULATION_GROUP_NAME = InspectionsBundle.message("group.names.encapsulation.issues");
+ String ERROR_HANDLING_GROUP_NAME = InspectionsBundle.message("group.names.error.handling");
+ String FINALIZATION_GROUP_NAME = InspectionsBundle.message("group.names.finalization.issues");
+ String IMPORTS_GROUP_NAME = InspectionsBundle.message("group.names.imports");
+ String INITIALIZATION_GROUP_NAME = InspectionsBundle.message("group.names.initialization.issues");
+ String INTERNATIONALIZATION_GROUP_NAME = InspectionsBundle.message("group.names.internationalization.issues");
+ String JUNIT_GROUP_NAME = InspectionsBundle.message("group.names.junit.issues");
+ String LOGGING_GROUP_NAME = InspectionsBundle.message("group.names.logging.issues");
+ String MATURITY_GROUP_NAME = InspectionsBundle.message("group.names.code.maturity.issues");
+ String METHOD_METRICS_GROUP_NAME = InspectionsBundle.message("group.names.method.metrics");
+ String NAMING_CONVENTIONS_GROUP_NAME = InspectionsBundle.message("group.names.naming.conventions");
+ String PERFORMANCE_GROUP_NAME = InspectionsBundle.message("group.names.performance.issues");
+ String MEMORY_GROUP_NAME = InspectionsBundle.message("group.names.memory.issues");
+ String JDK_GROUP_NAME = InspectionsBundle.message("group.names.java.language.level.issues");
+ String PORTABILITY_GROUP_NAME = InspectionsBundle.message("group.names.portability.issues");
+ String SECURITY_GROUP_NAME = InspectionsBundle.message("group.names.security.issues");
+ String SERIALIZATION_GROUP_NAME = InspectionsBundle.message("group.names.serialization.issues");
+ String STYLE_GROUP_NAME = InspectionsBundle.message("group.names.code.style.issues");
+ String THREADING_GROUP_NAME = InspectionsBundle.message("group.names.threading.issues");
+ String VERBOSE_GROUP_NAME = InspectionsBundle.message("group.names.verbose.or.redundant.code.constructs");
+ String VISIBILITY_GROUP_NAME = InspectionsBundle.message("group.names.visibility.issues");
+ String CLONEABLE_GROUP_NAME = InspectionsBundle.message("group.names.cloning.issues");
+ String RESOURCE_GROUP_NAME = InspectionsBundle.message("group.names.resource.management.issues");
+ String J2ME_GROUP_NAME = InspectionsBundle.message("group.names.j2me.issues");
+ String CONTROL_FLOW_GROUP_NAME = InspectionsBundle.message("group.names.control.flow.issues");
+ String NUMERIC_GROUP_NAME = InspectionsBundle.message("group.names.numeric.issues");
+ String LANGUAGE_LEVEL_SPECIFIC_GROUP_NAME = InspectionsBundle.message("group.names.language.level.specific.issues.and.migration.aids");
+ String JAVABEANS_GROUP_NAME = InspectionsBundle.message("group.names.javabeans.issues");
+ String INHERITANCE_GROUP_NAME = InspectionsBundle.message("group.names.inheritance.issues");
+ String DATA_FLOW_ISSUES = InspectionsBundle.message("group.names.data.flow.issues");
+ String DECLARATION_REDUNDANCY = InspectionsBundle.message("group.names.declaration.redundancy");
+ String PACKAGING_GROUP_NAME = InspectionsBundle.message("group.names.packaging.issues");
+ String DEPENDENCY_GROUP_NAME = InspectionsBundle.message("group.names.dependency.issues");
+ String MODULARIZATION_GROUP_NAME = InspectionsBundle.message("group.names.modularization.issues");
+ String JAVAEE_GROUP_NAME = InspectionsBundle.message("group.names.javaee.issues");
+ String CONCURRENCY_ANNOTATION_ISSUES = InspectionsBundle.message("group.names.concurrency.annotation.issues");
+ String JAVADOC_GROUP_NAME = InspectionsBundle.message("group.names.javadoc.issues");
+ String PROPERTIES_GROUP_NAME = InspectionsBundle.message("group.names.properties.files");
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/generation/GenerationInfo.java b/java/openapi/src/com/intellij/codeInsight/generation/GenerationInfo.java
new file mode 100644
index 0000000..5b2bb5e
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/generation/GenerationInfo.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.generation;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMember;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Medvedev Max
+ */
+public interface GenerationInfo {
+ GenerationInfo[] EMPTY_ARRAY = new GenerationInfo[0];
+
+ void insert(PsiClass aClass, PsiElement anchor, boolean before) throws IncorrectOperationException;
+
+ PsiMember getPsiMember();
+
+ /**
+ * @param aClass
+ * @param leaf leaf element. Is guaranteed to be a tree descendant of aClass.
+ * @return the value that will be passed to the {@link #insert(com.intellij.psi.PsiClass, com.intellij.psi.PsiElement, boolean)} method later.
+ */
+ @Nullable
+ PsiElement findInsertionAnchor(@NotNull PsiClass aClass, @NotNull PsiElement leaf);
+
+ /**
+ * Position caret in generated element in correct way
+ */
+ void positionCaret(Editor editor, boolean toEditMethodBody);
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java b/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java
new file mode 100644
index 0000000..cd3fed7
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.codeInsight.generation.actions;
+
+import com.intellij.codeInsight.CodeInsightActionHandler;
+import com.intellij.codeInsight.actions.CodeInsightAction;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.Nullable;
+
+public class BaseGenerateAction extends CodeInsightAction {
+ private final CodeInsightActionHandler myHandler;
+
+ public BaseGenerateAction(CodeInsightActionHandler handler) {
+ myHandler = handler;
+ }
+
+ @Override
+ protected final CodeInsightActionHandler getHandler() {
+ return myHandler;
+ }
+
+ @Nullable
+ protected PsiClass getTargetClass (Editor editor, PsiFile file) {
+ int offset = editor.getCaretModel().getOffset();
+ PsiElement element = file.findElementAt(offset);
+ if (element == null) return null;
+ final PsiClass target = PsiTreeUtil.getParentOfType(element, PsiClass.class);
+ return target instanceof SyntheticElement ? null : target;
+ }
+
+ @Override
+ protected boolean isValidForFile(Project project, Editor editor, PsiFile file) {
+ if (!(file instanceof PsiJavaFile)) return false;
+ if (file instanceof PsiCompiledElement) return false;
+
+ PsiDocumentManager.getInstance(project).commitAllDocuments();
+
+ PsiClass targetClass = getTargetClass(editor, file);
+ return targetClass != null && isValidForClass(targetClass);
+ }
+
+ protected boolean isValidForClass(final PsiClass targetClass) {
+ return !targetClass.isInterface();
+ }
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/generation/surroundWith/JavaExpressionSurrounder.java b/java/openapi/src/com/intellij/codeInsight/generation/surroundWith/JavaExpressionSurrounder.java
new file mode 100644
index 0000000..1265068
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/generation/surroundWith/JavaExpressionSurrounder.java
@@ -0,0 +1,52 @@
+
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.codeInsight.generation.surroundWith;
+
+import com.intellij.lang.surroundWith.Surrounder;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiExpression;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class JavaExpressionSurrounder implements Surrounder {
+ public static ExtensionPointName<JavaExpressionSurrounder> EP_NAME = ExtensionPointName.create("com.intellij.javaExpressionSurrounder");
+
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.surroundWith.SurroundExpressionHandler");
+
+ @Override
+ public boolean isApplicable(@NotNull PsiElement[] elements) {
+ LOG.assertTrue(elements.length == 1 && elements[0] instanceof PsiExpression);
+ return isApplicable((PsiExpression)elements[0]);
+ }
+
+ public abstract boolean isApplicable(PsiExpression expr);
+
+ @Override
+ public TextRange surroundElements(@NotNull Project project,
+ @NotNull Editor editor,
+ @NotNull PsiElement[] elements) throws IncorrectOperationException {
+ return surroundExpression(project, editor, (PsiExpression)elements[0]);
+ }
+
+ public abstract TextRange surroundExpression(Project project, Editor editor, PsiExpression expr) throws IncorrectOperationException;
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInsight/highlighting/package.html b/java/openapi/src/com/intellij/codeInsight/highlighting/package.html
new file mode 100644
index 0000000..6d970db
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/highlighting/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for highlighting regions of text in the IDEA editor.
+</body></html>
diff --git a/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java b/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
new file mode 100644
index 0000000..87ad87d
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.intention;
+
+import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PropertyMemberType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author cdr
+ */
+public abstract class QuickFixFactory {
+ public static QuickFixFactory getInstance() {
+ return ServiceManager.getService(QuickFixFactory.class);
+ }
+
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createModifierListFix(@NotNull PsiModifierList modifierList,
+ @PsiModifier.ModifierConstant @NotNull String modifier,
+ boolean shouldHave,
+ final boolean showContainingClass);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createModifierListFix(@NotNull PsiModifierListOwner owner,
+ @PsiModifier.ModifierConstant @NotNull String modifier,
+ boolean shouldHave,
+ final boolean showContainingClass);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createMethodReturnFix(@NotNull PsiMethod method, @NotNull PsiType toReturn, boolean fixWholeHierarchy);
+
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddMethodFix(@NotNull PsiMethod method, @NotNull PsiClass toClass);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddMethodFix(@NotNull String methodText, @NotNull PsiClass toClass, String... exceptions);
+
+ /**
+ * @param psiElement psiClass or enum constant without class initializer
+ */
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createImplementMethodsFix(@NotNull PsiElement psiElement);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createImplementMethodsFix(@NotNull PsiClass psiElement);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createMethodThrowsFix(@NotNull PsiMethod method, @NotNull PsiClassType exceptionClass, boolean shouldThrow, boolean showContainingClass);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddDefaultConstructorFix(@NotNull PsiClass aClass);
+ @Nullable
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddConstructorFix(@NotNull PsiClass aClass, @PsiModifier.ModifierConstant String modifier);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createMethodParameterTypeFix(@NotNull PsiMethod method, int index, @NotNull PsiType newType, boolean fixWholeHierarchy);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createMakeClassInterfaceFix(@NotNull PsiClass aClass);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createMakeClassInterfaceFix(@NotNull PsiClass aClass, final boolean makeInterface);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createExtendsListFix(@NotNull PsiClass aClass, @NotNull PsiClassType typeToExtendFrom, boolean toAdd);
+ public abstract LocalQuickFixAndIntentionActionOnPsiElement createRemoveUnusedParameterFix(@NotNull PsiParameter parameter);
+ public abstract IntentionAction createRemoveUnusedVariableFix(@NotNull PsiVariable variable);
+
+ @Nullable
+ public abstract IntentionAction createCreateClassOrPackageFix(@NotNull PsiElement context, @NotNull String qualifiedName, final boolean createClass, final String superClass);
+ @Nullable
+ public abstract IntentionAction createCreateClassOrInterfaceFix(@NotNull PsiElement context, @NotNull String qualifiedName, final boolean createClass, final String superClass);
+ public abstract IntentionAction createCreateFieldOrPropertyFix(final PsiClass aClass, final String name, final PsiType type, final PropertyMemberType targetMember, final PsiAnnotation... annotations);
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/package.html b/java/openapi/src/com/intellij/codeInsight/package.html
new file mode 100644
index 0000000..b8d2186
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/package.html
@@ -0,0 +1,22 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for working with highlighting in standard IDEA editors, interfaces
+and classes for defining intention actions and additional functionality related to background
+code analysis in IDEA.
+</body></html>
diff --git a/java/openapi/src/com/intellij/codeInsight/quickfix/ChangeVariableTypeQuickFixProvider.java b/java/openapi/src/com/intellij/codeInsight/quickfix/ChangeVariableTypeQuickFixProvider.java
new file mode 100644
index 0000000..5f0113e
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/quickfix/ChangeVariableTypeQuickFixProvider.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * User: anna
+ * Date: 27-Aug-2009
+ */
+package com.intellij.codeInsight.quickfix;
+
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiType;
+import com.intellij.psi.PsiVariable;
+
+public interface ChangeVariableTypeQuickFixProvider {
+ ExtensionPointName<ChangeVariableTypeQuickFixProvider> EP_NAME = ExtensionPointName.create("com.intellij.codeInsight.changeVariableTypeQuickFixProvider");
+
+ IntentionAction[] getFixes(PsiVariable variable, PsiType toReturn);
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java b/java/openapi/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java
new file mode 100644
index 0000000..7d37f4f
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java
@@ -0,0 +1,140 @@
+/*
+ * 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.codeInspection;
+
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Implement this abstract class in order to provide new inspection tool functionality. The major API limitation here is
+ * subclasses should be stateless. Thus <code>check<XXX></code> methods will be called in no particular order and
+ * instances of this class provided by {@link InspectionToolProvider#getInspectionClasses()} will be created on demand.
+ * The other important thing is problem anchors (PsiElements) reported by <code>check<XXX></code> methods should
+ * lie under corresponding first parameter of one method.
+ *
+ * @see GlobalInspectionTool
+ */
+public abstract class BaseJavaLocalInspectionTool extends LocalInspectionTool implements CustomSuppressableInspectionTool {
+ /**
+ * Override this to report problems at method level.
+ *
+ * @param method to check.
+ * @param manager InspectionManager to ask for ProblemDescriptor's from.
+ * @param isOnTheFly true if called during on the fly editor highlighting. Called from Inspect Code action otherwise.
+ * @return <code>null</code> if no problems found or not applicable at method level.
+ */
+ @Nullable
+ public ProblemDescriptor[] checkMethod(@NotNull PsiMethod method, @NotNull InspectionManager manager, boolean isOnTheFly) {
+ return null;
+ }
+
+ /**
+ * Override this to report problems at class level.
+ *
+ * @param aClass to check.
+ * @param manager InspectionManager to ask for ProblemDescriptor's from.
+ * @param isOnTheFly true if called during on the fly editor highlighting. Called from Inspect Code action otherwise.
+ * @return <code>null</code> if no problems found or not applicable at class level.
+ */
+ @Nullable
+ public ProblemDescriptor[] checkClass(@NotNull PsiClass aClass, @NotNull InspectionManager manager, boolean isOnTheFly) {
+ return null;
+ }
+
+ /**
+ * Override this to report problems at field level.
+ *
+ * @param field to check.
+ * @param manager InspectionManager to ask for ProblemDescriptor's from.
+ * @param isOnTheFly true if called during on the fly editor highlighting. Called from Inspect Code action otherwise.
+ * @return <code>null</code> if no problems found or not applicable at field level.
+ */
+ @Nullable
+ public ProblemDescriptor[] checkField(@NotNull PsiField field, @NotNull InspectionManager manager, boolean isOnTheFly) {
+ return null;
+ }
+
+ /**
+ * Override this to report problems at file level.
+ *
+ * @param file to check.
+ * @param manager InspectionManager to ask for ProblemDescriptor's from.
+ * @param isOnTheFly true if called during on the fly editor highlighting. Called from Inspect Code action otherwise.
+ * @return <code>null</code> if no problems found or not applicable at file level.
+ */
+ @Override
+ @Nullable
+ public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
+ return null;
+ }
+
+ @Override
+ @NotNull
+ public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
+ return new JavaElementVisitor() {
+ @Override public void visitMethod(PsiMethod method) {
+ addDescriptors(checkMethod(method, holder.getManager(), isOnTheFly));
+ }
+
+ @Override public void visitClass(PsiClass aClass) {
+ addDescriptors(checkClass(aClass, holder.getManager(), isOnTheFly));
+ }
+
+ @Override public void visitField(PsiField field) {
+ addDescriptors(checkField(field, holder.getManager(), isOnTheFly));
+ }
+
+ @Override public void visitFile(PsiFile file) {
+ addDescriptors(checkFile(file, holder.getManager(), isOnTheFly));
+ }
+ private void addDescriptors(final ProblemDescriptor[] descriptors) {
+ if (descriptors != null) {
+ for (ProblemDescriptor descriptor : descriptors) {
+ holder.registerProblem(descriptor);
+ }
+ }
+ }
+ };
+ }
+
+ @Override
+ public PsiNamedElement getProblemElement(final PsiElement psiElement) {
+ return PsiTreeUtil.getNonStrictParentOfType(psiElement, PsiFile.class, PsiClass.class, PsiMethod.class, PsiField.class);
+ }
+
+ @Override
+ public SuppressIntentionAction[] getSuppressActions(final PsiElement element) {
+ return SuppressManager.getInstance().createSuppressActions(HighlightDisplayKey.find(getShortName()));
+ }
+
+ @Override
+ public boolean isSuppressedFor(@NotNull PsiElement element) {
+ return isSuppressedFor(element, this);
+ }
+
+ public static boolean isSuppressedFor(@NotNull PsiElement element, @NotNull LocalInspectionTool tool) {
+ final SuppressManager manager = SuppressManager.getInstance();
+ String alternativeId;
+ String id;
+ return manager.isSuppressedFor(element, id = tool.getID()) ||
+ (alternativeId = tool.getAlternativeID()) != null &&
+ !alternativeId.equals(id) &&
+ manager.isSuppressedFor(element, alternativeId);
+ }
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionContext.java b/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionContext.java
new file mode 100644
index 0000000..7e2a3c5
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionContext.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * User: anna
+ * Date: 18-Dec-2007
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInspection.ex.EntryPointsManager;
+import com.intellij.codeInspection.lang.GlobalInspectionContextExtension;
+import com.intellij.codeInspection.reference.RefClass;
+import com.intellij.codeInspection.reference.RefField;
+import com.intellij.codeInspection.reference.RefManager;
+import com.intellij.codeInspection.reference.RefMethod;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiReference;
+import com.intellij.util.Processor;
+
+public abstract class GlobalJavaInspectionContext implements GlobalInspectionContextExtension<GlobalJavaInspectionContext> {
+ public static final Key<GlobalJavaInspectionContext> CONTEXT = Key.create("GlobalJavaInspectionContext");
+
+ public interface DerivedClassesProcessor extends Processor<PsiClass> {
+ }
+
+ public interface DerivedMethodsProcessor extends Processor<PsiMethod> {
+ }
+
+ public interface UsagesProcessor extends Processor<PsiReference> {
+ }
+
+ /**
+ * Requests that usages of the specified class outside the current analysis
+ * scope be passed to the specified processor.
+ *
+ * @param refClass the reference graph node for the class whose usages should be processed.
+ * @param p the processor to pass the usages to.
+ */
+ public abstract void enqueueClassUsagesProcessor(RefClass refClass, UsagesProcessor p);
+
+ /**
+ * Requests that derived classes of the specified class outside the current analysis
+ * scope be passed to the specified processor.
+ *
+ * @param refClass the reference graph node for the class whose derived classes should be processed.
+ * @param p the processor to pass the classes to.
+ */
+ public abstract void enqueueDerivedClassesProcessor(RefClass refClass, DerivedClassesProcessor p);
+
+ /**
+ * Requests that implementing or overriding methods of the specified method outside
+ * the current analysis scope be passed to the specified processor.
+ *
+ * @param refMethod the reference graph node for the method whose derived methods should be processed.
+ * @param p the processor to pass the methods to.
+ */
+ public abstract void enqueueDerivedMethodsProcessor(RefMethod refMethod, DerivedMethodsProcessor p);
+
+ /**
+ * Requests that usages of the specified field outside the current analysis
+ * scope be passed to the specified processor.
+ *
+ * @param refField the reference graph node for the field whose usages should be processed.
+ * @param p the processor to pass the usages to.
+ */
+ public abstract void enqueueFieldUsagesProcessor(RefField refField, UsagesProcessor p);
+
+ /**
+ * Requests that usages of the specified method outside the current analysis
+ * scope be passed to the specified processor.
+ *
+ * @param refMethod the reference graph node for the method whose usages should be processed.
+ * @param p the processor to pass the usages to.
+ */
+ public abstract void enqueueMethodUsagesProcessor(RefMethod refMethod, UsagesProcessor p);
+
+ public abstract EntryPointsManager getEntryPointsManager(RefManager manager);
+
+ @Override
+ public Key<GlobalJavaInspectionContext> getID() {
+ return CONTEXT;
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionTool.java b/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionTool.java
new file mode 100644
index 0000000..cb19ce9
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionTool.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * User: anna
+ * Date: 19-Dec-2007
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.codeInspection.reference.RefManager;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class GlobalJavaInspectionTool extends GlobalInspectionTool implements CustomSuppressableInspectionTool {
+ @Override
+ public boolean queryExternalUsagesRequests(final InspectionManager manager,
+ final GlobalInspectionContext globalContext,
+ final ProblemDescriptionsProcessor problemDescriptionsProcessor) {
+ return queryExternalUsagesRequests(globalContext.getRefManager(), globalContext.getExtension(GlobalJavaInspectionContext.CONTEXT), problemDescriptionsProcessor);
+ }
+
+ protected boolean queryExternalUsagesRequests(RefManager manager, GlobalJavaInspectionContext globalContext, ProblemDescriptionsProcessor processor) {
+ return false;
+ }
+
+ @Override
+ @Nullable
+ public SuppressIntentionAction[] getSuppressActions(final PsiElement element) {
+ return SuppressManager.getInstance().createSuppressActions(HighlightDisplayKey.find(getShortName()));
+ }
+
+ @Override
+ public boolean isSuppressedFor(@NotNull final PsiElement element) {
+ return SuppressManager.getInstance().isSuppressedFor(element, getShortName());
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/HTMLJavaHTMLComposer.java b/java/openapi/src/com/intellij/codeInspection/HTMLJavaHTMLComposer.java
new file mode 100644
index 0000000..028447e
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/HTMLJavaHTMLComposer.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * User: anna
+ * Date: 19-Dec-2007
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInspection.lang.HTMLComposerExtension;
+import com.intellij.codeInspection.reference.RefClass;
+import com.intellij.codeInspection.reference.RefMethod;
+import com.intellij.lang.Language;
+import com.intellij.lang.StdLanguages;
+import com.intellij.openapi.util.Key;
+
+public abstract class HTMLJavaHTMLComposer implements HTMLComposerExtension<HTMLJavaHTMLComposer> {
+ public static final Key<HTMLJavaHTMLComposer> COMPOSER = Key.create("HTMLJavaComposer");
+
+ public abstract void appendClassOrInterface(StringBuffer buf, RefClass refClass, boolean capitalizeFirstLetter);
+
+ public static String getClassOrInterface(RefClass refClass, boolean capitalizeFirstLetter) {
+ if (refClass.isInterface()) {
+ return capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.interface") : InspectionsBundle.message("inspection.export.results.interface");
+ }
+ else if (refClass.isAbstract()) {
+ return capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.abstract.class") : InspectionsBundle.message("inspection.export.results.abstract.class");
+ }
+ else {
+ return capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.class") : InspectionsBundle.message("inspection.export.results.class");
+ }
+ }
+
+ public abstract void appendClassExtendsImplements(StringBuffer buf, RefClass refClass);
+
+ public abstract void appendDerivedClasses(StringBuffer buf, RefClass refClass);
+
+ public abstract void appendLibraryMethods(StringBuffer buf, RefClass refClass);
+
+ public abstract void appendSuperMethods(StringBuffer buf, RefMethod refMethod);
+
+ public abstract void appendDerivedMethods(StringBuffer buf, RefMethod refMethod);
+
+ public abstract void appendTypeReferences(StringBuffer buf, RefClass refClass);
+
+ @Override
+ public Key<HTMLJavaHTMLComposer> getID() {
+ return COMPOSER;
+ }
+
+ @Override
+ public Language getLanguage() {
+ return StdLanguages.JAVA;
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/SuppressManager.java b/java/openapi/src/com/intellij/codeInspection/SuppressManager.java
new file mode 100644
index 0000000..8b60d46
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/SuppressManager.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * User: anna
+ * Date: 24-Dec-2007
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+public abstract class SuppressManager {
+ public static final String SUPPRESS_INSPECTIONS_ANNOTATION_NAME = "java.lang.SuppressWarnings";
+
+ public static SuppressManager getInstance() {
+ return ServiceManager.getService(SuppressManager.class);
+ }
+
+ @NotNull
+ public abstract SuppressIntentionAction[] createSuppressActions(@NotNull HighlightDisplayKey key);
+
+ public abstract boolean isSuppressedFor(@NotNull PsiElement element, final String toolId);
+
+ public abstract PsiElement getElementMemberSuppressedIn(@NotNull PsiDocCommentOwner owner, final String inspectionToolID);
+
+ @Nullable
+ public abstract PsiElement getAnnotationMemberSuppressedIn(@NotNull PsiModifierListOwner owner, String inspectionToolID);
+
+ @Nullable
+ public abstract PsiElement getDocCommentToolSuppressedIn(@NotNull PsiDocCommentOwner owner, String inspectionToolID);
+
+ @NotNull
+ public abstract Collection<String> getInspectionIdsSuppressedInAnnotation(@NotNull PsiModifierListOwner owner);
+
+ @Nullable
+ public abstract String getSuppressedInspectionIdsIn(@NotNull PsiElement element);
+
+ @Nullable
+ public abstract PsiElement getElementToolSuppressedIn(@NotNull PsiElement place, String toolId);
+
+ public abstract boolean canHave15Suppressions(@NotNull PsiElement file);
+
+ public abstract boolean alreadyHas14Suppressions(@NotNull PsiDocCommentOwner commentOwner);
+
+ public static boolean isSuppressedInspectionName(PsiLiteralExpression expression) {
+ PsiAnnotation annotation = PsiTreeUtil.getParentOfType(expression, PsiAnnotation.class, true, PsiCodeBlock.class, PsiField.class);
+ return annotation != null && SUPPRESS_INSPECTIONS_ANNOTATION_NAME.equals(annotation.getQualifiedName());
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/ex/EntryPointsManager.java b/java/openapi/src/com/intellij/codeInspection/ex/EntryPointsManager.java
new file mode 100644
index 0000000..3b90822
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/ex/EntryPointsManager.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * User: anna
+ * Date: 28-Feb-2007
+ */
+package com.intellij.codeInspection.ex;
+
+import com.intellij.codeInspection.reference.RefElement;
+import com.intellij.codeInspection.reference.RefManager;
+import com.intellij.openapi.Disposable;
+
+public interface EntryPointsManager extends Disposable {
+ void resolveEntryPoints(RefManager manager);
+
+ void addEntryPoint(RefElement newEntryPoint, boolean isPersistent);
+
+ void removeEntryPoint(RefElement anEntryPoint);
+
+ RefElement[] getEntryPoints();
+
+ void cleanup();
+
+ boolean isAddNonJavaEntries();
+
+ void configureAnnotations();
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/package.html b/java/openapi/src/com/intellij/codeInspection/package.html
new file mode 100644
index 0000000..476d2af
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/package.html
@@ -0,0 +1,29 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for registering and implementing code inspections. To register inspections,
+a plugin should implement the {@link com.intellij.codeInspection.InspectionToolProvider} interface and return the
+list of inspection classes from the <code>getInspectionClasses()</code> method.
+An inspection is a class extending {@link com.intellij.codeInspection.LocalInspectionTool}. During background code
+analysis or when the "Inspect Code..." action is invoked,, IDEA calls the inspection
+to inspect individual files, classes, methods and fields, and if the inspection detects any problems,
+it returns an array of {@link com.intellij.codeInspection.ProblemDescriptor} classes reporting the problem. Each problem
+descriptor can return a list of {@link com.intellij.codeInspection.LocalQuickFix} classes, each of which represents an
+action which the user can invoke by pressing Alt-Enter in order to fix the problem detected
+by the inspection.
+</body></html>
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefClass.java b/java/openapi/src/com/intellij/codeInspection/reference/RefClass.java
new file mode 100644
index 0000000..da8a04f
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefClass.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2009 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.codeInspection.reference;
+
+import com.intellij.psi.PsiClass;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * User: anna
+ * Date: 27-Dec-2005
+ */
+public interface RefClass extends RefJavaElement {
+
+ @NotNull
+ Set<RefClass> getBaseClasses();
+
+ @NotNull
+ Set<RefClass> getSubClasses();
+
+ @NotNull
+ List<RefMethod> getConstructors();
+
+ @NotNull
+ Set<RefElement> getInTypeReferences();
+
+ @NotNull
+ Set<RefElement> getInstanceReferences();
+
+ RefMethod getDefaultConstructor();
+
+ @NotNull
+ List<RefMethod> getLibraryMethods();
+
+ boolean isAnonymous();
+
+ boolean isInterface();
+
+ boolean isUtilityClass();
+
+ boolean isAbstract();
+
+ boolean isApplet();
+
+ boolean isServlet();
+
+ boolean isTestCase();
+
+ boolean isLocalClass();
+
+ boolean isSelfInheritor(PsiClass psiClass);
+
+ @Override
+ PsiClass getElement();
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefField.java b/java/openapi/src/com/intellij/codeInspection/reference/RefField.java
new file mode 100644
index 0000000..4418b0f
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefField.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2009 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.codeInspection.reference;
+
+import com.intellij.psi.PsiField;
+
+/**
+ * A node in the reference graph corresponding to a Java field.
+ *
+ * @author anna
+ * @since 6.0
+ */
+public interface RefField extends RefJavaElement {
+ /**
+ * Checks if the field is used for reading.
+ *
+ * @return true if the field has read accesses, false otherwise.
+ */
+ boolean isUsedForReading();
+
+ /**
+ * Checks if the field is used for writing.
+ *
+ * @return true if the field has write accesses, false otherwise.
+ */
+ boolean isUsedForWriting();
+
+ /**
+ * Checks if the only write access of the field is its initializer.
+ *
+ * @return true if the only write access of the field is its initializer, false otherwise.
+ */
+ boolean isOnlyAssignedInInitializer();
+
+ /**
+ * Returns the reference graph node for the class to which the field belongs.
+ *
+ * @return the owner class of the field.
+ */
+ RefClass getOwnerClass();
+
+ @Override
+ PsiField getElement();
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefImplicitConstructor.java b/java/openapi/src/com/intellij/codeInspection/reference/RefImplicitConstructor.java
new file mode 100644
index 0000000..036bdd6
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefImplicitConstructor.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2009 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.codeInspection.reference;
+
+/**
+ * A node in the reference graph corresponding to the implicit constructor of a Java class.
+ *
+ * @author anna
+ * @since 6.0
+ */
+public interface RefImplicitConstructor extends RefMethod {
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefJavaElement.java b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaElement.java
new file mode 100644
index 0000000..59e9cb0
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaElement.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * User: anna
+ * Date: 18-Dec-2007
+ */
+package com.intellij.codeInspection.reference;
+
+import com.intellij.psi.PsiModifier;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+public interface RefJavaElement extends RefElement {
+ /**
+ * Returns the collection of references used in this element.
+ * @return the collection of used types
+ */
+ @NotNull
+ Collection<RefClass> getOutTypeReferences();
+
+
+ /**
+ * Checks if the element is <code>final</code>.
+ *
+ * @return true if the element is final, false otherwise.
+ */
+ boolean isFinal();
+
+ /**
+ * Checks if the element is <code>static</code>.
+ *
+ * @return true if the element is static, false otherwise.
+ */
+ boolean isStatic();
+
+ /**
+ * Checks if the element directly references any elements marked as deprecated.
+ *
+ * @return true if the element references any deprecated elements, false otherwise.
+ */
+ boolean isUsesDeprecatedApi();
+
+ /**
+ * Checks if the element is, or belongs to, a synthetic class or method created for a JSP page.
+ *
+ * @return true if the element is a synthetic JSP element, false otherwise.
+ */
+ boolean isSyntheticJSP();
+
+ /**
+ * Returns the access modifier for the element, as one of the keywords from the
+ * {@link com.intellij.psi.PsiModifier} class.
+ *
+ * @return the modifier, or null if the element does not have any access modifier.
+ */
+ @Nullable
+ @PsiModifier.ModifierConstant
+ String getAccessModifier();
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefJavaManager.java b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaManager.java
new file mode 100644
index 0000000..b217cef
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaManager.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * User: anna
+ * Date: 18-Dec-2007
+ */
+package com.intellij.codeInspection.reference;
+
+import com.intellij.codeInspection.ex.EntryPointsManager;
+import com.intellij.codeInspection.lang.RefManagerExtension;
+import com.intellij.lang.Language;
+import com.intellij.lang.StdLanguages;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiParameter;
+import org.jetbrains.annotations.NonNls;
+
+public abstract class RefJavaManager implements RefManagerExtension<RefJavaManager> {
+ @NonNls public static final String CLASS = "class";
+ @NonNls public static final String METHOD = "method";
+ @NonNls public static final String FIELD = "field";
+ @NonNls public static final String PARAMETER = "parameter";
+ //used in OfflineProjectDescriptor
+ @NonNls public static final String PACKAGE = "package";
+ public static final Key<RefJavaManager> MANAGER = Key.create("RefJavaManager");
+
+ /**
+ * Creates (if necessary) and returns the reference graph node for the package
+ * with the specified name.
+ *
+ * @param packageName the name of the package for which the reference graph node is requested.
+ * @return the node for the package.
+ */
+ public abstract RefPackage getPackage(String packageName);
+
+ /**
+ * Creates (if necessary) and returns the reference graph node for the specified PSI parameter.
+ *
+ * @param param the parameter for which the reference graph node is requested.
+ * @param index the index of the parameter in its parameter list.
+ * @return the node for the element, or null if the element is not valid or does not have
+ * a corresponding reference graph node type (is not a field, method, class or file).
+ */
+ public abstract RefParameter getParameterReference(PsiParameter param, int index);
+
+ public abstract RefPackage getDefaultPackage();
+
+ public abstract PsiMethod getAppMainPattern();
+
+ public abstract PsiMethod getAppPremainPattern();
+
+ public abstract PsiClass getApplet();
+
+ public abstract PsiClass getServlet();
+
+ public abstract EntryPointsManager getEntryPointsManager();
+
+ @Override
+ public Language getLanguage() {
+ return StdLanguages.JAVA;
+ }
+
+ @Override
+ public Key<RefJavaManager> getID() {
+ return MANAGER;
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefJavaUtil.java b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaUtil.java
new file mode 100644
index 0000000..5065117
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaUtil.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * User: anna
+ * Date: 21-Dec-2007
+ */
+package com.intellij.codeInspection.reference;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.psi.*;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class RefJavaUtil {
+ public abstract void addReferences(final PsiModifierListOwner psiFrom, final RefJavaElement ref, @Nullable PsiElement findIn);
+
+ public abstract RefClass getTopLevelClass(RefElement refElement);
+
+ public abstract boolean isInheritor(RefClass subClass, RefClass superClass);
+
+ @Nullable //default package name
+ public abstract String getPackageName(RefEntity refEntity);
+
+ @Nullable
+ public abstract RefClass getOwnerClass(RefManager refManager, PsiElement psiElement);
+
+ @Nullable
+ public abstract RefClass getOwnerClass(RefElement refElement);
+
+ public abstract int compareAccess(String a1, String a2);
+
+ public abstract String getAccessModifier(PsiModifierListOwner psiElement);
+
+ public abstract void setAccessModifier(RefJavaElement refElement, String newAccess);
+
+ public abstract void setIsStatic(RefJavaElement refElement, boolean isStatic);
+
+ public abstract void setIsFinal(RefJavaElement refElement, boolean isFinal);
+
+ public abstract boolean isMethodOnlyCallsSuper(final PsiMethod derivedMethod);
+
+ public static boolean isDeprecated(PsiElement psiResolved) {
+ return psiResolved instanceof PsiDocCommentOwner && ((PsiDocCommentOwner)psiResolved).isDeprecated();
+ }
+
+ @Nullable
+ public static RefPackage getPackage(RefEntity refEntity) {
+ while (refEntity != null && !(refEntity instanceof RefPackage)) refEntity = refEntity.getOwner();
+
+ return (RefPackage)refEntity;
+ }
+
+ public static RefJavaUtil getInstance() {
+ return ServiceManager.getService(RefJavaUtil.class);
+ }
+
+ public abstract boolean isCallToSuperMethod(PsiExpression expression, PsiMethod method);
+
+ public abstract void addTypeReference(PsiElement psiElement, PsiType psiType, RefManager refManager);
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefJavaVisitor.java b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaVisitor.java
new file mode 100644
index 0000000..4117c69
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaVisitor.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2009 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.codeInspection.reference;
+
+/**
+ * Visitor for reference graph nodes.
+ *
+ * @see RefEntity#accept
+ * @see RefManager#iterate
+ * @since 6.0
+ */
+public class RefJavaVisitor extends RefVisitor {
+
+ public void visitField(RefField field) {
+ visitElement(field);
+ }
+
+ public void visitMethod(RefMethod method) {
+ visitElement(method);
+ }
+
+ public void visitParameter(RefParameter parameter) {
+ visitElement(parameter);
+ }
+
+ public void visitClass(RefClass aClass) {
+ visitElement(aClass);
+ }
+
+ public void visitPackage(RefPackage aPackage) {
+ visitElement(aPackage);
+ }
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefMethod.java b/java/openapi/src/com/intellij/codeInspection/reference/RefMethod.java
new file mode 100644
index 0000000..3803f38
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefMethod.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2000-2009 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.codeInspection.reference;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiModifierListOwner;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * A node in the reference graph corresponding to a Java method.
+ *
+ * @author anna
+ * @since 6.0
+ */
+public interface RefMethod extends RefJavaElement {
+ /**
+ * Returns the collection of the direct super methods of this method in the
+ * analysis scope.
+ *
+ * @return the collection of super methods.
+ * @see com.intellij.psi.PsiMethod#findSuperMethods()
+ * @see #hasSuperMethods
+ */
+ @NotNull Collection<RefMethod> getSuperMethods();
+
+ /**
+ * Returns the collection of the overriding methods of this method in the
+ * analysis scope.
+ *
+ * @return the collection of overriding methods.
+ */
+ @NotNull Collection<RefMethod> getDerivedMethods();
+
+ /**
+ * Checks if this method has a body (that is, not a method of an interface or an abstract
+ * method).
+ *
+ * @return true if the method has a body, false otherwise.
+ */
+ boolean hasBody();
+
+ /**
+ * Checks if the method has no body or its body contains no statements besides
+ * (possibly) a call to its super method.
+ *
+ * @return true if the element has no body or the body is empty, false otherwise.
+ */
+ boolean isBodyEmpty();
+
+ /**
+ * Checks if the method has a body which consists only of the call to its super method.
+ *
+ * @return true if the method only calls its super method, false otherwise.
+ */
+ boolean isOnlyCallsSuper();
+
+ /**
+ * Checks if the method is a test method in a testcase class.
+ *
+ * @return true if the method is a test method, false otherwise.
+ */
+ boolean isTestMethod();
+
+ /**
+ * Checks if the signature of the method matches the signature of the standard <code>main</code>
+ * or <code>premain</code> method.
+ *
+ * @return true if the method can be a main function of the application, false otherwise.
+ */
+ boolean isAppMain();
+
+ /**
+ * Checks if the method has super methods either in the analysis scope or outside of it.
+ *
+ * @return true if the method has super methods, false otherwise.
+ * @see #getSuperMethods()
+ */
+ boolean hasSuperMethods();
+
+ /**
+ * Checks if the method overrides a method outside the current analysis scope.
+ *
+ * @return true if the method overrides a method not in the analysis scope, false otherwise.
+ */
+ boolean isExternalOverride();
+
+ /**
+ * Checks if the method is a constructor.
+ *
+ * @return true if the method is a constructor, false otherwise.
+ */
+ boolean isConstructor();
+
+ /**
+ * Checks if the method is abstract.
+ *
+ * @return true if the method is abstract, false otherwise.
+ */
+ boolean isAbstract();
+
+ /**
+ * Checks if the return value of the method is used by any of its callers.
+ *
+ * @return true if the method return value is used, false otherwise.
+ */
+ boolean isReturnValueUsed();
+
+ /**
+ * If the method always returns the same value, returns that value (the name of a static
+ * final field or the text of a literal expression). Otherwise, returns null.
+ *
+ * @return the method return value or null if it's different or impossible to determine.
+ */
+ @Nullable String getReturnValueIfSame();
+
+ /**
+ * Returns the list of exceptions which are included in the <code>throws</code> list
+ * of the method but cannot be actually thrown.
+ *
+ * @return the list of exceptions declared but not thrown, or null if there are no
+ * such exceptions.
+ */
+ @Nullable PsiClass[] getUnThrownExceptions();
+
+ /**
+ * Returns the list of reference graph nodes for the method parameters.
+ *
+ * @return the method parameters.
+ */
+ @NotNull RefParameter[] getParameters();
+
+ /**
+ * Returns the class to which the method belongs.
+ *
+ * @return the class instance.
+ */
+ RefClass getOwnerClass();
+
+ @Override
+ PsiModifierListOwner getElement();
+
+ boolean isCalledOnSubClass();
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefPackage.java b/java/openapi/src/com/intellij/codeInspection/reference/RefPackage.java
new file mode 100644
index 0000000..699e57c
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefPackage.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2009 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.codeInspection.reference;
+
+/**
+ * A node in the reference graph corresponding to a Java package.
+ *
+ * @author anna
+ * @since 6.0
+ * @see RefJavaManager#getPackage
+ */
+public interface RefPackage extends RefEntity {
+ /**
+ * Returns the full-qualified name for the package, or an empty string for the default package.
+ *
+ * @return the full-qualified name for the package.
+ */
+ @Override
+ String getQualifiedName();
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefParameter.java b/java/openapi/src/com/intellij/codeInspection/reference/RefParameter.java
new file mode 100644
index 0000000..21c62f2
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefParameter.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2009 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.codeInspection.reference;
+
+import com.intellij.psi.PsiParameter;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * A node in the reference graph corresponding to a Java method parameter.
+ *
+ * @author anna
+ * @since 6.0
+ */
+public interface RefParameter extends RefJavaElement {
+ /**
+ * Checks if the parameter is used for reading.
+ *
+ * @return true if the parameter has read accesses, false otherwise.
+ */
+ boolean isUsedForReading();
+
+ /**
+ * Checks if the parameter is used for writing.
+ *
+ * @return true if the parameter has write accesses, false otherwise.
+ */
+ boolean isUsedForWriting();
+
+ /**
+ * Returns the index of the parameter in the parameter list of its owner method.
+ *
+ * @return the index of the parameter.
+ */
+ int getIndex();
+
+ /**
+ * If all invocations of the method pass the same value to the parameter, returns
+ * that value (the name of a static final field or the text of a literal expression).
+ * Otherwise, returns null.
+ *
+ * @return the parameter value or null if it's different or impossible to determine.
+ */
+ @Nullable String getActualValueIfSame();
+
+ /**
+ * Marks the parameter as referenced for reading or writing.
+ *
+ * @param forWriting true if the parameter is marked as referenced for writing, false
+ * otherwise.
+ */
+ void parameterReferenced(final boolean forWriting);
+
+ @Override
+ PsiParameter getElement();
+}
diff --git a/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java b/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java
new file mode 100644
index 0000000..e00d4d6
--- /dev/null
+++ b/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java
@@ -0,0 +1,257 @@
+/*
+ * 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.execution.filters;
+
+import com.intellij.openapi.application.AccessToken;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.editor.colors.CodeInsightColors;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.Trinity;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.*;
+
+/**
+ * User: Irina.Chernushina
+ * Date: 8/5/11
+ * Time: 8:36 PM
+ */
+public class ExceptionWorker {
+ @NonNls private static final String AT = "at";
+ private static final String AT_PREFIX = AT + " ";
+ private static final String STANDALONE_AT = " " + AT + " ";
+
+ private static final TextAttributes HYPERLINK_ATTRIBUTES = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.HYPERLINK_ATTRIBUTES);
+
+ private final Project myProject;
+ private final GlobalSearchScope mySearchScope;
+ private Filter.Result myResult;
+ private PsiClass myClass;
+ private PsiFile myFile;
+ private String myMethod;
+ private Trinity<TextRange, TextRange, TextRange> myInfo;
+
+ public ExceptionWorker(@NotNull Project project, @NotNull GlobalSearchScope searchScope) {
+ myProject = project;
+ mySearchScope = searchScope;
+ }
+
+ public void execute(final String line, final int textEndOffset) {
+ myResult = null;
+ myInfo = parseExceptionLine(line);
+ if (myInfo == null) {
+ return;
+ }
+
+ myMethod = myInfo.getSecond().substring(line);
+
+ final int lparenthIndex = myInfo.third.getStartOffset();
+ final int rparenthIndex = myInfo.third.getEndOffset();
+ final String fileAndLine = line.substring(lparenthIndex + 1, rparenthIndex).trim();
+
+ final int colonIndex = fileAndLine.lastIndexOf(':');
+ if (colonIndex < 0) return;
+
+ final String lineString = fileAndLine.substring(colonIndex + 1);
+ try {
+ final int lineNumber = Integer.parseInt(lineString);
+ myClass = findPositionClass(line);
+ myFile = myClass == null ? null : (PsiFile)myClass.getContainingFile().getNavigationElement();
+ if (myFile == null) {
+ // try find the file with the required name
+ PsiFile[] files = PsiShortNamesCache.getInstance(myProject).getFilesByName(fileAndLine.substring(0, colonIndex).trim());
+ if (files.length > 0) {
+ myFile = files[0];
+ }
+ }
+ if (myFile == null) return;
+
+ /*
+ IDEADEV-4976: Some scramblers put something like SourceFile mock instead of real class name.
+ final String filePath = fileAndLine.substring(0, colonIndex).replace('/', File.separatorChar);
+ final int slashIndex = filePath.lastIndexOf(File.separatorChar);
+ final String shortFileName = slashIndex < 0 ? filePath : filePath.substring(slashIndex + 1);
+ if (!file.getName().equalsIgnoreCase(shortFileName)) return null;
+ */
+
+ final int textStartOffset = textEndOffset - line.length();
+
+ final int highlightStartOffset = textStartOffset + lparenthIndex + 1;
+ final int highlightEndOffset = textStartOffset + rparenthIndex;
+ final VirtualFile virtualFile = myFile.getVirtualFile();
+
+ HyperlinkInfo linkInfo = new MyHyperlinkInfo(myProject, virtualFile, lineNumber);
+
+ TextAttributes attributes = HYPERLINK_ATTRIBUTES.clone();
+ if (!ProjectRootManager.getInstance(myProject).getFileIndex().isInContent(virtualFile)) {
+ Color color = UIUtil.getInactiveTextColor();
+ attributes.setForegroundColor(color);
+ attributes.setEffectColor(color);
+ }
+ myResult = new Filter.Result(highlightStartOffset, highlightEndOffset, linkInfo, attributes);
+ }
+ catch (NumberFormatException e) {
+ //
+ }
+ }
+
+ private PsiClass findPositionClass(String line) {
+ String className = myInfo.first.substring(line).trim();
+ PsiClass result = findClassPreferringMyScope(className);
+ if (result == null) {
+ final int dollarIndex = className.indexOf('$');
+ if (dollarIndex >= 0) {
+ result = findClassPreferringMyScope(className.substring(0, dollarIndex));
+ }
+ }
+ return result;
+ }
+
+ private PsiClass findClassPreferringMyScope(String className) {
+ JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject);
+ PsiClass result = psiFacade.findClass(className, mySearchScope);
+ return result != null ? result : psiFacade.findClass(className, GlobalSearchScope.allScope(myProject));
+ }
+
+ public Filter.Result getResult() {
+ return myResult;
+ }
+
+ public PsiClass getPsiClass() {
+ return myClass;
+ }
+
+ public String getMethod() {
+ return myMethod;
+ }
+
+ public PsiFile getFile() {
+ return myFile;
+ }
+
+ public Trinity<TextRange, TextRange, TextRange> getInfo() {
+ return myInfo;
+ }
+
+ //todo [roma] regexp
+ @Nullable
+ static Trinity<TextRange, TextRange, TextRange> parseExceptionLine(final String line) {
+ int startIdx;
+ if (line.startsWith(AT_PREFIX)){
+ startIdx = 0;
+ }
+ else{
+ startIdx = line.indexOf(STANDALONE_AT);
+ if (startIdx < 0) {
+ startIdx = line.indexOf(AT_PREFIX);
+ }
+
+ if (startIdx < 0) {
+ startIdx = -1;
+ }
+ }
+
+ final int lparenIdx = line.indexOf('(', startIdx);
+ if (lparenIdx < 0) return null;
+ final int dotIdx = line.lastIndexOf('.', lparenIdx);
+ if (dotIdx < 0 || dotIdx < startIdx) return null;
+
+ final int rparenIdx = line.indexOf(')', lparenIdx);
+ if (rparenIdx < 0) return null;
+
+ // class, method, link
+ return Trinity.create(new TextRange(startIdx + 1 + (startIdx >= 0 ? AT.length() : 0), handleSpaces(line, dotIdx, -1, true)),
+ new TextRange(handleSpaces(line, dotIdx + 1, 1, true), handleSpaces(line, lparenIdx + 1, -1, true)),
+ new TextRange(lparenIdx, rparenIdx));
+ }
+
+ private static int handleSpaces(String line, int pos, int delta, boolean skip) {
+ int len = line.length();
+ while (pos >= 0 && pos < len) {
+ final char c = line.charAt(pos);
+ if (skip != Character.isSpaceChar(c)) break;
+ pos += delta;
+ }
+ return pos;
+ }
+
+ @Nullable
+ static OpenFileHyperlinkInfo getOpenFileHyperlinkInfo(Filter.Result result) {
+ if (result.hyperlinkInfo instanceof MyHyperlinkInfo) {
+ MyHyperlinkInfo info = (MyHyperlinkInfo)result.hyperlinkInfo;
+ return new OpenFileHyperlinkInfo(info.myProject, info.myVirtualFile, info.myLineNumber);
+ }
+ return null;
+ }
+
+ private static class MyHyperlinkInfo implements FileHyperlinkInfo {
+ private final VirtualFile myVirtualFile;
+ private final int myLineNumber;
+ private final Project myProject;
+
+ public MyHyperlinkInfo(@NotNull Project project, @NotNull VirtualFile virtualFile, int lineNumber) {
+ myProject = project;
+ myVirtualFile = virtualFile;
+ myLineNumber = lineNumber;
+ }
+
+ @Override
+ public void navigate(Project project) {
+ VirtualFile currentVirtualFile = null;
+
+ AccessToken accessToken = ReadAction.start();
+
+ try {
+ if (!myVirtualFile.isValid()) return;
+
+ PsiFile psiFile = PsiManager.getInstance(project).findFile(myVirtualFile);
+ if (psiFile != null) {
+ PsiElement navigationElement = psiFile.getNavigationElement(); // Sources may be downloaded.
+ if (navigationElement instanceof PsiFile) {
+ currentVirtualFile = ((PsiFile)navigationElement).getVirtualFile();
+ }
+ }
+
+ if (currentVirtualFile == null) {
+ currentVirtualFile = myVirtualFile;
+ }
+ }
+ finally {
+ accessToken.finish();
+ }
+
+ new OpenFileHyperlinkInfo(myProject, currentVirtualFile, myLineNumber - 1).navigate(project);
+ }
+
+ @Nullable
+ @Override
+ public OpenFileDescriptor getDescriptor() {
+ return new OpenFileDescriptor(myProject, myVirtualFile, myLineNumber);
+ }
+ }
+}
diff --git a/java/openapi/src/com/intellij/facet/ui/FacetEditorsFactory.java b/java/openapi/src/com/intellij/facet/ui/FacetEditorsFactory.java
new file mode 100644
index 0000000..fbc8144
--- /dev/null
+++ b/java/openapi/src/com/intellij/facet/ui/FacetEditorsFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2009 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.facet.ui;
+
+import com.intellij.facet.ui.libraries.*;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.Module;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class FacetEditorsFactory {
+ public static FacetEditorsFactory getInstance() {
+ return ServiceManager.getService(FacetEditorsFactory.class);
+ }
+
+
+ public abstract FacetLibrariesValidator createLibrariesValidator(@NotNull LibraryInfo[] libraries,
+ FacetLibrariesValidatorDescription description,
+ FacetEditorContext context,
+ final FacetValidatorsManager validatorsManager);
+
+ public abstract FacetLibrariesValidator createLibrariesValidator(@NotNull final LibraryInfo[] libraries,
+ @NotNull final Module module,
+ @NotNull final String libraryName);
+
+ public abstract LibrariesValidationComponent createLibrariesValidationComponent(LibraryInfo[] libraryInfos, Module module,
+ String defaultLibraryName);
+
+ public abstract MultipleFacetEditorHelper createMultipleFacetEditorHelper();
+}
diff --git a/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidator.java b/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidator.java
new file mode 100644
index 0000000..24ad0a1
--- /dev/null
+++ b/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidator.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2009 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.facet.ui.libraries;
+
+import com.intellij.facet.ui.FacetEditorValidator;
+import com.intellij.facet.Facet;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class FacetLibrariesValidator extends FacetEditorValidator {
+
+ public abstract void setRequiredLibraries(LibraryInfo[] requiredLibraries);
+
+ public abstract void setDescription(@NotNull FacetLibrariesValidatorDescription description);
+
+ public abstract void onFacetInitialized(Facet facet);
+
+ public abstract boolean isLibrariesAdded();
+}
diff --git a/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidatorDescription.java b/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidatorDescription.java
new file mode 100644
index 0000000..0b2c44e
--- /dev/null
+++ b/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidatorDescription.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2009 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.facet.ui.libraries;
+
+import com.intellij.facet.Facet;
+import com.intellij.openapi.roots.libraries.Library;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class FacetLibrariesValidatorDescription {
+ private final String myDefaultLibraryName;
+
+ public FacetLibrariesValidatorDescription(final @NonNls String defaultLibraryName) {
+ myDefaultLibraryName = defaultLibraryName;
+ }
+
+ @NonNls
+ public String getDefaultLibraryName() {
+ return myDefaultLibraryName;
+ }
+
+
+ public void onLibraryAdded(final Facet facet, @NotNull Library library) {
+ }
+}
diff --git a/java/openapi/src/com/intellij/facet/ui/libraries/LibrariesValidationComponent.java b/java/openapi/src/com/intellij/facet/ui/libraries/LibrariesValidationComponent.java
new file mode 100644
index 0000000..6dfa6a5
--- /dev/null
+++ b/java/openapi/src/com/intellij/facet/ui/libraries/LibrariesValidationComponent.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2009 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.facet.ui.libraries;
+
+import javax.swing.*;
+import java.util.EventListener;
+
+/**
+ * @author nik
+ */
+public interface LibrariesValidationComponent {
+
+ JComponent getComponent();
+
+ void validate();
+
+ void setupLibraries();
+
+ boolean isValid();
+
+ void addValidityListener(ValidityListener listener);
+
+ void removeValidityListener(ValidityListener listener);
+
+ interface ValidityListener extends EventListener {
+ void valididyChanged(boolean isValid);
+ }
+}
diff --git a/java/openapi/src/com/intellij/ide/IconUtilEx.java b/java/openapi/src/com/intellij/ide/IconUtilEx.java
new file mode 100644
index 0000000..566b1a3
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/IconUtilEx.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2009 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.ide;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Iconable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.IconUtil;
+import com.intellij.util.xml.ElementPresentationManager;
+
+import javax.swing.*;
+
+public class IconUtilEx {
+
+ public static Icon getIcon(Object object, @Iconable.IconFlags int flags, Project project) {
+ if (object instanceof PsiElement) {
+ return ((PsiElement)object).getIcon(flags);
+ }
+ if (object instanceof Module) {
+ return ModuleType.get((Module)object).getIcon();
+ }
+ if (object instanceof VirtualFile) {
+ VirtualFile file = (VirtualFile)object;
+ return IconUtil.getIcon(file, flags, project);
+ }
+ return ElementPresentationManager.getIcon(object);
+ }
+}
diff --git a/java/openapi/src/com/intellij/ide/package.html b/java/openapi/src/com/intellij/ide/package.html
new file mode 100644
index 0000000..1c297c7
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for accessing common IDEA actions, services and user interface components.
+</body></html>
diff --git a/java/openapi/src/com/intellij/ide/palette/PaletteDragEventListener.java b/java/openapi/src/com/intellij/ide/palette/PaletteDragEventListener.java
new file mode 100644
index 0000000..1a6b681
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/palette/PaletteDragEventListener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2009 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.ide.palette;
+
+/**
+ * @author yole
+ */
+public interface PaletteDragEventListener {
+ void dropActionChanged(int gestureModifiers);
+}
diff --git a/java/openapi/src/com/intellij/ide/palette/PaletteGroup.java b/java/openapi/src/com/intellij/ide/palette/PaletteGroup.java
new file mode 100644
index 0000000..a19c1ab
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/palette/PaletteGroup.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2009 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.ide.palette;
+
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author yole
+ */
+public interface PaletteGroup {
+ PaletteGroup[] EMPTY_ARRAY = new PaletteGroup[0];
+
+ PaletteItem[] getItems();
+
+ /**
+ * Returns the text of the group header for the palette group.
+ *
+ * @return the text of the group header for the palette group, or null if no header should be shown.
+ */
+ @Nullable String getName();
+
+ String getTabName();
+
+ /**
+ * Returns the action group from which the context menu is built when the palette
+ * item is right-clicked.
+ *
+ * @return the action group, or null if no context menu should be shown.
+ */
+ @Nullable ActionGroup getPopupActionGroup();
+
+ /**
+ * Returns the data for the specified data constant.
+ *
+ * @param project the project in the context of which data is requested.
+ * @param dataId the data constant id (see {@link com.intellij.openapi.actionSystem.PlatformDataKeys}).
+ * @return the data item, or null if no data is available for this constant.
+ */
+ @Nullable Object getData(Project project, String dataId);
+
+ /**
+ * Processes the drop of a palette item on the specified index in the palette group.
+ *
+ * @param project the project to which the drop target palette belongs.
+ * @param item the dropped item.
+ * @param index the index at which the dropped item should be inserted (from 0 to getItems().length).
+ */
+ void handleDrop(Project project, PaletteItem item, int index);
+}
diff --git a/java/openapi/src/com/intellij/ide/palette/PaletteItem.java b/java/openapi/src/com/intellij/ide/palette/PaletteItem.java
new file mode 100644
index 0000000..372839d
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/palette/PaletteItem.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2009 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.ide.palette;
+
+import com.intellij.ide.dnd.DnDDragStartBean;
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.project.Project;
+import com.intellij.ui.ColoredListCellRenderer;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author yole
+ */
+public interface PaletteItem {
+ void customizeCellRenderer(ColoredListCellRenderer cellRenderer,
+ boolean selected,
+ boolean hasFocus);
+
+ /**
+ * Processes dragging the item.
+ *
+ * @return the drag start bean for the drag process, or null if the item cannot be dragged.
+ */
+ @Nullable DnDDragStartBean startDragging();
+
+ /**
+ * Returns the action group from which the context menu is built when the palette
+ * item is right-clicked.
+ *
+ * @return the action group, or null if no context menu should be shown.
+ */
+ @Nullable ActionGroup getPopupActionGroup();
+
+ /**
+ * Returns the data for the specified data constant.
+ *
+ * @param project the project in the context of which data is requested.
+ * @param dataId the data constant id (see {@link com.intellij.openapi.actionSystem.PlatformDataKeys}).
+ * @return the data item, or null if no data is available for this constant.
+ */
+ @Nullable Object getData(Project project, String dataId);
+}
diff --git a/java/openapi/src/com/intellij/ide/palette/PaletteItemProvider.java b/java/openapi/src/com/intellij/ide/palette/PaletteItemProvider.java
new file mode 100644
index 0000000..3f1b99d
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/palette/PaletteItemProvider.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2009 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.ide.palette;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.vfs.VirtualFile;
+
+import java.beans.PropertyChangeListener;
+
+/**
+ * @author yole
+ */
+public interface PaletteItemProvider {
+ ExtensionPointName<PaletteItemProvider> EP_NAME = ExtensionPointName.create("com.intellij.paletteItemProvider");
+
+ PaletteGroup[] getActiveGroups(VirtualFile virtualFile);
+
+ void addListener(PropertyChangeListener listener);
+ void removeListener(PropertyChangeListener listener);
+}
diff --git a/java/openapi/src/com/intellij/ide/util/ClassFilter.java b/java/openapi/src/com/intellij/ide/util/ClassFilter.java
new file mode 100644
index 0000000..8b1fc2e
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/ClassFilter.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2010 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.ide.util;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiUtil;
+
+/**
+* @author traff
+*/
+public interface ClassFilter {
+ ClassFilter INSTANTIABLE = new ClassFilter() {
+ public boolean isAccepted(PsiClass aClass) {
+ return PsiUtil.isInstantiatable(aClass);
+ }
+ };
+
+ boolean isAccepted(PsiClass aClass);
+ ClassFilter ALL = new ClassFilter() {
+ public boolean isAccepted(PsiClass aClass) {
+ return true;
+ }
+ };
+
+ interface ClassFilterWithScope extends ClassFilter {
+ GlobalSearchScope getScope();
+ }
+}
diff --git a/java/openapi/src/com/intellij/ide/util/TreeClassChooser.java b/java/openapi/src/com/intellij/ide/util/TreeClassChooser.java
new file mode 100644
index 0000000..9a9536c
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/TreeClassChooser.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2009 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.ide.util;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiDirectory;
+
+/**
+ * User: anna
+ * Date: Jan 24, 2005
+ */
+public interface TreeClassChooser extends TreeChooser<PsiClass> {
+ PsiClass getSelected();
+
+ void select(final PsiClass aClass);
+
+ void selectDirectory(final PsiDirectory directory);
+
+ void showDialog();
+
+ void showPopup();
+}
diff --git a/java/openapi/src/com/intellij/ide/util/TreeClassChooserFactory.java b/java/openapi/src/com/intellij/ide/util/TreeClassChooserFactory.java
new file mode 100644
index 0000000..2a8d4cd
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/TreeClassChooserFactory.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2009 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.ide.util;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.search.GlobalSearchScope;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User: anna
+ * Date: Jan 25, 2005
+ */
+public abstract class TreeClassChooserFactory {
+
+ public static TreeClassChooserFactory getInstance(Project project) {
+ return ServiceManager.getService(project, TreeClassChooserFactory.class);
+ }
+
+
+ @NotNull
+ public abstract TreeClassChooser createWithInnerClassesScopeChooser(String title,
+ GlobalSearchScope scope,
+ final ClassFilter classFilter,
+ @Nullable PsiClass initialClass);
+
+
+ @NotNull
+ public abstract TreeClassChooser createNoInnerClassesScopeChooser(String title,
+ GlobalSearchScope scope,
+ ClassFilter classFilter,
+ @Nullable PsiClass initialClass);
+
+
+ @NotNull
+ public abstract TreeClassChooser createProjectScopeChooser(String title, @Nullable PsiClass initialClass);
+
+
+ @NotNull
+ public abstract TreeClassChooser createProjectScopeChooser(String title);
+
+
+ @NotNull
+ public abstract TreeClassChooser createAllProjectScopeChooser(String title);
+
+
+ @NotNull
+ public abstract TreeClassChooser createInheritanceClassChooser(String title,
+ GlobalSearchScope scope,
+ PsiClass base,
+ boolean acceptsSelf,
+ boolean acceptInner,
+ Condition<? super PsiClass> additionalCondition);
+
+ @NotNull
+ public abstract TreeClassChooser createInheritanceClassChooser(String title,
+ GlobalSearchScope scope,
+ PsiClass base,
+ PsiClass initialClass);
+
+ @NotNull
+ public abstract TreeClassChooser createInheritanceClassChooser(String title,
+ GlobalSearchScope scope,
+ PsiClass base,
+ PsiClass initialClass,
+ ClassFilter classFilter);
+
+
+ @NotNull
+ public abstract TreeFileChooser createFileChooser(@NotNull String title,
+ @Nullable PsiFile initialFile,
+ @Nullable FileType fileType,
+ @Nullable TreeFileChooser.PsiFileFilter filter);
+
+
+ @NotNull
+ public abstract TreeFileChooser createFileChooser(@NotNull String title,
+ @Nullable PsiFile initialFile,
+ @Nullable FileType fileType,
+ @Nullable TreeFileChooser.PsiFileFilter filter,
+ boolean disableStructureProviders);
+
+
+ @NotNull
+ public abstract TreeFileChooser createFileChooser(@NotNull String title,
+ @Nullable PsiFile initialFile,
+ @Nullable FileType fileType,
+ @Nullable TreeFileChooser.PsiFileFilter filter,
+ boolean disableStructureProviders,
+ boolean showLibraryContents);
+}
diff --git a/java/openapi/src/com/intellij/ide/util/package.html b/java/openapi/src/com/intellij/ide/util/package.html
new file mode 100644
index 0000000..7d974c1
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/package.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for accessing additional user interface services and the generic
+tree view framework.
+</body></html>
diff --git a/java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java b/java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java
new file mode 100644
index 0000000..b7224d0
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2000-2009 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.ide.util.projectWizard;
+
+
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.projectRoots.JavaSdkType;
+import com.intellij.openapi.projectRoots.SdkTypeId;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class JavaModuleBuilder extends ModuleBuilder implements SourcePathsBuilder {
+ private String myCompilerOutputPath;
+ // Pair<Source Path, Package Prefix>
+ private List<Pair<String,String>> mySourcePaths;
+ // Pair<Library path, Source path>
+ private final List<Pair<String, String>> myModuleLibraries = new ArrayList<Pair<String, String>>();
+
+ public final void setCompilerOutputPath(String compilerOutputPath) {
+ myCompilerOutputPath = acceptParameter(compilerOutputPath);
+ }
+
+ public List<Pair<String,String>> getSourcePaths() {
+ if (mySourcePaths == null) {
+ final List<Pair<String, String>> paths = new ArrayList<Pair<String, String>>();
+ @NonNls final String path = getContentEntryPath() + File.separator + "src";
+ new File(path).mkdirs();
+ paths.add(Pair.create(path, ""));
+ return paths;
+ }
+ return mySourcePaths;
+ }
+
+ public void setSourcePaths(List<Pair<String,String>> sourcePaths) {
+ mySourcePaths = sourcePaths != null? new ArrayList<Pair<String, String>>(sourcePaths) : null;
+ }
+
+ public void addSourcePath(Pair<String,String> sourcePathInfo) {
+ if (mySourcePaths == null) {
+ mySourcePaths = new ArrayList<Pair<String, String>>();
+ }
+ mySourcePaths.add(sourcePathInfo);
+ }
+
+ public ModuleType getModuleType() {
+ return StdModuleTypes.JAVA;
+ }
+
+ @Override
+ public boolean isSuitableSdkType(SdkTypeId sdkType) {
+ return sdkType instanceof JavaSdkType;
+ }
+
+ @Nullable
+ @Override
+ public ModuleWizardStep modifySettingsStep(SettingsStep settingsStep) {
+ return StdModuleTypes.JAVA.modifySettingsStep(settingsStep, this);
+ }
+
+ public void setupRootModel(ModifiableRootModel rootModel) throws ConfigurationException {
+ final CompilerModuleExtension compilerModuleExtension = rootModel.getModuleExtension(CompilerModuleExtension.class);
+ compilerModuleExtension.setExcludeOutput(true);
+ if (myJdk != null){
+ rootModel.setSdk(myJdk);
+ } else {
+ rootModel.inheritSdk();
+ }
+
+ ContentEntry contentEntry = doAddContentEntry(rootModel);
+ if (contentEntry != null) {
+ final List<Pair<String,String>> sourcePaths = getSourcePaths();
+
+ if (sourcePaths != null) {
+ for (final Pair<String, String> sourcePath : sourcePaths) {
+ String first = sourcePath.first;
+ new File(first).mkdirs();
+ final VirtualFile sourceRoot = LocalFileSystem.getInstance()
+ .refreshAndFindFileByPath(FileUtil.toSystemIndependentName(first));
+ if (sourceRoot != null) {
+ contentEntry.addSourceFolder(sourceRoot, false, sourcePath.second);
+ }
+ }
+ }
+ }
+
+ if (myCompilerOutputPath != null) {
+ // should set only absolute paths
+ String canonicalPath;
+ try {
+ canonicalPath = FileUtil.resolveShortWindowsName(myCompilerOutputPath);
+ }
+ catch (IOException e) {
+ canonicalPath = myCompilerOutputPath;
+ }
+ compilerModuleExtension
+ .setCompilerOutputPath(VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(canonicalPath)));
+ }
+ else {
+ compilerModuleExtension.inheritCompilerOutputPath(true);
+ }
+
+ LibraryTable libraryTable = rootModel.getModuleLibraryTable();
+ for (Pair<String, String> libInfo : myModuleLibraries) {
+ final String moduleLibraryPath = libInfo.first;
+ final String sourceLibraryPath = libInfo.second;
+ Library library = libraryTable.createLibrary();
+ Library.ModifiableModel modifiableModel = library.getModifiableModel();
+ modifiableModel.addRoot(getUrlByPath(moduleLibraryPath), OrderRootType.CLASSES);
+ if (sourceLibraryPath != null) {
+ modifiableModel.addRoot(getUrlByPath(sourceLibraryPath), OrderRootType.SOURCES);
+ }
+ modifiableModel.commit();
+ }
+ }
+
+ private static String getUrlByPath(final String path) {
+ return VfsUtil.getUrlForLibraryRoot(new File(path));
+ }
+
+ public void addModuleLibrary(String moduleLibraryPath, String sourcePath) {
+ myModuleLibraries.add(Pair.create(moduleLibraryPath,sourcePath));
+ }
+
+ @Nullable
+ protected static String getPathForOutputPathStep() {
+ return null;
+ }
+}
diff --git a/java/openapi/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactory.java b/java/openapi/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactory.java
new file mode 100644
index 0000000..9cb5fa0
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactory.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2009 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.ide.util.projectWizard;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkType;
+import com.intellij.openapi.projectRoots.SdkTypeId;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Condition;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * A factory for creating some commonly used project wizards steps
+ */
+public abstract class ProjectWizardStepFactory {
+
+ public static ProjectWizardStepFactory getInstance() {
+ return ServiceManager.getService(ProjectWizardStepFactory.class);
+ }
+ /**
+ * @deprecated
+ */
+ public abstract ModuleWizardStep createNameAndLocationStep(WizardContext wizardContext, JavaModuleBuilder builder, ModulesProvider modulesProvider, Icon icon, @NonNls String helpId);
+
+ public abstract ModuleWizardStep createNameAndLocationStep(WizardContext wizardContext);
+
+ public abstract ModuleWizardStep createOutputPathPathsStep(ModuleWizardStep nameAndLocationStep, JavaModuleBuilder builder, Icon icon, @NonNls String helpId);
+
+ /**
+ * @deprecated Use another version of this method:
+ * @see com.intellij.ide.util.projectWizard.ProjectWizardStepFactory#createSourcePathsStep(WizardContext, SourcePathsBuilder, javax.swing.Icon, String)
+ */
+ public abstract ModuleWizardStep createSourcePathsStep(ModuleWizardStep nameAndLocationStep, SourcePathsBuilder builder, Icon icon, @NonNls String helpId);
+
+ public abstract ModuleWizardStep createSourcePathsStep(WizardContext context, SourcePathsBuilder builder, Icon icon, @NonNls String helpId);
+
+ /**
+ * @deprecated
+ */
+ public abstract ModuleWizardStep createProjectJdkStep(WizardContext context, JavaModuleBuilder builder, Computable<Boolean> isVisibile, Icon icon, @NonNls String helpId);
+
+ public abstract ModuleWizardStep createProjectJdkStep(WizardContext context, SdkType type, JavaModuleBuilder builder, Computable<Boolean> isVisibile, Icon icon, @NonNls String helpId);
+
+ public abstract ModuleWizardStep createProjectJdkStep(final WizardContext wizardContext);
+
+ @Nullable
+ public abstract Sdk getNewProjectSdk(WizardContext wizardContext);
+
+ /**
+ * @deprecated use {@link #createSupportForFrameworksStep(WizardContext, ModuleBuilder, com.intellij.openapi.roots.ui.configuration.ModulesProvider)} instead
+ */
+ @Nullable
+ public abstract ModuleWizardStep createSupportForFrameworksStep(WizardContext context, ModuleBuilder builder);
+
+ @Nullable
+ public abstract ModuleWizardStep createSupportForFrameworksStep(WizardContext context, ModuleBuilder builder, ModulesProvider modulesProvider);
+
+ public abstract ModuleWizardStep createJavaSettingsStep(SettingsStep settingsStep, ModuleBuilder moduleBuilder, @NotNull Condition<SdkTypeId> sdkFilter);
+}
diff --git a/java/openapi/src/com/intellij/ide/util/projectWizard/SourcePathsBuilder.java b/java/openapi/src/com/intellij/ide/util/projectWizard/SourcePathsBuilder.java
new file mode 100644
index 0000000..bbcc289
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/projectWizard/SourcePathsBuilder.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 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.ide.util.projectWizard;
+
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Jul 20, 2007
+ */
+public interface SourcePathsBuilder {
+ @Nullable
+ String getContentEntryPath();
+
+ void setContentEntryPath(String moduleRootPath);
+
+ List<Pair<String,String>> getSourcePaths() throws ConfigurationException;
+
+ void setSourcePaths(List<Pair<String,String>> sourcePaths);
+
+ void addSourcePath(Pair<String,String> sourcePathInfo);
+}
diff --git a/java/openapi/src/com/intellij/ide/util/projectWizard/package.html b/java/openapi/src/com/intellij/ide/util/projectWizard/package.html
new file mode 100644
index 0000000..0abea7e
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/projectWizard/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for building customized "New Project" and "New Module" wizards.
+</body></html>
diff --git a/java/openapi/src/com/intellij/lang/refactoring/JavaNamesValidator.java b/java/openapi/src/com/intellij/lang/refactoring/JavaNamesValidator.java
new file mode 100644
index 0000000..602ee86
--- /dev/null
+++ b/java/openapi/src/com/intellij/lang/refactoring/JavaNamesValidator.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2009 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.lang.refactoring;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.JavaPsiFacade;
+
+/**
+ * Default NamesValidator interface implementation. Uses java language keyword set and java language rules for identifier.
+ */
+public class JavaNamesValidator implements NamesValidator {
+ public boolean isKeyword(String name, Project project) {
+ return JavaPsiFacade.getInstance(project).getNameHelper().isKeyword(name);
+ }
+
+ public boolean isIdentifier(String name, Project project) {
+ return JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(name);
+ }
+}
diff --git a/java/openapi/src/com/intellij/openapi/actionSystem/DataKeys.java b/java/openapi/src/com/intellij/openapi/actionSystem/DataKeys.java
new file mode 100644
index 0000000..da04094
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/actionSystem/DataKeys.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: yole
+ * Date: 23.10.2006
+ * Time: 17:00:37
+ */
+package com.intellij.openapi.actionSystem;
+
+import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vcs.changes.ChangeList;
+
+@SuppressWarnings({"deprecation"})
+public final class DataKeys extends LangDataKeys {
+ private DataKeys() {
+ }
+
+ @Deprecated
+ public static final DataKey<ChangeList[]> CHANGE_LISTS = DataKey.create("vcs.ChangeList");
+ @Deprecated
+ public static final DataKey<Change[]> CHANGES = DataKey.create("vcs.Change");
+
+}
+
diff --git a/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java b/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java
new file mode 100644
index 0000000..0ee5397
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.module;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.roots.LanguageLevelModuleExtension;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public class LanguageLevelUtil {
+ private LanguageLevelUtil() {
+ }
+
+ @NotNull
+ public static LanguageLevel getEffectiveLanguageLevel(@NotNull final Module module) {
+ ApplicationManager.getApplication().assertReadAccessAllowed();
+ LanguageLevel level = LanguageLevelModuleExtension.getInstance(module).getLanguageLevel();
+ if (level != null) return level;
+ return LanguageLevelProjectExtension.getInstance(module.getProject()).getLanguageLevel();
+ }
+
+ @NotNull
+ public static LanguageLevel getLanguageLevelForFile(final VirtualFile file) {
+ if (file == null) return LanguageLevel.HIGHEST;
+
+ if (file.isDirectory()) {
+ final LanguageLevel ll = file.getUserData(LanguageLevel.KEY);
+ return ll != null ? ll : LanguageLevel.HIGHEST;
+ }
+
+ return getLanguageLevelForFile(file.getParent());
+ }
+
+ /**
+ * @deprecated use {@link com.intellij.openapi.projectRoots.JavaSdkVersion#getMaxLanguageLevel()} instead
+ */
+ public static LanguageLevel getDefaultLanguageLevel(@NotNull String versionString) {
+ JavaSdkVersion version = JavaSdk.getInstance().getVersion(versionString);
+ return version != null ? version.getMaxLanguageLevel() : LanguageLevel.JDK_1_3;
+ }
+
+ /**
+ * @deprecated use {@link com.intellij.openapi.projectRoots.JavaSdkVersion#isAtLeast(com.intellij.openapi.projectRoots.JavaSdkVersion)} instead
+ */
+ public static boolean isOfVersionOrHigher(@NotNull String versionString, String checkedVersion) {
+ return JavaSdk.getInstance().compareTo(versionString, checkedVersion) >= 0;
+ }
+}
diff --git a/java/openapi/src/com/intellij/openapi/module/StdModuleTypes.java b/java/openapi/src/com/intellij/openapi/module/StdModuleTypes.java
new file mode 100644
index 0000000..66b33e6
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/module/StdModuleTypes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.module;
+
+public class StdModuleTypes {
+ // predefined module types
+ public static ModuleType JAVA;
+
+ private StdModuleTypes() {
+ }
+
+ static {
+ JAVA = instantiate("com.intellij.openapi.module.JavaModuleType");
+ }
+
+ private static ModuleType instantiate(String className) {
+ try {
+ return (ModuleType)Class.forName(className).newInstance();
+ }
+ catch (Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+}
diff --git a/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java
new file mode 100644
index 0000000..88a5c55
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.projectRoots;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.ApplicationComponent;
+import com.intellij.openapi.projectRoots.impl.SdkVersionUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+public abstract class JavaSdk extends SdkType implements JavaSdkType, ApplicationComponent {
+ public JavaSdk(@NonNls String name) {
+ super(name);
+ }
+
+ public static JavaSdk getInstance() {
+ return ApplicationManager.getApplication().getComponent(JavaSdk.class);
+ }
+
+ public final Sdk createJdk(@NotNull String jdkName, @NotNull String jreHome) {
+ return createJdk(jdkName, jreHome, true);
+ }
+
+ /**
+ * @deprecated use {@link #isOfVersionOrHigher(Sdk, JavaSdkVersion)} instead
+ */
+ public abstract int compareTo(@NotNull String versionString, @NotNull String versionNumber);
+
+ public abstract Sdk createJdk(@NonNls String jdkName, @NotNull String home, boolean isJre);
+
+ @Nullable
+ public abstract JavaSdkVersion getVersion(@NotNull Sdk sdk);
+
+ @Nullable
+ public abstract JavaSdkVersion getVersion(@NotNull String versionString);
+
+ public abstract boolean isOfVersionOrHigher(@NotNull Sdk sdk, @NotNull JavaSdkVersion version);
+
+ public static boolean checkForJdk(File file) {
+ return JdkUtil.checkForJdk(file);
+ }
+
+ public static boolean checkForJre(String file) {
+ return JdkUtil.checkForJre(file);
+ }
+
+ @Nullable
+ public static String getJdkVersion(final String sdkHome) {
+ return SdkVersionUtil.detectJdkVersion(sdkHome);
+ }
+}
diff --git a/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdkVersionUtil.java b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdkVersionUtil.java
new file mode 100644
index 0000000..6c85da3
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdkVersionUtil.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.projectRoots;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.psi.PsiElement;
+
+/**
+ * User: anna
+ * Date: 3/28/12
+ */
+public class JavaSdkVersionUtil {
+ public static boolean isAtLeast(PsiElement element, JavaSdkVersion minVersion) {
+ final Module module = ModuleUtil.findModuleForPsiElement(element);
+ if (module != null) {
+ final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
+ if (sdk != null && sdk.getSdkType() instanceof JavaSdk) {
+ final JavaSdkVersion version = JavaSdk.getInstance().getVersion(sdk);
+ return version != null && version.isAtLeast(minVersion);
+ }
+ }
+ return true;
+ }
+}
diff --git a/java/openapi/src/com/intellij/openapi/projectRoots/package.html b/java/openapi/src/com/intellij/openapi/projectRoots/package.html
new file mode 100644
index 0000000..ca5e461
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/projectRoots/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for working with JDKs and registering new JDK types.
+</body></html>
diff --git a/java/openapi/src/com/intellij/openapi/roots/FileIndexUtil.java b/java/openapi/src/com/intellij/openapi/roots/FileIndexUtil.java
new file mode 100644
index 0000000..42e5f38
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/FileIndexUtil.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.roots;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public class FileIndexUtil {
+ private FileIndexUtil() {
+ }
+
+ public static boolean isJavaSourceFile(@NotNull Project project, @NotNull VirtualFile file) {
+ FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+ if (file.isDirectory()) return false;
+ if (file.getFileType() != StdFileTypes.JAVA) return false;
+ if (fileTypeManager.isFileIgnored(file)) return false;
+ return ProjectRootManager.getInstance(project).getFileIndex().isInSource(file);
+ }
+}
diff --git a/java/openapi/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java b/java/openapi/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java
new file mode 100644
index 0000000..e6db187
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * User: anna
+ * Date: 27-Dec-2007
+ */
+package com.intellij.openapi.roots;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.pom.java.LanguageLevel;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+public class LanguageLevelModuleExtension extends ModuleExtension<LanguageLevelModuleExtension> {
+ @NonNls private static final String LANGUAGE_LEVEL_ELEMENT_NAME = "LANGUAGE_LEVEL";
+ private Module myModule;
+ private final boolean myWritable;
+ private static final Logger LOG = Logger.getInstance("#" + LanguageLevelModuleExtension.class.getName());
+
+ public static LanguageLevelModuleExtension getInstance(final Module module) {
+ return ModuleRootManager.getInstance(module).getModuleExtension(LanguageLevelModuleExtension.class);
+ }
+
+ private LanguageLevel myLanguageLevel;
+ private final LanguageLevelModuleExtension mySource;
+
+ public LanguageLevelModuleExtension(Module module) {
+ myModule = module;
+ mySource = null;
+ myWritable = false;
+ }
+
+ public LanguageLevelModuleExtension(final LanguageLevelModuleExtension source, boolean writable) {
+ myWritable = writable;
+ myModule = source.myModule;
+ myLanguageLevel = source.myLanguageLevel;
+ mySource = source;
+ }
+
+ public void setLanguageLevel(final LanguageLevel languageLevel) {
+ LOG.assertTrue(myWritable, "Writable model can be retrieved from writable ModifiableRootModel");
+ myLanguageLevel = languageLevel;
+ }
+
+ @Nullable
+ public LanguageLevel getLanguageLevel() {
+ return myLanguageLevel;
+ }
+
+ @Override
+ public void readExternal(final Element element) throws InvalidDataException {
+ final String languageLevel = element.getAttributeValue(LANGUAGE_LEVEL_ELEMENT_NAME);
+ if (languageLevel != null) {
+ try {
+ myLanguageLevel = LanguageLevel.valueOf(languageLevel);
+ }
+ catch (IllegalArgumentException e) {
+ //bad value was stored
+ }
+ }
+ }
+
+ @Override
+ public void writeExternal(final Element element) throws WriteExternalException {
+ if (myLanguageLevel != null) {
+ element.setAttribute(LANGUAGE_LEVEL_ELEMENT_NAME, myLanguageLevel.toString());
+ }
+ }
+
+ @Override
+ public ModuleExtension getModifiableModel(final boolean writable) {
+ return new LanguageLevelModuleExtension(this, writable);
+ }
+
+ @Override
+ public void commit() {
+ if (mySource != null && mySource.myLanguageLevel != myLanguageLevel) {
+ if (myModule.isLoaded()) { //do not reload project for non-committed modules: j2me|project imports
+ if (mySource.myLanguageLevel != myLanguageLevel) {
+ final LanguageLevelProjectExtension languageLevelProjectExtension =
+ LanguageLevelProjectExtension.getInstance(myModule.getProject());
+ final LanguageLevel projectLanguageLevel = languageLevelProjectExtension.getLanguageLevel();
+ final boolean explicit2ImplicitProjectLevel = myLanguageLevel == null && mySource.myLanguageLevel == projectLanguageLevel;
+ final boolean implicit2ExplicitProjectLevel = mySource.myLanguageLevel == null && myLanguageLevel == projectLanguageLevel;
+ if (!(explicit2ImplicitProjectLevel || implicit2ExplicitProjectLevel)) {
+ languageLevelProjectExtension.reloadProjectOnLanguageLevelChange(myLanguageLevel == null ? projectLanguageLevel : myLanguageLevel, true);
+ }
+ }
+ }
+ mySource.myLanguageLevel = myLanguageLevel;
+ }
+ }
+
+ @Override
+ public boolean isChanged() {
+ return mySource != null && mySource.myLanguageLevel != myLanguageLevel;
+ }
+
+ @Override
+ public void dispose() {
+ myModule = null;
+ myLanguageLevel = null;
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/openapi/roots/libraries/JarVersionDetectionUtil.java b/java/openapi/src/com/intellij/openapi/roots/libraries/JarVersionDetectionUtil.java
new file mode 100644
index 0000000..f92d61b
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/libraries/JarVersionDetectionUtil.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.openapi.roots.libraries;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.LibraryOrderEntry;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.OrderEntry;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+public class JarVersionDetectionUtil {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.libraries.JarVersionDetectionUtil");
+
+ private JarVersionDetectionUtil() {
+ }
+
+ @Nullable
+ public static String detectJarVersion(@NotNull final String detectionClass, @NotNull Module module) {
+ try {
+ return detectJarVersion(getDetectionJar(detectionClass, module));
+ }
+ catch (IOException e) {
+ return null;
+ }
+ }
+
+ @Nullable
+ public static String detectJarVersion(@NotNull String detectionClass, @NotNull List<VirtualFile> files) {
+ final VirtualFile jar = LibrariesHelper.getInstance().findRootByClass(files, detectionClass);
+ if (jar != null && jar.getFileSystem() instanceof JarFileSystem) {
+ final VirtualFile manifestFile = jar.findFileByRelativePath(JarFile.MANIFEST_NAME);
+ if (manifestFile != null) {
+ try {
+ final InputStream input = manifestFile.getInputStream();
+ try {
+ return new Manifest(input).getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
+ }
+ finally {
+ input.close();
+ }
+ }
+ catch (IOException e) {
+ LOG.debug(e);
+ return null;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ public static String detectJarVersion(com.intellij.openapi.vfs.JarFile zipFile) {
+ if (zipFile == null) {
+ return null;
+ }
+ try {
+ final com.intellij.openapi.vfs.JarFile.JarEntry zipEntry = zipFile.getEntry(JarFile.MANIFEST_NAME);
+ if (zipEntry == null) {
+ return null;
+ }
+ final InputStream inputStream = zipFile.getInputStream(zipEntry);
+ final Manifest manifest = new Manifest(inputStream);
+ final Attributes attributes = manifest.getMainAttributes();
+ return attributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
+ }
+ catch (IOException e) {
+ return null;
+ }
+ }
+
+ @Nullable
+ private static com.intellij.openapi.vfs.JarFile getDetectionJar(final String detectionClass, Module module) throws IOException {
+ for (OrderEntry library : ModuleRootManager.getInstance(module).getOrderEntries()) {
+ if (library instanceof LibraryOrderEntry) {
+ VirtualFile file = LibrariesHelper.getInstance().findJarByClass(((LibraryOrderEntry)library).getLibrary(), detectionClass);
+ if (file != null && file.getFileSystem() instanceof JarFileSystem) {
+ return JarFileSystem.getInstance().getJarFile(file);
+ }
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/java/openapi/src/com/intellij/openapi/roots/libraries/LibrariesHelper.java b/java/openapi/src/com/intellij/openapi/roots/libraries/LibrariesHelper.java
new file mode 100644
index 0000000..3367f11
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/libraries/LibrariesHelper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.roots.libraries;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * author: lesya
+ */
+public abstract class LibrariesHelper {
+ public static LibrariesHelper getInstance(){
+ return ServiceManager.getService(LibrariesHelper.class);
+ }
+
+ public abstract boolean isClassAvailableInLibrary(final Library library, @NonNls final String fqn);
+
+ public abstract boolean isClassAvailable(@NonNls String[] urls, @NonNls String fqn);
+
+ @Nullable
+ public abstract VirtualFile findJarByClass(final Library library, @NonNls String fqn);
+
+ @Nullable
+ public abstract VirtualFile findRootByClass(List<VirtualFile> roots, String fqn);
+}
diff --git a/java/openapi/src/com/intellij/openapi/roots/libraries/package.html b/java/openapi/src/com/intellij/openapi/roots/libraries/package.html
new file mode 100644
index 0000000..7a8b45a
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/libraries/package.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for defining the contents of a library and for working with lists
+of libraries.
+</body></html>
diff --git a/java/openapi/src/com/intellij/openapi/roots/package.html b/java/openapi/src/com/intellij/openapi/roots/package.html
new file mode 100644
index 0000000..0f1e1b1
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/package.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for defining the structure and contents of projects and modules
+and the libraries used in them.
+</body></html>
diff --git a/java/openapi/src/com/intellij/openapi/roots/ui/OrderEntryAppearanceService.java b/java/openapi/src/com/intellij/openapi/roots/ui/OrderEntryAppearanceService.java
new file mode 100644
index 0000000..85cb7d3
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/ui/OrderEntryAppearanceService.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.roots.ui;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ContentFolder;
+import com.intellij.openapi.roots.OrderEntry;
+import com.intellij.openapi.roots.libraries.Library;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class OrderEntryAppearanceService {
+ public static OrderEntryAppearanceService getInstance() {
+ return ServiceManager.getService(OrderEntryAppearanceService.class);
+ }
+
+ @NotNull
+ public abstract CellAppearanceEx forOrderEntry(Project project, @NotNull OrderEntry orderEntry, boolean selected);
+
+ @NotNull
+ public abstract CellAppearanceEx forLibrary(Project project, @NotNull Library library, boolean hasInvalidRoots);
+
+ @NotNull
+ public abstract CellAppearanceEx forJdk(@Nullable Sdk jdk, boolean isInComboBox, boolean selected, boolean showVersion);
+
+ @NotNull
+ public abstract CellAppearanceEx forContentFolder(@NotNull ContentFolder folder);
+
+ @NotNull
+ public abstract CellAppearanceEx forModule(@NotNull Module module);
+}
diff --git a/java/openapi/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactory.java b/java/openapi/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactory.java
new file mode 100644
index 0000000..35336c3
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.roots.ui.configuration;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.ModuleConfigurationEditor;
+
+public abstract class DefaultModuleConfigurationEditorFactory {
+
+ public abstract ModuleConfigurationEditor createModuleContentRootsEditor(ModuleConfigurationState state);
+
+ public abstract ModuleConfigurationEditor createClasspathEditor(ModuleConfigurationState state);
+
+ public abstract ModuleConfigurationEditor createOutputEditor(ModuleConfigurationState state);
+
+ public static DefaultModuleConfigurationEditorFactory getInstance() {
+ return ServiceManager.getService(DefaultModuleConfigurationEditorFactory.class);
+ }
+
+}
diff --git a/java/openapi/src/com/intellij/openapi/roots/ui/configuration/package.html b/java/openapi/src/com/intellij/openapi/roots/ui/configuration/package.html
new file mode 100644
index 0000000..e6d3b1d
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/ui/configuration/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for customizing the configuration interface for modules of specific types.
+</body></html>
diff --git a/java/openapi/src/com/intellij/openapi/ui/PackageChooser.java b/java/openapi/src/com/intellij/openapi/ui/PackageChooser.java
new file mode 100644
index 0000000..a0b0119
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/ui/PackageChooser.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.openapi.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiPackage;
+
+import java.util.List;
+
+/**
+ * @author ven
+ */
+public abstract class PackageChooser extends DialogWrapper {
+ public PackageChooser(Project project, boolean canBeParent) {
+ super(project, canBeParent);
+ }
+
+ public abstract PsiPackage getSelectedPackage();
+
+ public abstract List<PsiPackage> getSelectedPackages();
+
+ public abstract void selectPackage(String qualifiedName);
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiAnnotationPattern.java b/java/openapi/src/com/intellij/patterns/PsiAnnotationPattern.java
new file mode 100644
index 0000000..ddc7c69
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiAnnotationPattern.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.PsiAnnotation;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiAnnotationPattern extends PsiElementPattern<PsiAnnotation, PsiAnnotationPattern> {
+ protected PsiAnnotationPattern() {
+ super(PsiAnnotation.class);
+ }
+
+ public PsiAnnotationPattern qName(final ElementPattern<String> pattern) {
+ return with(new PatternCondition<PsiAnnotation>("qName") {
+ public boolean accepts(@NotNull final PsiAnnotation psiAnnotation, final ProcessingContext context) {
+ return pattern.getCondition().accepts(psiAnnotation.getQualifiedName(), context);
+ }
+ });
+ }
+ public PsiAnnotationPattern qName(@NonNls String qname) {
+ return qName(StandardPatterns.string().equalTo(qname));
+ }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiBinaryExpressionPattern.java b/java/openapi/src/com/intellij/patterns/PsiBinaryExpressionPattern.java
new file mode 100644
index 0000000..4a900d7
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiBinaryExpressionPattern.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.PsiBinaryExpression;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiBinaryExpressionPattern extends PsiExpressionPattern<PsiBinaryExpression, PsiBinaryExpressionPattern>{
+ protected PsiBinaryExpressionPattern() {
+ super(PsiBinaryExpression.class);
+ }
+
+ public PsiBinaryExpressionPattern left(@NotNull final ElementPattern pattern) {
+ return with(new PatternCondition<PsiBinaryExpression>("left") {
+ public boolean accepts(@NotNull final PsiBinaryExpression psiBinaryExpression, final ProcessingContext context) {
+ return pattern.getCondition().accepts(psiBinaryExpression.getLOperand(), context);
+ }
+ });
+ }
+
+ public PsiBinaryExpressionPattern right(@NotNull final ElementPattern pattern) {
+ return with(new PatternCondition<PsiBinaryExpression>("right") {
+ public boolean accepts(@NotNull final PsiBinaryExpression psiBinaryExpression, final ProcessingContext context) {
+ return pattern.getCondition().accepts(psiBinaryExpression.getROperand(), context);
+ }
+ });
+ }
+
+ public PsiBinaryExpressionPattern operation(final ElementPattern pattern) {
+ return with(new PatternCondition<PsiBinaryExpression>("operation") {
+ public boolean accepts(@NotNull final PsiBinaryExpression psiBinaryExpression, final ProcessingContext context) {
+ return pattern.getCondition().accepts(psiBinaryExpression.getOperationSign(), context);
+ }
+ });
+ }
+
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiClassPattern.java b/java/openapi/src/com/intellij/patterns/PsiClassPattern.java
new file mode 100644
index 0000000..d8933fd
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiClassPattern.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiClassPattern extends PsiMemberPattern<PsiClass, PsiClassPattern>{
+ protected PsiClassPattern() {
+ super(PsiClass.class);
+ }
+
+ public PsiClassPattern inheritorOf(final boolean strict, final PsiClassPattern pattern) {
+ return with(new PatternCondition<PsiClass>("inheritorOf") {
+ public boolean accepts(@NotNull PsiClass psiClass, final ProcessingContext context) {
+ return isInheritor(psiClass, pattern, context, !strict);
+ }
+ });
+ }
+
+ private static boolean isInheritor(PsiClass psiClass, ElementPattern pattern, final ProcessingContext matchingContext, boolean checkThisClass) {
+ if (psiClass == null) return false;
+ if (checkThisClass && pattern.getCondition().accepts(psiClass, matchingContext)) return true;
+ if (isInheritor(psiClass.getSuperClass(), pattern, matchingContext, true)) return true;
+ for (final PsiClass aClass : psiClass.getInterfaces()) {
+ if (isInheritor(aClass, pattern, matchingContext, true)) return true;
+ }
+ return false;
+ }
+
+ public PsiClassPattern inheritorOf(final boolean strict, final String className) {
+ return with(new PatternCondition<PsiClass>("inheritorOf") {
+ public boolean accepts(@NotNull PsiClass psiClass, final ProcessingContext context) {
+ return InheritanceUtil.isInheritor(psiClass, strict, className);
+ }
+ });
+ }
+
+ public PsiClassPattern isInterface() {
+ return with(new PatternCondition<PsiClass>("isInterface") {
+ public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+ return psiClass.isInterface();
+ }
+ });}
+ public PsiClassPattern isAnnotationType() {
+ return with(new PatternCondition<PsiClass>("isAnnotationType") {
+ public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+ return psiClass.isAnnotationType();
+ }
+ });}
+
+ public PsiClassPattern withMethod(final boolean checkDeep, final ElementPattern<? extends PsiMethod> memberPattern) {
+ return with(new PatternCondition<PsiClass>("withMethod") {
+ public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+ for (PsiMethod method : (checkDeep ? psiClass.getAllMethods() : psiClass.getMethods())) {
+ if (memberPattern.accepts(method, context)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+ }
+ public PsiClassPattern withField(final boolean checkDeep, final ElementPattern<? extends PsiField> memberPattern) {
+ return with(new PatternCondition<PsiClass>("withField") {
+ public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+ for (PsiField field : (checkDeep ? psiClass.getAllFields() : psiClass.getFields())) {
+ if (memberPattern.accepts(field, context)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+ }
+
+ public PsiClassPattern nonAnnotationType() {
+ return with(new PatternCondition<PsiClass>("nonAnnotationType") {
+ public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+ return !psiClass.isAnnotationType();
+ }
+ });
+ }
+
+ public PsiClassPattern withQualifiedName(@NonNls @NotNull final String qname) {
+ return with(new PatternCondition<PsiClass>("withQualifiedName") {
+ public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+ return qname.equals(psiClass.getQualifiedName());
+ }
+ });
+ }
+ public PsiClassPattern withQualifiedName(@NonNls @NotNull final ElementPattern<String> qname) {
+ return with(new PatternCondition<PsiClass>("withQualifiedName") {
+ public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+ return qname.accepts(psiClass.getQualifiedName(), context);
+ }
+ });
+ }
+
+
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiExpressionPattern.java b/java/openapi/src/com/intellij/patterns/PsiExpressionPattern.java
new file mode 100644
index 0000000..67b9cb0
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiExpressionPattern.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.*;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiExpressionPattern<T extends PsiExpression, Self extends PsiExpressionPattern<T,Self>> extends PsiJavaElementPattern<T,Self> {
+ protected PsiExpressionPattern(final Class<T> aClass) {
+ super(aClass);
+ }
+
+ public Self ofType(@NotNull final ElementPattern pattern) {
+ return with(new PatternCondition<T>("ofType") {
+ public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+ return pattern.getCondition().accepts(t.getType(), context);
+ }
+ });
+ }
+
+ public PsiMethodCallPattern methodCall(final ElementPattern<? extends PsiMethod> method) {
+ return new PsiMethodCallPattern().and(this).with(new PatternCondition<PsiMethodCallExpression>("methodCall") {
+ public boolean accepts(@NotNull PsiMethodCallExpression callExpression, ProcessingContext context) {
+ final JavaResolveResult[] results = callExpression.getMethodExpression().multiResolve(true);
+ for (JavaResolveResult result : results) {
+ if (method.getCondition().accepts(result.getElement(), context)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+ }
+
+ public Self skipParentheses(final ElementPattern<? extends PsiExpression> expressionPattern) {
+ return with(new PatternCondition<T>("skipParentheses") {
+ @Override
+ public boolean accepts(@NotNull T t, ProcessingContext context) {
+ PsiExpression expression = t;
+ while (expression instanceof PsiParenthesizedExpression) {
+ expression = ((PsiParenthesizedExpression)expression).getExpression();
+ }
+ return expressionPattern.accepts(expression, context);
+ }
+ });
+ }
+
+ public static class Capture<T extends PsiExpression> extends PsiExpressionPattern<T, Capture<T>> {
+ public Capture(final Class<T> aClass) {
+ super(aClass);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/patterns/PsiFieldPattern.java b/java/openapi/src/com/intellij/patterns/PsiFieldPattern.java
new file mode 100644
index 0000000..0b3d634
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiFieldPattern.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.PsiField;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+ */
+public class PsiFieldPattern extends PsiMemberPattern<PsiField, PsiFieldPattern>{
+ public PsiFieldPattern() {
+ super(new InitialPatternCondition<PsiField>(PsiField.class) {
+ public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
+ return o instanceof PsiField;
+ }
+ });
+ }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java b/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java
new file mode 100644
index 0000000..e91eb87
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.*;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiJavaElementPattern<T extends PsiElement,Self extends PsiJavaElementPattern<T,Self>> extends PsiElementPattern<T,Self> {
+ private static final @NonNls String VALUE = "value";
+
+ public PsiJavaElementPattern(final Class<T> aClass) {
+ super(aClass);
+ }
+
+ public PsiJavaElementPattern(@NotNull final InitialPatternCondition<T> condition) {
+ super(condition);
+ }
+
+ public Self annotationParam(@NonNls final String annotationQualifiedName, @NonNls final String parameterName) {
+ return annotationParam(StandardPatterns.string().equalTo(annotationQualifiedName), parameterName);
+ }
+
+ public Self annotationParam(@NonNls final String annotationQualifiedName) {
+ return annotationParam(annotationQualifiedName, VALUE);
+ }
+
+ public Self annotationParam(final ElementPattern<String> annotationQualifiedName, @NonNls final String parameterName) {
+ return withParent(
+ PsiJavaPatterns.psiNameValuePair().withName(parameterName).withParent(
+ PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(
+ PsiJavaPatterns.psiAnnotation().qName(annotationQualifiedName))));
+ }
+
+ public Self insideAnnotationParam(final ElementPattern<String> annotationQualifiedName, @NonNls final String parameterName) {
+ return inside(true,
+ PsiJavaPatterns.psiNameValuePair().withName(parameterName).withParent(
+ PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(
+ PsiJavaPatterns.psiAnnotation().qName(annotationQualifiedName))));
+ }
+
+ public Self insideAnnotationParam(final ElementPattern<String> annotationQualifiedName) {
+ return insideAnnotationParam(annotationQualifiedName, VALUE);
+ }
+
+ public Self nameIdentifierOf(final Class<? extends PsiMember> aClass) {
+ return nameIdentifierOf(PsiJavaPatterns.instanceOf(aClass));
+ }
+
+ public Self nameIdentifierOf(final ElementPattern<? extends PsiMember> pattern) {
+ return with(new PatternCondition<T>("nameIdentifierOf") {
+ public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+ if (!(t instanceof PsiIdentifier)) return false;
+
+ final PsiElement parent = t.getParent();
+ if (parent instanceof PsiClass && t != ((PsiClass) parent).getNameIdentifier()) return false;
+ if (parent instanceof PsiMethod && t != ((PsiMethod) parent).getNameIdentifier()) return false;
+ if (parent instanceof PsiVariable && t != ((PsiVariable) parent).getNameIdentifier()) return false;
+
+ return pattern.getCondition().accepts(parent, context);
+ }
+ });
+ }
+
+ public Self methodCallParameter(final int index, final ElementPattern<? extends PsiMethod> methodPattern) {
+ return with(new PatternCondition<T>("methodCallParameter") {
+ public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
+ final PsiElement parent = literal.getParent();
+ if (parent instanceof PsiExpressionList) {
+ final PsiExpressionList psiExpressionList = (PsiExpressionList)parent;
+ final PsiExpression[] psiExpressions = psiExpressionList.getExpressions();
+ if (!(psiExpressions.length > index && psiExpressions[index] == literal)) return false;
+
+ final PsiElement element = psiExpressionList.getParent();
+ if (element instanceof PsiMethodCallExpression) {
+ final JavaResolveResult[] results = ((PsiMethodCallExpression)element).getMethodExpression().multiResolve(false);
+ for (JavaResolveResult result : results) {
+ final PsiElement psiElement = result.getElement();
+ if (methodPattern.getCondition().accepts(psiElement, context)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ });
+ }
+
+ public Self constructorParameter(final int index, final String... fqns) {
+ return with(new PatternCondition<T>("methodCallParameter") {
+ public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
+ final PsiElement parent = literal.getParent();
+ if (parent instanceof PsiExpressionList) {
+ final PsiExpressionList psiExpressionList = (PsiExpressionList)parent;
+ final PsiExpression[] psiExpressions = psiExpressionList.getExpressions();
+ if (!(psiExpressions.length > index && psiExpressions[index] == literal)) return false;
+
+ final PsiElement element = psiExpressionList.getParent();
+ if (element instanceof PsiNewExpression) {
+ PsiJavaCodeReferenceElement reference = ((PsiNewExpression)element).getClassOrAnonymousClassReference();
+ if (reference != null) {
+ String qualifiedName = reference.getQualifiedName();
+ for (String fqn : fqns) {
+ if( fqn.equals(qualifiedName)) return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ });
+ }
+
+ public static class Capture<T extends PsiElement> extends PsiJavaElementPattern<T, Capture<T>> {
+ public Capture(final Class<T> aClass) {
+ super(aClass);
+ }
+
+ public Capture(@NotNull final InitialPatternCondition<T> condition) {
+ super(condition);
+ }
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/patterns/PsiJavaPatterns.java b/java/openapi/src/com/intellij/patterns/PsiJavaPatterns.java
new file mode 100644
index 0000000..3de211a
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiJavaPatterns.java
@@ -0,0 +1,181 @@
+/*
+ * 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.patterns;
+
+import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author peter
+ */
+public class PsiJavaPatterns extends StandardPatterns{
+
+ public static IElementTypePattern elementType() {
+ return PlatformPatterns.elementType();
+ }
+
+ public static VirtualFilePattern virtualFile() {
+ return PlatformPatterns.virtualFile();
+ }
+
+ public static PsiJavaElementPattern.Capture<PsiElement> psiElement() {
+ return new PsiJavaElementPattern.Capture<PsiElement>(PsiElement.class);
+ }
+
+ public static PsiJavaElementPattern.Capture<PsiElement> psiElement(IElementType type) {
+ return psiElement().withElementType(type);
+ }
+
+ public static <T extends PsiElement> PsiJavaElementPattern.Capture<T> psiElement(final Class<T> aClass) {
+ return new PsiJavaElementPattern.Capture<T>(aClass);
+ }
+
+ public static PsiJavaElementPattern.Capture<PsiElement> psiElement(final Class<? extends PsiElement>... classAlternatives) {
+ return new PsiJavaElementPattern.Capture<PsiElement>(new InitialPatternCondition<PsiElement>(PsiElement.class) {
+ @Override
+ public boolean accepts(@Nullable Object o, ProcessingContext context) {
+ for (Class<? extends PsiElement> classAlternative : classAlternatives) {
+ if (classAlternative.isInstance(o)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+ }
+
+ public static PsiJavaElementPattern.Capture<PsiLiteralExpression> literalExpression() {
+ return literalExpression(null);
+ }
+
+ public static PsiJavaElementPattern.Capture<PsiLiteral> psiLiteral() {
+ return psiLiteral(null);
+ }
+
+ public static PsiJavaElementPattern.Capture<PsiLiteral> psiLiteral(@Nullable final ElementPattern value) {
+ return new PsiJavaElementPattern.Capture<PsiLiteral>(new InitialPatternConditionPlus<PsiLiteral>(PsiLiteral.class) {
+ public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
+ return o instanceof PsiLiteral && (value == null || value.accepts(((PsiLiteral)o).getValue(), context));
+ }
+
+ @Override
+ public List<ElementPattern<?>> getPatterns() {
+ return Collections.<ElementPattern<?>>singletonList(value);
+ }
+ });
+ }
+
+ public static PsiJavaElementPattern.Capture<PsiNewExpression> psiNewExpression(@NotNull final String... fqns) {
+ return new PsiJavaElementPattern.Capture<PsiNewExpression>(new InitialPatternCondition<PsiNewExpression>(PsiNewExpression.class) {
+ public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
+ if(o instanceof PsiNewExpression) {
+ PsiJavaCodeReferenceElement reference = ((PsiNewExpression)o).getClassOrAnonymousClassReference();
+ if (reference != null) {
+ for (String fqn : fqns) {
+ if( fqn.equals(reference.getQualifiedName())) return true;
+ }
+ }
+ }
+ return false;
+ }
+ });
+ }
+
+ public static PsiJavaElementPattern.Capture<PsiLiteralExpression> literalExpression(@Nullable final ElementPattern value) {
+ return new PsiJavaElementPattern.Capture<PsiLiteralExpression>(new InitialPatternConditionPlus<PsiLiteralExpression>(PsiLiteralExpression.class) {
+ public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
+ return o instanceof PsiLiteralExpression && (value == null || value.accepts(((PsiLiteralExpression)o).getValue(), context));
+ }
+
+ @Override
+ public List<ElementPattern<?>> getPatterns() {
+ return Collections.<ElementPattern<?>>singletonList(value);
+ }
+ });
+ }
+
+ public static PsiMemberPattern.Capture psiMember() {
+ return new PsiMemberPattern.Capture();
+ }
+
+ public static PsiMethodPattern psiMethod() {
+ return new PsiMethodPattern();
+ }
+
+ public static PsiParameterPattern psiParameter() {
+ return new PsiParameterPattern();
+ }
+
+ public static PsiModifierListOwnerPattern.Capture<PsiModifierListOwner> psiModifierListOwner() {
+ return new PsiModifierListOwnerPattern.Capture<PsiModifierListOwner>(new InitialPatternCondition<PsiModifierListOwner>(PsiModifierListOwner.class) {
+ @Override
+ public boolean accepts(@Nullable Object o, ProcessingContext context) {
+ return o instanceof PsiModifierListOwner;
+ }
+ });
+ }
+
+
+ public static PsiFieldPattern psiField() {
+ return new PsiFieldPattern();
+ }
+
+ public static PsiClassPattern psiClass() {
+ return new PsiClassPattern();
+ }
+
+ public static PsiAnnotationPattern psiAnnotation() {
+ return new PsiAnnotationPattern();
+ }
+
+ public static PsiNameValuePairPattern psiNameValuePair() {
+ return new PsiNameValuePairPattern();
+ }
+
+ public static PsiTypePattern psiType() {
+ return new PsiTypePattern();
+ }
+
+ public static PsiExpressionPattern.Capture<PsiExpression> psiExpression() {
+ return new PsiExpressionPattern.Capture<PsiExpression>(PsiExpression.class);
+ }
+
+ public static PsiBinaryExpressionPattern psiBinaryExpression() {
+ return new PsiBinaryExpressionPattern();
+ }
+
+ public static PsiTypeCastExpressionPattern psiTypeCastExpression() {
+ return new PsiTypeCastExpressionPattern();
+ }
+
+ public static PsiJavaElementPattern.Capture<PsiReferenceExpression> psiReferenceExpression() {
+ return psiElement(PsiReferenceExpression.class);
+ }
+
+ public static PsiStatementPattern.Capture<PsiExpressionStatement> psiExpressionStatement() {
+ return new PsiStatementPattern.Capture<PsiExpressionStatement>(PsiExpressionStatement.class);
+ }
+
+ public static PsiStatementPattern.Capture<PsiReturnStatement> psiReturnStatement() {
+ return new PsiStatementPattern.Capture<PsiReturnStatement>(PsiReturnStatement.class);
+ }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiMemberPattern.java b/java/openapi/src/com/intellij/patterns/PsiMemberPattern.java
new file mode 100644
index 0000000..d6501d7
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiMemberPattern.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMember;
+import com.intellij.util.PairProcessor;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+ */
+public class PsiMemberPattern<T extends PsiMember, Self extends PsiMemberPattern<T,Self>> extends PsiModifierListOwnerPattern<T,Self> {
+ public PsiMemberPattern(@NotNull final InitialPatternCondition<T> condition) {
+ super(condition);
+ }
+
+ protected PsiMemberPattern(final Class<T> aClass) {
+ super(aClass);
+ }
+
+ public Self inClass(final @NonNls String qname) {
+ return inClass(PsiJavaPatterns.psiClass().withQualifiedName(qname));
+ }
+
+ public Self inClass(final ElementPattern pattern) {
+ return with(new PatternConditionPlus<T, PsiClass>("inClass", pattern) {
+ @Override
+ public boolean processValues(T t, ProcessingContext context, PairProcessor<PsiClass, ProcessingContext> processor) {
+ return processor.process(t.getContainingClass(), context);
+ }
+ });
+ }
+
+ public static class Capture extends PsiMemberPattern<PsiMember, Capture> {
+
+ protected Capture() {
+ super(new InitialPatternCondition<PsiMember>(PsiMember.class) {
+ public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
+ return o instanceof PsiMember;
+ }
+ });
+ }
+ }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiMethodCallPattern.java b/java/openapi/src/com/intellij/patterns/PsiMethodCallPattern.java
new file mode 100644
index 0000000..a649126
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiMethodCallPattern.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.PsiMethodCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class PsiMethodCallPattern extends PsiExpressionPattern<PsiMethodCallExpression, PsiMethodCallPattern> {
+ PsiMethodCallPattern() {
+ super(PsiMethodCallExpression.class);
+ }
+
+ public PsiMethodCallPattern withArguments(final ElementPattern<? extends PsiExpression>... arguments) {
+ return with(new PatternCondition<PsiMethodCallExpression>("withArguments") {
+ @Override
+ public boolean accepts(@NotNull PsiMethodCallExpression callExpression, ProcessingContext context) {
+ final PsiExpression[] actualArguments = callExpression.getArgumentList().getExpressions();
+ if (arguments.length != actualArguments.length) {
+ return false;
+ }
+ for (int i = 0; i < actualArguments.length; i++) {
+ if (!arguments[i].accepts(actualArguments[i], context)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ });
+ }
+
+ public PsiMethodCallPattern withQualifier(final ElementPattern<? extends PsiExpression> qualifier) {
+ return with(new PatternCondition<PsiMethodCallExpression>("withQualifier") {
+ @Override
+ public boolean accepts(@NotNull PsiMethodCallExpression psiMethodCallExpression, ProcessingContext context) {
+ return qualifier.accepts(psiMethodCallExpression.getMethodExpression().getQualifierExpression(), context);
+ }
+ });
+ }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiMethodPattern.java b/java/openapi/src/com/intellij/patterns/PsiMethodPattern.java
new file mode 100644
index 0000000..d4f6096
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiMethodPattern.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Ref;
+import com.intellij.psi.*;
+import com.intellij.psi.search.searches.SuperMethodsSearch;
+import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.PairProcessor;
+import com.intellij.util.ProcessingContext;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiMethodPattern extends PsiMemberPattern<PsiMethod,PsiMethodPattern> {
+ public PsiMethodPattern() {
+ super(PsiMethod.class);
+ }
+
+ public PsiMethodPattern withParameterCount(@NonNls final int paramCount) {
+ return with(new PatternCondition<PsiMethod>("withParameterCount") {
+ @Override
+ public boolean accepts(@NotNull final PsiMethod method, final ProcessingContext context) {
+ return method.getParameterList().getParametersCount() == paramCount;
+ }
+ });
+ }
+
+ /**
+ * Selects the corrected method by argument types
+ * @param inputTypes the array of FQN of the parameter types or wildcards.
+ * The special values are:<bl><li>"?" - means any type</li><li>".." - instructs pattern to accept the rest of the arguments</li></bl>
+ * @return
+ */
+ public PsiMethodPattern withParameters(@NonNls final String... inputTypes) {
+ final String[] types = inputTypes.length == 0 ? ArrayUtil.EMPTY_STRING_ARRAY : inputTypes;
+ return with(new PatternCondition<PsiMethod>("withParameters") {
+ @Override
+ public boolean accepts(@NotNull final PsiMethod psiMethod, final ProcessingContext context) {
+ final PsiParameterList parameterList = psiMethod.getParameterList();
+ int dotsIndex = -1;
+ while (++dotsIndex <types.length) {
+ if (Comparing.equal("..", types[dotsIndex])) break;
+ }
+
+ if (dotsIndex == types.length && parameterList.getParametersCount() != dotsIndex
+ || dotsIndex < types.length && parameterList.getParametersCount() < dotsIndex) {
+ return false;
+ }
+ if (dotsIndex > 0) {
+ final PsiParameter[] psiParameters = parameterList.getParameters();
+ for (int i = 0; i < dotsIndex; i++) {
+ if (!Comparing.equal("?", types[i]) && !typeEquivalent(psiParameters[i].getType(), types[i])) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean typeEquivalent(PsiType type, String expectedText) {
+ final PsiType erasure = TypeConversionUtil.erasure(type);
+ final String text;
+ if (erasure instanceof PsiEllipsisType && expectedText.endsWith("[]")) {
+ text = ((PsiEllipsisType)erasure).getComponentType().getCanonicalText() + "[]";
+ }
+ else if (erasure instanceof PsiArrayType && expectedText.endsWith("...")) {
+ text = ((PsiArrayType)erasure).getComponentType().getCanonicalText() +"...";
+ }
+ else {
+ text = erasure.getCanonicalText();
+ }
+ return expectedText.equals(text);
+ }
+ });
+ }
+
+ public PsiMethodPattern definedInClass(@NonNls final String qname) {
+ return definedInClass(PsiJavaPatterns.psiClass().withQualifiedName(qname));
+ }
+
+ public PsiMethodPattern definedInClass(final ElementPattern<? extends PsiClass> pattern) {
+ return with(new PatternConditionPlus<PsiMethod, PsiClass>("definedInClass", pattern) {
+
+ @Override
+ public boolean processValues(PsiMethod t, final ProcessingContext context, final PairProcessor<PsiClass, ProcessingContext> processor) {
+ if (!processor.process(t.getContainingClass(), context)) return false;
+ final Ref<Boolean> result = Ref.create(Boolean.TRUE);
+ SuperMethodsSearch.search(t, null, true, false).forEach(new Processor<MethodSignatureBackedByPsiMethod>() {
+ @Override
+ public boolean process(final MethodSignatureBackedByPsiMethod signature) {
+ if (!processor.process(signature.getMethod().getContainingClass(), context)) {
+ result.set(Boolean.FALSE);
+ return false;
+ }
+ return true;
+ }
+ });
+ return result.get();
+ }
+ });
+ }
+
+ public PsiMethodPattern constructor(final boolean isConstructor) {
+ return with(new PatternCondition<PsiMethod>("constructor") {
+ @Override
+ public boolean accepts(@NotNull final PsiMethod method, final ProcessingContext context) {
+ return method.isConstructor() == isConstructor;
+ }
+ });
+ }
+
+
+ public PsiMethodPattern withThrowsList(final ElementPattern<?> pattern) {
+ return with(new PatternCondition<PsiMethod>("withThrowsList") {
+ @Override
+ public boolean accepts(@NotNull final PsiMethod method, final ProcessingContext context) {
+ return pattern.accepts(method.getThrowsList());
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/patterns/PsiModifierListOwnerPattern.java b/java/openapi/src/com/intellij/patterns/PsiModifierListOwnerPattern.java
new file mode 100644
index 0000000..4fd3ae1
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiModifierListOwnerPattern.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.PsiModifierList;
+import com.intellij.psi.PsiModifierListOwner;
+import com.intellij.util.ProcessingContext;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.codeInsight.AnnotationUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiModifierListOwnerPattern<T extends PsiModifierListOwner, Self extends PsiModifierListOwnerPattern<T,Self>> extends PsiElementPattern<T,Self> {
+ public PsiModifierListOwnerPattern(@NotNull final InitialPatternCondition<T> condition) {
+ super(condition);
+ }
+
+ protected PsiModifierListOwnerPattern(final Class<T> aClass) {
+ super(aClass);
+ }
+
+ public Self withModifiers(final String... modifiers) {
+ return with(new PatternCondition<T>("withModifiers") {
+ public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+ return ContainerUtil.and(modifiers, new Condition<String>() {
+ public boolean value(final String s) {
+ return t.hasModifierProperty(s);
+ }
+ });
+ }
+ });
+ }
+
+ public Self withoutModifiers(final String... modifiers) {
+ return with(new PatternCondition<T>("withoutModifiers") {
+ public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+ return ContainerUtil.and(modifiers, new Condition<String>() {
+ public boolean value(final String s) {
+ return !t.hasModifierProperty(s);
+ }
+ });
+ }
+ });
+ }
+
+ public Self withAnnotation(@NonNls final String qualifiedName) {
+ return with(new PatternCondition<T>("withAnnotation") {
+ public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+ final PsiModifierList modifierList = t.getModifierList();
+ return modifierList != null && modifierList.findAnnotation(qualifiedName) != null;
+ }
+ });
+ }
+
+ public Self withAnnotations(@NonNls final String... qualifiedNames) {
+ return with(new PatternCondition<T>("withAnnotations") {
+ public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+ return AnnotationUtil.findAnnotation(t, qualifiedNames) != null;
+ }
+ });
+ }
+
+ public static class Capture<T extends PsiModifierListOwner> extends PsiModifierListOwnerPattern<T, Capture<T>> {
+ public Capture(@NotNull InitialPatternCondition<T> condition) {
+ super(condition);
+ }
+ }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiNameValuePairPattern.java b/java/openapi/src/com/intellij/patterns/PsiNameValuePairPattern.java
new file mode 100644
index 0000000..9612c87
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiNameValuePairPattern.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.PsiNameValuePair;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiNameValuePairPattern extends PsiElementPattern<PsiNameValuePair, PsiNameValuePairPattern> {
+ protected PsiNameValuePairPattern() {
+ super(PsiNameValuePair.class);
+ }
+
+ public PsiNameValuePairPattern withName(@NotNull @NonNls final String requiredName) {
+ return with(new PatternCondition<PsiNameValuePair>("withName") {
+ public boolean accepts(@NotNull final PsiNameValuePair psiNameValuePair, final ProcessingContext context) {
+ String actualName = psiNameValuePair.getName();
+ return requiredName.equals(actualName) || actualName == null && "value".equals(requiredName);
+ }
+ });
+ }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiParameterPattern.java b/java/openapi/src/com/intellij/patterns/PsiParameterPattern.java
new file mode 100644
index 0000000..e6f0cca
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiParameterPattern.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiParameter;
+import com.intellij.util.PairProcessor;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Gregory Shrago
+ */
+public class PsiParameterPattern extends PsiModifierListOwnerPattern<PsiParameter, PsiParameterPattern> {
+
+ protected PsiParameterPattern() {
+ super(PsiParameter.class);
+ }
+
+ public PsiParameterPattern ofMethod(final int index, final ElementPattern pattern) {
+ return with(new PatternConditionPlus<PsiParameter, PsiMethod>("ofMethod", pattern) {
+ @Override
+ public boolean processValues(PsiParameter t,
+ ProcessingContext context,
+ PairProcessor<PsiMethod, ProcessingContext> processor) {
+ PsiElement scope = t.getDeclarationScope();
+ if (!(scope instanceof PsiMethod)) return true;
+ return processor.process((PsiMethod)scope, context);
+ }
+
+ public boolean accepts(@NotNull final PsiParameter t, final ProcessingContext context) {
+ if (!super.accepts(t, context)) return false;
+ final PsiMethod psiMethod = (PsiMethod)t.getDeclarationScope();
+
+ final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
+ if (index < 0 || index >= parameters.length || !t.equals(parameters[index])) return false;
+ return true;
+ }
+ });
+ }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiStatementPattern.java b/java/openapi/src/com/intellij/patterns/PsiStatementPattern.java
new file mode 100644
index 0000000..aa1db7e
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiStatementPattern.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiStatement;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author nik
+ */
+public class PsiStatementPattern<T extends PsiStatement, Self extends PsiStatementPattern<T, Self>> extends PsiJavaElementPattern<T, Self>{
+ public PsiStatementPattern(final Class<T> aClass) {
+ super(aClass);
+ }
+
+ public Self insideMethod(final PsiMethodPattern pattern) {
+ return with(new PatternCondition<T>("insideMethod") {
+ public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+ PsiMethod method = PsiTreeUtil.getParentOfType(t, PsiMethod.class, false, PsiMember.class);
+ return method != null && pattern.accepts(method, context);
+ }
+ });
+ }
+
+ public Self insideMethod(StringPattern methodName, String qualifiedClassName) {
+ return insideMethod(PsiJavaPatterns.psiMethod().withName(methodName).definedInClass(qualifiedClassName));
+ }
+
+ public Self insideMethod(@NotNull @NonNls String methodName, @NotNull @NonNls String qualifiedClassName) {
+ return insideMethod(StandardPatterns.string().equalTo(methodName), qualifiedClassName);
+ }
+
+ public static class Capture<T extends PsiStatement> extends PsiStatementPattern<T, Capture<T>> {
+ public Capture(final Class<T> aClass) {
+ super(aClass);
+ }
+
+ }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiTypeCastExpressionPattern.java b/java/openapi/src/com/intellij/patterns/PsiTypeCastExpressionPattern.java
new file mode 100644
index 0000000..b119409
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiTypeCastExpressionPattern.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiTypeCastExpression;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class PsiTypeCastExpressionPattern extends PsiExpressionPattern<PsiTypeCastExpression, PsiTypeCastExpressionPattern> {
+ PsiTypeCastExpressionPattern() {
+ super(PsiTypeCastExpression.class);
+ }
+
+ public PsiTypeCastExpressionPattern withOperand(final ElementPattern<? extends PsiExpression> operand) {
+ return with(new PatternCondition<PsiTypeCastExpression>("withOperand") {
+ @Override
+ public boolean accepts(@NotNull PsiTypeCastExpression psiTypeCastExpression, ProcessingContext context) {
+ return operand.accepts(psiTypeCastExpression.getOperand(), context);
+ }
+ });
+ }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiTypePattern.java b/java/openapi/src/com/intellij/patterns/PsiTypePattern.java
new file mode 100644
index 0000000..b7d8e1b
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiTypePattern.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2009 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.patterns;
+
+import com.intellij.psi.PsiArrayType;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassType;
+import com.intellij.psi.PsiType;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiTypePattern extends ObjectPattern<PsiType,PsiTypePattern> {
+ protected PsiTypePattern() {
+ super(PsiType.class);
+ }
+
+ public PsiTypePattern arrayOf(final ElementPattern pattern) {
+ return with(new PatternCondition<PsiType>("arrayOf") {
+ public boolean accepts(@NotNull final PsiType psiType, final ProcessingContext context) {
+ return psiType instanceof PsiArrayType &&
+ pattern.getCondition().accepts(((PsiArrayType)psiType).getComponentType(), context);
+ }
+ });
+ }
+
+ public PsiTypePattern classType(final ElementPattern<? extends PsiClass> pattern) {
+ return with(new PatternCondition<PsiType>("classType") {
+ public boolean accepts(@NotNull final PsiType psiType, final ProcessingContext context) {
+ return psiType instanceof PsiClassType &&
+ pattern.getCondition().accepts(((PsiClassType)psiType).resolve(), context);
+ }
+ });
+ }
+}
diff --git a/java/openapi/src/com/intellij/peer/PeerFactory.java b/java/openapi/src/com/intellij/peer/PeerFactory.java
new file mode 100644
index 0000000..2f55b27
--- /dev/null
+++ b/java/openapi/src/com/intellij/peer/PeerFactory.java
@@ -0,0 +1,83 @@
+/*
+ * 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.peer;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.Language;
+import com.intellij.lang.PsiBuilder;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.diff.DiffRequestFactory;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.highlighter.EditorHighlighter;
+import com.intellij.openapi.fileChooser.FileSystemTreeFactory;
+import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.module.ModuleConfigurationEditor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkType;
+import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState;
+import com.intellij.openapi.ui.DialogWrapperPeerFactory;
+import com.intellij.openapi.vcs.FileStatusFactory;
+import com.intellij.openapi.vcs.actions.VcsContextFactory;
+import com.intellij.psi.search.scope.packageSet.PackageSetFactory;
+import com.intellij.ui.UIHelper;
+import com.intellij.ui.content.ContentFactory;
+import com.intellij.ui.errorView.ErrorViewFactory;
+import org.apache.xmlrpc.WebServer;
+import org.apache.xmlrpc.XmlRpcServer;
+
+import java.net.InetAddress;
+
+/** @deprecated to remove in IDEA 13 */
+@SuppressWarnings({"UnusedDeclaration", "deprecation"})
+public abstract class PeerFactory {
+ public static PeerFactory getInstance() {
+ return ServiceManager.getService(PeerFactory.class);
+ }
+
+ public abstract FileStatusFactory getFileStatusFactory();
+
+ public abstract DialogWrapperPeerFactory getDialogWrapperPeerFactory();
+
+ public abstract PackageSetFactory getPackageSetFactory();
+
+ public abstract UIHelper getUIHelper();
+
+ public abstract ErrorViewFactory getErrorViewFactory();
+
+ public abstract ContentFactory getContentFactory();
+
+ public abstract FileSystemTreeFactory getFileSystemTreeFactory();
+
+ public abstract DiffRequestFactory getDiffRequestFactory();
+
+ public abstract VcsContextFactory getVcsContextFactory();
+
+ public abstract PsiBuilder createBuilder(ASTNode tree, Language lang, CharSequence seq, final Project project);
+
+ public abstract PsiBuilder createBuilder(ASTNode tree, Lexer lexer, Language lang, CharSequence seq, final Project project);
+
+ public abstract XmlRpcServer createRpcServer();
+
+ public abstract WebServer createWebServer(int port, InetAddress addr, XmlRpcServer xmlRpc);
+
+ public abstract EditorHighlighter createEditorHighlighter(SyntaxHighlighter syntaxHighlighter, EditorColorsScheme colors);
+
+ public abstract Sdk createProjectJdk(String name, final String version, final String homePath, SdkType sdkType);
+
+ public abstract ModuleConfigurationEditor createModuleConfigurationEditor(String moduleName, ModuleConfigurationState state);
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/peer/package.html b/java/openapi/src/com/intellij/peer/package.html
new file mode 100644
index 0000000..604a8db
--- /dev/null
+++ b/java/openapi/src/com/intellij/peer/package.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for creating internal IDEA implementations of components defined by
+abstract interfaces.
+</body></html>
diff --git a/java/openapi/src/com/intellij/pom/java/PomJavaAspect.java b/java/openapi/src/com/intellij/pom/java/PomJavaAspect.java
new file mode 100644
index 0000000..36e5eaf
--- /dev/null
+++ b/java/openapi/src/com/intellij/pom/java/PomJavaAspect.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2009 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.pom.java;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.pom.PomModel;
+import com.intellij.pom.PomModelAspect;
+
+public abstract class PomJavaAspect implements PomModelAspect {
+ public static PomJavaAspect getInstance(Project project) {
+ return project.getComponent(PomJavaAspect.class);
+ }
+
+ public static PomJavaAspect getInstance(PomModel model) {
+ return model.getModelAspect(PomJavaAspect.class);
+ }
+
+ public abstract LanguageLevel getLanguageLevel();
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java b/java/openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java
new file mode 100644
index 0000000..3ae8f6e
--- /dev/null
+++ b/java/openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 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.pom.java.events;
+
+import com.intellij.pom.PomModel;
+import com.intellij.pom.PomModelAspect;
+import com.intellij.pom.event.PomChangeSet;
+import com.intellij.pom.java.PomJavaAspect;
+import org.jetbrains.annotations.NotNull;
+
+public class PomJavaAspectChangeSet implements PomChangeSet{
+ private final PomModel myModel;
+
+ public PomJavaAspectChangeSet(PomModel model) {
+ myModel = model;
+ }
+
+ @NotNull
+ public PomModelAspect getAspect() {
+ return myModel.getModelAspect(PomJavaAspect.class);
+ }
+
+ public void merge(@NotNull PomChangeSet blocked) {
+ }
+}
diff --git a/java/openapi/src/com/intellij/pom/java/events/PomJavaChange.java b/java/openapi/src/com/intellij/pom/java/events/PomJavaChange.java
new file mode 100644
index 0000000..87a8a1e
--- /dev/null
+++ b/java/openapi/src/com/intellij/pom/java/events/PomJavaChange.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2009 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.pom.java.events;
+
+/**
+ * @author peter
+ */
+public interface PomJavaChange {
+}
diff --git a/java/openapi/src/com/intellij/pom/java/package.html b/java/openapi/src/com/intellij/pom/java/package.html
new file mode 100644
index 0000000..6d18672
--- /dev/null
+++ b/java/openapi/src/com/intellij/pom/java/package.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+The POM API is unfinished, undocumented, does not allow to perform any tasks for which no other
+APIs exist, and thus should not be used.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/CommonReferenceProviderTypes.java b/java/openapi/src/com/intellij/psi/CommonReferenceProviderTypes.java
new file mode 100644
index 0000000..3710d5a
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/CommonReferenceProviderTypes.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2009 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.psi;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+
+/**
+ * @author peter
+ */
+public abstract class CommonReferenceProviderTypes {
+
+ /**
+ * @deprecated
+ * @see #getInstance()
+ */
+ public static CommonReferenceProviderTypes getInstance(final Project project) {
+ return getInstance();
+ }
+
+ public static CommonReferenceProviderTypes getInstance() {
+ return ServiceManager.getService(CommonReferenceProviderTypes.class);
+ }
+
+ public static final ReferenceProviderType PROPERTIES_FILE_KEY_PROVIDER = new ReferenceProviderType("Properties File Key Provider");
+ public static final ReferenceProviderType URI_PROVIDER = new ReferenceProviderType("Uri references provider");
+ public static final ReferenceProviderType SCHEMA_PROVIDER = new ReferenceProviderType("Schema references provider");
+
+ public abstract PsiReferenceProvider getClassReferenceProvider();
+}
diff --git a/java/openapi/src/com/intellij/psi/JavaCodeFragmentFactory.java b/java/openapi/src/com/intellij/psi/JavaCodeFragmentFactory.java
new file mode 100644
index 0000000..eefda40
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/JavaCodeFragmentFactory.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import org.intellij.lang.annotations.MagicConstant;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class JavaCodeFragmentFactory {
+ public static JavaCodeFragmentFactory getInstance(Project project) {
+ return ServiceManager.getService(project, JavaCodeFragmentFactory.class);
+ }
+
+ /**
+ * Creates a Java expression code fragment from the text of the expression.
+ *
+ * @param text the text of the expression to create.
+ * @param context the context for resolving references from the code fragment.
+ * @param expectedType expected type of the expression (does not have any effect on creation
+ * but can be accessed as {@link PsiExpressionCodeFragment#getExpectedType()}).
+ * @param isPhysical whether the code fragment is created as a physical element
+ * (see {@link PsiElement#isPhysical()}).
+ * @return the created code fragment.
+ */
+ @NotNull
+ public abstract PsiExpressionCodeFragment createExpressionCodeFragment(@NotNull String text,
+ @Nullable PsiElement context,
+ @Nullable final PsiType expectedType,
+ boolean isPhysical);
+
+ /**
+ * Creates a Java code fragment from the text of a Java code block.
+ *
+ * @param text the text of the code block to create.
+ * @param context the context for resolving references from the code fragment.
+ * @param isPhysical whether the code fragment is created as a physical element
+ * (see {@link PsiElement#isPhysical()}).
+ * @return the created code fragment.
+ */
+ @NotNull
+ public abstract JavaCodeFragment createCodeBlockCodeFragment(@NotNull String text, @Nullable PsiElement context, boolean isPhysical);
+
+ /**
+ * Flag for {@linkplain #createTypeCodeFragment(String, PsiElement, boolean, int)} - allows void type.
+ */
+ public static final int ALLOW_VOID = 0x01;
+ /**
+ * Flag for {@linkplain #createTypeCodeFragment(String, PsiElement, boolean, int)} - allows type with ellipsis.
+ */
+ public static final int ALLOW_ELLIPSIS = 0x02;
+ /**
+ * Flag for {@linkplain #createTypeCodeFragment(String, PsiElement, boolean, int)} - allows disjunctive type.
+ */
+ public static final int ALLOW_DISJUNCTION = 0x04;
+
+ /**
+ * Creates a Java type code fragment from the text of the name of a Java type (the name
+ * of a primitive type, array type or class), with <code>void</code> and ellipsis
+ * not treated as a valid type.
+ *
+ * @param text the text of the Java type to create.
+ * @param context the context for resolving references from the code fragment.
+ * @param isPhysical whether the code fragment is created as a physical element
+ * (see {@link PsiElement#isPhysical()}).
+ * @return the created code fragment.
+ */
+ @NotNull
+ public abstract PsiTypeCodeFragment createTypeCodeFragment(@NotNull String text, @Nullable PsiElement context, boolean isPhysical);
+
+ /**
+ * Creates a Java type code fragment from the text of the name of a Java type (the name
+ * of a primitive type, array type or class).<br>
+ * {@code void}, ellipsis and disjunctive types are optionally treated as valid ones.
+ *
+ * @param text the text of the Java type to create.
+ * @param context the context for resolving references from the code fragment.
+ * @param isPhysical whether the code fragment is created as a physical element
+ * (see {@link PsiElement#isPhysical()}).
+ * @param flags types allowed to present in text.
+ * @return the created code fragment.
+ */
+ @NotNull
+ public abstract PsiTypeCodeFragment createTypeCodeFragment(@NotNull String text,
+ @Nullable PsiElement context,
+ boolean isPhysical,
+ @MagicConstant(flags = {ALLOW_VOID, ALLOW_ELLIPSIS, ALLOW_DISJUNCTION}) int flags);
+
+ /**
+ * Creates a Java reference code fragment from the text of a Java reference to a
+ * package or class.
+ *
+ * @param text the text of the reference to create.
+ * @param context the context for resolving the reference.
+ * @param isPhysical whether the code fragment is created as a physical element
+ * (see {@link PsiElement#isPhysical()}).
+ * @param isClassesAccepted if true then classes as well as packages are accepted as
+ * reference target, otherwise only packages are
+ * @return the created reference fragment.
+ */
+ @NotNull
+ public abstract PsiJavaCodeReferenceCodeFragment createReferenceCodeFragment(@NotNull String text,
+ @Nullable PsiElement context,
+ boolean isPhysical,
+ boolean isClassesAccepted);
+
+}
diff --git a/java/openapi/src/com/intellij/psi/LanguageAnnotationSupport.java b/java/openapi/src/com/intellij/psi/LanguageAnnotationSupport.java
new file mode 100644
index 0000000..71389fb
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/LanguageAnnotationSupport.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2009 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.psi;
+
+import com.intellij.lang.LanguageExtension;
+
+/**
+ * @author Serega.Vasiliev
+ */
+public class LanguageAnnotationSupport extends LanguageExtension<PsiAnnotationSupport> {
+ public static final LanguageAnnotationSupport INSTANCE = new LanguageAnnotationSupport();
+
+ private LanguageAnnotationSupport() {
+ super("com.intellij.annotationSupport");
+ }
+}
diff --git a/java/openapi/src/com/intellij/psi/SmartTypePointer.java b/java/openapi/src/com/intellij/psi/SmartTypePointer.java
new file mode 100644
index 0000000..43556c8
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/SmartTypePointer.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2009 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.psi;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author dsl
+ */
+public interface SmartTypePointer {
+ @Nullable
+ PsiType getType();
+}
diff --git a/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java b/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java
new file mode 100644
index 0000000..2624506
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class SmartTypePointerManager {
+ public static SmartTypePointerManager getInstance(Project project) {
+ return ServiceManager.getService(project, SmartTypePointerManager.class);
+ }
+
+ @NotNull
+ public abstract SmartTypePointer createSmartTypePointer(@NotNull PsiType type);
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/infos/CandidatesGroup.java b/java/openapi/src/com/intellij/psi/infos/CandidatesGroup.java
new file mode 100644
index 0000000..1a91db0
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/infos/CandidatesGroup.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2009 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.psi.infos;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: ik
+ * Date: 10.06.2003
+ * Time: 13:37:39
+ * To change this template use Options | File Templates.
+ */
+public class CandidatesGroup {
+ public static final int UNKNOWN = -1;
+ public static final int CONFLICT = 0;
+
+ private List myCandidates = new ArrayList();
+ private int myCause = UNKNOWN;
+
+ public CandidateInfo get(int index){
+ return (CandidateInfo) myCandidates.get(index);
+ }
+
+ public int size(){
+ return myCandidates.size();
+ }
+
+ public Iterator iterator(){
+ return myCandidates.iterator();
+ }
+
+ public int getCause(){
+ return myCause;
+ }
+
+ public CandidatesGroup(List candidates, int cause){
+ myCandidates = candidates;
+ myCause = cause;
+ }
+
+ public CandidatesGroup(int cause){
+ myCause = cause;
+ }
+
+ public CandidatesGroup(){}
+
+ public void add(CandidateInfo candidate){
+ myCandidates.add(candidate);
+ }
+}
diff --git a/java/openapi/src/com/intellij/psi/infos/package.html b/java/openapi/src/com/intellij/psi/infos/package.html
new file mode 100644
index 0000000..8983870
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/infos/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides classes which represent possible completion variants in completion lists.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/javadoc/JavadocManager.java b/java/openapi/src/com/intellij/psi/javadoc/JavadocManager.java
new file mode 100644
index 0000000..0790306
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/javadoc/JavadocManager.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2009 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.psi.javadoc;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author mike
+ */
+public interface JavadocManager {
+ class SERVICE {
+ private SERVICE() {
+ }
+
+ public static JavadocManager getInstance(Project project) {
+ return ServiceManager.getService(project, JavadocManager.class);
+ }
+ }
+
+ @NotNull
+ JavadocTagInfo[] getTagInfos(PsiElement context);
+
+ @Nullable
+ JavadocTagInfo getTagInfo(String name);
+}
diff --git a/java/openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java b/java/openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java
new file mode 100644
index 0000000..7435213
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.javadoc;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author mike
+ */
+public interface JavadocTagInfo {
+ ExtensionPointName<JavadocTagInfo> EP_NAME = ExtensionPointName.create("com.intellij.javadocTagInfo");
+
+ @NonNls String getName();
+ boolean isInline();
+
+ boolean isValidInContext(PsiElement element);
+
+ Object[] getPossibleValues(PsiElement context, PsiElement place, String prefix);
+
+ /**
+ * Checks the tag value for correctness.
+ *
+ * @param value Doc tag to check.
+ * @return Returns null if correct, error message otherwise.
+ */
+ @Nullable
+ String checkTagValue(PsiDocTagValue value);
+
+ @Nullable
+ PsiReference getReference(PsiDocTagValue value);
+}
diff --git a/java/openapi/src/com/intellij/psi/javadoc/package.html b/java/openapi/src/com/intellij/psi/javadoc/package.html
new file mode 100644
index 0000000..d56bfa4
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/javadoc/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides the PSI structure for Javadoc comments and services for registering custom Javadoc tags.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/package.html b/java/openapi/src/com/intellij/psi/package.html
new file mode 100644
index 0000000..52dff27
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/package.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for working with the Program Source Interface (IDEA's internal representation
+of the program structure).
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/ref/AnnotationAttributeChildLink.java b/java/openapi/src/com/intellij/psi/ref/AnnotationAttributeChildLink.java
new file mode 100644
index 0000000..a65ebb3
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/ref/AnnotationAttributeChildLink.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2000-2009 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.psi.ref;
+
+import com.intellij.psi.*;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ObjectUtils;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+*/
+public class AnnotationAttributeChildLink extends PsiChildLink<PsiAnnotation, PsiAnnotationMemberValue> {
+ private final String myAttributeName;
+
+ public AnnotationAttributeChildLink(@NotNull @NonNls String attributeName) {
+ myAttributeName = attributeName;
+ }
+
+ @NotNull
+ public String getAttributeName() {
+ return myAttributeName;
+ }
+
+ @Override
+ public PsiAnnotationMemberValue findLinkedChild(@Nullable PsiAnnotation psiAnnotation) {
+ if (psiAnnotation == null) return null;
+
+ psiAnnotation.getText();
+ return psiAnnotation.findDeclaredAttributeValue(myAttributeName);
+ }
+
+ @Override
+ @NotNull
+ public PsiAnnotationMemberValue createChild(@NotNull PsiAnnotation psiAnnotation) throws IncorrectOperationException {
+ psiAnnotation.getText();
+ final PsiExpression nullValue = JavaPsiFacade.getElementFactory(psiAnnotation.getProject()).createExpressionFromText(PsiKeyword.NULL, null);
+ psiAnnotation.setDeclaredAttributeValue(myAttributeName, nullValue);
+ return ObjectUtils.assertNotNull(psiAnnotation.findDeclaredAttributeValue(myAttributeName));
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final AnnotationAttributeChildLink link = (AnnotationAttributeChildLink)o;
+
+ if (!myAttributeName.equals(link.myAttributeName)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return myAttributeName.hashCode();
+ }
+}
diff --git a/java/openapi/src/com/intellij/psi/ref/AnnotationChildLink.java b/java/openapi/src/com/intellij/psi/ref/AnnotationChildLink.java
new file mode 100644
index 0000000..f4b6e17
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/ref/AnnotationChildLink.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2009 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.psi.ref;
+
+import com.intellij.psi.*;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author peter
+ */
+public class AnnotationChildLink extends PsiChildLink<PsiModifierListOwner, PsiAnnotation> {
+ private final String myAnnoFqn;
+
+ public AnnotationChildLink(String fqn) {
+ myAnnoFqn = fqn;
+ }
+
+ public String getAnnotationQualifiedName() {
+ return myAnnoFqn;
+ }
+
+ public static PsiElementRef<PsiAnnotation> createRef(@NotNull PsiModifierListOwner parent, @NonNls String fqn) {
+ return new AnnotationChildLink(fqn).createChildRef(parent);
+ }
+
+ @Override
+ public PsiAnnotation findLinkedChild(@Nullable PsiModifierListOwner member) {
+ if (member == null) return null;
+
+ final PsiModifierList modifierList = member.getModifierList();
+ return modifierList != null ? modifierList.findAnnotation(myAnnoFqn) : null;
+ }
+
+ @Override
+ @NotNull
+ public PsiAnnotation createChild(@NotNull PsiModifierListOwner member) throws IncorrectOperationException {
+ final PsiModifierList modifierList = member.getModifierList();
+ assert modifierList != null;
+ return modifierList.addAnnotation(myAnnoFqn);
+ }
+
+ @Override
+ public String toString() {
+ return "AnnotationChildLink{" + "myAnnoFqn='" + myAnnoFqn + '\'' + '}';
+ }
+}
diff --git a/java/openapi/src/com/intellij/psi/ref/InstanceofLink.java b/java/openapi/src/com/intellij/psi/ref/InstanceofLink.java
new file mode 100644
index 0000000..921c6a0
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/ref/InstanceofLink.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2009 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.psi.ref;
+
+import com.intellij.psi.PsiChildLink;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class InstanceofLink<Parent extends PsiElement, Child extends PsiElement, CastTo extends Child> extends PsiChildLink<Parent, CastTo> {
+ private final PsiChildLink<Parent, Child> myDelegate;
+ private final Class<CastTo> myCastTo;
+
+ private InstanceofLink(PsiChildLink<Parent, Child> delegate, Class<CastTo> castTo) {
+ myDelegate = delegate;
+ myCastTo = castTo;
+ }
+
+ @Override
+ public CastTo findLinkedChild(@Nullable Parent parent) {
+ final Child existing = myDelegate.findLinkedChild(parent);
+ return myCastTo.isInstance(existing) ? (CastTo) existing : null;
+ }
+
+ @Override
+ @NotNull
+ public CastTo createChild(@NotNull Parent parent) throws IncorrectOperationException {
+ return (CastTo) myDelegate.createChild(parent);
+ }
+
+ public static <Parent extends PsiElement, Child extends PsiElement, CastTo extends Child> InstanceofLink<Parent, Child, CastTo> create(
+ PsiChildLink<Parent, Child> delegate, Class<CastTo> castTo) {
+ return new InstanceofLink<Parent, Child, CastTo>(delegate, castTo);
+ }
+}
diff --git a/java/openapi/src/com/intellij/psi/search/package.html b/java/openapi/src/com/intellij/psi/search/package.html
new file mode 100644
index 0000000..c4b46c1
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/package.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for searching references to elements, searching for classes and symbols by name,
+searching for TODO items and defining scope of searches.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java b/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java
new file mode 100644
index 0000000..fa8b3fa
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2000-2009 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.psi.search.scope.packageSet;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.problems.WolfTheProblemSolver;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.List;
+import java.util.regex.Pattern;
+
+public class PatternPackageSet extends PatternBasedPackageSet {
+ @NonNls public static final String SCOPE_TEST = "test";
+ @NonNls public static final String SCOPE_SOURCE = "src";
+ @NonNls public static final String SCOPE_LIBRARY = "lib";
+ @NonNls public static final String SCOPE_PROBLEM = "problem";
+ public static final String SCOPE_ANY = "";
+
+ private final Pattern myPattern;
+ private final Pattern myModulePattern;
+ private final Pattern myModuleGroupPattern;
+ private final String myAspectJSyntaxPattern;
+ private final String myScope;
+ private final String myModulePatternText;
+
+ public PatternPackageSet(@NonNls @Nullable String aspectPattern,
+ @NotNull String scope,
+ @NonNls String modulePattern) {
+ myAspectJSyntaxPattern = aspectPattern;
+ myScope = scope;
+ myModulePatternText = modulePattern;
+ Pattern mmgp = null;
+ Pattern mmp = null;
+ if (modulePattern == null || modulePattern.length() == 0) {
+ mmp = null;
+ }
+ else {
+ if (modulePattern.startsWith("group:")) {
+ int idx = modulePattern.indexOf(':', 6);
+ if (idx == -1) idx = modulePattern.length();
+ mmgp = Pattern.compile(StringUtil.replace(modulePattern.substring(6, idx), "*", ".*"));
+ if (idx < modulePattern.length() - 1) {
+ mmp = Pattern.compile(StringUtil.replace(modulePattern.substring(idx + 1), "*", ".*"));
+ }
+ } else {
+ mmp = Pattern.compile(StringUtil.replace(modulePattern, "*", ".*"));
+ }
+ }
+ myModulePattern = mmp;
+ myModuleGroupPattern = mmgp;
+ myPattern = aspectPattern != null ? Pattern.compile(FilePatternPackageSet.convertToRegexp(aspectPattern, '.')) : null;
+ }
+
+ @Override
+ public boolean contains(VirtualFile file, NamedScopesHolder holder) {
+ Project project = holder.getProject();
+ ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+ return matchesScope(file, holder.getProject(), fileIndex) && (myPattern == null || myPattern.matcher(getPackageName(file, fileIndex)).matches());
+ }
+
+ private boolean matchesScope(VirtualFile file, Project project, ProjectFileIndex fileIndex) {
+ if (file == null) return false;
+ boolean isSource = fileIndex.isInSourceContent(file);
+ if (myScope == SCOPE_ANY) {
+ return fileIndex.isInContent(file) && FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern, file, fileIndex);
+ }
+ if (myScope == SCOPE_SOURCE) {
+ return isSource && !fileIndex.isInTestSourceContent(file) && FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern,
+ file, fileIndex);
+ }
+ if (myScope == SCOPE_LIBRARY) {
+ return (fileIndex.isInLibraryClasses(file) || fileIndex.isInLibrarySource(file)) && matchesLibrary(myModulePattern, file, fileIndex);
+ }
+ if (myScope == SCOPE_TEST) {
+ return isSource && fileIndex.isInTestSourceContent(file) && FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern,
+ file, fileIndex);
+ }
+ if (myScope == SCOPE_PROBLEM) {
+ return isSource && WolfTheProblemSolver.getInstance(project).isProblemFile(file) &&
+ FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern, file, fileIndex);
+ }
+ throw new RuntimeException("Unknown scope: " + myScope);
+ }
+
+ private static String getPackageName(VirtualFile file, ProjectFileIndex fileIndex) {
+ return StringUtil.getQualifiedName(fileIndex.getPackageNameByDirectory(file.isDirectory() ? file : file.getParent()), file.getNameWithoutExtension());
+ }
+
+ @NotNull
+ @Override
+ public PackageSet createCopy() {
+ return new PatternPackageSet(myAspectJSyntaxPattern, myScope, myModulePatternText);
+ }
+
+ @Override
+ public int getNodePriority() {
+ return 0;
+ }
+
+ @NotNull
+ @Override
+ public String getText() {
+ StringBuilder buf = new StringBuilder();
+ if (myScope != SCOPE_ANY) {
+ buf.append(myScope);
+ }
+
+ if (myModulePattern != null || myModuleGroupPattern != null) {
+ buf.append("[").append(myModulePatternText).append("]");
+ }
+
+ if (buf.length() > 0) {
+ buf.append(':');
+ }
+
+ buf.append(myAspectJSyntaxPattern);
+ return buf.toString();
+ }
+
+ @Override
+ public String getModulePattern() {
+ return myModulePatternText;
+ }
+
+ @Override
+ public boolean isOn(String oldQName) {
+ return Comparing.strEqual(oldQName, myAspectJSyntaxPattern) || //class qname
+ Comparing.strEqual(oldQName + "..*", myAspectJSyntaxPattern) || //package req
+ Comparing.strEqual(oldQName + ".*", myAspectJSyntaxPattern); //package
+ }
+
+ @Override
+ public String getPattern() {
+ return myAspectJSyntaxPattern;
+ }
+
+ public static boolean matchesLibrary(final Pattern libPattern,
+ final VirtualFile file,
+ final ProjectFileIndex fileIndex) {
+ if (libPattern != null) {
+ final List<OrderEntry> entries = fileIndex.getOrderEntriesForFile(file);
+ for (OrderEntry orderEntry : entries) {
+ if (orderEntry instanceof LibraryOrderEntry) {
+ final String libraryName = ((LibraryOrderEntry)orderEntry).getLibraryName();
+ if (libraryName != null) {
+ if (libPattern.matcher(libraryName).matches()) return true;
+ } else {
+ final String presentableName = orderEntry.getPresentableName();
+ final String fileName = new File(presentableName).getName();
+ if (libPattern.matcher(fileName).matches()) return true;
+ }
+ } else if (orderEntry instanceof JdkOrderEntry) {
+ final String jdkName = ((JdkOrderEntry)orderEntry).getJdkName();
+ if (jdkName != null && libPattern.matcher(jdkName).matches()) return true;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/search/scope/packageSet/package.html b/java/openapi/src/com/intellij/psi/search/scope/packageSet/package.html
new file mode 100644
index 0000000..156ddbc
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/scope/packageSet/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for working with named search scopes containing sets of packages.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/search/searches/AnnotatedMembersSearch.java b/java/openapi/src/com/intellij/psi/search/searches/AnnotatedMembersSearch.java
new file mode 100644
index 0000000..213c3e4
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/searches/AnnotatedMembersSearch.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 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.psi.search.searches;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.util.Query;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author max
+ */
+public class AnnotatedMembersSearch {
+
+ private AnnotatedMembersSearch() {}
+
+ public static Query<PsiMember> search(@NotNull PsiClass annotationClass, @NotNull SearchScope scope) {
+ return AnnotatedElementsSearch.searchPsiMembers(annotationClass, scope);
+ }
+
+ public static Query<PsiMember> search(@NotNull PsiClass annotationClass) {
+ return search(annotationClass, GlobalSearchScope.allScope(annotationClass.getProject()));
+ }
+}
diff --git a/java/openapi/src/com/intellij/psi/search/searches/AnnotatedPackagesSearch.java b/java/openapi/src/com/intellij/psi/search/searches/AnnotatedPackagesSearch.java
new file mode 100644
index 0000000..bece77b
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/searches/AnnotatedPackagesSearch.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2009 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.psi.search.searches;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.util.Query;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author max
+ */
+public class AnnotatedPackagesSearch extends ExtensibleQueryFactory<PsiPackage, AnnotatedPackagesSearch.Parameters> {
+ public static final AnnotatedPackagesSearch INSTANCE = new AnnotatedPackagesSearch();
+
+ public static class Parameters {
+ private final PsiClass myAnnotationClass;
+ private final SearchScope myScope;
+
+ public Parameters(final PsiClass annotationClass, final SearchScope scope) {
+ myAnnotationClass = annotationClass;
+ myScope = scope;
+ }
+
+ public PsiClass getAnnotationClass() {
+ return myAnnotationClass;
+ }
+
+ public SearchScope getScope() {
+ return myScope;
+ }
+ }
+
+ private AnnotatedPackagesSearch() {}
+
+ public static Query<PsiPackage> search(@NotNull PsiClass annotationClass, @NotNull SearchScope scope) {
+ return INSTANCE.createQuery(new Parameters(annotationClass, scope));
+ }
+
+ public static Query<PsiPackage> search(@NotNull PsiClass annotationClass) {
+ return search(annotationClass, GlobalSearchScope.allScope(annotationClass.getProject()));
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/search/searches/AnnotationTargetsSearch.java b/java/openapi/src/com/intellij/psi/search/searches/AnnotationTargetsSearch.java
new file mode 100644
index 0000000..586bb3a
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/searches/AnnotationTargetsSearch.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000-2009 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.psi.search.searches;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiModifierListOwner;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.util.MergeQuery;
+import com.intellij.util.Query;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author max
+ */
+public class AnnotationTargetsSearch {
+ public static AnnotationTargetsSearch INSTANCE = new AnnotationTargetsSearch();
+
+ public static class Parameters {
+ private final PsiClass myAnnotationClass;
+ private final SearchScope myScope;
+
+ public Parameters(final PsiClass annotationClass, final SearchScope scope) {
+ myAnnotationClass = annotationClass;
+ myScope = scope;
+ }
+
+ public PsiClass getAnnotationClass() {
+ return myAnnotationClass;
+ }
+
+ public SearchScope getScope() {
+ return myScope;
+ }
+ }
+
+ private AnnotationTargetsSearch() {}
+
+ public static Query<PsiModifierListOwner> search(@NotNull PsiClass annotationClass, @NotNull SearchScope scope) {
+ final Query<PsiMember> members = AnnotatedMembersSearch.search(annotationClass, scope);
+ final Query<PsiPackage> packages = AnnotatedPackagesSearch.search(annotationClass, scope);
+ return new MergeQuery<PsiModifierListOwner>(members, packages);
+ }
+
+ public static Query<PsiModifierListOwner> search(@NotNull PsiClass annotationClass) {
+ return search(annotationClass, GlobalSearchScope.allScope(annotationClass.getProject()));
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/statistics/JavaStatisticsManager.java b/java/openapi/src/com/intellij/psi/statistics/JavaStatisticsManager.java
new file mode 100644
index 0000000..8d855d3
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/statistics/JavaStatisticsManager.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2000-2009 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.psi.statistics;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.VariableKind;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+
+/**
+ * @author yole
+ */
+public abstract class JavaStatisticsManager {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.psi.statistics.JavaStatisticsManager");
+ @NonNls public static final String CLASS_PREFIX = "class#";
+
+ private static StatisticsInfo createVariableUseInfo(final String name, final VariableKind variableKind,
+ final String propertyName,
+ final PsiType type) {
+ String key1 = getVariableNameUseKey1(propertyName, type);
+ String key2 = getVariableNameUseKey2(variableKind, name);
+ return new StatisticsInfo(key1, key2);
+ }
+
+ private static String getVariableNameUseKey1(String propertyName, PsiType type) {
+ @NonNls StringBuilder buffer = new StringBuilder();
+ buffer.append("variableName#");
+ if (propertyName != null){
+ buffer.append(propertyName);
+ }
+ buffer.append("#");
+ if (type != null){
+ buffer.append(type.getCanonicalText());
+ }
+ return buffer.toString();
+ }
+
+ private static String getVariableNameUseKey2(VariableKind kind, String name) {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append(kind);
+ buffer.append("#");
+ buffer.append(name);
+ return buffer.toString();
+ }
+
+ public static int getVariableNameUseCount(String name, VariableKind variableKind, String propertyName, PsiType type) {
+ return createVariableUseInfo(name, variableKind, propertyName, type).getUseCount();
+ }
+
+ public static void incVariableNameUseCount(String name, VariableKind variableKind, String propertyName, PsiType type) {
+ createVariableUseInfo(name, variableKind, propertyName, type).incUseCount();
+ }
+
+ @Nullable
+ public static String getName(String key2){
+ final int startIndex = key2.indexOf("#");
+ LOG.assertTrue(startIndex >= 0);
+ @NonNls String s = key2.substring(0, startIndex);
+ if(!"variableName".equals(s)) return null;
+ final int index = key2.indexOf("#", startIndex + 1);
+ LOG.assertTrue(index >= 0);
+ return key2.substring(index + 1);
+ }
+
+ private static VariableKind getVariableKindFromKey2(String key2){
+ int index = key2.indexOf("#");
+ LOG.assertTrue(index >= 0);
+ String s = key2.substring(0, index);
+ return VariableKind.valueOf(s);
+ }
+
+ private static String getVariableNameFromKey2(String key2){
+ int index = key2.indexOf("#");
+ LOG.assertTrue(index >= 0);
+ return key2.substring(index + 1);
+ }
+
+ @NonNls @NotNull
+ public static String getMemberUseKey1(@Nullable PsiType qualifierType) {
+ qualifierType = TypeConversionUtil.erasure(qualifierType);
+ return "member#" + (qualifierType == null ? "" : qualifierType.getCanonicalText());
+ }
+
+ @NonNls
+ public static String getMemberUseKey2(PsiMember member) {
+ if (member instanceof PsiMethod){
+ PsiMethod method = (PsiMethod)member;
+ @NonNls StringBuilder buffer = new StringBuilder();
+ buffer.append("method#");
+ buffer.append(method.getName());
+ for (PsiParameter parm : method.getParameterList().getParameters()) {
+ buffer.append("#");
+ buffer.append(parm.getType().getPresentableText());
+ }
+ return buffer.toString();
+ }
+
+ if (member instanceof PsiField){
+ return "field#" + member.getName();
+ }
+
+ return CLASS_PREFIX + ((PsiClass)member).getQualifiedName();
+ }
+
+ public static StatisticsInfo createInfo(@Nullable final PsiType qualifierType, final PsiMember member) {
+ return new StatisticsInfo(getMemberUseKey1(qualifierType), getMemberUseKey2(member));
+ }
+
+ public static String[] getAllVariableNamesUsed(VariableKind variableKind, String propertyName, PsiType type) {
+ StatisticsInfo[] keys2 = StatisticsManager.getInstance().getAllValues(getVariableNameUseKey1(propertyName, type));
+
+ ArrayList<String> list = new ArrayList<String>();
+
+ for (StatisticsInfo key2 : keys2) {
+ VariableKind variableKind1 = getVariableKindFromKey2(key2.getValue());
+ if (variableKind1 != variableKind) continue;
+ String name = getVariableNameFromKey2(key2.getValue());
+ list.add(name);
+ }
+
+ return ArrayUtil.toStringArray(list);
+ }
+
+ public static String getAfterNewKey(@Nullable PsiType expectedType) {
+ return getMemberUseKey1(expectedType) + "###smartAfterNew";
+ }
+
+}
diff --git a/java/openapi/src/com/intellij/psi/statistics/package.html b/java/openapi/src/com/intellij/psi/statistics/package.html
new file mode 100644
index 0000000..273ed0a
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/statistics/package.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for tracking the statistics of using different elements in
+completion lists.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/tree/java/package.html b/java/openapi/src/com/intellij/psi/tree/java/package.html
new file mode 100644
index 0000000..1ad6046
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/tree/java/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for Java elements found in AST trees.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/util/ClassKind.java b/java/openapi/src/com/intellij/psi/util/ClassKind.java
new file mode 100644
index 0000000..3c91030
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/ClassKind.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2009 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.psi.util;
+
+/**
+ * @author peter
+ */
+public enum ClassKind {
+ CLASS, INTERFACE, ENUM, ANNOTATION
+}
diff --git a/java/openapi/src/com/intellij/psi/util/EnclosingLoopMatcherExpression.java b/java/openapi/src/com/intellij/psi/util/EnclosingLoopMatcherExpression.java
new file mode 100644
index 0000000..4a370cd
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/EnclosingLoopMatcherExpression.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.util;
+
+import com.intellij.psi.*;
+
+public class EnclosingLoopMatcherExpression implements PsiMatcherExpression {
+ public static final PsiMatcherExpression INSTANCE = new EnclosingLoopMatcherExpression();
+
+ @Override
+ public Boolean match(PsiElement element) {
+ if (element instanceof PsiForStatement) return Boolean.TRUE;
+ if (element instanceof PsiForeachStatement) return Boolean.TRUE;
+ if (element instanceof PsiWhileStatement) return Boolean.TRUE;
+ if (element instanceof PsiDoWhileStatement) return Boolean.TRUE;
+ if (element instanceof PsiMethod || element instanceof PsiClassInitializer) return null;
+ return Boolean.FALSE;
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/util/EnclosingLoopOrSwitchMatcherExpression.java b/java/openapi/src/com/intellij/psi/util/EnclosingLoopOrSwitchMatcherExpression.java
new file mode 100644
index 0000000..b40ce68
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/EnclosingLoopOrSwitchMatcherExpression.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.util;
+
+import com.intellij.psi.*;
+
+public class EnclosingLoopOrSwitchMatcherExpression implements PsiMatcherExpression {
+ public static final PsiMatcherExpression INSTANCE = new EnclosingLoopOrSwitchMatcherExpression();
+
+ @Override
+ public Boolean match(PsiElement element) {
+ if (element instanceof PsiForStatement) return Boolean.TRUE;
+ if (element instanceof PsiForeachStatement) return Boolean.TRUE;
+ if (element instanceof PsiWhileStatement) return Boolean.TRUE;
+ if (element instanceof PsiDoWhileStatement) return Boolean.TRUE;
+ if (element instanceof PsiSwitchStatement) return Boolean.TRUE;
+ if (element instanceof PsiMethod || element instanceof PsiClassInitializer) return null;
+ return Boolean.FALSE;
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/util/ImportsUtil.java b/java/openapi/src/com/intellij/psi/util/ImportsUtil.java
new file mode 100644
index 0000000..7b61ade
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/ImportsUtil.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.util;
+
+import com.intellij.psi.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 9/1/11
+ */
+public class ImportsUtil {
+ private ImportsUtil() {
+ }
+
+ public static List<PsiJavaCodeReferenceElement> collectReferencesThrough(PsiFile file,
+ @Nullable final PsiJavaCodeReferenceElement refExpr,
+ final PsiImportStaticStatement staticImport) {
+ final List<PsiJavaCodeReferenceElement> expressionToExpand = new ArrayList<PsiJavaCodeReferenceElement>();
+ file.accept(new JavaRecursiveElementWalkingVisitor() {
+ @Override
+ public void visitReferenceElement(PsiJavaCodeReferenceElement expression) {
+ if (refExpr == null || refExpr != expression) {
+ final PsiElement resolveScope = expression.advancedResolve(true).getCurrentFileResolveScope();
+ if (resolveScope == staticImport) {
+ expressionToExpand.add(expression);
+ }
+ }
+ super.visitElement(expression);
+ }
+ });
+ return expressionToExpand;
+ }
+
+ public static void replaceAllAndDeleteImport(List<PsiJavaCodeReferenceElement> expressionToExpand,
+ @Nullable PsiJavaCodeReferenceElement refExpr,
+ PsiImportStaticStatement staticImport) {
+ if (refExpr != null) {
+ expressionToExpand.add(refExpr);
+ }
+ Collections.sort(expressionToExpand, new Comparator<PsiJavaCodeReferenceElement>() {
+ @Override
+ public int compare(PsiJavaCodeReferenceElement o1, PsiJavaCodeReferenceElement o2) {
+ return o2.getTextOffset() - o1.getTextOffset();
+ }
+ });
+ for (PsiJavaCodeReferenceElement expression : expressionToExpand) {
+ expand(expression, staticImport);
+ }
+ staticImport.delete();
+ }
+
+ public static void expand(@NotNull PsiJavaCodeReferenceElement refExpr, PsiImportStaticStatement staticImport) {
+ final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(refExpr.getProject());
+ final PsiReferenceExpression referenceExpression = elementFactory.createReferenceExpression(staticImport.resolveTargetClass());
+ if (refExpr instanceof PsiReferenceExpression) {
+ ((PsiReferenceExpression)refExpr).setQualifierExpression(referenceExpression);
+ }
+ else {
+ refExpr.replace(elementFactory.createReferenceFromText(referenceExpression.getText() + "." + refExpr.getText(), refExpr));
+ }
+ }
+}
diff --git a/java/openapi/src/com/intellij/psi/util/PropertyMemberType.java b/java/openapi/src/com/intellij/psi/util/PropertyMemberType.java
new file mode 100644
index 0000000..90bdec5
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/PropertyMemberType.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2009 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.psi.util;
+
+/**
+ * @author Gregory.Shrago
+*/
+public enum PropertyMemberType {
+ FIELD, GETTER, SETTER
+}
diff --git a/java/openapi/src/com/intellij/psi/util/PsiConcatenationUtil.java b/java/openapi/src/com/intellij/psi/util/PsiConcatenationUtil.java
new file mode 100644
index 0000000..9b60456
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/PsiConcatenationUtil.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.util;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.IncorrectOperationException;
+
+import java.util.List;
+
+/**
+ * User: cdr
+ */
+public class PsiConcatenationUtil {
+ public static void buildFormatString(
+ PsiExpression expression, StringBuilder formatString,
+ List<PsiExpression> formatParameters, boolean printfFormat) {
+ if (expression instanceof PsiLiteralExpression) {
+ final PsiLiteralExpression literalExpression =
+ (PsiLiteralExpression) expression;
+ final String text = String.valueOf(literalExpression.getValue());
+ final String formatText;
+ if (printfFormat) {
+ formatText = StringUtil.escapeStringCharacters(text)
+ .replace("%", "%%").replace("\\'", "'");
+ }
+ else {
+ formatText = StringUtil.escapeStringCharacters(text)
+ .replace("'", "''").replace("{", "'{").replace("}", "'}");
+ }
+ formatString.append(formatText);
+ } else if (expression instanceof PsiPolyadicExpression) {
+ final PsiType type = expression.getType();
+ if (type != null && type.equalsToText("java.lang.String")) {
+ final PsiPolyadicExpression binaryExpression =
+ (PsiPolyadicExpression) expression;
+ PsiExpression[] operands = binaryExpression.getOperands();
+ PsiType left = operands[0].getType();
+ boolean stringStarted = left != null && left.equalsToText("java.lang.String");
+ if (stringStarted) {
+ buildFormatString(operands[0], formatString, formatParameters, printfFormat);
+ }
+ for (int i = 1; i < operands.length; i++) {
+ PsiExpression op = operands[i];
+ PsiType optype = op.getType();
+ PsiType r = TypeConversionUtil.calcTypeForBinaryExpression(left, optype, binaryExpression.getOperationTokenType(), true);
+ if (r != null && r.equalsToText("java.lang.String") && !stringStarted) {
+ stringStarted = true;
+ PsiElement element = binaryExpression.getTokenBeforeOperand(op);
+ if (element.getPrevSibling() instanceof PsiWhiteSpace) element = element.getPrevSibling();
+ String text = binaryExpression.getText().substring(0, element.getStartOffsetInParent());
+ PsiExpression subExpression = JavaPsiFacade.getInstance(binaryExpression.getProject()).getElementFactory()
+ .createExpressionFromText(text, binaryExpression);
+ addFormatParameter(subExpression, formatString, formatParameters, printfFormat);
+ }
+ if (stringStarted) {
+ if (optype != null && (optype.equalsToText("java.lang.String") || optype == PsiType.CHAR)) {
+ buildFormatString(op, formatString, formatParameters, printfFormat);
+ }
+ else {
+ addFormatParameter(op, formatString, formatParameters, printfFormat);
+ }
+ }
+ left = r;
+ }
+ }
+ else {
+ addFormatParameter(expression, formatString, formatParameters, printfFormat);
+ }
+ }
+ else {
+ addFormatParameter(expression, formatString, formatParameters, printfFormat);
+ }
+ }
+
+ private static void addFormatParameter(PsiExpression expression,
+ StringBuilder formatString,
+ List<PsiExpression> formatParameters, boolean printfFormat) {
+ final PsiType type = expression.getType();
+ if (!printfFormat) {
+ formatString.append("{" + formatParameters.size() + "}");
+ }
+ else if (type != null &&
+ (type.equalsToText("long") ||
+ type.equalsToText("int") ||
+ type.equalsToText("java.lang.Long") ||
+ type.equalsToText("java.lang.Integer"))) {
+ formatString.append("%d");
+ }
+ else {
+ formatString.append("%s");
+ }
+ formatParameters.add(getBoxedArgument(expression));
+ }
+
+ private static PsiExpression getBoxedArgument(PsiExpression arg) throws IncorrectOperationException {
+ arg = PsiUtil.deparenthesizeExpression(arg);
+ assert arg != null;
+ if (PsiUtil.isLanguageLevel5OrHigher(arg)) {
+ return arg;
+ }
+ final PsiType type = arg.getType();
+ if (!(type instanceof PsiPrimitiveType) || type.equals(PsiType.NULL)) {
+ return arg;
+ }
+ final PsiPrimitiveType primitiveType = (PsiPrimitiveType)type;
+ final String boxedQName = primitiveType.getBoxedTypeName();
+ if (boxedQName == null) {
+ return arg;
+ }
+ final GlobalSearchScope resolveScope = arg.getResolveScope();
+ final PsiElementFactory factory = JavaPsiFacade.getElementFactory(arg.getProject());
+ final PsiJavaCodeReferenceElement ref = factory.createReferenceElementByFQClassName(boxedQName, resolveScope);
+ final PsiNewExpression newExpr = (PsiNewExpression)factory.createExpressionFromText("new A(b)", null);
+ final PsiElement classRef = newExpr.getClassReference();
+ assert classRef != null;
+ classRef.replace(ref);
+ final PsiExpressionList argumentList = newExpr.getArgumentList();
+ assert argumentList != null;
+ argumentList.getExpressions()[0].replace(arg);
+ return newExpr;
+ }
+
+}
diff --git a/java/openapi/src/com/intellij/psi/util/PsiMatchers.java b/java/openapi/src/com/intellij/psi/util/PsiMatchers.java
new file mode 100644
index 0000000..72f9367
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/PsiMatchers.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.util;
+
+import com.intellij.psi.*;
+import com.intellij.psi.xml.XmlTag;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+
+public class PsiMatchers {
+
+ private PsiMatchers() {
+ }
+
+ public static PsiMatcherExpression hasModifier(@PsiModifier.ModifierConstant final String modifier, final boolean shouldHave) {
+ return new PsiMatcherExpression() {
+ @Override
+ public Boolean match(PsiElement element) {
+ PsiModifierListOwner owner = element instanceof PsiModifierListOwner ? (PsiModifierListOwner) element : null;
+
+ if (owner != null && owner.hasModifierProperty(modifier) == shouldHave) return Boolean.TRUE;
+ return Boolean.FALSE;
+ }
+ };
+ }
+
+ public static PsiMatcherExpression hasText(final String text) {
+ return new PsiMatcherExpression() {
+ @Override
+ public Boolean match(PsiElement element) {
+ if (element.getTextLength() != text.length()) return Boolean.FALSE;
+ return text.equals(element.getText());
+ }
+ };
+ }
+
+ public static PsiMatcherExpression hasText(@NotNull final String... texts) {
+ return new PsiMatcherExpression() {
+ @Override
+ public Boolean match(PsiElement element) {
+ String text = element.getText();
+ return ArrayUtil.find(texts, text) != -1;
+ }
+ };
+ }
+
+ public static PsiMatcherExpression hasClass(final Class aClass) {
+ return new PsiMatcherExpression() {
+ @Override
+ public Boolean match(PsiElement element) {
+ if (aClass.isAssignableFrom(element.getClass())) return Boolean.TRUE;
+ return Boolean.FALSE;
+ }
+ };
+ }
+
+ public static PsiMatcherExpression hasClass(final Class... classes) {
+ return new PsiMatcherExpression() {
+ @Override
+ public Boolean match(PsiElement element) {
+ for (Class aClass : classes) {
+ if (aClass.isAssignableFrom(element.getClass())) return Boolean.TRUE;
+ }
+ return Boolean.FALSE;
+ }
+ };
+ }
+
+ public static PsiMatcherExpression hasName(final String name) {
+ return new PsiMatcherExpression() {
+ @Override
+ public Boolean match(PsiElement element) {
+ if (element instanceof PsiNamedElement && name.equals(((PsiNamedElement) element).getName())) return Boolean.TRUE;
+ if (element instanceof XmlTag && name.equals(((XmlTag) element).getName())) return Boolean.TRUE;
+ return Boolean.FALSE;
+ }
+ };
+ }
+
+ public static PsiMatcherExpression hasTagValue(final String value) {
+ return new PsiMatcherExpression() {
+ @Override
+ public Boolean match(PsiElement element) {
+ if (element instanceof XmlTag && value.equals(((XmlTag) element).getValue().getTrimmedText())) return Boolean.TRUE;
+ return Boolean.FALSE;
+ }
+ };
+ }
+
+ public static PsiMatcherExpression isConstructor(final boolean shouldBe) {
+ return new PsiMatcherExpression() {
+ @Override
+ public Boolean match(PsiElement element) {
+ return element instanceof PsiMethod && ((PsiMethod)element).isConstructor() == shouldBe;
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/util/RedundantCastUtil.java b/java/openapi/src/com/intellij/psi/util/RedundantCastUtil.java
new file mode 100644
index 0000000..ee390db
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/RedundantCastUtil.java
@@ -0,0 +1,595 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.util;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Ref;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author max
+ * Date: Mar 24, 2002
+ */
+public class RedundantCastUtil {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.redundantCast.RedundantCastUtil");
+
+ private RedundantCastUtil() { }
+
+ @NotNull
+ public static List<PsiTypeCastExpression> getRedundantCastsInside(PsiElement where) {
+ MyCollectingVisitor visitor = new MyCollectingVisitor();
+ if (where instanceof PsiEnumConstant) {
+ where.accept(visitor);
+ } else {
+ where.acceptChildren(visitor);
+ }
+ return new ArrayList<PsiTypeCastExpression>(visitor.myFoundCasts);
+ }
+
+ public static boolean isCastRedundant (PsiTypeCastExpression typeCast) {
+ PsiElement parent = typeCast.getParent();
+ while(parent instanceof PsiParenthesizedExpression) parent = parent.getParent();
+ if (parent instanceof PsiExpressionList) parent = parent.getParent();
+ if (parent instanceof PsiReferenceExpression) parent = parent.getParent();
+ MyIsRedundantVisitor visitor = new MyIsRedundantVisitor(false);
+ parent.accept(visitor);
+ return visitor.isRedundant;
+ }
+
+ @Nullable
+ private static PsiExpression deparenthesizeExpression(PsiExpression arg) {
+ while (arg instanceof PsiParenthesizedExpression) arg = ((PsiParenthesizedExpression) arg).getExpression();
+ return arg;
+ }
+
+ public static void removeCast(PsiTypeCastExpression castExpression) {
+ if (castExpression == null) return;
+ PsiExpression operand = castExpression.getOperand();
+ if (operand instanceof PsiParenthesizedExpression) {
+ final PsiParenthesizedExpression parExpr = (PsiParenthesizedExpression)operand;
+ operand = parExpr.getExpression();
+ }
+ if (operand == null) return;
+
+ PsiElement toBeReplaced = castExpression;
+
+ PsiElement parent = castExpression.getParent();
+ while (parent instanceof PsiParenthesizedExpression) {
+ toBeReplaced = parent;
+ parent = parent.getParent();
+ }
+
+ try {
+ toBeReplaced.replace(operand);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+
+ private static class MyCollectingVisitor extends MyIsRedundantVisitor {
+ private final Set<PsiTypeCastExpression> myFoundCasts = new HashSet<PsiTypeCastExpression>();
+
+ private MyCollectingVisitor() {
+ super(true);
+ }
+
+ @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
+ expression.acceptChildren(this);
+ }
+
+ @Override public void visitClass(PsiClass aClass) {
+ // avoid multiple visit
+ }
+
+ @Override public void visitMethod(PsiMethod method) {
+ // avoid multiple visit
+ }
+
+ @Override public void visitField(PsiField field) {
+ // avoid multiple visit
+ }
+
+ @Override
+ protected void addToResults(@NotNull PsiTypeCastExpression typeCast){
+ if (!isTypeCastSemantical(typeCast)) {
+ myFoundCasts.add(typeCast);
+ }
+ }
+ }
+
+ private static class MyIsRedundantVisitor extends JavaRecursiveElementVisitor {
+ private boolean isRedundant = false;
+ private final boolean myRecursive;
+
+ private MyIsRedundantVisitor(final boolean recursive) {
+ myRecursive = recursive;
+ }
+
+ @Override
+ public void visitElement(final PsiElement element) {
+ if (myRecursive) {
+ super.visitElement(element);
+ }
+ }
+
+ protected void addToResults(@NotNull PsiTypeCastExpression typeCast){
+ if (!isTypeCastSemantical(typeCast)) {
+ isRedundant = true;
+ }
+ }
+
+ @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) {
+ processPossibleTypeCast(expression.getRExpression(), expression.getLExpression().getType());
+ super.visitAssignmentExpression(expression);
+ }
+
+ @Override public void visitVariable(PsiVariable variable) {
+ processPossibleTypeCast(variable.getInitializer(), variable.getType());
+ super.visitVariable(variable);
+ }
+
+ @Override public void visitReturnStatement(PsiReturnStatement statement) {
+ final PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class);
+ if (method != null) {
+ final PsiType returnType = method.getReturnType();
+ final PsiExpression returnValue = statement.getReturnValue();
+ if (returnValue != null) {
+ processPossibleTypeCast(returnValue, returnType);
+ }
+ }
+ super.visitReturnStatement(statement);
+ }
+
+ @Override
+ public void visitPolyadicExpression(PsiPolyadicExpression expression) {
+ IElementType tokenType = expression.getOperationTokenType();
+ PsiExpression[] operands = expression.getOperands();
+ if (operands.length >= 2) {
+ PsiType lType = operands[0].getType();
+ processBinaryExpressionOperand(deparenthesizeExpression(operands[0]), operands[1].getType(), tokenType);
+ for (int i = 1; i < operands.length; i++) {
+ PsiExpression operand = deparenthesizeExpression(operands[i]);
+ if (operand == null) continue;
+ processBinaryExpressionOperand(operand, lType, tokenType);
+ lType = TypeConversionUtil.calcTypeForBinaryExpression(lType, operand.getType(), tokenType, true);
+ }
+ }
+ super.visitPolyadicExpression(expression);
+ }
+
+ private void processBinaryExpressionOperand(final PsiExpression operand,
+ final PsiType otherType,
+ final IElementType binaryToken) {
+ if (operand instanceof PsiTypeCastExpression) {
+ PsiTypeCastExpression typeCast = (PsiTypeCastExpression)operand;
+ PsiExpression toCast = typeCast.getOperand();
+ if (toCast != null && TypeConversionUtil.isBinaryOperatorApplicable(binaryToken, toCast.getType(), otherType, false)) {
+ addToResults(typeCast);
+ }
+ }
+ }
+
+ private void processPossibleTypeCast(PsiExpression rExpr, @Nullable PsiType lType) {
+ rExpr = deparenthesizeExpression(rExpr);
+ if (rExpr instanceof PsiTypeCastExpression) {
+ PsiExpression castOperand = ((PsiTypeCastExpression)rExpr).getOperand();
+ if (castOperand != null) {
+ PsiType operandType = castOperand.getType();
+ if (operandType != null) {
+ if (lType != null && TypeConversionUtil.isAssignable(lType, operandType, false)) {
+ addToResults((PsiTypeCastExpression)rExpr);
+ }
+ }
+ }
+ }
+ }
+
+ @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) {
+ processCall(expression);
+
+ checkForVirtual(expression);
+ super.visitMethodCallExpression(expression);
+ }
+
+ private void checkForVirtual(PsiMethodCallExpression methodCall) {
+ PsiReferenceExpression methodExpr = methodCall.getMethodExpression();
+ PsiExpression qualifier = methodExpr.getQualifierExpression();
+ if (!(qualifier instanceof PsiParenthesizedExpression)) return;
+ PsiExpression operand = ((PsiParenthesizedExpression)qualifier).getExpression();
+ if (!(operand instanceof PsiTypeCastExpression)) return;
+ PsiTypeCastExpression typeCast = (PsiTypeCastExpression)operand;
+ PsiExpression castOperand = typeCast.getOperand();
+ if (castOperand == null) return;
+
+ PsiType type = castOperand.getType();
+ if (type == null) return;
+ if (type instanceof PsiPrimitiveType) return;
+
+ final JavaResolveResult resolveResult = methodExpr.advancedResolve(false);
+ PsiMethod targetMethod = (PsiMethod)resolveResult.getElement();
+ if (targetMethod == null) return;
+ if (targetMethod.hasModifierProperty(PsiModifier.STATIC)) return;
+
+ try {
+ PsiManager manager = methodExpr.getManager();
+ PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
+
+ PsiMethodCallExpression newCall = (PsiMethodCallExpression)factory.createExpressionFromText(methodCall.getText(), methodCall);
+ PsiExpression newQualifier = newCall.getMethodExpression().getQualifierExpression();
+ PsiExpression newOperand = ((PsiTypeCastExpression)((PsiParenthesizedExpression)newQualifier).getExpression()).getOperand();
+ newQualifier.replace(newOperand);
+
+ final JavaResolveResult newResult = newCall.getMethodExpression().advancedResolve(false);
+ if (!newResult.isValidResult()) return;
+ final PsiMethod newTargetMethod = (PsiMethod)newResult.getElement();
+ final PsiType newReturnType = newResult.getSubstitutor().substitute(newTargetMethod.getReturnType());
+ final PsiType oldReturnType = resolveResult.getSubstitutor().substitute(targetMethod.getReturnType());
+ if (Comparing.equal(newReturnType, oldReturnType)) {
+ if (newTargetMethod.equals(targetMethod) ||
+ (newTargetMethod.getSignature(newResult.getSubstitutor()).equals(targetMethod.getSignature(resolveResult.getSubstitutor())) &&
+ !(newTargetMethod.isDeprecated() && !targetMethod.isDeprecated()) && // see SCR11555, SCR14559
+ areThrownExceptionsCompatible(targetMethod, newTargetMethod))) {
+ addToResults(typeCast);
+ }
+ }
+ }
+ catch (IncorrectOperationException ignore) { }
+ }
+
+ private static boolean areThrownExceptionsCompatible(final PsiMethod targetMethod, final PsiMethod newTargetMethod) {
+ final PsiClassType[] oldThrowsTypes = targetMethod.getThrowsList().getReferencedTypes();
+ final PsiClassType[] newThrowsTypes = newTargetMethod.getThrowsList().getReferencedTypes();
+ for (final PsiClassType throwsType : newThrowsTypes) {
+ if (!isExceptionThrown(throwsType, oldThrowsTypes)) return false;
+ }
+ return true;
+ }
+
+ private static boolean isExceptionThrown(PsiClassType exceptionType, PsiClassType[] thrownTypes) {
+ for (final PsiClassType type : thrownTypes) {
+ if (type.equals(exceptionType)) return true;
+ }
+ return false;
+ }
+
+ @Override public void visitNewExpression(PsiNewExpression expression) {
+ processCall(expression);
+ super.visitNewExpression(expression);
+ }
+
+ @Override
+ public void visitEnumConstant(PsiEnumConstant enumConstant) {
+ processCall(enumConstant);
+ super.visitEnumConstant(enumConstant);
+ }
+
+ @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
+ //expression.acceptChildren(this);
+ }
+
+ private void processCall(PsiCall expression){
+ PsiExpressionList argumentList = expression.getArgumentList();
+ if (argumentList == null) return;
+ PsiExpression[] args = argumentList.getExpressions();
+ PsiMethod oldMethod = expression.resolveMethod();
+ if (oldMethod == null) return;
+ PsiParameter[] parameters = oldMethod.getParameterList().getParameters();
+
+ try {
+ for (int i = 0; i < args.length; i++) {
+ final PsiExpression arg = deparenthesizeExpression(args[i]);
+ if (arg instanceof PsiTypeCastExpression) {
+ PsiTypeCastExpression cast = (PsiTypeCastExpression)arg;
+ if (i == args.length - 1 && args.length == parameters.length && parameters[i].isVarArgs()) {
+ //do not mark cast to resolve ambiguity for calling varargs method with inexact argument
+ continue;
+ }
+ PsiCall newCall = (PsiCall) expression.copy();
+ final PsiExpressionList argList = newCall.getArgumentList();
+ LOG.assertTrue(argList != null);
+ PsiExpression[] newArgs = argList.getExpressions();
+ PsiTypeCastExpression castExpression = (PsiTypeCastExpression) deparenthesizeExpression(newArgs[i]);
+ PsiExpression castOperand = castExpression.getOperand();
+ if (castOperand == null) return;
+ castExpression.replace(castOperand);
+ if (newCall instanceof PsiEnumConstant) {
+ // do this manually, because PsiEnumConstantImpl.resolveMethodGenerics() will assert (no containing class for the copy)
+ final PsiEnumConstant enumConstant = (PsiEnumConstant)expression;
+ PsiClass containingClass = enumConstant.getContainingClass();
+ final JavaPsiFacade facade = JavaPsiFacade.getInstance(enumConstant.getProject());
+ final PsiClassType type = facade.getElementFactory().createType(containingClass);
+ final JavaResolveResult newResult = facade.getResolveHelper().resolveConstructor(type, newCall.getArgumentList(), enumConstant);
+ if (oldMethod.equals(newResult.getElement()) && newResult.isValidResult()) {
+ addToResults(cast);
+ }
+ } else {
+ final JavaResolveResult newResult = newCall.resolveMethodGenerics();
+ if (oldMethod.equals(newResult.getElement()) && newResult.isValidResult() &&
+ Comparing.equal(((PsiCallExpression)newCall).getType(), ((PsiCallExpression)expression).getType())) {
+ addToResults(cast);
+ }
+ }
+ }
+ }
+ }
+ catch (IncorrectOperationException e) {
+ return;
+ }
+
+ for (PsiExpression arg : args) {
+ if (arg instanceof PsiTypeCastExpression) {
+ PsiExpression castOperand = ((PsiTypeCastExpression)arg).getOperand();
+ if (castOperand != null) {
+ castOperand.accept(this);
+ }
+ }
+ else {
+ arg.accept(this);
+ }
+ }
+ }
+
+ @Override public void visitTypeCastExpression(PsiTypeCastExpression typeCast) {
+ PsiExpression operand = typeCast.getOperand();
+ if (operand == null) return;
+
+ PsiElement expr = deparenthesizeExpression(operand);
+
+ final PsiType topCastType = typeCast.getType();
+ if (expr instanceof PsiTypeCastExpression) {
+ PsiTypeElement typeElement = ((PsiTypeCastExpression)expr).getCastType();
+ if (typeElement == null) return;
+ PsiType castType = typeElement.getType();
+ final PsiExpression innerOperand = ((PsiTypeCastExpression)expr).getOperand();
+ final PsiType operandType = innerOperand != null ? innerOperand.getType() : null;
+ if (!(castType instanceof PsiPrimitiveType)) {
+ if (operandType != null && topCastType != null && TypeConversionUtil.areTypesConvertible(operandType, topCastType)) {
+ addToResults((PsiTypeCastExpression)expr);
+ }
+ } else if (PsiPrimitiveType.getUnboxedType(operandType) == topCastType) {
+ addToResults((PsiTypeCastExpression)expr);
+ }
+ }
+ else {
+ PsiElement parent = typeCast.getParent();
+ if (parent instanceof PsiConditionalExpression) {
+ //branches need to be of the same type
+ if (!Comparing.equal(operand.getType(), ((PsiConditionalExpression)parent).getType())) {
+ if (!PsiUtil.isLanguageLevel5OrHigher(typeCast)) {
+ return;
+ }
+ if (!checkResolveAfterRemoveCast(parent)) return;
+ }
+ } else if (parent instanceof PsiSynchronizedStatement && (expr instanceof PsiExpression && ((PsiExpression)expr).getType() instanceof PsiPrimitiveType)) {
+ return;
+ } else if (expr instanceof PsiLambdaExpression || expr instanceof PsiMethodReferenceExpression) {
+ if (parent instanceof PsiParenthesizedExpression && parent.getParent() instanceof PsiReferenceExpression) {
+ return;
+ }
+
+ final PsiType functionalInterfaceType = LambdaUtil.getFunctionalInterfaceType(typeCast, true);
+ if (topCastType != null && functionalInterfaceType != null && !TypeConversionUtil.isAssignable(topCastType, functionalInterfaceType, false)) return;
+ }
+ processAlreadyHasTypeCast(typeCast);
+ }
+ super.visitTypeCastExpression(typeCast);
+ }
+
+ private static boolean checkResolveAfterRemoveCast(PsiElement parent) {
+ PsiElement grandPa = parent.getParent();
+ if (grandPa instanceof PsiExpressionList) {
+ PsiExpression[] expressions = ((PsiExpressionList)grandPa).getExpressions();
+ int idx = ArrayUtil.find(expressions, parent);
+ PsiElement grandGrandPa = grandPa.getParent();
+ if (grandGrandPa instanceof PsiCall) {
+ PsiElement resolve = ((PsiCall)grandGrandPa).resolveMethod();
+ if (resolve instanceof PsiMethod) {
+ PsiCall expression = (PsiCall)grandGrandPa.copy();
+ PsiExpressionList argumentList = expression.getArgumentList();
+ LOG.assertTrue(argumentList != null);
+ PsiExpression toReplace = argumentList.getExpressions()[idx];
+ if (toReplace instanceof PsiConditionalExpression) {
+ PsiExpression thenExpression = ((PsiConditionalExpression)toReplace).getThenExpression();
+ PsiExpression elseExpression = ((PsiConditionalExpression)toReplace).getElseExpression();
+ if (thenExpression instanceof PsiTypeCastExpression) {
+ final PsiExpression thenOperand = ((PsiTypeCastExpression)thenExpression).getOperand();
+ if (thenOperand != null) {
+ thenExpression.replace(thenOperand);
+ }
+ } else if (elseExpression instanceof PsiTypeCastExpression) {
+ final PsiExpression elseOperand = ((PsiTypeCastExpression)elseExpression).getOperand();
+ if (elseOperand != null) {
+ elseExpression.replace(elseOperand);
+ }
+ }
+ }
+ if (expression.resolveMethod() != resolve) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ private void processAlreadyHasTypeCast(PsiTypeCastExpression typeCast){
+ PsiElement parent = typeCast.getParent();
+ while(parent instanceof PsiParenthesizedExpression) parent = parent.getParent();
+ if (parent instanceof PsiExpressionList) return; // do not replace in arg lists - should be handled by parent
+ if (parent instanceof PsiReturnStatement) return;
+ if (parent instanceof PsiTypeCastExpression) return;
+
+ if (isTypeCastSemantical(typeCast)) return;
+
+ PsiTypeElement typeElement = typeCast.getCastType();
+ if (typeElement == null) return;
+ final PsiType castTo = typeElement.getType();
+ final PsiType opType = typeCast.getOperand().getType();
+ if (opType == null) return;
+ if (parent instanceof PsiReferenceExpression) {
+ if (castTo instanceof PsiClassType && opType instanceof PsiPrimitiveType) return; //explicit boxing
+ //Check accessibility
+ if (opType instanceof PsiClassType) {
+ final PsiReferenceExpression refExpression = (PsiReferenceExpression)parent;
+ PsiElement element = refExpression.resolve();
+ if (!(element instanceof PsiMember)) return;
+ PsiClass accessClass = ((PsiClassType)opType).resolve();
+ if (accessClass == null) return;
+ if (!JavaPsiFacade.getInstance(parent.getProject()).getResolveHelper().isAccessible((PsiMember)element, typeCast, accessClass)) return;
+ if (!isCastRedundantInRefExpression(refExpression, typeCast.getOperand())) return;
+ }
+ }
+
+ if (arrayAccessAtTheLeftSideOfAssignment(parent)) {
+ if (TypeConversionUtil.isAssignable(opType, castTo, false) && opType.getArrayDimensions() == castTo.getArrayDimensions()) {
+ addToResults(typeCast);
+ }
+ }
+ else {
+ if (TypeConversionUtil.isAssignable(castTo, opType, false)) {
+ addToResults(typeCast);
+ }
+ }
+ }
+
+ private static boolean arrayAccessAtTheLeftSideOfAssignment(PsiElement element) {
+ PsiAssignmentExpression assignment = PsiTreeUtil.getParentOfType(element, PsiAssignmentExpression.class, false, PsiMember.class);
+ if (assignment == null) return false;
+ PsiExpression lExpression = assignment.getLExpression();
+ return PsiTreeUtil.isAncestor(lExpression, element, false) && lExpression instanceof PsiArrayAccessExpression;
+ }
+ }
+
+ private static boolean isCastRedundantInRefExpression (final PsiReferenceExpression refExpression, final PsiExpression castOperand) {
+ final PsiElement resolved = refExpression.resolve();
+ final Ref<Boolean> result = new Ref<Boolean>(Boolean.FALSE);
+ CodeStyleManager.getInstance(refExpression.getProject()).performActionWithFormatterDisabled(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(refExpression.getProject()).getElementFactory();
+ final PsiExpression copyExpression = elementFactory.createExpressionFromText(refExpression.getText(), refExpression);
+ if (copyExpression instanceof PsiReferenceExpression) {
+ final PsiReferenceExpression copy = (PsiReferenceExpression)copyExpression;
+ final PsiExpression qualifier = copy.getQualifierExpression();
+ if (qualifier != null) {
+ qualifier.replace(castOperand);
+ result.set(Boolean.valueOf(copy.resolve() == resolved));
+ }
+ }
+ }
+ catch (IncorrectOperationException ignore) { }
+ }
+ });
+ return result.get().booleanValue();
+ }
+
+ public static boolean isTypeCastSemantical(PsiTypeCastExpression typeCast) {
+ PsiExpression operand = typeCast.getOperand();
+ if (operand == null) return false;
+
+ if (isInPolymorphicCall(typeCast)) return true;
+
+ PsiType opType = operand.getType();
+ PsiTypeElement typeElement = typeCast.getCastType();
+ if (typeElement == null) return false;
+
+ PsiType castType = typeElement.getType();
+ if (castType instanceof PsiPrimitiveType) {
+ if (opType instanceof PsiPrimitiveType) {
+ return !opType.equals(castType); // let's suppose all not equal primitive casts are necessary
+ }
+ final PsiPrimitiveType unboxedOpType = PsiPrimitiveType.getUnboxedType(opType);
+ if (unboxedOpType != null && !unboxedOpType.equals(castType) ) {
+ return true;
+ }
+ }
+ else if (castType instanceof PsiClassType && ((PsiClassType)castType).hasParameters()) {
+ if (opType instanceof PsiClassType && ((PsiClassType)opType).isRaw()) return true;
+ } else if (castType instanceof PsiClassType && ((PsiClassType)castType).isRaw()) {
+ if (opType instanceof PsiClassType && ((PsiClassType)opType).hasParameters()) return true;
+ }
+
+ PsiElement parent = typeCast.getParent();
+ while(parent instanceof PsiParenthesizedExpression) parent = parent.getParent();
+
+ if (parent instanceof PsiBinaryExpression) {
+ PsiBinaryExpression expression = (PsiBinaryExpression)parent;
+ PsiExpression firstOperand = expression.getLOperand();
+ PsiExpression otherOperand = expression.getROperand();
+ if (PsiTreeUtil.isAncestor(otherOperand, typeCast, false)) {
+ PsiExpression temp = otherOperand;
+ otherOperand = firstOperand;
+ firstOperand = temp;
+ }
+ if (firstOperand != null && otherOperand != null && wrapperCastChangeSemantics(firstOperand, otherOperand, operand)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean wrapperCastChangeSemantics(PsiExpression operand, PsiExpression otherOperand, PsiExpression toCast) {
+ boolean isPrimitiveComparisonWithCast = TypeConversionUtil.isPrimitiveAndNotNull(operand.getType()) ||
+ TypeConversionUtil.isPrimitiveAndNotNull(otherOperand.getType());
+ boolean isPrimitiveComparisonWithoutCast = TypeConversionUtil.isPrimitiveAndNotNull(toCast.getType()) ||
+ TypeConversionUtil.isPrimitiveAndNotNull(otherOperand.getType());
+ // wrapper casted to primitive vs wrapper comparison
+ return isPrimitiveComparisonWithCast != isPrimitiveComparisonWithoutCast;
+ }
+
+ // see http://download.java.net/jdk7/docs/api/java/lang/invoke/MethodHandle.html#sigpoly
+ public static boolean isInPolymorphicCall(final PsiTypeCastExpression typeCast) {
+ if (!PsiUtil.isLanguageLevel7OrHigher(typeCast)) return false;
+
+ // return type
+ final PsiExpression operand = typeCast.getOperand();
+ if (operand instanceof PsiMethodCallExpression) {
+ if (isPolymorphicMethod((PsiMethodCallExpression)operand)) return true;
+ }
+
+ // argument type
+ final PsiElement exprList = typeCast.getParent();
+ if (exprList instanceof PsiExpressionList) {
+ final PsiElement methodCall = exprList.getParent();
+ if (methodCall instanceof PsiMethodCallExpression) {
+ if (isPolymorphicMethod((PsiMethodCallExpression)methodCall)) return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean isPolymorphicMethod(PsiMethodCallExpression expression) {
+ final PsiElement method = expression.getMethodExpression().resolve();
+ return method instanceof PsiMethod &&
+ AnnotationUtil.isAnnotated((PsiMethod)method, CommonClassNames.JAVA_LANG_INVOKE_MH_POLYMORPHIC, false, true);
+ }
+}
diff --git a/java/openapi/src/com/intellij/psi/util/package.html b/java/openapi/src/com/intellij/psi/util/package.html
new file mode 100644
index 0000000..879ab75
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides utility classes for working with the PSI.
+</body></html>
diff --git a/java/openapi/src/com/intellij/refactoring/ConvertToInstanceMethodRefactoring.java b/java/openapi/src/com/intellij/refactoring/ConvertToInstanceMethodRefactoring.java
new file mode 100644
index 0000000..5e85056
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/ConvertToInstanceMethodRefactoring.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiParameter;
+
+/**
+ * @author dsl
+ */
+public interface ConvertToInstanceMethodRefactoring extends Refactoring {
+ PsiMethod getMethod();
+ PsiParameter getTargetParameter();
+ PsiClass getTargetClass();
+}
+
diff --git a/java/openapi/src/com/intellij/refactoring/IntroduceParameterRefactoring.java b/java/openapi/src/com/intellij/refactoring/IntroduceParameterRefactoring.java
new file mode 100644
index 0000000..9f61de9
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/IntroduceParameterRefactoring.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.psi.PsiType;
+
+/**
+ * @author dsl
+ */
+public interface IntroduceParameterRefactoring extends Refactoring {
+ int REPLACE_FIELDS_WITH_GETTERS_NONE = 0;
+ int REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE = 1;
+ int REPLACE_FIELDS_WITH_GETTERS_ALL = 2;
+
+ void enforceParameterType(PsiType forcedType);
+ void setFieldReplacementPolicy(int policy);
+
+ PsiType getForcedType();
+ int getFieldReplacementPolicy();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/JavaRefactoringActionHandlerFactory.java b/java/openapi/src/com/intellij/refactoring/JavaRefactoringActionHandlerFactory.java
new file mode 100644
index 0000000..de1f07a
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/JavaRefactoringActionHandlerFactory.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.openapi.components.ServiceManager;
+
+public abstract class JavaRefactoringActionHandlerFactory {
+ public static JavaRefactoringActionHandlerFactory getInstance() {
+ return ServiceManager.getService(JavaRefactoringActionHandlerFactory.class);
+ }
+
+ /**
+ * Creates handler for Anonymous To Inner refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * is not implemented.
+ * @return
+ */
+ public abstract RefactoringActionHandler createAnonymousToInnerHandler();
+
+ /**
+ * Creates handler for Pull Members Up refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts either a {@link com.intellij.psi.PsiClass}, {@link com.intellij.psi.PsiField} or {@link com.intellij.psi.PsiMethod}.
+ * In latter two cases, <code>elements[0]</code> is a member that will be preselected.
+ */
+ public abstract RefactoringActionHandler createPullUpHandler();
+
+ /**
+ * Creates handler for Push Members Down refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts either a {@link com.intellij.psi.PsiClass}, {@link com.intellij.psi.PsiField} or {@link com.intellij.psi.PsiMethod}.
+ * In latter two cases, <code>elements[0]</code> is a member that will be preselected.
+ */
+ public abstract RefactoringActionHandler createPushDownHandler();
+
+ /**
+ * Creates handler for Use Interface Where Possible refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts 1 <code>PsiClass</code>.
+ * @return
+ */
+ public abstract RefactoringActionHandler createTurnRefsToSuperHandler();
+
+ /**
+ * Creates handler for Replace Temp With Query refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * is not implemented.
+ */
+ public abstract RefactoringActionHandler createTempWithQueryHandler();
+
+ /**
+ * Creates handler for Introduce Parameter refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts either 1 <code>PsiExpression</code>, that will be an initialzier for introduced parameter,
+ * or 1 <code>PsiLocalVariable</code>, that will be replaced with introduced parameter.
+ */
+ public abstract RefactoringActionHandler createIntroduceParameterHandler();
+
+ /**
+ * Creates handler for Make Method Static refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts 1 <code>PsiMethod</code>.
+ */
+ public abstract RefactoringActionHandler createMakeMethodStaticHandler();
+
+ /**
+ * Creates handler for Convert To Instance Method refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts 1 <code>PsiMethod</code>.
+ */
+ public abstract RefactoringActionHandler createConvertToInstanceMethodHandler();
+
+ /**
+ * Creates handler for Replace Constructor With Factory Method refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts either a <code>PsiMethod</code> that is a constructor, or a <code>PsiClass</code>
+ * with implicit default constructor.
+ */
+ public abstract RefactoringActionHandler createReplaceConstructorWithFactoryHandler();
+
+
+ /**
+ * Creates handler for Replace Constructor With Factory Method refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts either a <code>PsiClass</code> or any number of <code>PsiField</code>s.
+ */
+ public abstract RefactoringActionHandler createEncapsulateFieldsHandler();
+
+ /**
+ * Creates handler for Replace Method Code Duplicates refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts one <code>PsiMethod</code>.
+ */
+ public abstract RefactoringActionHandler createMethodDuplicatesHandler();
+
+ /**
+ * Creates handler for Change Method/Class Signature refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts either 1 <code>PsiMethod</code> or 1 <code>PsiClass</code>
+ */
+ public abstract RefactoringActionHandler createChangeSignatureHandler();
+
+ /**
+ * Creates handler for Extract Superclass refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts 1 <code>PsiClass</code>.
+ */
+ public abstract RefactoringActionHandler createExtractSuperclassHandler();
+
+ /**
+ * Creates handler for Generify (aka Type Cook) refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts any number of arbitrary <code>PsiElement</code>s. All code inside these elements will be generified.
+ */
+ public abstract RefactoringActionHandler createTypeCookHandler();
+
+ /**
+ * Creates handler for Inline refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts 1 inlinable <code>PsiElement</code> (method, local variable or constant).
+ */
+ public abstract RefactoringActionHandler createInlineHandler();
+
+ /**
+ * Creates handler for Extract Method refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * is not implemented.
+ */
+ public abstract RefactoringActionHandler createExtractMethodHandler();
+
+ public abstract RefactoringActionHandler createInheritanceToDelegationHandler();
+
+ /**
+ * Creates handler for Extract Interface refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts 1 <code>PsiClass</code>.
+ */
+ public abstract RefactoringActionHandler createExtractInterfaceHandler();
+
+ /**
+ * Creates handler for Introduce Field refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts either 1 <code>PsiExpression</code>, that will be an initialzier for introduced field,
+ * or 1 <code>PsiLocalVariable</code>, that will be replaced with introduced field.
+ */
+ public abstract RefactoringActionHandler createIntroduceFieldHandler();
+
+ /**
+ * Creates handler for Introduce Variable refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts 1 <code>PsiExpression</code>, that will be an initialzier for introduced variable.
+ */
+ public abstract RefactoringActionHandler createIntroduceVariableHandler();
+
+ /**
+ * Creates handler for Introduce Constant refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts either 1 <code>PsiExpression</code>, that will be an initialzier for introduced constant,
+ * or 1 <code>PsiLocalVariable</code>, that will be replaced with introduced constant.
+ */
+ public abstract RefactoringActionHandler createIntroduceConstantHandler();
+
+ /**
+ * Creates handler for Invert Boolean refactoring.<p>
+ *
+ * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+ * accepts 1 <code>PsiMethod</code>, that will be inverted
+ */
+ public abstract RefactoringActionHandler createInvertBooleanHandler();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/JavaRefactoringFactory.java b/java/openapi/src/com/intellij/refactoring/JavaRefactoringFactory.java
new file mode 100644
index 0000000..0713b41
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/JavaRefactoringFactory.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author dsl
+ */
+public abstract class JavaRefactoringFactory extends RefactoringFactory {
+ public static JavaRefactoringFactory getInstance(Project project) {
+ return (JavaRefactoringFactory) ServiceManager.getService(project, RefactoringFactory.class);
+ }
+
+ public abstract JavaRenameRefactoring createRename(PsiElement element, String newName);
+
+ @Nullable("in case the source file is not located under any source root")
+ public abstract MoveInnerRefactoring createMoveInner(PsiClass innerClass, String newName,
+ boolean passOuterClass, String parameterName);
+
+ /**
+ * Creates move destination for a specified package that preserves source folders for moved items.
+ */
+ public abstract MoveDestination createSourceFolderPreservingMoveDestination(@NotNull String targetPackageQualifiedName);
+
+ /**
+ * Creates move destination for a specified package that moves all items to a specifed source folder
+ */
+ public abstract MoveDestination createSourceRootMoveDestination(@NotNull String targetPackageQualifiedName, @NotNull VirtualFile sourceRoot);
+
+ public abstract MoveClassesOrPackagesRefactoring createMoveClassesOrPackages(PsiElement[] elements, MoveDestination moveDestination);
+
+ public abstract MoveMembersRefactoring createMoveMembers(PsiMember[] elements,
+ String targetClassQualifiedName,
+ String newVisibility);
+
+ public abstract MoveMembersRefactoring createMoveMembers(PsiMember[] elements,
+ String targetClassQualifiedName,
+ String newVisibility,
+ boolean makeEnumConstants);
+
+ public abstract MakeStaticRefactoring<PsiMethod> createMakeMethodStatic(PsiMethod method,
+ boolean replaceUsages,
+ String classParameterName,
+ PsiField[] fields,
+ String[] names);
+
+ public abstract MakeStaticRefactoring<PsiClass> createMakeClassStatic(PsiClass aClass,
+ boolean replaceUsages,
+ String classParameterName,
+ PsiField[] fields,
+ String[] names);
+
+ public abstract ConvertToInstanceMethodRefactoring createConvertToInstanceMethod(PsiMethod method,
+ PsiParameter targetParameter);
+
+ public abstract TurnRefsToSuperRefactoring createTurnRefsToSuper(PsiClass aClass,
+ PsiClass aSuper,
+ boolean replaceInstanceOf);
+
+ public abstract ReplaceConstructorWithFactoryRefactoring createReplaceConstructorWithFactory(PsiMethod method,
+ PsiClass targetClass,
+ String factoryName);
+
+ public abstract ReplaceConstructorWithFactoryRefactoring createReplaceConstructorWithFactory(PsiClass originalClass,
+ PsiClass targetClass,
+ String factoryName);
+
+ public abstract TypeCookRefactoring createTypeCook(PsiElement[] elements,
+ boolean dropObsoleteCasts,
+ boolean leaveObjectsRaw,
+ boolean preserveRawArrays,
+ boolean exhaustive,
+ boolean cookObjects,
+ boolean cookToWildcards);
+
+ /**
+ * Creates Introduce Parameter refactoring that replaces local variable with parameter.
+ * @param methodToReplaceIn Method that the local variable should be replaced in.
+ * @param methodToSearchFor Method that usages of should be updated (for overriding methods)
+ * @param parameterName Name of new parameter.
+ * @param parameterInitializer Initializer to use in method calls.
+ * @param localVariable local variable that will be replaced
+ * @param removeLocalVariable should local variable be removed
+ * @param declareFinal should created parameter be declared <code>final</code>
+ */
+ public abstract IntroduceParameterRefactoring createIntroduceParameterRefactoring(PsiMethod methodToReplaceIn,
+ PsiMethod methodToSearchFor,
+ String parameterName, PsiExpression parameterInitializer,
+ PsiLocalVariable localVariable,
+ boolean removeLocalVariable, boolean declareFinal);
+
+ /**
+ * Creates Introduce Parameter refactoring that replaces expression with parameter.
+ * @param methodToReplaceIn Method that the local variable should be replaced in.
+ * @param methodToSearchFor Method that usages of should be updated (for overriding methods)
+ * @param parameterName Name of new parameter.
+ * @param parameterInitializer Initializer to use in method calls.
+ * @param expressionToSearchFor expression that should be replaced with parameters
+ * @param declareFinal should created parameter be declared <code>final</code>
+ * @param replaceAllOccurences should all occurences of expression be replaced
+ */
+ public abstract IntroduceParameterRefactoring createIntroduceParameterRefactoring(PsiMethod methodToReplaceIn,
+ PsiMethod methodToSearchFor,
+ String parameterName,
+ PsiExpression parameterInitializer,
+ PsiExpression expressionToSearchFor,
+ boolean declareFinal,
+ final boolean replaceAllOccurences);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/JavaRenameRefactoring.java b/java/openapi/src/com/intellij/refactoring/JavaRenameRefactoring.java
new file mode 100644
index 0000000..1bc9994
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/JavaRenameRefactoring.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+/**
+ * @author yole
+ */
+public interface JavaRenameRefactoring extends RenameRefactoring {
+ void setShouldRenameVariables(boolean value);
+
+ void setShouldRenameInheritors(boolean value);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/MakeStaticRefactoring.java b/java/openapi/src/com/intellij/refactoring/MakeStaticRefactoring.java
new file mode 100644
index 0000000..5460e5c
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MakeStaticRefactoring.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiTypeParameterListOwner;
+
+import java.util.List;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author ven
+ */
+public interface MakeStaticRefactoring<T extends PsiTypeParameterListOwner> extends Refactoring {
+ T getMember();
+
+ boolean isReplaceUsages();
+
+ String getClassParameterName();
+
+ List<PsiField> getFields();
+
+ @Nullable
+ String getParameterNameForField(PsiField field);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/MoveClassesOrPackagesRefactoring.java b/java/openapi/src/com/intellij/refactoring/MoveClassesOrPackagesRefactoring.java
new file mode 100644
index 0000000..41905e1
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MoveClassesOrPackagesRefactoring.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.psi.PsiElement;
+
+import java.util.List;
+
+/**
+ * @author dsl
+ */
+public interface MoveClassesOrPackagesRefactoring extends Refactoring {
+ List<PsiElement> getElements();
+
+ PackageWrapper getTargetPackage();
+
+ void setSearchInComments(boolean value);
+
+ void setSearchInNonJavaFiles(boolean value);
+
+ boolean isSearchInComments();
+
+ boolean isSearchInNonJavaFiles();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/MoveDestination.java b/java/openapi/src/com/intellij/refactoring/MoveDestination.java
new file mode 100644
index 0000000..229a5dc
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MoveDestination.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.usageView.UsageInfo;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Represents a destination of Move Classes/Packages refactoring.
+ * Destination of Move refactoring is generally a single package,
+ * and various <code>MoveDestination</code>s control how moved items
+ * will be layouted in directories corresponding to target packages.
+ *
+ * Instances of this interface can be obtained via methods of {@link RefactoringFactory}.
+ *
+ * @see JavaRefactoringFactory#createSourceFolderPreservingMoveDestination(String)
+ * @see JavaRefactoringFactory#createSourceRootMoveDestination(java.lang.String, com.intellij.openapi.vfs.VirtualFile)
+ * @author dsl
+ */
+public interface MoveDestination {
+ /**
+ * Invoked in command & write action
+ */
+ PsiDirectory getTargetDirectory(PsiDirectory source) throws IncorrectOperationException;
+ /**
+ * Invoked in command & write action
+ */
+ PsiDirectory getTargetDirectory(PsiFile source) throws IncorrectOperationException;
+
+ PackageWrapper getTargetPackage();
+
+ PsiDirectory getTargetIfExists(PsiDirectory source);
+ PsiDirectory getTargetIfExists(PsiFile source);
+
+ @Nullable
+ String verify(PsiFile source);
+ @Nullable
+ String verify(PsiDirectory source);
+ @Nullable
+ String verify(PsiPackage source);
+
+ void analyzeModuleConflicts(final Collection<PsiElement> elements, MultiMap<PsiElement,String> conflicts, final UsageInfo[] usages);
+
+ boolean isTargetAccessible(Project project, VirtualFile place);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/MoveInnerRefactoring.java b/java/openapi/src/com/intellij/refactoring/MoveInnerRefactoring.java
new file mode 100644
index 0000000..a22b890
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MoveInnerRefactoring.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.psi.PsiClass;
+
+/**
+ * @author dsl
+ */
+public interface MoveInnerRefactoring extends Refactoring {
+
+ PsiClass getInnerClass();
+
+ String getNewClassName();
+
+ boolean shouldPassParameter();
+
+ String getParameterName();
+
+ void setSearchInComments(boolean value);
+
+ void setSearchInNonJavaFiles(boolean value);
+
+ boolean isSearchInComments();
+
+ boolean isSearchInNonJavaFiles();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/MoveInstanceMethodRefactoring.java b/java/openapi/src/com/intellij/refactoring/MoveInstanceMethodRefactoring.java
new file mode 100644
index 0000000..9cd9570
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MoveInstanceMethodRefactoring.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiVariable;
+
+/**
+ * @author ven
+ */
+public interface MoveInstanceMethodRefactoring extends Refactoring {
+ PsiMethod getMethod();
+ PsiVariable getTargetVariable();
+ PsiClass getTargetClass();
+}
+
diff --git a/java/openapi/src/com/intellij/refactoring/MoveMembersRefactoring.java b/java/openapi/src/com/intellij/refactoring/MoveMembersRefactoring.java
new file mode 100644
index 0000000..3beafce
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MoveMembersRefactoring.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+
+import java.util.List;
+
+/**
+ * @author dsl
+ */
+public interface MoveMembersRefactoring extends Refactoring {
+ List<PsiElement> getMembers();
+
+ PsiClass getTargetClass();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/PackageWrapper.java b/java/openapi/src/com/intellij/refactoring/PackageWrapper.java
new file mode 100644
index 0000000..7fd5de5
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/PackageWrapper.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.PsiPackage;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Represents a package.
+ * @author dsl
+ */
+public class PackageWrapper {
+ private final PsiManager myManager;
+ @NotNull private final String myQualifiedName;
+
+ public PackageWrapper(PsiManager manager, @NotNull String qualifiedName) {
+ myManager = manager;
+ myQualifiedName = qualifiedName;
+ }
+
+ public PackageWrapper(PsiPackage aPackage) {
+ myManager = aPackage.getManager();
+ myQualifiedName = aPackage.getQualifiedName();
+ }
+
+ public PsiManager getManager() { return myManager; }
+
+ public PsiDirectory[] getDirectories() {
+ String qName = myQualifiedName;
+ while (qName.endsWith(".")) {
+ qName = StringUtil.trimEnd(qName, ".");
+ }
+ final PsiPackage aPackage = JavaPsiFacade.getInstance(myManager.getProject()).findPackage(qName);
+ if (aPackage != null) {
+ return aPackage.getDirectories();
+ } else {
+ return PsiDirectory.EMPTY_ARRAY;
+ }
+ }
+
+ public boolean exists() {
+ return JavaPsiFacade.getInstance(myManager.getProject()).findPackage(myQualifiedName) != null;
+ }
+
+ @NotNull
+ public String getQualifiedName() {
+ return myQualifiedName;
+ }
+
+ public boolean equalToPackage(PsiPackage aPackage) {
+ return aPackage != null && myQualifiedName.equals(aPackage.getQualifiedName());
+ }
+
+ public static PackageWrapper create(PsiPackage aPackage) {
+ return new PackageWrapper(aPackage);
+ }
+}
diff --git a/java/openapi/src/com/intellij/refactoring/ReplaceConstructorWithFactoryRefactoring.java b/java/openapi/src/com/intellij/refactoring/ReplaceConstructorWithFactoryRefactoring.java
new file mode 100644
index 0000000..4b488f6
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/ReplaceConstructorWithFactoryRefactoring.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+
+/**
+ * @author dsl
+ */
+public interface ReplaceConstructorWithFactoryRefactoring extends Refactoring {
+ PsiClass getOriginalClass();
+ PsiClass getTargetClass();
+
+ /**
+ * @return null if applied to implicit default constructor
+ */
+ PsiMethod getConstructor();
+
+ String getFactoryName();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/TurnRefsToSuperRefactoring.java b/java/openapi/src/com/intellij/refactoring/TurnRefsToSuperRefactoring.java
new file mode 100644
index 0000000..90b15a9
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/TurnRefsToSuperRefactoring.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.psi.PsiClass;
+
+/**
+ * @author dsl
+ */
+public interface TurnRefsToSuperRefactoring extends Refactoring {
+ PsiClass getSuper();
+ PsiClass getTarget();
+ boolean isReplaceInstanceOf();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/TypeCookRefactoring.java b/java/openapi/src/com/intellij/refactoring/TypeCookRefactoring.java
new file mode 100644
index 0000000..f5ed79d
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/TypeCookRefactoring.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.psi.PsiElement;
+
+import java.util.List;
+
+/**
+ * @author dsl
+ */
+public interface TypeCookRefactoring extends Refactoring {
+ List<PsiElement> getElements();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/listeners/JavaRefactoringListenerManager.java b/java/openapi/src/com/intellij/refactoring/listeners/JavaRefactoringListenerManager.java
new file mode 100644
index 0000000..095f6b1
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/listeners/JavaRefactoringListenerManager.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 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.refactoring.listeners;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.components.ServiceManager;
+
+/**
+ * @author yole
+ */
+public abstract class JavaRefactoringListenerManager {
+ /**
+ * Registers a listener for moving member by pull up, push down and extract super class/interface refactorings.
+ * @param moveMembersListener listener to register
+ */
+ public abstract void addMoveMembersListener(MoveMemberListener moveMembersListener);
+
+ /**
+ * Unregisters a previously registered listener.
+ * @param moveMembersListener listener to unregister
+ */
+ public abstract void removeMoveMembersListener(MoveMemberListener moveMembersListener);
+
+ public static JavaRefactoringListenerManager getInstance(Project project) {
+ return ServiceManager.getService(project, JavaRefactoringListenerManager.class);
+ }
+}
diff --git a/java/openapi/src/com/intellij/refactoring/listeners/MoveMemberListener.java b/java/openapi/src/com/intellij/refactoring/listeners/MoveMemberListener.java
new file mode 100644
index 0000000..88f3022
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/listeners/MoveMemberListener.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2009 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.refactoring.listeners;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMember;
+
+/**
+ * Notifies that a certain member has been moved.
+ * This listener is invoked by pull up, push down and extract super refactorings.
+ * To subscribe to move refactoring use {@link com.intellij.refactoring.listeners.RefactoringElementListener} class.
+ * @author ven
+ */
+public interface MoveMemberListener {
+ /**
+ * @param sourceClass the class member was in before the refactoring
+ * @param member the member that has been moved. To obtain target class use
+ * {@link com.intellij.psi.PsiMember#getContainingClass()}. In all cases but
+ * "Move inner to upper level" target class wil be non null.
+ */
+ void memberMoved (PsiClass sourceClass, PsiMember member);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/listeners/package.html b/java/openapi/src/com/intellij/refactoring/listeners/package.html
new file mode 100644
index 0000000..2be93a0
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/listeners/package.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for receiving notifications when elements are renamed or moved by
+refactoring operations.
+</body></html>
diff --git a/java/openapi/src/com/intellij/refactoring/package.html b/java/openapi/src/com/intellij/refactoring/package.html
new file mode 100644
index 0000000..a61221c
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for invoking IDEA refactorings.
+</body></html>
diff --git a/java/openapi/src/com/intellij/refactoring/rename/RegExpValidator.java b/java/openapi/src/com/intellij/refactoring/rename/RegExpValidator.java
new file mode 100644
index 0000000..e75e9c7
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/rename/RegExpValidator.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2009 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.refactoring.rename;
+
+import com.intellij.openapi.util.Condition;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public class RegExpValidator implements Condition<String> {
+
+ private final String myPattern;
+
+ public RegExpValidator(@NonNls String pattern) {
+ myPattern = pattern;
+ }
+
+ public boolean value(final String object) {
+ return object.matches(myPattern);
+ }
+}
diff --git a/java/openapi/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegate.java b/java/openapi/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegate.java
new file mode 100644
index 0000000..af731fb
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegate.java
@@ -0,0 +1,37 @@
+/*
+ * 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.refactoring.safeDelete;
+
+import com.intellij.lang.LanguageExtension;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiParameter;
+import com.intellij.psi.PsiReference;
+import com.intellij.usageView.UsageInfo;
+
+import java.util.List;
+
+/**
+ * @author Max Medvedev
+ */
+public interface JavaSafeDeleteDelegate {
+ LanguageExtension<JavaSafeDeleteDelegate> EP =
+ new LanguageExtension<JavaSafeDeleteDelegate>("com.intellij.refactoring.safeDelete.JavaSafeDeleteDelegate");
+
+ void createUsageInfoForParameter(final PsiReference reference,
+ final List<UsageInfo> usages,
+ final PsiParameter parameter,
+ final PsiMethod method);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/util/package.html b/java/openapi/src/com/intellij/refactoring/util/package.html
new file mode 100644
index 0000000..7f7b2f6
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/util/package.html
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides classes which represent usages of elements affected by refactoring.
+Provides common utility methods used by refactorings
+</body></html>
diff --git a/java/openapi/src/com/intellij/ui/UIHelper.java b/java/openapi/src/com/intellij/ui/UIHelper.java
new file mode 100644
index 0000000..977e897
--- /dev/null
+++ b/java/openapi/src/com/intellij/ui/UIHelper.java
@@ -0,0 +1,76 @@
+/*
+ * 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.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.PackageChooser;
+import com.intellij.openapi.ui.SplitterProportionsData;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiType;
+import com.intellij.util.Function;
+import com.intellij.util.containers.Convertor;
+import com.intellij.util.ui.Table;
+import com.intellij.ui.treeStructure.treetable.TreeTable;
+
+import javax.swing.*;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.tree.TreeCellRenderer;
+import javax.swing.tree.TreePath;
+import java.awt.*;
+
+/** @deprecated to remove in IDEA 13 */
+@SuppressWarnings({"UnusedDeclaration", "deprecation"})
+public interface UIHelper {
+ void installToolTipHandler(JTree tree);
+
+ void installToolTipHandler(JTable table);
+
+ void installEditSourceOnDoubleClick(JTree tree);
+
+ void installEditSourceOnDoubleClick(TreeTable tree);
+
+ void installEditSourceOnDoubleClick(Table table);
+
+ void installTreeTableSpeedSearch(TreeTable treeTable);
+
+ void installTreeTableSpeedSearch(TreeTable treeTable, Convertor<TreePath, String> convertor);
+
+ void installTreeSpeedSearch(JTree tree);
+
+ void installTreeSpeedSearch(JTree tree, Convertor<TreePath, String> convertor);
+
+ void installListSpeedSearch(JList list);
+
+ void installListSpeedSearch(JList list, Function<Object, String> elementTextDelegate);
+
+ void installEditSourceOnEnterKeyHandler(JTree tree);
+
+ SplitterProportionsData createSplitterProportionsData();
+
+ TableCellRenderer createPsiElementRenderer(PsiElement psiElement, Project project);
+
+ TreeCellRenderer createHighlightableTreeCellRenderer();
+
+ void drawDottedRectangle(Graphics g, int x, int y, int i, int i1);
+
+ void installSmartExpander(JTree tree);
+
+ void installSelectionSaver(JTree tree);
+
+ TextComponent createTypedTextField(final String text, PsiType type, PsiElement context, final Project project);
+
+ PackageChooser createPackageChooser(String title, Project project);
+}
diff --git a/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java b/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java
new file mode 100644
index 0000000..2749c34
--- /dev/null
+++ b/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2000-2009 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.ui.classFilter;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.DefaultJDOMExternalizer;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
+import org.jdom.Element;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ClassFilter implements JDOMExternalizable, Cloneable{
+ private static final Logger LOG = Logger.getInstance("#com.intellij.ui.classFilter.ClassFilter");
+ public static final ClassFilter[] EMPTY_ARRAY = new ClassFilter[0];
+
+ public String PATTERN = "";
+ public boolean ENABLED = true;
+ private Matcher myMatcher; // to speedup matching
+
+ public ClassFilter() {
+ }
+
+ public ClassFilter(String pattern) {
+ PATTERN = pattern;
+ ENABLED = true;
+ }
+
+ public String getPattern() {
+ return PATTERN;
+ }
+ public boolean isEnabled() {
+ return ENABLED;
+ }
+
+ public void setPattern(String pattern) {
+ if (pattern != null && !pattern.equals(PATTERN)) {
+ PATTERN = pattern;
+ myMatcher = null;
+ }
+ }
+ public void setEnabled(boolean value) {
+ ENABLED = value;
+ }
+
+ public String toString() {
+ return getPattern();
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ DefaultJDOMExternalizer.readExternal(this, element);
+ }
+
+ public void writeExternal(Element element) throws WriteExternalException {
+ DefaultJDOMExternalizer.writeExternal(this, element);
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ClassFilter)) return false;
+
+ ClassFilter classFilter = (ClassFilter)o;
+
+ if (isEnabled() != classFilter.isEnabled()) return false;
+ if (!getPattern().equals(classFilter.getPattern())) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = PATTERN.hashCode();
+ result = 29 * result + (ENABLED ? 1 : 0);
+ return result;
+ }
+
+ public ClassFilter clone() {
+ try {
+ return (ClassFilter) super.clone();
+ } catch (CloneNotSupportedException e) {
+ LOG.error(e);
+ return null;
+ }
+ }
+
+ public boolean matches(String name) {
+ return getMatcher(name).matches();
+ }
+
+ private Matcher getMatcher(final String name) {
+ if (myMatcher == null) {
+ // need to quote dots and dollars
+ final String regex = getPattern().replaceAll("\\.", "\\\\.").replaceAll("\\$", "\\\\\\$").replaceAll("\\*", ".*");
+ final Pattern pattern = Pattern.compile(regex);
+ myMatcher = pattern.matcher("");
+ }
+ myMatcher.reset(name);
+ return myMatcher;
+ }
+
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java b/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java
new file mode 100644
index 0000000..85d92f5
--- /dev/null
+++ b/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * Class ClassFilterEditor
+ * @author Jeka
+ */
+package com.intellij.ui.classFilter;
+
+import com.intellij.ide.util.ClassFilter;
+import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.TreeClassChooserFactory;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.ui.*;
+import com.intellij.ui.table.JBTable;
+import com.intellij.util.IconUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.ComponentWithEmptyText;
+import com.intellij.util.ui.ItemRemovable;
+import com.intellij.util.ui.StatusText;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.table.*;
+import java.awt.*;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ClassFilterEditor extends JPanel implements ComponentWithEmptyText {
+ protected JBTable myTable = null;
+ protected FilterTableModel myTableModel = null;
+ protected final Project myProject;
+ private final ClassFilter myChooserFilter;
+ @Nullable
+ private final String myPatternsHelpId;
+
+ public ClassFilterEditor(Project project) {
+ this(project, null);
+ }
+
+ public ClassFilterEditor(Project project, ClassFilter classFilter) {
+ this(project, classFilter, null);
+ }
+
+ public ClassFilterEditor(Project project, ClassFilter classFilter, @Nullable String patternsHelpId) {
+ super(new BorderLayout());
+ myPatternsHelpId = patternsHelpId;
+ myTable = new JBTable();
+
+ final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTable)
+ .addExtraAction(new AnActionButton(getAddButtonText(), getAddButtonIcon()) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ addClassFilter();
+ }
+
+ @Override
+ public void updateButton(AnActionEvent e) {
+ super.updateButton(e);
+ setEnabled(!myProject.isDefault());
+ }
+ });
+ if (addPatternButtonVisible()) {
+ decorator.addExtraAction(new AnActionButton(getAddPatternButtonText(), getAddPatternButtonIcon()) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ addPatternFilter();
+ }
+
+ @Override
+ public void updateButton(AnActionEvent e) {
+ super.updateButton(e);
+ setEnabled(!myProject.isDefault());
+ }
+ });
+ }
+ add(decorator.setRemoveAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton button) {
+ TableUtil.removeSelectedItems(myTable);
+ }
+ }).setButtonComparator(getAddButtonText(), getAddPatternButtonText(), "Remove")
+ .disableUpDownActions().createPanel(), BorderLayout.CENTER);
+
+ myChooserFilter = classFilter;
+ myProject = project;
+
+ myTableModel = new FilterTableModel();
+ myTable.setModel(myTableModel);
+ myTable.setShowGrid(false);
+ myTable.setIntercellSpacing(new Dimension(0, 0));
+ myTable.setTableHeader(null);
+ myTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+ myTable.setColumnSelectionAllowed(false);
+ myTable.setPreferredScrollableViewportSize(new Dimension(200, 100));
+
+ TableColumnModel columnModel = myTable.getColumnModel();
+ TableColumn column = columnModel.getColumn(FilterTableModel.CHECK_MARK);
+ int width = new JCheckBox().getPreferredSize().width;
+ column.setPreferredWidth(width);
+ column.setMaxWidth(width);
+ column.setCellRenderer(new EnabledCellRenderer(myTable.getDefaultRenderer(Boolean.class)));
+ columnModel.getColumn(FilterTableModel.FILTER).setCellRenderer(new FilterCellRenderer());
+
+ getEmptyText().setText(UIBundle.message("no.patterns"));
+ }
+
+ @NotNull
+ @Override
+ public StatusText getEmptyText() {
+ return myTable.getEmptyText();
+ }
+
+ protected String getAddButtonText() {
+ return UIBundle.message("button.add.class");
+ }
+
+ protected String getAddPatternButtonText() {
+ return UIBundle.message("button.add.pattern");
+ }
+
+ protected Icon getAddButtonIcon() {
+ return IconUtil.getAddClassIcon();
+ }
+
+ protected Icon getAddPatternButtonIcon() {
+ return IconUtil.getAddPatternIcon();
+ }
+
+ protected boolean addPatternButtonVisible() {
+ return true;
+ }
+
+ public void setFilters(com.intellij.ui.classFilter.ClassFilter[] filters) {
+ myTableModel.setFilters(filters);
+ }
+
+ public com.intellij.ui.classFilter.ClassFilter[] getFilters() {
+ return myTableModel.getFilters();
+ }
+
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ myTable.setEnabled(enabled);
+ myTable.setRowSelectionAllowed(enabled);
+ myTableModel.fireTableDataChanged();
+ }
+
+ public void stopEditing() {
+ TableCellEditor editor = myTable.getCellEditor();
+ if (editor != null) {
+ editor.stopCellEditing();
+ }
+ }
+
+ protected final class FilterTableModel extends AbstractTableModel implements ItemRemovable {
+ private final List<com.intellij.ui.classFilter.ClassFilter> myFilters = new LinkedList<com.intellij.ui.classFilter.ClassFilter>();
+ public static final int CHECK_MARK = 0;
+ public static final int FILTER = 1;
+
+ public final void setFilters(com.intellij.ui.classFilter.ClassFilter[] filters) {
+ myFilters.clear();
+ if (filters != null) {
+ ContainerUtil.addAll(myFilters, filters);
+ }
+ fireTableDataChanged();
+ }
+
+ public com.intellij.ui.classFilter.ClassFilter[] getFilters() {
+ for (Iterator<com.intellij.ui.classFilter.ClassFilter> it = myFilters.iterator(); it.hasNext(); ) {
+ com.intellij.ui.classFilter.ClassFilter filter = it.next();
+ String pattern = filter.getPattern();
+ if (pattern == null || "".equals(pattern)) {
+ it.remove();
+ }
+ }
+ return myFilters.toArray(new com.intellij.ui.classFilter.ClassFilter[myFilters.size()]);
+ }
+
+ public com.intellij.ui.classFilter.ClassFilter getFilterAt(int index) {
+ return myFilters.get(index);
+ }
+
+ public int getFilterIndex(com.intellij.ui.classFilter.ClassFilter filter) {
+ return myFilters.indexOf(filter);
+ }
+
+ public void addRow(com.intellij.ui.classFilter.ClassFilter filter) {
+ myFilters.add(filter);
+ int row = myFilters.size() - 1;
+ fireTableRowsInserted(row, row);
+ }
+
+ public int getRowCount() {
+ return myFilters.size();
+ }
+
+ public int getColumnCount() {
+ return 2;
+ }
+
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ com.intellij.ui.classFilter.ClassFilter filter = myFilters.get(rowIndex);
+ if (columnIndex == FILTER) {
+ return filter;
+ }
+ if (columnIndex == CHECK_MARK) {
+ return filter.isEnabled() ? Boolean.TRUE : Boolean.FALSE;
+ }
+ return null;
+ }
+
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+ com.intellij.ui.classFilter.ClassFilter filter = myFilters.get(rowIndex);
+ if (columnIndex == FILTER) {
+ filter.setPattern(aValue != null ? aValue.toString() : "");
+ }
+ else if (columnIndex == CHECK_MARK) {
+ filter.setEnabled(aValue == null || ((Boolean)aValue).booleanValue());
+ }
+// fireTableCellUpdated(rowIndex, columnIndex);
+ fireTableRowsUpdated(rowIndex, rowIndex);
+ }
+
+ public Class getColumnClass(int columnIndex) {
+ if (columnIndex == CHECK_MARK) {
+ return Boolean.class;
+ }
+ return super.getColumnClass(columnIndex);
+ }
+
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return isEnabled() && (columnIndex == CHECK_MARK);
+ }
+
+ public void removeRow(final int idx) {
+ myFilters.remove(idx);
+ fireTableDataChanged();
+ }
+ }
+
+ private class FilterCellRenderer extends DefaultTableCellRenderer {
+ public Component getTableCellRendererComponent(JTable table, Object value,
+ boolean isSelected, boolean hasFocus, int row, int column) {
+ Color color = UIUtil.getTableFocusCellBackground();
+ UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, table.getSelectionBackground());
+ Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ if (component instanceof JLabel) {
+ ((JLabel)component).setBorder(noFocusBorder);
+ }
+ UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, color);
+ com.intellij.ui.classFilter.ClassFilter filter =
+ (com.intellij.ui.classFilter.ClassFilter)table.getValueAt(row, FilterTableModel.FILTER);
+ component.setEnabled(ClassFilterEditor.this.isEnabled() && filter.isEnabled());
+ return component;
+ }
+ }
+
+ private class EnabledCellRenderer extends DefaultTableCellRenderer {
+ private final TableCellRenderer myDelegate;
+
+ public EnabledCellRenderer(TableCellRenderer delegate) {
+ myDelegate = delegate;
+ }
+
+ public Component getTableCellRendererComponent(JTable table, Object value,
+ boolean isSelected, boolean hasFocus, int row, int column) {
+ Component component = myDelegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ component.setEnabled(ClassFilterEditor.this.isEnabled());
+ return component;
+ }
+ }
+
+ @NotNull
+ protected com.intellij.ui.classFilter.ClassFilter createFilter(String pattern) {
+ return new com.intellij.ui.classFilter.ClassFilter(pattern);
+ }
+
+ protected void addPatternFilter() {
+ ClassFilterEditorAddDialog dialog = new ClassFilterEditorAddDialog(myProject, myPatternsHelpId);
+ dialog.show();
+ if (dialog.isOK()) {
+ String pattern = dialog.getPattern();
+ if (pattern != null) {
+ com.intellij.ui.classFilter.ClassFilter filter = createFilter(pattern);
+ myTableModel.addRow(filter);
+ int row = myTableModel.getRowCount() - 1;
+ myTable.getSelectionModel().setSelectionInterval(row, row);
+ myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
+
+ myTable.requestFocus();
+ }
+ }
+ }
+
+ protected void addClassFilter() {
+ TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject).createNoInnerClassesScopeChooser(
+ UIBundle.message("class.filter.editor.choose.class.title"), GlobalSearchScope.allScope(myProject), myChooserFilter, null);
+ chooser.showDialog();
+ PsiClass selectedClass = chooser.getSelected();
+ if (selectedClass != null) {
+ com.intellij.ui.classFilter.ClassFilter filter = createFilter(getJvmClassName(selectedClass));
+ myTableModel.addRow(filter);
+ int row = myTableModel.getRowCount() - 1;
+ myTable.getSelectionModel().setSelectionInterval(row, row);
+ myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
+
+ myTable.requestFocus();
+ }
+ }
+
+ @Nullable
+ private static String getJvmClassName(PsiClass aClass) {
+ PsiClass parentClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true);
+ if (parentClass != null) {
+ final String parentName = getJvmClassName(parentClass);
+ if (parentName == null) {
+ return null;
+ }
+ return parentName + "$" + aClass.getName();
+ }
+ return aClass.getQualifiedName();
+ }
+
+ public void addPattern(String pattern) {
+ com.intellij.ui.classFilter.ClassFilter filter = createFilter(pattern);
+ myTableModel.addRow(filter);
+ }
+}
diff --git a/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditorAddDialog.java b/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditorAddDialog.java
new file mode 100644
index 0000000..693f359
--- /dev/null
+++ b/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditorAddDialog.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author: Eugene Zhuravlev
+ * Date: Sep 11, 2002
+ * Time: 5:23:47 PM
+ */
+package com.intellij.ui.classFilter;
+
+import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.TreeClassChooserFactory;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.ui.UIBundle;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+class ClassFilterEditorAddDialog extends DialogWrapper {
+ private final Project myProject;
+ private TextFieldWithBrowseButton myClassName;
+ @Nullable
+ private final String myHelpId;
+
+ public ClassFilterEditorAddDialog(Project project, @Nullable String helpId) {
+ super(project, true);
+ myProject = project;
+ myHelpId = helpId;
+ setTitle(UIBundle.message("class.filter.editor.add.dialog.title"));
+ init();
+ }
+
+ protected JComponent createCenterPanel() {
+ final JPanel panel = new JPanel(new GridBagLayout());
+ final JLabel header = new JLabel(UIBundle.message("label.class.filter.editor.add.dialog.filter.pattern"));
+ myClassName = new TextFieldWithBrowseButton(new JTextField(35));
+ final JLabel iconLabel = new JLabel(Messages.getQuestionIcon());
+
+ panel.add(header, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 10, 0, 0), 0, 0));
+ panel.add(myClassName, new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 10, 0, 0), 0, 0));
+ panel.add(iconLabel, new GridBagConstraints(0, 0, 1, 2, 0.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(15, 0, 0, 0), 0, 0));
+
+ myClassName.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ PsiClass currentClass = getSelectedClass();
+ TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject).createNoInnerClassesScopeChooser(
+ UIBundle.message("class.filter.editor.choose.class.title"), GlobalSearchScope.allScope(myProject), null, null);
+ if (currentClass != null) {
+ PsiFile containingFile = currentClass.getContainingFile();
+ if (containingFile != null) {
+ PsiDirectory containingDirectory = containingFile.getContainingDirectory();
+ if (containingDirectory != null) {
+ chooser.selectDirectory(containingDirectory);
+ }
+ }
+ }
+ chooser.showDialog();
+ PsiClass selectedClass = chooser.getSelected();
+ if (selectedClass != null) {
+ myClassName.setText(selectedClass.getQualifiedName());
+ }
+ }
+ });
+
+ myClassName.setEnabled(myProject != null);
+
+ return panel;
+ }
+
+ private PsiClass getSelectedClass() {
+ final PsiManager psiManager = PsiManager.getInstance(myProject);
+ String classQName = myClassName.getText();
+ if ("".equals(classQName)) {
+ return null;
+ }
+ return JavaPsiFacade.getInstance(psiManager.getProject()).findClass(classQName, GlobalSearchScope.allScope(myProject));
+ }
+
+ public JComponent getPreferredFocusedComponent() {
+ return myClassName.getTextField();
+ }
+
+ public String getPattern() {
+ return myClassName.getText();
+ }
+
+ protected String getDimensionServiceKey(){
+ return "#com.intellij.debugger.ui.breakpoints.BreakpointsConfigurationDialogFactory.BreakpointsConfigurationDialog.AddFieldBreakpointDialog";
+ }
+
+ @Override @Nullable
+ protected String getHelpId() {
+ return myHelpId;
+ }
+}
diff --git a/java/openapi/src/com/intellij/ui/classFilter/DebuggerClassFilterProvider.java b/java/openapi/src/com/intellij/ui/classFilter/DebuggerClassFilterProvider.java
new file mode 100644
index 0000000..115d57f
--- /dev/null
+++ b/java/openapi/src/com/intellij/ui/classFilter/DebuggerClassFilterProvider.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2009 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.ui.classFilter;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Oct 22, 2008
+ */
+public interface DebuggerClassFilterProvider {
+ ExtensionPointName<DebuggerClassFilterProvider> EP_NAME = new ExtensionPointName<DebuggerClassFilterProvider>("com.intellij.debuggerClassFilterProvider");
+
+ List<ClassFilter> getFilters();
+}
diff --git a/java/openapi/src/com/intellij/unscramble/UnscrambleSupport.java b/java/openapi/src/com/intellij/unscramble/UnscrambleSupport.java
new file mode 100644
index 0000000..0035c60
--- /dev/null
+++ b/java/openapi/src/com/intellij/unscramble/UnscrambleSupport.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2009 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.unscramble;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.Nullable;
+
+public interface UnscrambleSupport {
+ ExtensionPointName<UnscrambleSupport> EP_NAME = ExtensionPointName.create("com.intellij.unscrambleSupport");
+
+ @Nullable
+ String unscramble(Project project, String text, String logName);
+ String getPresentableName();
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/unscramble/package.html b/java/openapi/src/com/intellij/unscramble/package.html
new file mode 100644
index 0000000..e24ba98
--- /dev/null
+++ b/java/openapi/src/com/intellij/unscramble/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for integrating custom stacktrace unscramblers with IDEA.
+</body></html>
diff --git a/java/openapi/src/com/intellij/util/VisibilityUtil.java b/java/openapi/src/com/intellij/util/VisibilityUtil.java
new file mode 100644
index 0000000..ed44304
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/VisibilityUtil.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: dsl
+ * Date: 07.06.2002
+ * Time: 18:48:01
+ * To change template for new class use
+ * Code Style | Class Templates options (Tools | IDE Options).
+ */
+package com.intellij.util;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.usageView.UsageInfo;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NonNls;
+
+
+public class VisibilityUtil {
+ @NonNls public static final String ESCALATE_VISIBILITY = "EscalateVisible";
+ private static final String[] visibilityModifiers = {
+ PsiModifier.PRIVATE,
+ PsiModifier.PACKAGE_LOCAL,
+ PsiModifier.PROTECTED,
+ PsiModifier.PUBLIC
+ };
+
+ private VisibilityUtil() {
+ }
+
+ public static int compare(@PsiModifier.ModifierConstant String v1, @PsiModifier.ModifierConstant String v2) {
+ return ArrayUtil.find(visibilityModifiers, v2) - ArrayUtil.find(visibilityModifiers, v1);
+ }
+
+ @PsiModifier.ModifierConstant
+ public static String getHighestVisibility(@PsiModifier.ModifierConstant String v1, @PsiModifier.ModifierConstant String v2) {
+ if(v1.equals(v2)) return v1;
+
+ if(PsiModifier.PRIVATE.equals(v1)) return v2;
+ if(PsiModifier.PUBLIC.equals(v1)) return PsiModifier.PUBLIC;
+ if(PsiModifier.PRIVATE.equals(v2)) return v1;
+
+ return PsiModifier.PUBLIC;
+ }
+
+ public static void escalateVisibility(PsiMember modifierListOwner, PsiElement place) throws IncorrectOperationException {
+ final String visibilityModifier = getVisibilityModifier(modifierListOwner.getModifierList());
+ int index;
+ for (index = 0; index < visibilityModifiers.length; index++) {
+ String modifier = visibilityModifiers[index];
+ if(modifier.equals(visibilityModifier)) break;
+ }
+ for(;index < visibilityModifiers.length && !PsiUtil.isAccessible(modifierListOwner, place, null); index++) {
+ @PsiModifier.ModifierConstant String modifier = visibilityModifiers[index];
+ PsiUtil.setModifierProperty(modifierListOwner, modifier, true);
+ }
+ }
+
+
+ @PsiModifier.ModifierConstant
+ public static String getPossibleVisibility(final PsiMember psiMethod, final PsiElement place) {
+ if (PsiUtil.isAccessible(psiMethod, place, null)) return getVisibilityModifier(psiMethod.getModifierList());
+ if (JavaPsiFacade.getInstance(psiMethod.getProject()).arePackagesTheSame(psiMethod, place)) {
+ return PsiModifier.PACKAGE_LOCAL;
+ }
+ if (InheritanceUtil.isInheritorOrSelf(PsiTreeUtil.getParentOfType(place, PsiClass.class),
+ psiMethod.getContainingClass(), true)) {
+ return PsiModifier.PROTECTED;
+ }
+ return PsiModifier.PUBLIC;
+ }
+
+ @PsiModifier.ModifierConstant
+ public static String getVisibilityModifier(PsiModifierList list) {
+ if (list == null) return PsiModifier.PACKAGE_LOCAL;
+ for (@PsiModifier.ModifierConstant String modifier : visibilityModifiers) {
+ if (list.hasModifierProperty(modifier)) {
+ return modifier;
+ }
+ }
+ return PsiModifier.PACKAGE_LOCAL;
+ }
+
+ public static String getVisibilityString(@PsiModifier.ModifierConstant String visibilityModifier) {
+ if(PsiModifier.PACKAGE_LOCAL.equals(visibilityModifier)) {
+ return "";
+ }
+ return visibilityModifier;
+ }
+
+ @Nls
+ public static String getVisibilityStringToDisplay(PsiMember member) {
+ if (member.hasModifierProperty(PsiModifier.PUBLIC)) {
+ return toPresentableText(PsiModifier.PUBLIC);
+ }
+ if (member.hasModifierProperty(PsiModifier.PROTECTED)) {
+ return toPresentableText(PsiModifier.PROTECTED);
+ }
+ if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
+ return toPresentableText(PsiModifier.PRIVATE);
+ }
+ return toPresentableText(PsiModifier.PACKAGE_LOCAL);
+ }
+
+ public static String toPresentableText(@PsiModifier.ModifierConstant String modifier) {
+ return PsiBundle.visibilityPresentation(modifier);
+ }
+
+ public static void fixVisibility(UsageInfo[] usageInfos, PsiMember member, @PsiModifier.ModifierConstant String newVisibility) {
+ if (newVisibility == null) return;
+ if (ESCALATE_VISIBILITY.equals(newVisibility)) {
+ for (UsageInfo info : usageInfos) {
+ final PsiElement element = info.getElement();
+ if (element != null) {
+ escalateVisibility(member, element);
+ }
+ }
+ } else {
+ setVisibility(member.getModifierList(), newVisibility);
+ }
+ }
+
+ public static void setVisibility(PsiModifierList modifierList, @PsiModifier.ModifierConstant String newVisibility) throws IncorrectOperationException {
+ modifierList.setModifierProperty(newVisibility, true);
+ }
+
+ public static void fixVisibility(PsiExpression[] expressions, PsiMember member, String newVisibility) {
+ if (newVisibility == null) return;
+ if (ESCALATE_VISIBILITY.equals(newVisibility)) {
+ for (PsiExpression element : expressions) {
+ escalateVisibility(member, element);
+ }
+ }
+ else {
+ setVisibility(member.getModifierList(), newVisibility);
+ }
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFile.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFile.java
new file mode 100644
index 0000000..25fb330
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFile.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.xml.XmlFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface ConfigFile extends Disposable, ModificationTracker {
+ ConfigFile[] EMPTY_ARRAY = new ConfigFile[0];
+
+ String getUrl();
+
+ @Nullable
+ VirtualFile getVirtualFile();
+
+ @Nullable
+ PsiFile getPsiFile();
+
+ @Nullable
+ XmlFile getXmlFile();
+
+
+ @NotNull
+ ConfigFileMetaData getMetaData();
+
+ @NotNull
+ ConfigFileInfo getInfo();
+
+ boolean isValid();
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileAdapter.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileAdapter.java
new file mode 100644
index 0000000..b8b016d
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileAdapter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+/**
+ * @author Gregory.Shrago
+ */
+public abstract class ConfigFileAdapter implements ConfigFileListener {
+ protected void configChanged(ConfigFile configFile) {
+ }
+
+ public void configFileAdded(ConfigFile configFile) {
+ configChanged(configFile);
+ }
+
+ public void configFileRemoved(ConfigFile configFile) {
+ configChanged(configFile);
+ }
+
+ public void configFileChanged(ConfigFile configFile) {
+ configChanged(configFile);
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileContainer.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileContainer.java
new file mode 100644
index 0000000..adfd415
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileContainer.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.Disposable;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface ConfigFileContainer extends Disposable {
+ Project getProject();
+
+ void addListener(ConfigFileListener listener, Disposable parentDisposable);
+
+ void addListener(ConfigFileListener listener);
+
+ void removeListener(ConfigFileListener listener);
+
+ ConfigFile[] getConfigFiles();
+
+ ConfigFileInfoSet getConfiguration();
+
+ @Nullable
+ ConfigFile getConfigFile(ConfigFileMetaData metaData);
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileFactory.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileFactory.java
new file mode 100644
index 0000000..34690fe
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public abstract class ConfigFileFactory {
+
+ public static ConfigFileFactory getInstance() {
+ return ServiceManager.getService(ConfigFileFactory.class);
+ }
+
+
+ public abstract ConfigFileMetaDataProvider createMetaDataProvider(ConfigFileMetaData... metaDatas);
+
+ public abstract ConfigFileInfoSet createConfigFileInfoSet(ConfigFileMetaDataProvider metaDataProvider);
+
+ public abstract ConfigFileContainer createConfigFileContainer(Project project, ConfigFileMetaDataProvider metaDataProvider,
+ ConfigFileInfoSet configuration);
+
+ public abstract ConfigFileMetaDataRegistry createMetaDataRegistry();
+
+ @Nullable
+ public abstract VirtualFile createFile(@Nullable Project project, String url, ConfigFileVersion version, final boolean forceNew);
+
+ public abstract ConfigFileContainer createSingleFileContainer(Project project, ConfigFileMetaData metaData);
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfo.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfo.java
new file mode 100644
index 0000000..0814871
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfo.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class ConfigFileInfo {
+ @NotNull private final ConfigFileMetaData myMetaData;
+ @NotNull private final String myUrl;
+
+
+ public ConfigFileInfo(@NotNull final ConfigFileMetaData metaData, @NotNull final String url) {
+ myMetaData = metaData;
+ myUrl = url;
+ }
+
+ @NotNull
+ public ConfigFileMetaData getMetaData() {
+ return myMetaData;
+ }
+
+ @NotNull
+ public String getUrl() {
+ return myUrl;
+ }
+
+
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final ConfigFileInfo that = (ConfigFileInfo)o;
+
+ if (!myMetaData.equals(that.myMetaData)) return false;
+ if (!myUrl.equals(that.myUrl)) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = myMetaData.hashCode();
+ result = 31 * result + myUrl.hashCode();
+ return result;
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfoSet.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfoSet.java
new file mode 100644
index 0000000..862389b
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfoSet.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+import com.intellij.openapi.util.JDOMExternalizable;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public interface ConfigFileInfoSet extends JDOMExternalizable {
+ void addConfigFile(ConfigFileInfo descriptor);
+
+ void addConfigFile(ConfigFileMetaData metaData, @NonNls String url);
+
+ void removeConfigFile(ConfigFileInfo descriptor);
+
+ void replaceConfigFile(ConfigFileMetaData metaData, @NonNls String newUrl);
+
+ void removeConfigFiles(ConfigFileMetaData... metaData);
+
+ ConfigFileInfo[] getConfigFileInfos();
+
+ void setConfigFileInfos(Collection<ConfigFileInfo> descriptors);
+
+ ConfigFileMetaDataProvider getMetaDataProvider();
+
+ @Nullable
+ ConfigFileInfo getConfigFileInfo(ConfigFileMetaData metaData);
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileListener.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileListener.java
new file mode 100644
index 0000000..2d1e778
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileListener.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+import java.util.EventListener;
+
+/**
+ * @author nik
+ */
+public interface ConfigFileListener extends EventListener {
+
+ void configFileAdded(ConfigFile configFile);
+
+ void configFileRemoved(ConfigFile configFile);
+
+ void configFileChanged(ConfigFile descriptor);
+
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaData.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaData.java
new file mode 100644
index 0000000..c3b1d0c
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaData.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+import com.intellij.openapi.diagnostic.Logger;
+
+import java.util.Arrays;
+
+/**
+ * @author nik
+ */
+public class ConfigFileMetaData {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.util.descriptors.ConfigFileMetaData");
+ private final String myTitle;
+ private final String myId;
+ private final String myFileName;
+ private final String myDirectoryPath;
+ private final ConfigFileVersion[] myVersions;
+ private final ConfigFileVersion myDefaultVersion;
+ private final boolean myOptional;
+ private final boolean myFileNameFixed;
+ private final boolean myUnique;
+
+ public ConfigFileMetaData(final String title,
+ final @NonNls String id,
+ final @NonNls String fileName,
+ final @NonNls String directoryPath,
+ final ConfigFileVersion[] versions,
+ final @Nullable ConfigFileVersion defaultVersion,
+ final boolean optional,
+ final boolean fileNameFixed,
+ final boolean unique) {
+ myTitle = title;
+ myId = id;
+ myFileName = fileName;
+ myDirectoryPath = directoryPath;
+ myFileNameFixed = fileNameFixed;
+ myUnique = unique;
+ LOG.assertTrue(versions.length > 0);
+ myVersions = versions;
+ myOptional = optional;
+ myDefaultVersion = defaultVersion != null ? defaultVersion : myVersions[myVersions.length - 1];
+ LOG.assertTrue(Arrays.asList(myVersions).contains(myDefaultVersion));
+ }
+
+ public ConfigFileMetaData(final String title,
+ final @NonNls String fileName,
+ final @NonNls String directoryPath,
+ final ConfigFileVersion[] versions,
+ ConfigFileVersion defaultVersion,
+ boolean optional,
+ final boolean fileNameFixed,
+ final boolean unique) {
+ this(title, fileName, fileName, directoryPath, versions, defaultVersion, optional, fileNameFixed, unique);
+ }
+
+ public String getTitle() {
+ return myTitle;
+ }
+
+ public String getId() {
+ return myId;
+ }
+
+ public String getFileName() {
+ return myFileName;
+ }
+
+ public String getDirectoryPath() {
+ return myDirectoryPath;
+ }
+
+ public boolean isOptional() {
+ return myOptional;
+ }
+
+ public ConfigFileVersion[] getVersions() {
+ return myVersions;
+ }
+
+
+ public String toString() {
+ return myTitle;
+ }
+
+ public ConfigFileVersion getDefaultVersion() {
+ return myDefaultVersion;
+ }
+
+ public boolean isFileNameFixed() {
+ return myFileNameFixed;
+ }
+
+ public boolean isUnique() {
+ return myUnique;
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataProvider.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataProvider.java
new file mode 100644
index 0000000..3ba20c2
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataProvider.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author nik
+ */
+public interface ConfigFileMetaDataProvider {
+
+ @NotNull
+ ConfigFileMetaData[] getMetaData();
+
+ @Nullable
+ ConfigFileMetaData findMetaData(@NonNls @NotNull String id);
+
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataRegistry.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataRegistry.java
new file mode 100644
index 0000000..aaba2c4
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataRegistry.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface ConfigFileMetaDataRegistry extends ConfigFileMetaDataProvider {
+
+ void registerMetaData(@NotNull ConfigFileMetaData... metaData);
+
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileUtil.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileUtil.java
new file mode 100644
index 0000000..43c028d
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileUtil.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class ConfigFileUtil {
+ private ConfigFileUtil() {
+ }
+
+ @NotNull
+ public static ConfigFileVersion getVersionByName(ConfigFileMetaData metaData, String name) {
+ for (ConfigFileVersion version : metaData.getVersions()) {
+ if (name.equals(version.getName())) {
+ return version;
+ }
+ }
+ return metaData.getDefaultVersion();
+ }
+
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileVersion.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileVersion.java
new file mode 100644
index 0000000..1f03b7e
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileVersion.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2009 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.util.descriptors;
+
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author nik
+ */
+public class ConfigFileVersion {
+ private final String myName;
+ private @NonNls final String myTemplateName;
+
+ public ConfigFileVersion(final String name, final @NonNls String templateName) {
+ myName = name;
+ myTemplateName = templateName;
+ }
+
+
+ public String getName() {
+ return myName;
+ }
+
+ public String getTemplateName() {
+ return myTemplateName;
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/net/LockException.java b/java/openapi/src/com/intellij/util/net/LockException.java
new file mode 100644
index 0000000..4213e65
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/net/LockException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2009 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.util.net;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: stathik
+ * Date: Dec 16, 2003
+ * Time: 9:47:01 PM
+ * To change this template use Options | File Templates.
+ */
+public class LockException extends Exception {
+ public LockException(int port) {
+ super (Integer.toString(port));
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/net/package.html b/java/openapi/src/com/intellij/util/net/package.html
new file mode 100644
index 0000000..e848fb4
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/net/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides user interface components for configuring HTTP settings.
+</body></html>
diff --git a/java/openapi/src/com/intellij/util/package.html b/java/openapi/src/com/intellij/util/package.html
new file mode 100644
index 0000000..bc7cbd7
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/package.html
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright 2000-2007 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.
+ -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides assorted utility classes.
+</body></html>
diff --git a/java/openapi/src/com/intellij/util/xml/CanonicalPsiTypeConverter.java b/java/openapi/src/com/intellij/util/xml/CanonicalPsiTypeConverter.java
new file mode 100644
index 0000000..093fac1
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/CanonicalPsiTypeConverter.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2009 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.util.xml;
+
+import com.intellij.psi.PsiType;
+
+/**
+ * Converter for {@link com.intellij.psi.PsiType} that uses {@link com.intellij.psi.PsiType#getCanonicalText()}
+ * as string representation
+ *
+ * @author peter
+ */
+public abstract class CanonicalPsiTypeConverter extends Converter<PsiType> {
+}
diff --git a/java/openapi/src/com/intellij/util/xml/ClassMappingNameConverter.java b/java/openapi/src/com/intellij/util/xml/ClassMappingNameConverter.java
new file mode 100644
index 0000000..3c81020
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/ClassMappingNameConverter.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2010 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.util.xml;
+
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassType;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.codeStyle.SuggestedNameInfo;
+import com.intellij.psi.codeStyle.VariableKind;
+import com.intellij.psi.util.PsiTypesUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @see com.intellij.util.xml.MappingClass
+ * @author Dmitry Avdeev
+ */
+public class ClassMappingNameConverter extends ResolvingConverter.StringConverter {
+
+ @NotNull
+ @Override
+ public Collection<? extends String> getVariants(ConvertContext context) {
+ DomElement parent = context.getInvocationElement().getParent();
+ assert parent != null;
+ List<DomElement> children = DomUtil.getDefinedChildren(parent, true, true);
+ DomElement classElement = ContainerUtil.find(children, new Condition<DomElement>() {
+ @Override
+ public boolean value(DomElement domElement) {
+ return domElement.getAnnotation(MappingClass.class) != null;
+ }
+ });
+ if (classElement == null) return Collections.emptyList();
+ Object value = ((GenericDomValue)classElement).getValue();
+ if (value == null) return Collections.emptyList();
+ assert value instanceof PsiClass : classElement + " should have PsiClass type";
+ PsiClass psiClass = (PsiClass)value;
+
+ JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(context.getProject());
+ PsiClassType classType = PsiTypesUtil.getClassType(psiClass);
+ SuggestedNameInfo info = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, classType);
+ return Arrays.asList(info.names);
+ }
+
+ @Override
+ public PsiElement resolve(String o, ConvertContext context) {
+ DomElement parent = context.getInvocationElement().getParent();
+ assert parent != null;
+ return parent.getXmlElement();
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/xml/ClassTemplate.java b/java/openapi/src/com/intellij/util/xml/ClassTemplate.java
new file mode 100644
index 0000000..8d256bb
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/ClassTemplate.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 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.util.xml;
+
+import com.intellij.psi.util.ClassKind;
+import org.jetbrains.annotations.NonNls;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * To be used together with {@link com.intellij.util.xml.ExtendClass}.
+ *
+ * If specified, a 'create from usage' quick fix will create class based on the {@link #value()} template.
+ *
+ * @author peter
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ClassTemplate {
+ @NonNls String value() default "";
+
+ /**
+ * @return affects the quick fix presentable text, 'Create class ...' or 'Create interface ...', etc.
+ */
+ ClassKind kind() default ClassKind.CLASS;
+
+}
diff --git a/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java b/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java
new file mode 100644
index 0000000..a246206
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2010 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.util.xml;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.xml.XmlElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+ */
+public class DomJavaUtil {
+ private DomJavaUtil() {
+ }
+
+ @Nullable
+ public static PsiClass findClass(@Nullable String name, @NotNull PsiFile file, @Nullable final Module module, @Nullable final GlobalSearchScope searchScope) {
+ if (name == null) return null;
+ if (name.indexOf('$')>=0) name = name.replace('$', '.');
+
+ final GlobalSearchScope scope;
+ if (searchScope == null) {
+
+ if (module != null) {
+ file = file.getOriginalFile();
+ VirtualFile virtualFile = file.getVirtualFile();
+ if (virtualFile == null) {
+ scope = GlobalSearchScope.moduleRuntimeScope(module, true);
+ }
+ else {
+ ProjectFileIndex fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex();
+ boolean tests = fileIndex.isInTestSourceContent(virtualFile);
+ scope = module.getModuleRuntimeScope(tests);
+ }
+ }
+ else {
+ scope = file.getResolveScope();
+ }
+ }
+ else {
+ scope = searchScope;
+ }
+
+ final PsiClass aClass = JavaPsiFacade.getInstance(file.getProject()).findClass(name, scope);
+ if (aClass != null) {
+ assert aClass.isValid() : name;
+ }
+ return aClass;
+ }
+
+ @Nullable
+ public static PsiClass findClass(@Nullable String name, @NotNull DomElement element) {
+ assert element.isValid();
+ XmlElement xmlElement = element.getXmlElement();
+ if (xmlElement != null) {
+ assert xmlElement.isValid();
+ return findClass(name, xmlElement.getContainingFile(), element.getModule(), element.getResolveScope());
+ }
+ return null;
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/xml/ExtendClass.java b/java/openapi/src/com/intellij/util/xml/ExtendClass.java
new file mode 100644
index 0000000..c207b12
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/ExtendClass.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2009 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.util.xml;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Annotates DOM methods that return either {@link com.intellij.psi.PsiClass} or
+ * {@link com.intellij.util.xml.GenericDomValue}<{@link com.intellij.psi.PsiClass}>.
+ * Specifies that the references class should extend some other class (or implement interface).
+ * If this doesn't happen, error will appear.
+ *
+ * @see com.intellij.util.xml.ClassTemplate
+ * @author Dmitry Avdeev
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExtendClass {
+
+ /**
+ * @return qualified name of the base class
+ */
+ String value() default "";
+
+ /**
+ * @return states that the class should be concrete and have public default constructor.
+ */
+ boolean instantiatable() default true;
+
+ /**
+ * @return states that the class implements "decorator" pattern, i.e. it should have constructor with
+ * one parameter of the same type
+ */
+ boolean canBeDecorator() default false;
+
+ boolean allowEmpty() default false;
+
+ boolean allowNonPublic() default false;
+
+ boolean allowAbstract() default true;
+
+ boolean allowInterface() default true;
+
+ boolean allowEnum() default true;
+
+ boolean jvmFormat() default true;
+}
diff --git a/java/openapi/src/com/intellij/util/xml/ExtendClassImpl.java b/java/openapi/src/com/intellij/util/xml/ExtendClassImpl.java
new file mode 100644
index 0000000..864e434
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/ExtendClassImpl.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2009 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.util.xml;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * @author peter
+*/
+@SuppressWarnings({"ClassExplicitlyAnnotation"})
+public abstract class ExtendClassImpl implements ExtendClass {
+
+ public boolean instantiatable() {
+ return false;
+ }
+
+ public boolean canBeDecorator() {
+ return false;
+ }
+
+ public boolean allowEmpty() {
+ return false;
+ }
+
+ public boolean allowNonPublic() {
+ return false;
+ }
+
+ public boolean allowAbstract() {
+ return true;
+ }
+
+ public boolean allowInterface() {
+ return true;
+ }
+
+ public boolean allowEnum() {
+ return true;
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return ExtendClass.class;
+ }
+
+ public boolean jvmFormat() {
+ return true;
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/xml/JvmPsiTypeConverter.java b/java/openapi/src/com/intellij/util/xml/JvmPsiTypeConverter.java
new file mode 100644
index 0000000..40de5f8
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/JvmPsiTypeConverter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2009 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.util.xml;
+
+import com.intellij.psi.PsiType;
+
+/**
+ * Converter for {@link com.intellij.psi.PsiType} that uses JVM internal representation. See {@link Class#getName()}
+ *
+ * @author peter
+ */
+public abstract class JvmPsiTypeConverter extends Converter<PsiType> {
+}
diff --git a/java/openapi/src/com/intellij/util/xml/MappingClass.java b/java/openapi/src/com/intellij/util/xml/MappingClass.java
new file mode 100644
index 0000000..1267a6a
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/MappingClass.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2010 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.util.xml;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Marks a DomElement as containing class fqn for {@link com.intellij.util.xml.ClassMappingNameConverter}
+ * @author Dmitry Avdeev
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MappingClass {
+}
diff --git a/java/openapi/src/com/intellij/util/xml/actions/CreateClassMappingAction.java b/java/openapi/src/com/intellij/util/xml/actions/CreateClassMappingAction.java
new file mode 100644
index 0000000..80b5ede
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/actions/CreateClassMappingAction.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2010 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.util.xml.actions;
+
+import com.intellij.ide.util.ClassFilter;
+import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.TreeClassChooserFactory;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.containers.HashMap;
+import com.intellij.util.xml.DomElement;
+import com.intellij.util.xml.actions.generate.DomTemplateRunner;
+import com.intellij.util.xml.ui.actions.generate.CreateDomElementAction;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Map;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public abstract class CreateClassMappingAction<T extends DomElement> extends CreateDomElementAction<T> {
+
+ @Nullable private final String myBaseClass;
+ private final String myTemplate;
+
+ public CreateClassMappingAction(Class<T> contextClass, @Nullable String baseClass, String template) {
+ super(contextClass);
+ myBaseClass = baseClass;
+ myTemplate = template;
+ }
+
+ @Override
+ protected DomElement createElement(final T context, final Editor editor, PsiFile file, final Project project) {
+ PsiClass selectedClass;
+ if (!ApplicationManager.getApplication().isUnitTestMode()) {
+ PsiClass baseClass = getBaseClass(context, project, myBaseClass);
+ TreeClassChooser chooser = TreeClassChooserFactory.getInstance(project)
+ .createInheritanceClassChooser(getChooserTitle(), GlobalSearchScope.allScope(project), baseClass, null, new ClassFilter() {
+ @Override
+ public boolean isAccepted(PsiClass aClass) {
+ return !aClass.isInterface() && !aClass.hasModifierProperty(PsiModifier.ABSTRACT);
+ }
+ });
+ chooser.showDialog();
+ selectedClass = chooser.getSelected();
+ }
+ else {
+ selectedClass = getBaseClass(context, project, myBaseClass == null ? CommonClassNames.JAVA_LANG_OBJECT : myBaseClass);
+ }
+ if (selectedClass == null) return null;
+
+ return createElement(context, editor, file, project, selectedClass);
+ }
+
+ @Nullable
+ protected DomElement createElement(final T context,
+ final Editor editor,
+ final PsiFile file,
+ final Project project,
+ PsiClass selectedClass) {
+ final Map<String,String> map = new HashMap<String, String>();
+ map.put("CLASS_NAME", selectedClass.getQualifiedName());
+ new WriteCommandAction.Simple(project, file) {
+ @Override
+ protected void run() throws Throwable {
+ DomTemplateRunner.getInstance(project).runTemplate(createElement(context), myTemplate, editor, map);
+ }
+ }.execute();
+ return null;
+ }
+
+ protected String getChooserTitle() {
+ String text = getTemplatePresentation().getText();
+ if (text.endsWith("...")) {
+ text = StringUtil.trimEnd(text, "...");
+ }
+ return "Choose " + text + " Class";
+ }
+
+ protected abstract DomElement createElement(T context);
+
+ @Nullable
+ protected PsiClass getBaseClass(T context, Project project, String baseClass) {
+ return baseClass == null ? null : JavaPsiFacade.getInstance(project).findClass(baseClass, GlobalSearchScope.allScope(project));
+ }
+
+ @Override
+ public boolean startInWriteAction() {
+ return false;
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/xml/converters/AbstractMemberResolveConverter.java b/java/openapi/src/com/intellij/util/xml/converters/AbstractMemberResolveConverter.java
new file mode 100644
index 0000000..230fa14
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/AbstractMemberResolveConverter.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2000-2009 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.util.xml.converters;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInsight.intention.QuickFixFactory;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.ide.TypePresentationService;
+import com.intellij.psi.*;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.psi.util.PropertyMemberType;
+import com.intellij.psi.util.PropertyUtil;
+import com.intellij.util.xml.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * @author Gregory.Shrago
+ */
+public abstract class AbstractMemberResolveConverter extends ResolvingConverter<PsiMember> {
+ @Nullable
+ protected abstract PsiClass getTargetClass(final ConvertContext context);
+
+ @NotNull
+ protected abstract PropertyMemberType[] getMemberTypes(final ConvertContext context);
+
+ @NotNull
+ protected PsiType getPsiType(final ConvertContext context) {
+ return PsiType.getJavaLangObject(context.getPsiManager(), ProjectScope.getAllScope(context.getPsiManager().getProject()));
+ }
+
+ protected boolean isLookDeep() {
+ return true;
+ }
+
+ protected String getPropertyName(final String s, final ConvertContext context) {
+ return s;
+ }
+
+ public PsiMember fromString(final String s, final ConvertContext context) {
+ if (s == null) return null;
+ final PsiClass psiClass = getTargetClass(context);
+ if (psiClass == null) return null;
+ for (PropertyMemberType type : getMemberTypes(context)) {
+ switch (type) {
+ case FIELD:
+ final PsiField field = psiClass.findFieldByName(s, isLookDeep());
+ if (field != null) return field;
+ break;
+ case GETTER:
+ final PsiMethod getter = PropertyUtil.findPropertyGetter(psiClass, getPropertyName(s, context), false, isLookDeep());
+ if (getter != null) return getter;
+ break;
+ case SETTER:
+ final PsiMethod setter = PropertyUtil.findPropertySetter(psiClass, getPropertyName(s, context), false, isLookDeep());
+ if (setter != null) return setter;
+ break;
+ }
+ }
+ return null;
+ }
+
+
+ public String toString(final PsiMember t, final ConvertContext context) {
+ return t == null? null : getPropertyName(t.getName(), context);
+ }
+
+ public String getErrorMessage(final String s, final ConvertContext context) {
+ final DomElement parent = context.getInvocationElement().getParent();
+ assert parent != null;
+ return CodeInsightBundle.message("error.cannot.resolve.0.1", TypePresentationService.getService().getTypeName(parent), s);
+ }
+
+ @NotNull
+ public Collection<? extends PsiMember> getVariants(final ConvertContext context) {
+ final PsiClass psiClass = getTargetClass(context);
+ if (psiClass == null) return Collections.emptyList();
+
+ final ArrayList<PsiMember> list = new ArrayList<PsiMember>();
+ for (PsiField psiField : isLookDeep()? psiClass.getAllFields() : psiClass.getFields()) {
+ if (fieldSuits(psiField)) {
+ list.add(psiField);
+ }
+ }
+ for (PsiMethod psiMethod : isLookDeep()? psiClass.getAllMethods() : psiClass.getMethods()) {
+ if (methodSuits(psiMethod)) {
+ list.add(psiMethod);
+ }
+ }
+ return list;
+ }
+
+ protected boolean methodSuits(final PsiMethod psiMethod) {
+ return !psiMethod.isConstructor() && !psiMethod.hasModifierProperty(PsiModifier.STATIC) && PropertyUtil.getPropertyName(psiMethod) != null;
+ }
+
+ protected boolean fieldSuits(final PsiField psiField) {
+ return !psiField.hasModifierProperty(PsiModifier.STATIC);
+ }
+
+ public LocalQuickFix[] getQuickFixes(final ConvertContext context) {
+ final String targetName = ((GenericValue)context.getInvocationElement()).getStringValue();
+ if (!JavaPsiFacade.getInstance(context.getProject()).getNameHelper().isIdentifier(targetName)) return super.getQuickFixes(context);
+ final PsiClass targetClass = getTargetClass(context);
+ if (targetClass == null) return super.getQuickFixes(context);
+ final PropertyMemberType memberType = getMemberTypes(context)[0];
+
+ final PsiType psiType = getPsiType(context);
+ final IntentionAction fix = QuickFixFactory.getInstance().createCreateFieldOrPropertyFix(targetClass, targetName, psiType, memberType);
+ return fix instanceof LocalQuickFix? new LocalQuickFix[] {(LocalQuickFix)fix} : super.getQuickFixes(context);
+ }
+
+ public void handleElementRename(final GenericDomValue<PsiMember> genericValue, final ConvertContext context, final String newElementName) {
+ super.handleElementRename(genericValue, context, getPropertyName(newElementName, context));
+ }
+
+ public void bindReference(final GenericDomValue<PsiMember> genericValue, final ConvertContext context, final PsiElement newTarget) {
+ if (newTarget instanceof PsiMember) {
+ final String elementName = ((PsiMember)newTarget).getName();
+ genericValue.setStringValue(getPropertyName(elementName, context));
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodParams.java b/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodParams.java
new file mode 100644
index 0000000..1f9ee82
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodParams.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2009 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.util.xml.converters;
+
+import com.intellij.psi.PsiType;
+import com.intellij.util.xml.GenericDomValue;
+import com.intellij.util.xml.DomElement;
+
+import java.util.List;
+
+/**
+ * @author peter
+ */
+public interface AbstractMethodParams extends DomElement {
+ List<GenericDomValue<PsiType>> getMethodParams();
+
+ GenericDomValue<PsiType> addMethodParam();
+}
diff --git a/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodResolveConverter.java b/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodResolveConverter.java
new file mode 100644
index 0000000..d917c15
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodResolveConverter.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2000-2009 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.util.xml.converters;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.ide.IdeBundle;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Ref;
+import com.intellij.psi.*;
+import com.intellij.util.CommonProcessors;
+import com.intellij.util.Function;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.xml.ConvertContext;
+import com.intellij.util.xml.DomElement;
+import com.intellij.util.xml.GenericDomValue;
+import com.intellij.util.xml.ResolvingConverter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author peter
+ */
+public abstract class AbstractMethodResolveConverter<ParentType extends DomElement> extends ResolvingConverter<PsiMethod> {
+ public static final String ALL_METHODS = "*";
+ private final Class<ParentType> myDomMethodClass;
+
+ protected AbstractMethodResolveConverter(final Class<ParentType> domMethodClass) {
+ myDomMethodClass = domMethodClass;
+ }
+
+ @NotNull
+ protected abstract Collection<PsiClass> getPsiClasses(final ParentType parent, final ConvertContext context);
+
+ @Nullable
+ protected abstract AbstractMethodParams getMethodParams(@NotNull ParentType parent);
+
+ public void bindReference(final GenericDomValue<PsiMethod> genericValue, final ConvertContext context, final PsiElement element) {
+ assert element instanceof PsiMethod : "PsiMethod expected";
+ final PsiMethod psiMethod = (PsiMethod)element;
+ final ParentType parent = getParent(context);
+ final AbstractMethodParams methodParams = getMethodParams(parent);
+ genericValue.setStringValue(psiMethod.getName());
+ if (methodParams != null) {
+ methodParams.undefine();
+ for (PsiParameter parameter : psiMethod.getParameterList().getParameters()) {
+ methodParams.addMethodParam().setValue(parameter.getType());
+ }
+ }
+ }
+
+ public String getErrorMessage(final String s, final ConvertContext context) {
+ final ParentType parent = getParent(context);
+ return CodeInsightBundle
+ .message("error.cannot.resolve.0.1", IdeBundle.message("element.method"), getReferenceCanonicalText(s, getMethodParams(parent)));
+ }
+
+ @NotNull
+ protected final ParentType getParent(final ConvertContext context) {
+ ParentType parent = context.getInvocationElement().getParentOfType(myDomMethodClass, true);
+ assert parent != null: "Can't get parent of type " + myDomMethodClass + " for " + context.getInvocationElement();
+ return parent;
+ }
+
+ public boolean isReferenceTo(@NotNull final PsiElement element, final String stringValue, final PsiMethod resolveResult,
+ final ConvertContext context) {
+ if (super.isReferenceTo(element, stringValue, resolveResult, context)) return true;
+
+ final Ref<Boolean> result = new Ref<Boolean>(Boolean.FALSE);
+ processMethods(context, new Processor<PsiMethod>() {
+ public boolean process(final PsiMethod method) {
+ if (method.equals(element)) {
+ result.set(Boolean.TRUE);
+ return false;
+ }
+ return true;
+ }
+ }, new Function<PsiClass, PsiMethod[]>() {
+ public PsiMethod[] fun(final PsiClass s) {
+ return s.findMethodsByName(stringValue, true);
+ }
+ });
+
+ return result.get();
+ }
+
+ @SuppressWarnings({"WeakerAccess"})
+ protected void processMethods(final ConvertContext context, Processor<PsiMethod> processor, Function<PsiClass, PsiMethod[]> methodGetter) {
+ for (PsiClass psiClass : getPsiClasses(getParent(context), context)) {
+ if (psiClass != null) {
+ for (PsiMethod psiMethod : methodGetter.fun(psiClass)) {
+ if (!processor.process(psiMethod)) {
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ @NotNull
+ public Collection<? extends PsiMethod> getVariants(final ConvertContext context) {
+ LinkedHashSet<PsiMethod> methodList = new LinkedHashSet<PsiMethod>();
+ Processor<PsiMethod> processor = CommonProcessors.notNullProcessor(new CommonProcessors.CollectProcessor<PsiMethod>(methodList));
+ processMethods(context, processor, new Function<PsiClass, PsiMethod[]>() {
+ public PsiMethod[] fun(final PsiClass s) {
+ final List<PsiMethod> list = ContainerUtil.findAll(getVariants(s), new Condition<PsiMethod>() {
+ public boolean value(final PsiMethod object) {
+ return acceptMethod(object, context);
+ }
+ });
+ return list.toArray(new PsiMethod[list.size()]);
+ }
+ });
+ return methodList;
+ }
+
+ protected Collection<PsiMethod> getVariants(final PsiClass s) {
+ return Arrays.asList(s.getAllMethods());
+ }
+
+ protected boolean acceptMethod(final PsiMethod psiMethod, final ConvertContext context) {
+ return methodSuits(psiMethod);
+ }
+
+ public static boolean methodSuits(final PsiMethod psiMethod) {
+ if (psiMethod.isConstructor()) return false;
+ return psiMethod.getContainingClass().isInterface() || (!psiMethod.hasModifierProperty(PsiModifier.FINAL) && !psiMethod.hasModifierProperty(PsiModifier.STATIC));
+ }
+
+ public Set<String> getAdditionalVariants() {
+ return Collections.singleton(ALL_METHODS);
+ }
+
+ public PsiMethod fromString(final String methodName, final ConvertContext context) {
+ final CommonProcessors.FindFirstProcessor<PsiMethod> processor = new CommonProcessors.FindFirstProcessor<PsiMethod>();
+ processMethods(context, processor, new Function<PsiClass, PsiMethod[]>() {
+ public PsiMethod[] fun(final PsiClass s) {
+ final PsiMethod method = findMethod(s, methodName, getMethodParams(getParent(context)));
+ if (method != null && acceptMethod(method, context)) {
+ return new PsiMethod[]{method};
+ }
+ return PsiMethod.EMPTY_ARRAY;
+ }
+ });
+ if (processor.isFound()) return processor.getFoundValue();
+
+ processMethods(context, processor, new Function<PsiClass, PsiMethod[]>() {
+ public PsiMethod[] fun(final PsiClass s) {
+ return s.findMethodsByName(methodName, true);
+ }
+ });
+ return processor.getFoundValue();
+ }
+
+ public String toString(final PsiMethod method, final ConvertContext context) {
+ return method.getName();
+ }
+
+ public static String getReferenceCanonicalText(final String name, @Nullable final AbstractMethodParams methodParams) {
+ StringBuilder sb = new StringBuilder(name);
+ if (methodParams == null) {
+ sb.append("()");
+ }
+ else if (methodParams.getXmlTag() != null) {
+ sb.append("(");
+ final List<GenericDomValue<PsiType>> list = methodParams.getMethodParams();
+ boolean first = true;
+ for (GenericDomValue<PsiType> value : list) {
+ if (first) first = false;
+ else sb.append(", ");
+ sb.append(value.getStringValue());
+ }
+ sb.append(")");
+ }
+ return sb.toString();
+ }
+
+ @Nullable
+ public static PsiMethod findMethod(final PsiClass psiClass, final String methodName, @Nullable final AbstractMethodParams methodParameters) {
+ if (psiClass == null || methodName == null) return null;
+ return ContainerUtil.find(psiClass.findMethodsByName(methodName, true), new Condition<PsiMethod>() {
+ public boolean value(final PsiMethod object) {
+ return methodParamsMatchSignature(methodParameters, object);
+ }
+ });
+ }
+
+ public static boolean methodParamsMatchSignature(@Nullable final AbstractMethodParams params, final PsiMethod psiMethod) {
+ if (params != null && params.getXmlTag() == null) return true;
+
+ PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
+ if (params == null) return parameters.length == 0;
+
+ List<GenericDomValue<PsiType>> methodParams = params.getMethodParams();
+ if (methodParams.size() != parameters.length) return false;
+ for (int i = 0; i < parameters.length; i++) {
+ if (!Comparing.equal(parameters[i].getType(), methodParams.get(i).getValue())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/java/openapi/src/com/intellij/util/xml/converters/values/ClassArrayConverter.java b/java/openapi/src/com/intellij/util/xml/converters/values/ClassArrayConverter.java
new file mode 100644
index 0000000..123ff41
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/values/ClassArrayConverter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2009 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.util.xml.converters.values;
+
+import com.intellij.openapi.components.ServiceManager;
+
+public abstract class ClassArrayConverter extends ClassValueConverter {
+
+ public static ClassArrayConverter getClassArrayConverter() {
+ return ServiceManager.getService(ClassArrayConverter.class);
+ }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/util/xml/converters/values/ClassValueConverter.java b/java/openapi/src/com/intellij/util/xml/converters/values/ClassValueConverter.java
new file mode 100644
index 0000000..cb2820c
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/values/ClassValueConverter.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2009 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.util.xml.converters.values;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.util.xml.*;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class ClassValueConverter extends Converter<PsiClass> implements CustomReferenceConverter {
+
+ public static ClassValueConverter getClassValueConverter() {
+ return ServiceManager.getService(ClassValueConverter.class);
+ }
+
+ public PsiClass fromString(@Nullable @NonNls String s, final ConvertContext context) {
+ if (s == null) return null;
+ final Module module = context.getModule();
+ final PsiFile psiFile = context.getFile();
+ final Project project = psiFile.getProject();
+ return DomJavaUtil.findClass(s, context.getFile(), context.getModule(), getScope(project, module, psiFile));
+ }
+
+ public String toString(@Nullable PsiClass psiClass, final ConvertContext context) {
+ return psiClass == null? null : psiClass.getQualifiedName();
+ }
+
+ @NotNull
+ public abstract PsiReference[] createReferences(GenericDomValue genericDomValue, PsiElement element, ConvertContext context);
+
+ public static GlobalSearchScope getScope(Project project, @Nullable Module module, @Nullable PsiFile psiFile) {
+ if (module == null || psiFile == null) {
+ return ProjectScope.getAllScope(project);
+ }
+ VirtualFile file = psiFile.getOriginalFile().getVirtualFile();
+ if (file == null) {
+ return ProjectScope.getAllScope(project);
+ }
+ final boolean inTests = ProjectRootManager.getInstance(project).getFileIndex().isInTestSourceContent(file);
+
+ return module.getModuleRuntimeScope(inTests);
+ }
+}
diff --git a/java/openapi/src/com/intellij/util/xml/converters/values/GenericDomValueConvertersRegistry.java b/java/openapi/src/com/intellij/util/xml/converters/values/GenericDomValueConvertersRegistry.java
new file mode 100644
index 0000000..34fb74d
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/values/GenericDomValueConvertersRegistry.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2000-2009 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.util.xml.converters.values;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiType;
+import com.intellij.util.xml.Converter;
+import com.intellij.util.xml.GenericDomValue;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * User: Sergey.Vasiliev
+ */
+public class GenericDomValueConvertersRegistry {
+
+ public interface Provider {
+ Converter getConverter();
+ Condition<Pair<PsiType, GenericDomValue>> getCondition();
+ }
+
+ public void registerFromExtensions(ExtensionPointName<Provider> extensionPointName) {
+ Provider[] providers = Extensions.getExtensions(extensionPointName);
+ for (Provider provider : providers) {
+ registerConverter(provider.getConverter(), provider.getCondition());
+ }
+ }
+
+ private final Map<Condition<Pair<PsiType, GenericDomValue>>, Converter<?>> myConditionConverters =
+ new LinkedHashMap<Condition<Pair<PsiType, GenericDomValue>>, Converter<?>>();
+
+ public void registerDefaultConverters() {
+ registerBooleanConverters();
+
+ registerCharacterConverter();
+
+ registerNumberValueConverters();
+
+ registerClassValueConverters();
+ }
+
+ private void registerBooleanConverters() {
+ registerConverter(new BooleanValueConverter(false), PsiType.BOOLEAN);
+ registerConverter(new BooleanValueConverter(true), Boolean.class);
+ }
+
+ public void registerClassValueConverters() {
+ registerConverter(ClassValueConverter.getClassValueConverter(), Class.class);
+ registerConverter(ClassArrayConverter.getClassArrayConverter(), Class[].class);
+ }
+
+ public void registerCharacterConverter() {
+ registerConverter(new CharacterValueConverter(false), PsiType.CHAR);
+ registerConverter(new CharacterValueConverter(true), Character.class);
+ }
+
+ public void registerNumberValueConverters() {
+ registerConverter(new NumberValueConverter(byte.class, false), PsiType.BYTE);
+ registerConverter(new NumberValueConverter(Byte.class, true), Byte.class);
+
+ registerConverter(new NumberValueConverter(short.class, false), PsiType.SHORT);
+ registerConverter(new NumberValueConverter(Short.class, true), Short.class);
+
+ registerConverter(new NumberValueConverter(int.class, false), PsiType.INT);
+ registerConverter(new NumberValueConverter(Integer.class, true), Integer.class);
+
+ registerConverter(new NumberValueConverter(long.class, false), PsiType.LONG);
+ registerConverter(new NumberValueConverter(Long.class, true), Long.class);
+
+ registerConverter(new NumberValueConverter(float.class, false), PsiType.FLOAT);
+ registerConverter(new NumberValueConverter(Float.class, true), Float.class);
+
+ registerConverter(new NumberValueConverter(double.class, false), PsiType.DOUBLE);
+ registerConverter(new NumberValueConverter(Double.class, true), Double.class);
+
+ registerConverter(new NumberValueConverter(BigDecimal.class, true), BigDecimal.class);
+ registerConverter(new NumberValueConverter(BigInteger.class, true), BigInteger.class);
+ }
+
+ public void registerConverter(@NotNull Converter<?> provider, @NotNull final PsiType type) {
+ registerConverter(provider, new Condition<Pair<PsiType, GenericDomValue>>() {
+ public boolean value(final Pair<PsiType, GenericDomValue> pair) {
+ return Comparing.equal(pair.getFirst(), type);
+ }
+ });
+ }
+
+ public void registerConverter(@NotNull Converter<?> provider, @NotNull Condition<Pair<PsiType, GenericDomValue>> condition) {
+ myConditionConverters.put(condition, provider);
+ }
+
+ @Nullable
+ public Converter<?> getConverter(@NotNull GenericDomValue domValue, @Nullable PsiType type) {
+ final Pair<PsiType, GenericDomValue> pair = new Pair<PsiType, GenericDomValue>(type, domValue);
+ for (@NotNull Condition<Pair<PsiType, GenericDomValue>> condition : myConditionConverters.keySet()) {
+ if (condition.value(pair)) {
+ return myConditionConverters.get(condition);
+ }
+ }
+ return null;
+ }
+
+ public void registerConverter(@NotNull Converter<?> provider, @NotNull Class type) {
+ final String name = type.getCanonicalName();
+ registerConverter(provider, new Condition<Pair<PsiType, GenericDomValue>>() {
+ public boolean value(final Pair<PsiType, GenericDomValue> pair) {
+ return pair.first != null && Comparing.equal(name, pair.first.getCanonicalText());
+ }
+ });
+ }
+
+}