Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2014-09-08 17:56:16 +04:00
58 changed files with 1103 additions and 545 deletions
@@ -30,6 +30,7 @@ public final class EvaluationContextImpl implements EvaluationContext{
private final SuspendContextImpl mySuspendContext;
private final StackFrameProxyImpl myFrameProxy;
private boolean myAutoLoadClasses = true;
private ClassLoaderReference myClassLoader;
public EvaluationContextImpl(@NotNull SuspendContextImpl suspendContext, StackFrameProxyImpl frameProxy, @Nullable Value thisObject) {
myThisObject = thisObject;
@@ -77,9 +78,16 @@ public final class EvaluationContextImpl implements EvaluationContext{
@Override
public ClassLoaderReference getClassLoader() throws EvaluateException {
DebuggerManagerThreadImpl.assertIsManagerThread();
if (myClassLoader != null) {
return myClassLoader;
}
return myFrameProxy != null ? myFrameProxy.getClassLoader() : null;
}
public void setClassLoader(ClassLoaderReference classLoader) {
myClassLoader = classLoader;
}
public boolean isAutoLoadClasses() {
return myAutoLoadClasses;
}
@@ -79,7 +79,14 @@
</constraints>
<properties/>
<border type="none"/>
<children/>
<children>
<component id="916d9" class="com.intellij.ui.components.JBLabel" binding="myFrameworksLabel">
<constraints border-constraint="North"/>
<properties>
<text value="Additional Libraries and &amp;Frameworks:"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
@@ -54,6 +54,7 @@ import com.intellij.ui.CollectionListModel;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.ListSpeedSearch;
import com.intellij.ui.SingleSelectionModel;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBList;
import com.intellij.ui.popup.list.GroupedItemsListRenderer;
import com.intellij.util.Function;
@@ -81,10 +82,6 @@ import java.util.List;
@SuppressWarnings("unchecked")
public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, Disposable {
private static final String TEMPLATES_CARD = "templates card";
private static final String FRAMEWORKS_CARD = "frameworks card";
private static final String PROJECT_WIZARD_GROUP = "project.wizard.group";
public static final Convertor<FrameworkSupportInModuleProvider,String> PROVIDER_STRING_CONVERTOR =
new Convertor<FrameworkSupportInModuleProvider, String>() {
@Override
@@ -98,23 +95,14 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D
return node.getId();
}
};
private JPanel myPanel;
private JPanel myOptionsPanel;
private JBList myProjectTypeList;
private ProjectTemplateList myTemplatesList;
private JPanel myFrameworksPanelPlaceholder;
private JPanel myHeaderPanel;
private static final String TEMPLATES_CARD = "templates card";
private static final String FRAMEWORKS_CARD = "frameworks card";
private static final String PROJECT_WIZARD_GROUP = "project.wizard.group";
private final WizardContext myContext;
private final NewProjectWizard myWizard;
private final ModulesProvider myModulesProvider;
private final AddSupportForFrameworksPanel myFrameworksPanel;
private final ModuleBuilder.ModuleConfigurationUpdater myConfigurationUpdater;
@Nullable
private ModuleWizardStep mySettingsStep;
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
private final FactoryMap<ProjectTemplate, ModuleBuilder> myBuilders = new FactoryMap<ProjectTemplate, ModuleBuilder>() {
@Nullable
@@ -125,6 +113,15 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D
};
private final Map<String, ModuleWizardStep> myCustomSteps = new HashMap<String, ModuleWizardStep>();
private final MultiMap<TemplatesGroup,ProjectTemplate> myTemplatesMap;
private JPanel myPanel;
private JPanel myOptionsPanel;
private JBList myProjectTypeList;
private ProjectTemplateList myTemplatesList;
private JPanel myFrameworksPanelPlaceholder;
private JPanel myHeaderPanel;
private JBLabel myFrameworksLabel;
@Nullable
private ModuleWizardStep mySettingsStep;
private String myCurrentCard;
private TemplatesGroup myLastSelectedGroup;
@@ -206,6 +203,8 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D
myFrameworksPanel = new AddSupportForFrameworksPanel(Collections.<FrameworkSupportInModuleProvider>emptyList(), model, true, myHeaderPanel);
Disposer.register(this, myFrameworksPanel);
myFrameworksPanelPlaceholder.add(myFrameworksPanel.getMainPanel());
myFrameworksLabel.setLabelFor(myFrameworksPanel.getFrameworksTree());
myFrameworksLabel.setBorder(IdeBorderFactory.createEmptyBorder(3));
myConfigurationUpdater = new ModuleBuilder.ModuleConfigurationUpdater() {
@Override
@@ -258,6 +257,20 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D
myTemplatesList.restoreSelection();
}
private static ModuleType getModuleType(TemplatesGroup group) {
ModuleBuilder moduleBuilder = group.getModuleBuilder();
return moduleBuilder == null ? null : moduleBuilder.getModuleType();
}
private static boolean matchFramework(ProjectCategory projectCategory, FrameworkSupportInModuleProvider framework) {
FrameworkRole[] roles = framework.getRoles();
if (roles.length == 0) return true;
List<FrameworkRole> acceptable = Arrays.asList(projectCategory.getAcceptableFrameworkRoles());
return ContainerUtil.intersects(Arrays.asList(roles), acceptable);
}
private boolean isFrameworksMode() {
return FRAMEWORKS_CARD.equals(myCurrentCard) && getSelectedBuilder().equals(myContext.getProjectBuilder());
}
@@ -356,11 +369,6 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D
return groups;
}
private static ModuleType getModuleType(TemplatesGroup group) {
ModuleBuilder moduleBuilder = group.getModuleBuilder();
return moduleBuilder == null ? null : moduleBuilder.getModuleType();
}
// new TemplatesGroup selected
public void projectTypeChanged() {
TemplatesGroup group = getSelectedGroup();
@@ -438,15 +446,6 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D
showCard(TEMPLATES_CARD);
}
private static boolean matchFramework(ProjectCategory projectCategory, FrameworkSupportInModuleProvider framework) {
FrameworkRole[] roles = framework.getRoles();
if (roles.length == 0) return true;
List<FrameworkRole> acceptable = Arrays.asList(projectCategory.getAcceptableFrameworkRoles());
return ContainerUtil.intersects(Arrays.asList(roles), acceptable);
}
private void setTemplatesList(TemplatesGroup group, Collection<ProjectTemplate> templates, boolean preserveSelection) {
List<ProjectTemplate> list = new ArrayList<ProjectTemplate>(templates);
ModuleBuilder moduleBuilder = group.getModuleBuilder();
@@ -72,79 +72,86 @@ public class JavaLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSett
}
else if (settingsType == SettingsType.WRAPPING_AND_BRACES_SETTINGS) {
consumer.showStandardOptions("RIGHT_MARGIN",
"KEEP_CONTROL_STATEMENT_IN_ONE_LINE",
"LINE_COMMENT_AT_FIRST_COLUMN",
"BLOCK_COMMENT_AT_FIRST_COLUMN",
"KEEP_LINE_BREAKS",
"KEEP_FIRST_COLUMN_COMMENT",
"KEEP_CONTROL_STATEMENT_IN_ONE_LINE",
"KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE",
"KEEP_SIMPLE_BLOCKS_IN_ONE_LINE",
"KEEP_SIMPLE_METHODS_IN_ONE_LINE",
"KEEP_SIMPLE_CLASSES_IN_ONE_LINE",
"WRAP_LONG_LINES",
"CLASS_BRACE_STYLE",
"METHOD_BRACE_STYLE",
"BRACE_STYLE",
"EXTENDS_LIST_WRAP",
"ALIGN_MULTILINE_EXTENDS_LIST",
"EXTENDS_KEYWORD_WRAP",
"THROWS_LIST_WRAP",
"ALIGN_MULTILINE_THROWS_LIST",
"ALIGN_THROWS_KEYWORD",
"THROWS_KEYWORD_WRAP",
"METHOD_PARAMETERS_WRAP",
"ALIGN_MULTILINE_PARAMETERS",
"METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE",
"METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE",
"CALL_PARAMETERS_WRAP",
"ALIGN_MULTILINE_PARAMETERS_IN_CALLS",
"PREFER_PARAMETERS_WRAP",
"CALL_PARAMETERS_LPAREN_ON_NEXT_LINE",
"CALL_PARAMETERS_RPAREN_ON_NEXT_LINE",
"ALIGN_MULTILINE_METHOD_BRACKETS",
"METHOD_CALL_CHAIN_WRAP",
"ALIGN_MULTILINE_CHAINED_METHODS",
"ALIGN_GROUP_FIELD_DECLARATIONS",
"IF_BRACE_FORCE",
"ELSE_ON_NEW_LINE",
"SPECIAL_ELSE_IF_TREATMENT",
"FOR_STATEMENT_WRAP",
"ALIGN_MULTILINE_FOR",
"FOR_STATEMENT_LPAREN_ON_NEXT_LINE",
"FOR_STATEMENT_RPAREN_ON_NEXT_LINE",
"FOR_BRACE_FORCE",
"WHILE_BRACE_FORCE",
"DOWHILE_BRACE_FORCE",
"WHILE_ON_NEW_LINE",
"INDENT_CASE_FROM_SWITCH",
"METHOD_PARAMETERS_WRAP",
"METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE",
"METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE",
"RESOURCE_LIST_WRAP",
"ALIGN_MULTILINE_RESOURCES",
"RESOURCE_LIST_LPAREN_ON_NEXT_LINE",
"RESOURCE_LIST_RPAREN_ON_NEXT_LINE",
"CATCH_ON_NEW_LINE",
"FINALLY_ON_NEW_LINE",
"BINARY_OPERATION_WRAP",
"ALIGN_MULTILINE_BINARY_OPERATION",
"BINARY_OPERATION_SIGN_ON_NEXT_LINE",
"ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION",
"EXTENDS_LIST_WRAP",
"THROWS_LIST_WRAP",
"EXTENDS_KEYWORD_WRAP",
"THROWS_KEYWORD_WRAP",
"METHOD_CALL_CHAIN_WRAP",
"PARENTHESES_EXPRESSION_LPAREN_WRAP",
"PARENTHESES_EXPRESSION_RPAREN_WRAP",
"ASSIGNMENT_WRAP",
"ALIGN_MULTILINE_ASSIGNMENT",
"PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE",
"BINARY_OPERATION_WRAP",
"BINARY_OPERATION_SIGN_ON_NEXT_LINE",
"TERNARY_OPERATION_WRAP",
"ALIGN_MULTILINE_TERNARY_OPERATION",
"TERNARY_OPERATION_SIGNS_ON_NEXT_LINE",
"MODIFIER_LIST_WRAP",
"KEEP_SIMPLE_BLOCKS_IN_ONE_LINE",
"KEEP_SIMPLE_METHODS_IN_ONE_LINE",
"KEEP_SIMPLE_CLASSES_IN_ONE_LINE",
"KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE",
"FOR_STATEMENT_WRAP",
"FOR_STATEMENT_LPAREN_ON_NEXT_LINE",
"FOR_STATEMENT_RPAREN_ON_NEXT_LINE",
"ARRAY_INITIALIZER_WRAP",
"ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION",
"ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE",
"ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE",
"MODIFIER_LIST_WRAP",
"ASSIGNMENT_WRAP",
"PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE",
"LABELED_STATEMENT_WRAP",
"ASSERT_STATEMENT_WRAP",
"ASSERT_STATEMENT_COLON_ON_NEXT_LINE",
"CLASS_ANNOTATION_WRAP",
"IF_BRACE_FORCE",
"DOWHILE_BRACE_FORCE",
"WHILE_BRACE_FORCE",
"FOR_BRACE_FORCE",
"WRAP_LONG_LINES",
"METHOD_ANNOTATION_WRAP",
"CLASS_ANNOTATION_WRAP",
"FIELD_ANNOTATION_WRAP",
"PARAMETER_ANNOTATION_WRAP",
"VARIABLE_ANNOTATION_WRAP",
"ALIGN_MULTILINE_CHAINED_METHODS",
"ALIGN_MULTILINE_PARAMETERS",
"ALIGN_MULTILINE_PARAMETERS_IN_CALLS",
"ALIGN_MULTILINE_RESOURCES",
"ALIGN_MULTILINE_FOR",
"INDENT_WHEN_CASES",
"ALIGN_MULTILINE_BINARY_OPERATION",
"ALIGN_MULTILINE_ASSIGNMENT",
"ALIGN_MULTILINE_TERNARY_OPERATION",
"ALIGN_MULTILINE_THROWS_LIST",
"ALIGN_THROWS_KEYWORD",
"ALIGN_MULTILINE_EXTENDS_LIST",
"ALIGN_MULTILINE_METHOD_BRACKETS",
"ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION",
"ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION",
"ALIGN_GROUP_FIELD_DECLARATIONS",
"BRACE_STYLE",
"CLASS_BRACE_STYLE",
"METHOD_BRACE_STYLE",
"USE_FLYING_GEESE_BRACES",
"FLYING_GEESE_BRACES_GAP",
"DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS",
"ELSE_ON_NEW_LINE",
"WHILE_ON_NEW_LINE",
"CATCH_ON_NEW_LINE",
"FINALLY_ON_NEW_LINE",
"INDENT_CASE_FROM_SWITCH",
"SPECIAL_ELSE_IF_TREATMENT",
"ENUM_CONSTANTS_WRAP");
String groupName = ApplicationBundle.message("wrapping.fields.annotation");
consumer.showCustomOption(JavaCodeStyleSettings.class, "DO_NOT_WRAP_AFTER_SINGLE_ANNOTATION", "Do not wrap after single annotation", groupName);
@@ -86,7 +86,7 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor {
private boolean myMadeStatic = false;
private final Set<MethodToMoveUsageInfo> myUsages = new LinkedHashSet<MethodToMoveUsageInfo>();
private PsiClass myInnerClass;
private ChangeSignatureProcessor myChangeSignatureProcessor;
private boolean myChangeReturnType;
private Runnable myCopyMethodToInner;
public ExtractMethodObjectProcessor(Project project, Editor editor, PsiElement[] elements, final String innerClassName) {
@@ -266,12 +266,6 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor {
myInnerClass.add(GenerateMembersUtil.generateGetterPrototype(field));
}
PsiParameter[] params = getMethod().getParameterList().getParameters();
ParameterInfoImpl[] infos = new ParameterInfoImpl[params.length];
for (int i = 0; i < params.length; i++) {
PsiParameter param = params[i];
infos[i] = new ParameterInfoImpl(i, param.getName(), param.getType());
}
final PsiCodeBlock body = getMethod().getBody();
LOG.assertTrue(body != null);
final LinkedHashSet<PsiLocalVariable> vars = new LinkedHashSet<PsiLocalVariable>();
@@ -393,17 +387,25 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor {
}
}
myChangeSignatureProcessor = new ChangeSignatureProcessor(myProject, getMethod(), false, null, getMethod().getName(),
new PsiImmediateClassType(myInnerClass, PsiSubstitutor.EMPTY), infos);
myChangeReturnType = true;
}
void runChangeSignature() {
if (myChangeSignatureProcessor != null) {
myChangeSignatureProcessor.run();
}
if (myCopyMethodToInner != null) {
ApplicationManager.getApplication().runWriteAction(myCopyMethodToInner);
}
if (myChangeReturnType) {
final Runnable runnable = new Runnable() {
public void run() {
final PsiTypeElement typeElement = ((PsiLocalVariable)((PsiDeclarationStatement)JavaPsiFacade.getElementFactory(myProject)
.createStatementFromText(myInnerClassName + " l =null;", myInnerClass)).getDeclaredElements()[0]).getTypeElement();
final PsiTypeElement innerMethodReturnTypeElement = myInnerMethod.getReturnTypeElement();
LOG.assertTrue(innerMethodReturnTypeElement != null);
innerMethodReturnTypeElement.replace(typeElement);
}
};
ApplicationManager.getApplication().runWriteAction(runnable);
}
}
private String getPureName(PsiVariable var) {
@@ -524,7 +526,7 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor {
LOG.assertTrue(methodBody != null);
replacedMethodBody.replace(methodBody);
PsiUtil.setModifierProperty(newMethod, PsiModifier.STATIC, myInnerClass.hasModifierProperty(PsiModifier.STATIC) && notHasGeneratedFields());
myInnerMethod = (PsiMethod)JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(myInnerClass.add(newMethod));
myInnerMethod = (PsiMethod)myInnerClass.add(newMethod);
}
private boolean notHasGeneratedFields() {
@@ -167,7 +167,12 @@ public class ClassInheritorsSearch extends ExtensibleQueryFactory<PsiClass, Clas
}
public static Query<PsiClass> search(@NotNull final PsiClass aClass, final boolean checkDeep) {
return search(aClass, aClass.getUseScope(), checkDeep);
return search(aClass, ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
@Override
public SearchScope compute() {
return aClass.getUseScope();
}
}), checkDeep);
}
public static Query<PsiClass> search(@NotNull PsiClass aClass) {
@@ -0,0 +1,15 @@
import java.util.ArrayList;
import java.util.List;
interface A{};
interface B extends A{};
class GenericTest {
public static <M extends V, V> List<V> convert(List<M> list){
return new ArrayList<V>();
}
public static void test(){
List<A> as = convert(new ArrayList<B>());
}
}
@@ -0,0 +1,31 @@
import java.util.function.IntFunction;
import java.util.function.IntUnaryOperator;
import java.util.function.Supplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;
class Test {
interface IntStream1 {
Stream<Integer> map(IntFunction<Integer> mapper);
IntStream1 map(IntUnaryOperator mapper);
Stream<Integer> boxed();
}
void fooBar(IntStream1 instr){
Supplier<Stream<Integer>> si = () -> instr.map ((i) -> (( <error descr="Operator '%' cannot be applied to '<lambda parameter>', 'int'">i % 2</error>) == 0) ? i : <error descr="Incompatible types. Found: '<lambda parameter>', required: '<lambda parameter>'">-i</error>).boxed();
System.out.println(si);
Supplier<Stream<Integer>> si1 = () -> instr.map <error descr="Ambiguous method call: both 'IntStream1.map(IntFunction<Integer>)' and 'IntStream1.map(IntUnaryOperator)' match">(null)</error>.boxed();
System.out.println(si1);
}
}
class TestInitial {
void fooBar(){
Supplier<Stream<Integer>> si = () -> IntStream.range(0, 20).map((i) -> ((i % 2) == 0) ? i : -i).boxed();
System.out.println(si);
}
}
@@ -0,0 +1,9 @@
package my;
class Sample {
static void foo() {
int x =5;
int y =5;
int <caret>z =5;
}
}
@@ -373,6 +373,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA124363() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
public void testIDEA78402() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
public void testIDEA106985() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
public void testIDEA114797() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
public void testCaptureWildcardFromUnboundCaptureWildcard() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
public void testSuperCaptureSubstitutionWhenTypeParameterHasUpperBounds() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
public void testParameterBoundsWithCapturedWildcard() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
@@ -43,6 +43,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testIDEA102800() throws Exception {
doTest();
}
private void doTest() {
doTest(true);
}
@@ -14,16 +14,14 @@
* limitations under the License.
*/
package com.intellij.codeInsight.template
import com.intellij.JavaTestUtil
import com.intellij.codeInsight.CodeInsightSettings
import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.codeInsight.lookup.impl.LookupImpl
import com.intellij.codeInsight.lookup.impl.LookupManagerImpl
import com.intellij.codeInsight.template.impl.*
import com.intellij.codeInsight.template.macro.ClassNameCompleteMacro
import com.intellij.codeInsight.template.macro.CompleteMacro
import com.intellij.codeInsight.template.macro.MethodReturnTypeMacro
import com.intellij.codeInsight.template.macro.SnakeCaseMacro
import com.intellij.codeInsight.template.macro.*
import com.intellij.openapi.Disposable
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.editor.Editor
@@ -39,6 +37,7 @@ import com.intellij.util.ui.UIUtil
import org.jetbrains.annotations.NotNull
import static com.intellij.codeInsight.template.Template.Property.USE_STATIC_IMPORT_IF_POSSIBLE
/**
* @author spleaner
*/
@@ -462,7 +461,8 @@ class Foo {
@Override
protected void invokeTestRunnable(@NotNull final Runnable runnable) throws Exception {
if (name in ["testNavigationActionsDontTerminateTemplate", "testTemplateWithEnd", "testDisappearingVar", "test escape string characters in soutv"]) {
if (name in ["testNavigationActionsDontTerminateTemplate", "testTemplateWithEnd", "testDisappearingVar",
"test escape string characters in soutv", "test do not replace macro value with empty result"]) {
runnable.run();
return;
}
@@ -821,6 +821,40 @@ class Foo {
abs(PI);<caret>
}
}
"""
}
public void "test do not replace macro value with empty result"() {
myFixture.configureByText "a.java", """\
class Foo {
{
<caret>
}
}
"""
final TemplateManager manager = TemplateManager.getInstance(getProject());
final Template template = manager.createTemplate("xxx", "user", '$VAR1$ $VAR2$ $VAR1$');
template.addVariable("VAR1", "", "", true)
template.addVariable("VAR2", new MacroCallNode(new FileNameMacro()), new ConstantNode("default"), true)
((TemplateImpl)template).templateContext.setEnabled(contextType(JavaCodeContextType.class), true)
addTemplate(template, testRootDisposable)
startTemplate(template);
myFixture.checkResult """\
class Foo {
{
<caret> a.java
}
}
"""
myFixture.type 'test'
myFixture.checkResult """\
class Foo {
{
test<caret> a.java test
}
}
"""
}
}
@@ -21,6 +21,7 @@
package com.intellij.refactoring;
import com.intellij.JavaTestUtil;
import com.intellij.idea.Bombed;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.psi.*;
@@ -28,6 +29,8 @@ import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHand
import com.intellij.testFramework.IdeaTestUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Calendar;
public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase {
@NotNull
@Override
@@ -51,8 +54,8 @@ public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase {
public void testSimpleGeneration() throws Exception {
doTest("int i = 0; int j = 0;", "Test test = new Test().invoke();\n" +
" int i = test.getI();\n" +
" int j = test.getJ();",
" int i = test.getI();\n" +
" int j = test.getJ();",
"public class Test {\n" +
" private int i;\n" +
@@ -74,6 +77,31 @@ public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase {
" }");
}
public void testInvokeReturnType() throws Exception {
doTest("x = 6; y = 6;", "Test test = new Test().invoke();\n" +
" x = test.getX();\n" +
" y = test.getY();",
"public static class Test {\n" +
" private int x;\n" +
" private int y;\n" +
"\n" +
" public int getX() {\n" +
" return x;\n" +
" }\n" +
"\n" +
" public int getY() {\n" +
" return y;\n" +
" }\n" +
"\n" +
" public Test invoke() {\n" +
" x = 6;\n" +
" y = 6;\n" +
" return this;\n" +
" }\n" +
" }");
}
@Override
protected Sdk getProjectJDK() {
return IdeaTestUtil.getMockJdk18();
@@ -33,6 +33,8 @@ import com.intellij.openapi.editor.impl.RedBlackTree;
import com.intellij.openapi.editor.markup.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.NonPhysicalFileSystem;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.util.Consumer;
@@ -49,7 +51,7 @@ import java.util.List;
public class UpdateHighlightersUtil {
private static final Comparator<HighlightInfo> BY_START_OFFSET_NODUPS = new Comparator<HighlightInfo>() {
@Override
public int compare(HighlightInfo o1, HighlightInfo o2) {
public int compare(@NotNull HighlightInfo o1, @NotNull HighlightInfo o2) {
int d = o1.getActualStartOffset() - o2.getActualStartOffset();
if (d != 0) return d;
d = o1.getActualEndOffset() - o2.getActualEndOffset();
@@ -212,7 +214,8 @@ public class UpdateHighlightersUtil {
if (!atStart) return true;
if (!info.isFromInjection() && info.getEndOffset() < document.getTextLength() && (info.getEndOffset() <= startOffset || info.getStartOffset()>=endOffset)) return true; // injections are oblivious to restricting range
if (info.isFileLevelAnnotation() && psiFile.getViewProvider().isPhysical()) {
FileViewProvider provider = psiFile.getViewProvider();
if (info.isFileLevelAnnotation() && (provider.isPhysical() || provider.getVirtualFile().getFileSystem() instanceof NonPhysicalFileSystem)) {
codeAnalyzer.addFileLevelHighlight(project, group, info, psiFile);
changed[0] = true;
return true;
@@ -63,8 +63,13 @@ public class DefinitionsScopedSearch extends ExtensibleQueryFactory<PsiElement,
private final SearchScope myScope;
private final boolean myCheckDeep;
public SearchParameters(@NotNull PsiElement element) {
this(element, element.getUseScope(), true);
public SearchParameters(@NotNull final PsiElement element) {
this(element, ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
@Override
public SearchScope compute() {
return element.getUseScope();
}
}), true);
}
public SearchParameters(@NotNull PsiElement element, @NotNull SearchScope scope, final boolean checkDeep) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -21,7 +21,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.*;
import com.intellij.psi.codeStyle.arrangement.ArrangementSettings;
import com.intellij.psi.codeStyle.arrangement.ArrangementUtil;
import com.intellij.util.containers.HashSet;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.XmlSerializer;
import org.intellij.lang.annotations.MagicConstant;
@@ -31,8 +31,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Set;
/**
@@ -155,63 +153,20 @@ public class CommonCodeStyleSettings {
protected static void copyPublicFields(Object from, Object to) {
assert from != to;
copyFields(to.getClass().getFields(), from, to);
ReflectionUtil.copyFields(to.getClass().getFields(), from, to);
}
void copyNonDefaultValuesFrom(CommonCodeStyleSettings from) {
CommonCodeStyleSettings defaultSettings = new CommonCodeStyleSettings(null);
PARENT_SETTINGS_INSTALLED =
copyFields(getClass().getFields(), from, this, new SupportedFieldsDiffFilter(from, getSupportedFields(), defaultSettings) {
@Override
public boolean isAccept(@NotNull Field field) {
if ("RIGHT_MARGIN".equals(field.getName())) return false; // Never copy RIGHT_MARGIN, it is inherited automatically if -1
return super.isAccept(field);
}
});
}
private static void copyFields(Field[] fields, Object from, Object to) {
copyFields(fields, from, to, null);
}
private static boolean copyFields(Field[] fields, Object from, Object to, @Nullable DifferenceFilter diffFilter) {
Set<Field> sourceFields = new HashSet<Field>(Arrays.asList(from.getClass().getFields()));
boolean valuesChanged = false;
for (Field field : fields) {
if (sourceFields.contains(field)) {
if (isPublic(field) && !isFinal(field)) {
try {
if (diffFilter == null || diffFilter.isAccept(field)) {
copyFieldValue(from, to, field);
valuesChanged = true;
}
ReflectionUtil
.copyFields(getClass().getFields(), from, this, new SupportedFieldsDiffFilter(from, getSupportedFields(), defaultSettings) {
@Override
public boolean isAccept(@NotNull Field field) {
if ("RIGHT_MARGIN".equals(field.getName())) return false; // Never copy RIGHT_MARGIN, it is inherited automatically if -1
return super.isAccept(field);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
return valuesChanged;
}
private static void copyFieldValue(final Object from, Object to, final Field field)
throws IllegalAccessException {
Class<?> fieldType = field.getType();
if (fieldType.isPrimitive() || fieldType.equals(String.class)) {
field.set(to, field.get(from));
}
else {
throw new RuntimeException("Field not copied " + field.getName());
}
}
private static boolean isPublic(final Field field) {
return (field.getModifiers() & Modifier.PUBLIC) != 0;
}
private static boolean isFinal(final Field field) {
return (field.getModifiers() & Modifier.FINAL) != 0;
});
}
@Nullable
@@ -54,10 +54,12 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.NonPhysicalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.RefreshQueueImpl;
import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiCompiledElement;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
@@ -184,8 +186,10 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements JDOM
@Override
public void cleanFileLevelHighlights(@NotNull Project project, final int group, PsiFile psiFile) {
if (psiFile == null || !psiFile.getViewProvider().isPhysical()) return;
VirtualFile vFile = psiFile.getViewProvider().getVirtualFile();
if (psiFile == null) return;
FileViewProvider provider = psiFile.getViewProvider();
if (!provider.isPhysical() && !(provider.getVirtualFile().getFileSystem() instanceof NonPhysicalFileSystem)) return;
VirtualFile vFile = provider.getVirtualFile();
final FileEditorManager manager = FileEditorManager.getInstance(project);
for (FileEditor fileEditor : manager.getEditors(vFile)) {
final List<HighlightInfo> infos = fileEditor.getUserData(FILE_LEVEL_HIGHLIGHTS);
@@ -723,7 +723,10 @@ public class TemplateState implements Disposable {
ExpressionContext context = createExpressionContext(start);
Result result = isQuick ? expressionNode.calculateQuickResult(context) : expressionNode.calculateResult(context);
if ((result == null || result.equalsToText("", element)) && defaultValue != null) {
if (isQuick && isEmptyResult(result, element) && !oldValue.isEmpty()) {
return;
}
if (isEmptyResult(result, element) && defaultValue != null) {
result = defaultValue.calculateResult(context);
}
if (element != null) {
@@ -743,6 +746,10 @@ public class TemplateState implements Disposable {
}
}
private static boolean isEmptyResult(Result result, PsiElement context) {
return result == null || result.equalsToText("", context);
}
private void replaceString(String newValue, int start, int end, int segmentNumber) {
String oldText = myDocument.getCharsSequence().subSequence(start, end).toString();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -35,6 +35,7 @@ import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -53,7 +54,7 @@ public class BrowserUtil {
private BrowserUtil() { }
public static boolean isAbsoluteURL(String url) {
return ourExternalPrefix.matcher(url.toLowerCase()).find();
return ourExternalPrefix.matcher(url.toLowerCase(Locale.ENGLISH)).find();
}
public static String getDocURL(String url) {
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupAdapter;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.reference.SoftReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -62,7 +63,7 @@ public class Notification {
myType = type;
myListener = listener;
LOG.assertTrue(myContent.trim().length() > 0, "Notification should have content, groupId: " + myGroupId);
LOG.assertTrue(!StringUtil.isEmptyOrSpaces(myContent), "Notification should have content, groupId: " + myGroupId);
}
@SuppressWarnings("MethodMayBeStatic")
@@ -0,0 +1,29 @@
/*
* Copyright 2000-2014 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.designer;
import com.intellij.openapi.ui.ThreeComponentsSplitter;
/**
* @author Alexander Lobas
*/
public interface DesignerEditorPanelFacade {
Object getClientProperty(Object key);
void putClientProperty(Object key, Object value);
ThreeComponentsSplitter getContentSplitter();
}
@@ -54,7 +54,7 @@ public class LightToolWindow extends JPanel {
private final ThreeComponentsSplitter myContentSplitter;
private ToolWindowAnchor myAnchor;
private final Project myProject;
private final AbstractToolWindowManager myManager;
private final LightToolWindowManager myManager;
private final PropertiesComponent myPropertiesComponent;
private boolean myShowContent;
private final String myShowStateKey;
@@ -86,7 +86,7 @@ public class LightToolWindow extends JPanel {
JComponent focusedComponent,
ThreeComponentsSplitter contentSplitter,
ToolWindowAnchor anchor,
AbstractToolWindowManager manager,
LightToolWindowManager manager,
Project project,
PropertiesComponent propertiesComponent,
String key,
@@ -101,8 +101,8 @@ public class LightToolWindow extends JPanel {
myManager = manager;
myPropertiesComponent = propertiesComponent;
myShowStateKey = AbstractToolWindowManager.EDITOR_MODE + key + ".SHOW";
myWidthKey = AbstractToolWindowManager.EDITOR_MODE + key + ".WIDTH";
myShowStateKey = LightToolWindowManager.EDITOR_MODE + key + ".SHOW";
myWidthKey = LightToolWindowManager.EDITOR_MODE + key + ".WIDTH";
HeaderPanel header = new HeaderPanel();
header.setLayout(new BorderLayout());
@@ -0,0 +1,323 @@
/*
* Copyright 2000-2014 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.designer;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ex.ToolWindowEx;
import com.intellij.util.ParameterizedRunnable;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* @author Alexander Lobas
*/
public abstract class LightToolWindowManager implements ProjectComponent {
public static final String EDITOR_MODE = "UI_DESIGNER_EDITOR_MODE.";
private final MergingUpdateQueue myWindowQueue = new MergingUpdateQueue(getComponentName(), 200, true, null);
protected final Project myProject;
protected final FileEditorManager myFileEditorManager;
protected volatile ToolWindow myToolWindow;
private volatile boolean myToolWindowDisposed;
private final PropertiesComponent myPropertiesComponent;
public final String myEditorModeKey;
private ToggleEditorModeAction myLeftEditorModeAction;
private ToggleEditorModeAction myRightEditorModeAction;
private MessageBusConnection myConnection;
private final FileEditorManagerListener myListener = new FileEditorManagerListener() {
@Override
public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
bindToDesigner(getActiveDesigner());
}
@Override
public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
bindToDesigner(getActiveDesigner());
}
});
}
@Override
public void selectionChanged(@NotNull FileEditorManagerEvent event) {
bindToDesigner(getDesigner(event.getNewEditor()));
}
};
//////////////////////////////////////////////////////////////////////////////////////////
//
// ToolWindow
//
//////////////////////////////////////////////////////////////////////////////////////////
protected LightToolWindowManager(Project project, FileEditorManager fileEditorManager) {
myProject = project;
myFileEditorManager = fileEditorManager;
myPropertiesComponent = PropertiesComponent.getInstance(myProject);
myEditorModeKey = EDITOR_MODE + getComponentName() + ".STATE";
}
@Override
public void projectOpened() {
initToolWindow();
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
public void run() {
if (getEditorMode() == null) {
initListeners();
bindToDesigner(getActiveDesigner());
}
}
});
}
@Override
public void projectClosed() {
if (!myToolWindowDisposed) {
disposeComponent();
myToolWindowDisposed = true;
myToolWindow = null;
}
}
private void initListeners() {
myConnection = myProject.getMessageBus().connect(myProject);
myConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, myListener);
}
private void removeListeners() {
myConnection.disconnect();
myConnection = null;
}
@Nullable
protected abstract DesignerEditorPanelFacade getDesigner(FileEditor editor);
@Nullable
public DesignerEditorPanelFacade getActiveDesigner() {
for (FileEditor editor : myFileEditorManager.getSelectedEditors()) {
DesignerEditorPanelFacade designer = getDesigner(editor);
if (designer != null) {
return designer;
}
}
return null;
}
private void bindToDesigner(final DesignerEditorPanelFacade designer) {
myWindowQueue.cancelAllUpdates();
myWindowQueue.queue(new Update("update") {
@Override
public void run() {
if (myToolWindowDisposed) {
return;
}
if (myToolWindow == null) {
if (designer == null) {
return;
}
initToolWindow();
}
updateToolWindow(designer);
}
});
}
protected abstract void initToolWindow();
protected abstract void updateToolWindow(@Nullable DesignerEditorPanelFacade designer);
protected final void initGearActions() {
ToolWindowEx toolWindow = (ToolWindowEx)myToolWindow;
toolWindow.setAdditionalGearActions(new DefaultActionGroup(createGearActions()));
}
protected abstract ToolWindowAnchor getAnchor();
@Override
public void initComponent() {
}
@Override
public void disposeComponent() {
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// LightToolWindow
//
//////////////////////////////////////////////////////////////////////////////////////////
public final ActionGroup createGearActions() {
DefaultActionGroup group = new DefaultActionGroup("In Editor Mode", true);
if (myLeftEditorModeAction == null) {
myLeftEditorModeAction = createToggleAction(ToolWindowAnchor.LEFT);
}
group.add(myLeftEditorModeAction);
if (myRightEditorModeAction == null) {
myRightEditorModeAction = createToggleAction(ToolWindowAnchor.RIGHT);
}
group.add(myRightEditorModeAction);
return group;
}
protected abstract ToggleEditorModeAction createToggleAction(ToolWindowAnchor anchor);
public final void bind(DesignerEditorPanelFacade designer) {
if (isEditorMode()) {
myCreateAction.run(designer);
}
}
public final void dispose(DesignerEditorPanelFacade designer) {
if (isEditorMode()) {
disposeContent(designer);
}
}
protected final Object getContent(DesignerEditorPanelFacade designer) {
LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(getComponentName());
return toolWindow.getContent();
}
protected abstract LightToolWindow createContent(DesignerEditorPanelFacade designer);
protected final LightToolWindow createContent(DesignerEditorPanelFacade designer,
LightToolWindowContent content,
String title,
Icon icon,
JComponent component,
JComponent focusedComponent,
int defaultWidth,
AnAction[] actions) {
return new LightToolWindow(content,
title,
icon,
component,
focusedComponent,
designer.getContentSplitter(),
getEditorMode(),
this,
myProject,
myPropertiesComponent,
getComponentName(),
defaultWidth,
actions);
}
protected final void disposeContent(DesignerEditorPanelFacade designer) {
String key = getComponentName();
LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(key);
designer.putClientProperty(key, null);
toolWindow.dispose();
}
private final ParameterizedRunnable<DesignerEditorPanelFacade> myCreateAction = new ParameterizedRunnable<DesignerEditorPanelFacade>() {
@Override
public void run(DesignerEditorPanelFacade designer) {
designer.putClientProperty(getComponentName(), createContent(designer));
}
};
private final ParameterizedRunnable<DesignerEditorPanelFacade> myUpdateAnchorAction =
new ParameterizedRunnable<DesignerEditorPanelFacade>() {
@Override
public void run(DesignerEditorPanelFacade designer) {
LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(getComponentName());
toolWindow.updateAnchor(getEditorMode());
}
};
private final ParameterizedRunnable<DesignerEditorPanelFacade> myDisposeAction = new ParameterizedRunnable<DesignerEditorPanelFacade>() {
@Override
public void run(DesignerEditorPanelFacade designer) {
disposeContent(designer);
}
};
private void runUpdateContent(ParameterizedRunnable<DesignerEditorPanelFacade> action) {
for (FileEditor editor : myFileEditorManager.getAllEditors()) {
DesignerEditorPanelFacade designer = getDesigner(editor);
if (designer != null) {
action.run(designer);
}
}
}
protected final boolean isEditorMode() {
return getEditorMode() != null;
}
@Nullable
final ToolWindowAnchor getEditorMode() {
String value = myPropertiesComponent.getValue(myEditorModeKey);
if (value == null) {
return getAnchor();
}
return value.equals("ToolWindow") ? null : ToolWindowAnchor.fromText(value);
}
final void setEditorMode(@Nullable ToolWindowAnchor newState) {
ToolWindowAnchor oldState = getEditorMode();
myPropertiesComponent.setValue(myEditorModeKey, newState == null ? "ToolWindow" : newState.toString());
if (oldState != null && newState != null) {
runUpdateContent(myUpdateAnchorAction);
}
else if (newState != null) {
removeListeners();
updateToolWindow(null);
runUpdateContent(myCreateAction);
}
else {
runUpdateContent(myDisposeAction);
initListeners();
bindToDesigner(getActiveDesigner());
}
}
final ToolWindow getToolWindow() {
return myToolWindow;
}
}
@@ -15,7 +15,6 @@
*/
package com.intellij.designer;
import com.intellij.designer.palette.PaletteToolWindowManager;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.Project;
@@ -25,12 +24,12 @@ import com.intellij.openapi.wm.ToolWindowAnchor;
/**
* @author Alexander Lobas
*/
public class ToggleEditorModeAction extends ToggleAction {
private final AbstractToolWindowManager myManager;
private final Project myProject;
public abstract class ToggleEditorModeAction extends ToggleAction {
protected final LightToolWindowManager myManager;
protected final Project myProject;
private final ToolWindowAnchor myAnchor;
public ToggleEditorModeAction(AbstractToolWindowManager manager, Project project, ToolWindowAnchor anchor) {
public ToggleEditorModeAction(LightToolWindowManager manager, Project project, ToolWindowAnchor anchor) {
super(StringUtil.capitalize(anchor.toString()), "Pin/unpin tool window to " + anchor + " side UI Designer Editor", null);
myManager = manager;
myProject = project;
@@ -47,7 +46,7 @@ public class ToggleEditorModeAction extends ToggleAction {
if (state) {
myManager.setEditorMode(myAnchor);
AbstractToolWindowManager manager = getOppositeManager();
LightToolWindowManager manager = getOppositeManager();
if (manager.getEditorMode() == myAnchor) {
manager.setEditorMode(myAnchor == ToolWindowAnchor.LEFT ? ToolWindowAnchor.RIGHT : ToolWindowAnchor.LEFT);
}
@@ -57,9 +56,5 @@ public class ToggleEditorModeAction extends ToggleAction {
}
}
private AbstractToolWindowManager getOppositeManager() {
AbstractToolWindowManager designerManager = DesignerToolWindowManager.getInstance(myProject);
AbstractToolWindowManager paletteManager = PaletteToolWindowManager.getInstance(myProject);
return myManager == designerManager ? paletteManager : designerManager;
}
protected abstract LightToolWindowManager getOppositeManager();
}
@@ -70,6 +70,7 @@ import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.Future;
public final class ActionManagerImpl extends ActionManagerEx implements ApplicationComponent {
@NonNls public static final String ACTION_ELEMENT_NAME = "action";
@@ -1264,7 +1265,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
public void preloadActions() {
public Future<?> preloadActions() {
if (myPreloadActionsRunnable == null) {
myPreloadActionsRunnable = new Runnable() {
@Override
@@ -1275,8 +1276,9 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
};
ApplicationManager.getApplication().executeOnPooledThread(myPreloadActionsRunnable);
return ApplicationManager.getApplication().executeOnPooledThread(myPreloadActionsRunnable);
}
return null;
}
private void doPreloadActions() {
@@ -16,16 +16,23 @@ public class SourceMap {
private final String outFile;
private final SourceResolver sourceResolver;
private final boolean hasNameMappings;
// sources - is not originally specified, but canonicalized/normalized
public SourceMap(@Nullable String outFile,
@NotNull MappingList mappings,
@NotNull MappingList[] sourceIndexToMappings,
@NotNull SourceResolver sourceResolver) {
@NotNull SourceResolver sourceResolver,
boolean hasNameMappings) {
this.outFile = outFile;
this.mappings = mappings;
this.sourceIndexToMappings = sourceIndexToMappings;
this.sourceResolver = sourceResolver;
this.hasNameMappings = hasNameMappings;
}
public boolean hasNameMappings() {
return hasNameMappings;
}
@NotNull
@@ -5,6 +5,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.util.PathUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.CharSequenceSubSequence;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -176,7 +177,7 @@ public final class SourceMapDecoder {
sourceToEntries[i] = new SourceMappingList(entries);
}
}
return new SourceMap(file, new GeneratedMappingList(mappings), sourceToEntries, sourceResolverFactory.create(sources, sourcesContent));
return new SourceMap(file, new GeneratedMappingList(mappings), sourceToEntries, sourceResolverFactory.create(sources, sourcesContent), !ContainerUtil.isEmpty(names));
}
@Nullable
@@ -95,6 +95,17 @@ public class BasicDebuggerViewSupport implements DebuggerViewSupport, MemberFilt
return Collections.emptyList();
}
@NotNull
@Override
public String getName(@NotNull Variable variable) {
return variable.getName();
}
@Override
public boolean hasNameMappings() {
return false;
}
@NotNull
@Override
public String normalizeMemberName(@NotNull Variable variable) {
@@ -71,7 +71,7 @@ public final class LazyVariablesGroup extends XValueGroup {
@Override
public void consumeVariables(@NotNull List<Variable> variables) {
node.addChildren(Variables.createVariablesList(variables, context), true);
node.addChildren(Variables.createVariablesList(variables, context, null), true);
}
}, componentType);
}
@@ -9,4 +9,9 @@ public interface MemberFilter {
@NotNull
Collection<Variable> getAdditionalVariables();
@NotNull
String getName(@NotNull Variable variable);
boolean hasNameMappings();
}
@@ -57,7 +57,11 @@ public final class VariableView extends XNamedValue implements VariableContext {
private volatile int remainingChildrenOffset;
public VariableView(@NotNull Variable variable, @NotNull VariableContext context) {
super(context.getViewSupport().normalizeMemberName(variable));
this(context.getViewSupport().normalizeMemberName(variable), variable, context);
}
public VariableView(@NotNull String name, @NotNull Variable variable, @NotNull VariableContext context) {
super(name);
this.context = context;
this.variable = variable;
@@ -362,7 +366,7 @@ public final class VariableView extends XNamedValue implements VariableContext {
@Override
public void consumeVariables(@NotNull List<Variable> variables) {
node.addChildren(Variables.createVariablesList(variables, VariableView.this), isLastChildren);
node.addChildren(Variables.createVariablesList(variables, VariableView.this, null), isLastChildren);
}
}, null);
}
@@ -399,7 +403,7 @@ public final class VariableView extends XNamedValue implements VariableContext {
int count = variables.size();
int bucketSize = XCompositeNode.MAX_CHILDREN_TO_SHOW;
if (count <= bucketSize) {
node.addChildren(Variables.createVariablesList(variables, this), true);
node.addChildren(Variables.createVariablesList(variables, this, null), true);
return;
}
@@ -417,7 +421,7 @@ public final class VariableView extends XNamedValue implements VariableContext {
int notGroupedVariablesOffset;
if ((variables.size() - count) > bucketSize) {
for (notGroupedVariablesOffset = variables.size(); notGroupedVariablesOffset > 0; notGroupedVariablesOffset--) {
if (!variables.get(notGroupedVariablesOffset - 1).getName().startsWith(Variables.SPECIAL_PROPERTY_PREFIX)) {
if (!variables.get(notGroupedVariablesOffset - 1).getName().startsWith("__")) {
break;
}
}
@@ -18,13 +18,11 @@ import java.util.*;
import java.util.regex.Pattern;
public final class Variables {
static final String SPECIAL_PROPERTY_PREFIX = "__";
private static final Pattern UNNAMED_FUNCTION_PATTERN = Pattern.compile("^function[\\t ]*\\(");
private static final Comparator<Variable> NATURAL_NAME_COMPARATOR = new Comparator<Variable>() {
@Override
public int compare(Variable o1, Variable o2) {
public int compare(@NotNull Variable o1, @NotNull Variable o2) {
return naturalCompare(o1.getName(), o2.getName());
}
};
@@ -37,7 +35,7 @@ public final class Variables {
AsyncResult<?> result = ObsolescentAsyncResults.consume(scope.getVariables(), node, new PairConsumer<List<Variable>, XCompositeNode>() {
@Override
public void consume(List<Variable> variables, XCompositeNode node) {
MemberFilter memberFilter = context.createMemberFilter();
final MemberFilter memberFilter = context.createMemberFilter();
Collection<Variable> additionalVariables = memberFilter.getAdditionalVariables();
List<Variable> properties = new ArrayList<Variable>(variables.size() + additionalVariables.size());
List<Variable> functions = new SmartList<Variable>();
@@ -56,7 +54,12 @@ public final class Variables {
}
}
sort(properties);
ContainerUtil.sort(properties, memberFilter.hasNameMappings() ? new Comparator<Variable>() {
@Override
public int compare(@NotNull Variable o1, @NotNull Variable o2) {
return naturalCompare(memberFilter.getName(o1), memberFilter.getName(o2));
}
} : NATURAL_NAME_COMPARATOR);
sort(functions);
for (Variable variable : additionalVariables) {
@@ -64,7 +67,7 @@ public final class Variables {
}
if (!properties.isEmpty()) {
node.addChildren(createVariablesList(properties, context), functions.isEmpty() && isLast);
node.addChildren(createVariablesList(properties, context, memberFilter), functions.isEmpty() && isLast);
}
if (!functions.isEmpty()) {
@@ -110,6 +113,7 @@ public final class Variables {
}
}
@NotNull
public static List<Variable> filterAndSort(@NotNull List<? extends Variable> variables, @NotNull VariableContext context, boolean filterFunctions) {
if (variables.isEmpty()) {
return Collections.emptyList();
@@ -219,16 +223,28 @@ public final class Variables {
return string1Length - string2Length;
}
@NotNull
public static XValueChildrenList createVariablesList(@NotNull List<Variable> variables, @NotNull VariableContext variableContext) {
return createVariablesList(variables, 0, variables.size(), variableContext);
return createVariablesList(variables, variableContext, null);
}
@NotNull
public static XValueChildrenList createVariablesList(@NotNull List<Variable> variables, @NotNull VariableContext variableContext, @Nullable MemberFilter memberFilter) {
return createVariablesList(variables, 0, variables.size(), variableContext, memberFilter);
}
@NotNull
public static XValueChildrenList createVariablesList(@NotNull List<Variable> variables, int from, int to, @NotNull VariableContext variableContext) {
return createVariablesList(variables, from, to, variableContext, null);
}
@NotNull
public static XValueChildrenList createVariablesList(@NotNull List<Variable> variables, int from, int to, @NotNull VariableContext variableContext, @Nullable MemberFilter memberFilter) {
XValueChildrenList list = new XValueChildrenList(to - from);
VariableContext getterOrSetterContext = null;
for (int i = from; i < to; i++) {
Variable variable = variables.get(i);
list.add(new VariableView(variable, variableContext));
list.add(memberFilter == null ? new VariableView(variable, variableContext) : new VariableView(memberFilter.getName(variable), variable, variableContext));
if (variable instanceof ObjectProperty) {
ObjectProperty property = (ObjectProperty)variable;
if (property.getGetter() != null) {
@@ -36,6 +36,11 @@ public final class CallFrameView extends StackFrameImplBase implements VariableC
inLibraryContent = sourceInfo != null && debugProcess.isInLibraryContent(sourceInfo, script);
}
@Nullable
public Script getScript() {
return script;
}
@Override
protected boolean isInFileScope() {
List<Scope> scopes = callFrame.getVariableScopes();
@@ -1,36 +1,35 @@
/*
* Copyright 2000-2014 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.testFramework;
import com.intellij.mock.MockApplicationEx;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import junit.framework.TestCase;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.Future;
public abstract class FlyIdeaTestCase extends TestCase {
private Disposable myRootDisposable;
private final Disposable myRootDisposable = Disposer.newDisposable();
private File myTempDir;
@Override
protected void setUp() throws Exception {
final Application old = ApplicationManagerEx.getApplication();
myRootDisposable = Disposer.newDisposable();
MockApplicationEx app = new MockApplicationEx(getRootDisposable()) {
@NotNull
@Override
public Future<?> executeOnPooledThread(@NotNull Runnable action) {
return old != null ? old.executeOnPooledThread(action) : super.executeOnPooledThread(action);
}
};
ApplicationManager.setApplication(app, myRootDisposable);
LightPlatformTestCase.initApplication();
}
public File getTempDir() throws IOException {
@@ -224,7 +224,7 @@ public abstract class UsefulTestCase extends TestCase {
}
public static CompositeException doCheckForSettingsDamage(@NotNull CodeStyleSettings oldCodeStyleSettings,
@NotNull CodeStyleSettings currentCodeStyleSettings) throws Exception {
@NotNull CodeStyleSettings currentCodeStyleSettings) throws Exception {
CompositeException result = new CompositeException();
final CodeInsightSettings settings = CodeInsightSettings.getInstance();
try {
@@ -234,9 +234,13 @@ public abstract class UsefulTestCase extends TestCase {
}
catch (AssertionError error) {
CodeInsightSettings clean = new CodeInsightSettings();
Element temp = new Element("temp");
clean.writeExternal(temp);
settings.loadState(temp);
for (Field field : clean.getClass().getFields()) {
try {
ReflectionUtil.copyFieldValue(clean, settings, field);
}
catch (Exception ignored) {
}
}
result.add(error);
}
@@ -15,6 +15,7 @@
*/
package com.intellij.util.containers;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -32,11 +33,11 @@ public class Stack<T> extends ArrayList<T> {
super(initialCapacity);
}
public Stack(Collection<T> init) {
public Stack(@NotNull Collection<T> init) {
super(init);
}
public Stack(T... items) {
public Stack(@NotNull T... items) {
for (T item : items) {
push(item);
}
@@ -19,17 +19,15 @@ package com.intellij.util;
import com.intellij.Patches;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.openapi.util.DifferenceFilter;
import com.intellij.util.containers.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import sun.reflect.ConstructorAccessor;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.*;
public class ReflectionUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.util.ReflectionUtil");
@@ -479,6 +477,50 @@ public class ReflectionUtil {
return callerClass;
}
public static void copyFields(@NotNull Field[] fields, @NotNull Object from, @NotNull Object to) {
copyFields(fields, from, to, null);
}
public static boolean copyFields(@NotNull Field[] fields, @NotNull Object from, @NotNull Object to, @Nullable DifferenceFilter diffFilter) {
Set<Field> sourceFields = new com.intellij.util.containers.HashSet<Field>(Arrays.asList(from.getClass().getFields()));
boolean valuesChanged = false;
for (Field field : fields) {
if (sourceFields.contains(field)) {
if (isPublic(field) && !isFinal(field)) {
try {
if (diffFilter == null || diffFilter.isAccept(field)) {
copyFieldValue(from, to, field);
valuesChanged = true;
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
return valuesChanged;
}
public static void copyFieldValue(@NotNull Object from, @NotNull Object to, @NotNull Field field)
throws IllegalAccessException {
Class<?> fieldType = field.getType();
if (fieldType.isPrimitive() || fieldType.equals(String.class)) {
field.set(to, field.get(from));
}
else {
throw new RuntimeException("Field '" + field.getName()+"' not copied: unsupported type: "+field.getType());
}
}
private static boolean isPublic(final Field field) {
return (field.getModifiers() & Modifier.PUBLIC) != 0;
}
private static boolean isFinal(final Field field) {
return (field.getModifiers() & Modifier.FINAL) != 0;
}
private static class MySecurityManager extends SecurityManager {
private static final MySecurityManager INSTANCE = new MySecurityManager();
@@ -187,14 +187,14 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
myTemporaryMessageChildren != null ? myTemporaryMessageChildren : Collections.<MessageTreeNode>emptyList());
final int[] indices = getNodesIndices(allMessageChildren);
final TreeNode[] nodes = getChildNodes(indices);
myMessageChildren = null;
myTemporaryMessageChildren = null;
fireNodesRemoved(indices, nodes);
if (!temporary) {
myMessageChildren = messages;
myTemporaryMessageChildren = null;
}
else {
myTemporaryMessageChildren = messages;
myMessageChildren = null;
}
myCachedAllChildren = null;
fireNodesInserted(messages);
@@ -110,13 +110,19 @@ public abstract class IGQuickFixesTestCase extends JavaCodeInsightFixtureTestCas
}
public IntentionAction findIntention(@NotNull final String hint) {
final List<IntentionAction> list =
final List<IntentionAction> availableIntentions =
ContainerUtil.findAll(myFixture.getAvailableIntentions(), new Condition<IntentionAction>() {
@Override
public boolean value(final IntentionAction intentionAction) {
return intentionAction instanceof QuickFixWrapper;
}
});
final List<IntentionAction> list = ContainerUtil.findAll(availableIntentions, new Condition<IntentionAction>() {
@Override
public boolean value(IntentionAction intentionAction) {
return intentionAction.getText().equals(hint);
}
});
if (list.isEmpty()) {
Assert.fail("\"" + hint + "\" not in " + list);
}
@@ -15,121 +15,25 @@
*/
package com.intellij.designer;
import com.intellij.designer.designSurface.DesignerEditorPanel;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.designer.palette.PaletteToolWindowManager;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ex.ToolWindowEx;
import com.intellij.util.ParameterizedRunnable;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* @author Alexander Lobas
*/
public abstract class AbstractToolWindowManager implements ProjectComponent {
public static final String EDITOR_MODE = "UI_DESIGNER_EDITOR_MODE.";
private final MergingUpdateQueue myWindowQueue = new MergingUpdateQueue(getComponentName(), 200, true, null);
protected final Project myProject;
protected final FileEditorManager myFileEditorManager;
protected volatile ToolWindow myToolWindow;
private volatile boolean myToolWindowDisposed;
private final PropertiesComponent myPropertiesComponent;
public final String myEditorModeKey;
private ToggleEditorModeAction myLeftEditorModeAction;
private ToggleEditorModeAction myRightEditorModeAction;
private MessageBusConnection myConnection;
private final FileEditorManagerListener myListener = new FileEditorManagerListener() {
@Override
public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
bindToDesigner(getActiveDesigner());
}
@Override
public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
bindToDesigner(getActiveDesigner());
}
});
}
@Override
public void selectionChanged(@NotNull FileEditorManagerEvent event) {
bindToDesigner(getDesigner(event.getNewEditor()));
}
};
//////////////////////////////////////////////////////////////////////////////////////////
//
// ToolWindow
//
//////////////////////////////////////////////////////////////////////////////////////////
public abstract class AbstractToolWindowManager extends LightToolWindowManager {
protected AbstractToolWindowManager(Project project, FileEditorManager fileEditorManager) {
myProject = project;
myFileEditorManager = fileEditorManager;
myPropertiesComponent = PropertiesComponent.getInstance(myProject);
myEditorModeKey = EDITOR_MODE + getComponentName() + ".STATE";
}
@Override
public void projectOpened() {
initToolWindow();
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
public void run() {
if (getEditorMode() == null) {
initListeners();
bindToDesigner(getActiveDesigner());
}
}
});
}
@Override
public void projectClosed() {
if (!myToolWindowDisposed) {
disposeComponent();
myToolWindowDisposed = true;
myToolWindow = null;
}
}
private void initListeners() {
myConnection = myProject.getMessageBus().connect(myProject);
myConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, myListener);
}
private void removeListeners() {
myConnection.disconnect();
myConnection = null;
super(project, fileEditorManager);
}
@Nullable
private static DesignerEditorPanel getDesigner(FileEditor editor) {
@Override
protected DesignerEditorPanelFacade getDesigner(FileEditor editor) {
if (editor instanceof DesignerEditor) {
DesignerEditor designerEditor = (DesignerEditor)editor;
return designerEditor.getDesignerPanel();
@@ -137,196 +41,20 @@ public abstract class AbstractToolWindowManager implements ProjectComponent {
return null;
}
@Nullable
public DesignerEditorPanel getActiveDesigner() {
for (FileEditor editor : myFileEditorManager.getSelectedEditors()) {
DesignerEditorPanel designer = getDesigner(editor);
if (designer != null) {
return designer;
@Override
protected ToggleEditorModeAction createToggleAction(ToolWindowAnchor anchor) {
return new ToggleEditorModeAction(this, myProject, anchor) {
@Override
protected LightToolWindowManager getOppositeManager() {
AbstractToolWindowManager designerManager = DesignerToolWindowManager.getInstance(myProject);
AbstractToolWindowManager paletteManager = PaletteToolWindowManager.getInstance(myProject);
return myManager == designerManager ? paletteManager : designerManager;
}
}
return null;
};
}
@Nullable
protected static DesignerCustomizations getCustomizations() {
return DesignerCustomizations.EP_NAME.findExtension(DesignerCustomizations.class);
}
private void bindToDesigner(final DesignerEditorPanel designer) {
myWindowQueue.cancelAllUpdates();
myWindowQueue.queue(new Update("update") {
@Override
public void run() {
if (myToolWindowDisposed) {
return;
}
if (myToolWindow == null) {
if (designer == null) {
return;
}
initToolWindow();
}
updateToolWindow(designer);
}
});
}
protected abstract void initToolWindow();
protected abstract void updateToolWindow(@Nullable DesignerEditorPanel designer);
protected final void initGearActions() {
ToolWindowEx toolWindow = (ToolWindowEx)myToolWindow;
toolWindow.setAdditionalGearActions(new DefaultActionGroup(createGearActions()));
}
protected abstract ToolWindowAnchor getAnchor();
@Override
public void initComponent() {
}
@Override
public void disposeComponent() {
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// LightToolWindow
//
//////////////////////////////////////////////////////////////////////////////////////////
public final ActionGroup createGearActions() {
DefaultActionGroup group = new DefaultActionGroup("In Editor Mode", true);
if (myLeftEditorModeAction == null) {
myLeftEditorModeAction = new ToggleEditorModeAction(this, myProject, ToolWindowAnchor.LEFT);
}
group.add(myLeftEditorModeAction);
if (myRightEditorModeAction == null) {
myRightEditorModeAction = new ToggleEditorModeAction(this, myProject, ToolWindowAnchor.RIGHT);
}
group.add(myRightEditorModeAction);
return group;
}
public final void bind(DesignerEditorPanel designer) {
if (isEditorMode()) {
myCreateAction.run(designer);
}
}
public final void dispose(DesignerEditorPanel designer) {
if (isEditorMode()) {
disposeContent(designer);
}
}
protected final Object getContent(DesignerEditorPanel designer) {
LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(getComponentName());
return toolWindow.getContent();
}
protected abstract LightToolWindow createContent(DesignerEditorPanel designer);
protected final LightToolWindow createContent(DesignerEditorPanel designer,
LightToolWindowContent content,
String title,
Icon icon,
JComponent component,
JComponent focusedComponent,
int defaultWidth,
AnAction[] actions) {
return new LightToolWindow(content,
title,
icon,
component,
focusedComponent,
designer.getContentSplitter(),
getEditorMode(),
this,
myProject,
myPropertiesComponent,
getComponentName(),
defaultWidth,
actions);
}
protected final void disposeContent(DesignerEditorPanel designer) {
String key = getComponentName();
LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(key);
designer.putClientProperty(key, null);
toolWindow.dispose();
}
private final ParameterizedRunnable<DesignerEditorPanel> myCreateAction = new ParameterizedRunnable<DesignerEditorPanel>() {
@Override
public void run(DesignerEditorPanel designer) {
designer.putClientProperty(getComponentName(), createContent(designer));
}
};
private final ParameterizedRunnable<DesignerEditorPanel> myUpdateAnchorAction = new ParameterizedRunnable<DesignerEditorPanel>() {
@Override
public void run(DesignerEditorPanel designer) {
LightToolWindow toolWindow = (LightToolWindow)designer.getClientProperty(getComponentName());
toolWindow.updateAnchor(getEditorMode());
}
};
private final ParameterizedRunnable<DesignerEditorPanel> myDisposeAction = new ParameterizedRunnable<DesignerEditorPanel>() {
@Override
public void run(DesignerEditorPanel designer) {
disposeContent(designer);
}
};
private void runUpdateContent(ParameterizedRunnable<DesignerEditorPanel> action) {
for (FileEditor editor : myFileEditorManager.getAllEditors()) {
DesignerEditorPanel designer = getDesigner(editor);
if (designer != null) {
action.run(designer);
}
}
}
protected final boolean isEditorMode() {
return getEditorMode() != null;
}
@Nullable
final ToolWindowAnchor getEditorMode() {
String value = myPropertiesComponent.getValue(myEditorModeKey);
if (value == null) {
return getAnchor();
}
return value.equals("ToolWindow") ? null : ToolWindowAnchor.fromText(value);
}
final void setEditorMode(@Nullable ToolWindowAnchor newState) {
ToolWindowAnchor oldState = getEditorMode();
myPropertiesComponent.setValue(myEditorModeKey, newState == null ? "ToolWindow" : newState.toString());
if (oldState != null && newState != null) {
runUpdateContent(myUpdateAnchorAction);
}
else if (newState != null) {
removeListeners();
updateToolWindow(null);
runUpdateContent(myCreateAction);
}
else {
runUpdateContent(myDisposeAction);
initListeners();
bindToDesigner(getActiveDesigner());
}
}
final ToolWindow getToolWindow() {
return myToolWindow;
}
}
@@ -96,8 +96,8 @@ public final class DesignerToolWindowManager extends AbstractToolWindowManager {
}
@Override
protected void updateToolWindow(@Nullable DesignerEditorPanel designer) {
myToolWindowContent.update(designer);
protected void updateToolWindow(@Nullable DesignerEditorPanelFacade designer) {
myToolWindowContent.update((DesignerEditorPanel)designer);
if (designer == null) {
myToolWindow.setAvailable(false, null);
@@ -126,9 +126,9 @@ public final class DesignerToolWindowManager extends AbstractToolWindowManager {
//////////////////////////////////////////////////////////////////////////////////////////
@Override
protected LightToolWindow createContent(DesignerEditorPanel designer) {
protected LightToolWindow createContent(DesignerEditorPanelFacade designer) {
DesignerToolWindow toolWindowContent = new DesignerToolWindow(myProject, false);
toolWindowContent.update(designer);
toolWindowContent.update((DesignerEditorPanel)designer);
return createContent(designer,
toolWindowContent,
@@ -78,7 +78,8 @@ import java.util.List;
/**
* @author Alexander Lobas
*/
public abstract class DesignerEditorPanel extends JPanel implements DataProvider, ModuleProvider, RadPropertyContext {
public abstract class DesignerEditorPanel extends JPanel
implements DesignerEditorPanelFacade, DataProvider, ModuleProvider, RadPropertyContext {
private static final Logger LOG = Logger.getInstance("#com.intellij.designer.designSurface.DesignerEditorPanel");
protected static final Integer LAYER_COMPONENT = JLayeredPane.DEFAULT_LAYER;
@@ -17,6 +17,7 @@ package com.intellij.designer.palette;
import com.intellij.designer.AbstractToolWindowManager;
import com.intellij.designer.DesignerCustomizations;
import com.intellij.designer.DesignerEditorPanelFacade;
import com.intellij.designer.LightToolWindow;
import com.intellij.designer.designSurface.DesignerEditorPanel;
import com.intellij.icons.AllIcons;
@@ -85,8 +86,8 @@ public class PaletteToolWindowManager extends AbstractToolWindowManager {
}
@Override
protected void updateToolWindow(@Nullable DesignerEditorPanel designer) {
myToolWindowPanel.loadPalette(designer);
protected void updateToolWindow(@Nullable DesignerEditorPanelFacade designer) {
myToolWindowPanel.loadPalette((DesignerEditorPanel)designer);
if (myToolWindowPanel.isEmpty()) {
myToolWindow.setAvailable(false, null);
@@ -115,9 +116,9 @@ public class PaletteToolWindowManager extends AbstractToolWindowManager {
//////////////////////////////////////////////////////////////////////////////////////////
@Override
protected LightToolWindow createContent(DesignerEditorPanel designer) {
protected LightToolWindow createContent(DesignerEditorPanelFacade designer) {
PalettePanel palettePanel = new PalettePanel();
palettePanel.loadPalette(designer);
palettePanel.loadPalette((DesignerEditorPanel)designer);
return createContent(designer,
palettePanel,
@@ -58,6 +58,12 @@
<action id="ShowPreview" class="org.jetbrains.plugins.coursecreator.actions.CCShowPreview">
<add-to-group group-id="ProjectViewPopupMenu" anchor="first"/>
</action>
<action id="RenameLesson" class="org.jetbrains.plugins.coursecreator.actions.CCRenameLesson">
<add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="CutCopyPasteGroup"/>
</action>
<action id="RenameTask" class="org.jetbrains.plugins.coursecreator.actions.CCRenameTask">
<add-to-group group-id="ProjectViewPopupMenu" anchor="before" relative-to-action="CutCopyPasteGroup"/>
</action>
<action id="PackCourse" class="org.jetbrains.plugins.coursecreator.actions.CreateCourseArchive">
<add-to-group group-id="MainToolBar" anchor="last" />
</action>
@@ -151,7 +151,7 @@ public class CCProjectComponent implements ProjectComponent {
if (task == null) {
return;
}
lesson.getTasklist().remove(task);
lesson.getTaskList().remove(task);
lesson.getTasksMap().remove(removedFile.getName());
}
@@ -71,6 +71,9 @@ public class CCProjectService implements PersistentStateComponent<Element> {
@Override
public void loadState(Element el) {
myCourse = XmlSerializer.deserialize(el.getChild(COURSE_ELEMENT), Course.class);
if (myCourse != null) {
myCourse.init();
}
}
public static CCProjectService getInstance(@NotNull Project project) {
@@ -155,7 +158,7 @@ public class CCProjectService implements PersistentStateComponent<Element> {
}
Lesson lesson = lessons.get(lessonIndex);
int taskIndex = getIndex(taskDirName, "task");
List<Task> tasks = lesson.getTasklist();
List<Task> tasks = lesson.getTaskList();
if (!indexIsValid(taskIndex, tasks)) {
return false;
}
@@ -228,8 +228,8 @@ public class CCRunTests extends AnAction {
.createChildDirectory(project, taskDir.getName());
if (CCProjectService.indexIsValid(lessonIndex, course.getLessons())) {
Lesson lesson = course.getLessons().get(lessonIndex);
if (CCProjectService.indexIsValid(index, lesson.getTasklist())) {
Task task = lesson.getTasklist().get(index);
if (CCProjectService.indexIsValid(index, lesson.getTaskList())) {
Task task = lesson.getTaskList().get(index);
HashMap<TaskFile, TaskFile> taskFilesCopy = new HashMap<TaskFile, TaskFile>();
for (Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
CreateCourseArchive.createUserFile(project, taskFilesCopy, taskResourceDir, taskDir, entry);
@@ -0,0 +1,95 @@
/*
* Copyright 2000-2014 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 org.jetbrains.plugins.coursecreator.actions;
import com.intellij.ide.IdeView;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.util.DirectoryChooserUtil;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.coursecreator.CCProjectService;
import org.jetbrains.plugins.coursecreator.format.Course;
import javax.swing.*;
public abstract class CCRename extends DumbAwareAction {
public CCRename(String text, String description, Icon icon) {
super(text, description, icon);
}
@Override
public void update(@NotNull AnActionEvent event) {
final Presentation presentation = event.getPresentation();
final Project project = event.getData(CommonDataKeys.PROJECT);
if (project == null) {
presentation.setVisible(false);
presentation.setEnabled(false);
return;
}
final IdeView view = event.getData(LangDataKeys.IDE_VIEW);
if (view == null) {
presentation.setVisible(false);
presentation.setEnabled(false);
return;
}
final PsiDirectory[] directories = view.getDirectories();
if (directories.length == 0) {
presentation.setVisible(false);
presentation.setEnabled(false);
return;
}
final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
if (directory == null || !directory.getName().contains(getFolderName())) {
presentation.setEnabled(false);
presentation.setVisible(false);
return;
}
presentation.setVisible(true);
presentation.setEnabled(true);
}
public abstract String getFolderName();
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
final IdeView view = e.getData(LangDataKeys.IDE_VIEW);
final Project project = e.getData(CommonDataKeys.PROJECT);
if (view == null || project == null) {
return;
}
final PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
if (directory == null || !directory.getName().contains("lesson")) {
return;
}
Course course = CCProjectService.getInstance(project).getCourse();
if (course == null) {
return;
}
if (!processRename(project, directory, course)) return;
ProjectView.getInstance(project).refresh();
}
public abstract boolean processRename(Project project, PsiDirectory directory, Course course);
}
@@ -0,0 +1,48 @@
/*
* Copyright 2000-2014 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 org.jetbrains.plugins.coursecreator.actions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiDirectory;
import org.jetbrains.plugins.coursecreator.format.Course;
import org.jetbrains.plugins.coursecreator.format.Lesson;
public class CCRenameLesson extends CCRename {
public CCRenameLesson() {
super("Rename Lesson", "Rename Lesson", null);
}
@Override
public String getFolderName() {
return "lesson";
}
@Override
public boolean processRename(Project project, PsiDirectory directory, Course course) {
Lesson lesson = course.getLesson(directory.getName());
if (lesson == null) {
return false;
}
String newName = Messages.showInputDialog(project, "Enter new name", "Rename " + getFolderName(), null);
if (newName == null) {
return false;
}
lesson.setName(newName);
return true;
}
}
@@ -0,0 +1,57 @@
/*
* Copyright 2000-2014 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 org.jetbrains.plugins.coursecreator.actions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiDirectory;
import org.jetbrains.plugins.coursecreator.format.Course;
import org.jetbrains.plugins.coursecreator.format.Lesson;
import org.jetbrains.plugins.coursecreator.format.Task;
public class CCRenameTask extends CCRename {
public CCRenameTask() {
super("Rename Task", "Rename Task", null);
}
@Override
public String getFolderName() {
return "task";
}
@Override
public boolean processRename(Project project, PsiDirectory directory, Course course) {
PsiDirectory lessonDir = directory.getParent();
if (lessonDir == null || !lessonDir.getName().contains("lesson")) {
return false;
}
Lesson lesson = course.getLesson(lessonDir.getName());
if (lesson == null) {
return false;
}
Task task = lesson.getTask(directory.getName());
if (task == null) {
return false;
}
String newName = Messages.showInputDialog(project, "Enter new name", "Rename " + getFolderName(), null);
if (newName == null) {
return false;
}
task.setName(newName);
return true;
}
}
@@ -18,6 +18,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.coursecreator.CCProjectService;
import org.jetbrains.plugins.coursecreator.format.Course;
import org.jetbrains.plugins.coursecreator.format.Lesson;
@@ -42,7 +43,7 @@ public class CreateTask extends DumbAwareAction {
final CCProjectService service = CCProjectService.getInstance(project);
final Course course = service.getCourse();
final Lesson lesson = course.getLesson(directory.getName());
final int size = lesson.getTasklist().size();
final int size = lesson.getTaskList().size();
final String taskName = Messages.showInputDialog("Name:", "Task Name", null, "task" + (size + 1), null);
if (taskName == null) return;
@@ -83,7 +84,7 @@ public class CreateTask extends DumbAwareAction {
}
@Override
public void update(AnActionEvent event) {
public void update(@NotNull AnActionEvent event) {
final Presentation presentation = event.getPresentation();
final Project project = event.getData(CommonDataKeys.PROJECT);
if (project == null) {
@@ -4,10 +4,7 @@ import com.google.gson.annotations.Expose;
import com.intellij.psi.PsiDirectory;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class Course {
@Expose public List<Lesson> lessons = new ArrayList<Lesson>();
@@ -52,4 +49,13 @@ public class Course {
public String getDescription() {
return description;
}
public void init() {
lessons.clear();
for (Lesson lesson: myLessonsMap.values()) {
lessons.add(lesson);
lesson.init();
}
Collections.sort(lessons);
}
}
@@ -4,12 +4,9 @@ import com.google.gson.annotations.Expose;
import com.intellij.psi.PsiDirectory;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class Lesson {
public class Lesson implements Comparable{
@Expose public String name;
@Expose public List<Task> task_list = new ArrayList<Task>();
@@ -27,11 +24,15 @@ public class Lesson {
task_list.add(task);
}
public void setName(String name) {
this.name = name;
}
public Task getTask(@NotNull final String name) {
return myTasksMap.get(name);
}
public List<Task> getTasklist() {
public List<Task> getTaskList() {
return task_list;
}
@@ -46,4 +47,18 @@ public class Lesson {
public Map<String, Task> getTasksMap() {
return myTasksMap;
}
public void init() {
task_list.clear();
for (Task task : myTasksMap.values()) {
task_list.add(task);
}
Collections.sort(task_list);
}
@Override
public int compareTo(@NotNull Object o) {
Lesson lesson = (Lesson) o;
return myIndex - lesson.getIndex();
}
}
@@ -7,7 +7,7 @@ import org.jetbrains.plugins.coursecreator.CCProjectService;
import java.util.HashMap;
import java.util.Map;
public class Task {
public class Task implements Comparable{
@Expose public String name;
@Expose public Map<String, TaskFile> task_files = new HashMap<String, TaskFile>();
public int myIndex;
@@ -44,4 +44,14 @@ public class Task {
public boolean isTaskFile(String name) {
return task_files.get(name) != null;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(@NotNull Object o) {
Task task = (Task) o;
return myIndex - task.getIndex();
}
}
@@ -27,7 +27,7 @@
<component id="160bb" class="javax.swing.JTextField" binding="myNameField" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="2" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
<preferred-size width="300" height="-1"/>
</grid>
</constraints>
<properties/>
@@ -150,4 +150,10 @@ public class CreateTaskWindowDialog extends DialogWrapper {
public void validateInput() {
super.initValidation();
}
@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
return myPanel.getPreferredFocusedComponent();
}
}
@@ -37,6 +37,7 @@ public class CreateTaskWindowPanel extends JPanel {
}
});
myTaskWindowText.grabFocus();
myHintName.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
@@ -93,4 +94,8 @@ public class CreateTaskWindowPanel extends JPanel {
public void setGeneratedHintName(String generatedHintName) {
myGeneratedHintName = generatedHintName;
}
public JComponent getPreferredFocusedComponent() {
return myTaskWindowText;
}
}