Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2014-08-16 14:45:05 +04:00
26 changed files with 237 additions and 183 deletions
@@ -17,7 +17,9 @@
<grid id="a052" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints border-constraint="Center"/>
<properties/>
<border type="none"/>
<border type="empty">
<size top="5" left="5" bottom="10" right="5"/>
</border>
<children>
<grid id="b7b2b" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints border-constraint="North"/>
@@ -66,14 +68,14 @@
<properties/>
<border type="none"/>
<children>
<component id="5de69" class="com.intellij.ui.components.JBLabel">
<component id="5de69" class="com.intellij.ui.components.JBLabel" binding="myMessage">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<alignmentX value="0.5"/>
<componentStyle value="SMALL"/>
<text value="Red means Sample does not match RegExp"/>
<text value="Red means I can't hear you!"/>
</properties>
</component>
<hspacer id="c8c90">
@@ -16,33 +16,30 @@
package org.intellij.lang.regexp.intention;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonShortcuts;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.fileTypes.PlainTextFileType;
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.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.resolve.FileContextUtil;
import com.intellij.ui.BalloonImpl;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.Alarm;
import com.intellij.util.ui.UIUtil;
import org.intellij.lang.regexp.RegExpLanguage;
import org.intellij.lang.regexp.RegExpModifierProvider;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.CompoundBorder;
@@ -56,52 +53,40 @@ import java.util.regex.Pattern;
*/
public class CheckRegExpForm {
private static final String LAST_EDITED_REGEXP = "last.edited.regexp";
private Pair<PsiFile, Ref<Balloon>> myParams;
private final PsiFile myRegexpFile;
private EditorTextField mySampleText; //TODO[kb]: make it multiline
private EditorTextField myRegExp;
private JPanel myRootPanel;
private Ref<Balloon> myRef;
private JBLabel myMessage;
private Project myProject;
public CheckRegExpForm(Pair<PsiFile, Ref<Balloon>> params) {
myParams = params;
public CheckRegExpForm(@NotNull PsiFile regexpFile) {
myRegexpFile = regexpFile;
}
private void createUIComponents() {
PsiFile file = myParams.first;
myProject = file.getProject();
myRef = myParams.second;
Document document = PsiDocumentManager.getInstance(myProject).getDocument(file);
myProject = myRegexpFile.getProject();
Document document = PsiDocumentManager.getInstance(myProject).getDocument(myRegexpFile);
myRegExp = new EditorTextField(document, myProject, RegExpLanguage.INSTANCE.getAssociatedFileType());
myRegExp.setPreferredWidth(Math.max(300, myRegExp.getPreferredSize().width));
final String sampleText = PropertiesComponent.getInstance(myProject).getValue(LAST_EDITED_REGEXP, "Sample Text");
mySampleText = new EditorTextField(sampleText, myProject, PlainTextFileType.INSTANCE);
mySampleText.setBorder(
new CompoundBorder(new EmptyBorder(2, 2, 2, 4), new LineBorder(UIUtil.isUnderDarcula() ? Gray._100 : UIUtil.getBorderColor())));
new CompoundBorder(new EmptyBorder(2, 2, 2, 4), new LineBorder(UIUtil.isUnderDarcula() ? Gray._100 : JBColor.border())));
mySampleText.setOneLineMode(false);
mySampleText.addDocumentListener(new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
public void run() {
myRootPanel.revalidate();
final Balloon balloon = myRef.get();
if (balloon != null) {
balloon.revalidate();
}
}
});
}
});
myRootPanel = new JPanel(new BorderLayout()) {
Disposable disposable;
@Override
public void addNotify() {
super.addNotify();
disposable = Disposer.newDisposable();
IdeFocusManager.getGlobalInstance().requestFocus(mySampleText, true);
new AnAction(){
@@ -109,26 +94,10 @@ public class CheckRegExpForm {
public void actionPerformed(AnActionEvent e) {
IdeFocusManager.findInstance().requestFocus(myRegExp.getFocusTarget(), true);
}
}.registerCustomShortcutSet(CustomShortcutSet.fromString("shift TAB"), mySampleText, myRef.get());
final AnAction escaper = new AnAction() {
@Override
public void actionPerformed(AnActionEvent e) {
myRef.get().hide();
}
};
escaper.registerCustomShortcutSet(CommonShortcuts.ESCAPE, myRegExp.getFocusTarget(), myRef.get());
escaper.registerCustomShortcutSet(CommonShortcuts.ESCAPE, mySampleText.getFocusTarget(), myRef.get());
}.registerCustomShortcutSet(CustomShortcutSet.fromString("shift TAB"), mySampleText);
myRef.get().addListener(new JBPopupAdapter() {
@Override
public void onClosed(LightweightWindowEvent event) {
PropertiesComponent.getInstance(myProject).setValue(LAST_EDITED_REGEXP, mySampleText.getText());
}
});
final Alarm updater = new Alarm(Alarm.ThreadToUse.SWING_THREAD, myRef.get());
final DocumentAdapter documentListener = new DocumentAdapter() {
final Alarm updater = new Alarm(Alarm.ThreadToUse.SWING_THREAD, disposable);
DocumentAdapter documentListener = new DocumentAdapter() {
@Override
public void documentChanged(DocumentEvent e) {
updater.cancelAllRequests();
@@ -148,48 +117,44 @@ public class CheckRegExpForm {
updateBalloon();
mySampleText.selectAll();
}
@Override
public void removeNotify() {
super.removeNotify();
Disposer.dispose(disposable);
PropertiesComponent.getInstance(myProject).setValue(LAST_EDITED_REGEXP, mySampleText.getText());
}
};
}
@NotNull
public JComponent getPreferredFocusedComponent() {
return mySampleText;
}
@NotNull
public JPanel getRootPanel() {
return myRootPanel;
}
private void updateBalloon() {
boolean correct = false;
try {
final PsiFile file = myParams.first;
//todo: unfortunately there is no way to access host element representing regexp
int offset = -1;
try {
final String name = file.getName();
offset = Integer.parseInt(name.substring(name.lastIndexOf(':') + 1, name.lastIndexOf(')')));
} catch (Exception ignore) {}
int flags = 0;
if (offset != -1) {
final PsiFile host = FileContextUtil.getContextFile(file);
if (host != null) {
final PsiElement regexpInHost = host.findElementAt(offset);
if (regexpInHost != null) {
for (RegExpModifierProvider provider : RegExpModifierProvider.EP.getExtensions()) {
final int modifiers = provider.getFlags(regexpInHost, file);
if (modifiers > 0) {
flags = modifiers;
break;
}
}
}
}
PsiLanguageInjectionHost host = InjectedLanguageUtil.findInjectionHost(myRegexpFile);
int flags = 0;
if (host != null) {
for (RegExpModifierProvider provider : RegExpModifierProvider.EP.getExtensions()) {
flags = provider.getFlags(host, myRegexpFile);
if (flags > 0) break;
}
}
try {
correct = Pattern.compile(myRegExp.getText(), flags).matcher(mySampleText.getText()).matches();
} catch (Exception ignore) {}
mySampleText.setBackground(correct ? new JBColor(new Color(231, 250, 219), new Color(68, 85, 66)) : new JBColor(new Color(255, 177, 160), new Color(110, 43, 40)));
BalloonImpl balloon = (BalloonImpl)myRef.get();
if (balloon != null && balloon.isDisposed()) {
balloon.revalidate();
}
JBColor color1 = new JBColor(new Color(231, 250, 219), new Color(68, 85, 66));
JBColor color2 = new JBColor(new Color(255, 177, 160), new Color(110, 43, 40));
mySampleText.setBackground(correct ? color1 : color2);
myMessage.setText(correct ? "Matches!" : "no match");
myRootPanel.revalidate();
}
}
@@ -20,10 +20,8 @@ import com.intellij.lang.Language;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
@@ -41,12 +39,10 @@ public class CheckRegExpIntentionAction extends QuickEditAction implements Icona
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final Pair<PsiElement, TextRange> pair = getRangePair(file, editor);
/*super.isAvailable(project, editor, file) && */
Pair<PsiElement, TextRange> pair = getRangePair(file, editor);
if (pair != null && pair.first != null) {
Language language = pair.first.getLanguage();
Language baseLanguage = language.getBaseLanguage();
return language == RegExpLanguage.INSTANCE || baseLanguage == RegExpLanguage.INSTANCE;
return language.isKindOf(RegExpLanguage.INSTANCE);
}
return false;
}
@@ -57,11 +53,11 @@ public class CheckRegExpIntentionAction extends QuickEditAction implements Icona
}
@Override
protected JComponent createBalloonComponent(PsiFile file, final Ref<Balloon> ref) {
protected JComponent createBalloonComponent(@NotNull PsiFile file) {
final Project project = file.getProject();
final Document document = PsiDocumentManager.getInstance(project).getDocument(file);
if (document != null) {
return new CheckRegExpForm(Pair.create(file, ref)).getRootPanel();
return new CheckRegExpForm(file).getRootPanel();
}
return null;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 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.
@@ -29,6 +29,7 @@ import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.util.RefactoringChangeUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -126,9 +127,7 @@ public abstract class BaseMoveInitializerToMethodAction extends PsiElementBaseIn
final PsiExpressionStatement statement = (PsiExpressionStatement)factory.createStatementFromText(field.getName() + " = y;", codeBlock);
PsiExpression initializer = field.getInitializer();
if (initializer instanceof PsiArrayInitializerExpression) {
initializer = arrayInitializerToNewExpression((PsiArrayInitializerExpression)initializer, factory, codeBlock);
}
initializer = RefactoringUtil.convertInitializerToNormalExpression(initializer, field.getType());
final PsiAssignmentExpression expression = (PsiAssignmentExpression)statement.getExpression();
expression.getRExpression().replace(initializer);
@@ -158,15 +157,6 @@ public abstract class BaseMoveInitializerToMethodAction extends PsiElementBaseIn
return false;
}
private static PsiExpression arrayInitializerToNewExpression(@NotNull PsiArrayInitializerExpression initializer,
@NotNull PsiElementFactory factory,
@NotNull PsiElement context) {
final PsiType type = initializer.getType();
final PsiNewExpression newExpression = (PsiNewExpression)factory.createExpressionFromText("new " + type.getCanonicalText() + "{}", context);
newExpression.getArrayInitializer().replace(initializer);
return newExpression;
}
private static boolean containsReference(final @NotNull PsiElement element,
final @NotNull PsiField field) {
final Ref<Boolean> result = new Ref<Boolean>(Boolean.FALSE);
@@ -0,0 +1,8 @@
// "Move initializer to constructor" "true"
class X {
final String s;
X() {
s = {};
}
}
@@ -0,0 +1,7 @@
// "Move initializer to constructor" "true"
class X {
final String <caret>s = {};
X() {
}
}
Binary file not shown.
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 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.
@@ -39,13 +39,13 @@ public abstract class LightCodeInsightFixtureTestCase extends UsefulTestCase{
public static final LightProjectDescriptor JAVA_1_4 = new DefaultLightProjectDescriptor() {
@Override
public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_6);
model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_4);
}
};
public static final LightProjectDescriptor JAVA_1_5 = new DefaultLightProjectDescriptor() {
@Override
public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_6);
model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_5);
}
};
public static final LightProjectDescriptor JAVA_1_6 = new DefaultLightProjectDescriptor() {
@@ -25,7 +25,10 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
@@ -138,7 +141,7 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
}
@Nullable
protected JComponent createBalloonComponent(PsiFile file, Ref<Balloon> ref) {
protected JComponent createBalloonComponent(@NotNull PsiFile file) {
return null;
}
@@ -150,22 +150,23 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable {
if (event.getEditor().getDocument() != myNewDocument) return;
myEditorCount ++;
final EditorActionHandler editorEscape = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_ESCAPE);
new AnAction() {
@Override
public void update(AnActionEvent e) {
Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
e.getPresentation().setEnabled(
!myAction.isShowInBalloon() &&
editor != null && LookupManager.getActiveLookup(editor) == null &&
TemplateManager.getInstance(myProject).getActiveTemplate(editor) == null &&
(editorEscape == null || !editorEscape.isEnabled(editor, e.getDataContext())));
}
if (!myAction.isShowInBalloon()) {
new AnAction() {
@Override
public void update(AnActionEvent e) {
Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
e.getPresentation().setEnabled(
editor != null && LookupManager.getActiveLookup(editor) == null &&
TemplateManager.getInstance(myProject).getActiveTemplate(editor) == null &&
(editorEscape == null || !editorEscape.isEnabled(editor, e.getDataContext())));
}
@Override
public void actionPerformed(AnActionEvent e) {
closeEditor();
}
}.registerCustomShortcutSet(CommonShortcuts.ESCAPE, event.getEditor().getContentComponent());
@Override
public void actionPerformed(AnActionEvent e) {
closeEditor();
}
}.registerCustomShortcutSet(CommonShortcuts.ESCAPE, event.getEditor().getContentComponent());
}
}
@Override
@@ -203,8 +204,7 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable {
public void navigate(int injectedOffset) {
if (myAction.isShowInBalloon()) {
Ref<Balloon> ref = Ref.create(null);
final JComponent component = myAction.createBalloonComponent(myNewFile, ref);
final JComponent component = myAction.createBalloonComponent(myNewFile);
if (component != null) {
final Balloon balloon = JBPopupFactory.getInstance().createBalloonBuilder(component)
.setShadow(true)
@@ -214,7 +214,12 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable {
.setHideOnAction(false)
.setFillColor(UIUtil.getControlColor())
.createBalloon();
ref.set(balloon);
new AnAction() {
@Override
public void actionPerformed(AnActionEvent e) {
balloon.hide();
}
}.registerCustomShortcutSet(CommonShortcuts.ESCAPE, component);
Disposer.register(myNewFile.getProject(), balloon);
final Balloon.Position position = QuickEditAction.getBalloonPosition(myEditor);
RelativePoint point = JBPopupFactory.getInstance().guessBestPopupLocation(myEditor);
@@ -556,13 +556,19 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
}
@TestOnly
public void waitUntilAllCommitted() throws InterruptedException {
public void waitUntilAllCommitted(long timeout) throws InterruptedException {
if (!myEnabled) {
throw new IllegalStateException("DocumentCommitThread is disabled");
}
int attempts = 0;
int delay = 100;
synchronized (documentsToCommit) {
while(!documentsToCommit.isEmpty()) {
documentsToCommit.wait();
documentsToCommit.wait(delay);
if (delay * attempts > timeout) {
throw new RuntimeException("timeout");
}
attempts++;
}
}
}
@@ -40,7 +40,8 @@ public class CaretSpecificDataContext extends DataContextWrapper {
if (project == null) {
return null;
}
Object data = FileEditorManager.getInstance(project).getData(dataId, myCaret.getEditor(), myCaret);
FileEditorManager fm = FileEditorManager.getInstance(project);
Object data = fm == null ? null : fm.getData(dataId, myCaret.getEditor(), myCaret);
return data == null ? super.getData(dataId) : data;
}
}
@@ -2580,6 +2580,7 @@ public class JBTabsImpl extends JComponent
}
private void updateContainer(boolean forced, final boolean layoutNow) {
if (myProject != null && !myProject.isOpen()) return;
for (TabInfo each : new ArrayList<TabInfo>(myVisibleInfos)) {
final JComponent eachComponent = each.getComponent();
if (getSelectedInfo() == each && getSelectedInfo() != null) {
@@ -63,6 +63,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
@Nullable
private XDebugSessionImpl mySession;
private XDebugSessionData mySessionData;
@NotNull
public static XDebugSessionTab create(@NotNull XDebugSessionImpl session,
@@ -126,6 +127,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
}
mySession = session;
mySessionData = session.getSessionData();
myConsole = session.getConsoleView();
myRunContentDescriptor = new RunContentDescriptor(myConsole, session.getDebugProcess().getProcessHandler(), myUi.getComponent(), session.getSessionName(), icon);
}
@@ -139,6 +141,9 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
else if (TAB_KEY.is(dataId)) {
return this;
}
else if (XDebugSessionData.DATA_KEY.is(dataId)) {
return mySessionData;
}
if (mySession != null) {
if (SESSION_KEY.is(dataId)) {
@@ -147,9 +152,6 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
else if (LangDataKeys.CONSOLE_VIEW.is(dataId)) {
return mySession.getConsoleView();
}
else if (XDebugSessionData.DATA_KEY.is(dataId)) {
return mySession.getSessionData();
}
}
return super.getData(dataId);
@@ -19,6 +19,7 @@ import com.intellij.psi.*;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -143,9 +144,10 @@ public class ImplicitDefaultCharsetUsageInspection extends BaseInspection {
}
private static boolean hasCharsetType(PsiVariable variable) {
final PsiType lastType = variable.getType();
return lastType.equalsToText(CommonClassNames.JAVA_LANG_STRING) ||
lastType.equalsToText("java.nio.charset.Charset");
return TypeUtils.variableHasTypeOrSubtype(variable, CommonClassNames.JAVA_LANG_STRING,
"java.nio.charset.Charset",
"java.nio.charset.CharsetEncoder",
"java.nio.charset.CharsetDecoder");
}
}
}
@@ -1,6 +1,9 @@
package com.siyeh.igtest.internationalization.implicit_default_charset_usage;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.Locale;
@@ -37,4 +40,12 @@ class ImplicitDefaultCharsetUsage {
new Scanner("string input");
new ArrayList(10);
}
void charsetEnAndDecoders(InputStream inputStream, OutputStream outputStream) throws IOException {
final Charset cs = Charset.forName("UTF-8");
CharsetDecoder cd = cs.newDecoder();
InputStreamReader is = new InputStreamReader(inputStream, cd);
CharsetEncoder ce = cs.newEncoder();
final OutputStreamWriter ow = new OutputStreamWriter(outputStream, ce);
}
}
@@ -16,13 +16,22 @@
package com.siyeh.ig.internationalization;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.testFramework.LightProjectDescriptor;
import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.NotNull;
/**
* @author Bas Leijdekkers
*/
public class ImplicitDefaultCharsetUsageInspectionTest extends LightInspectionTestCase {
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_8;
}
@Override
protected InspectionProfileEntry getInspection() {
return new ImplicitDefaultCharsetUsageInspection();
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package com.siyeh.ipp.initialization;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.util.IncorrectOperationException;
import com.intellij.refactoring.util.RefactoringUtil;
import com.siyeh.IntentionPowerPackBundle;
import com.siyeh.ipp.base.Intention;
import com.siyeh.ipp.base.PsiElementPredicate;
@@ -35,28 +35,14 @@ public class SplitDeclarationAndInitializationIntention extends Intention {
}
@Override
public void processIntention(@NotNull PsiElement element)
throws IncorrectOperationException {
public void processIntention(@NotNull PsiElement element) {
final PsiField field = (PsiField)element.getParent();
field.normalizeDeclaration();
final PsiExpression initializer = field.getInitializer();
final PsiExpression initializer = RefactoringUtil.convertInitializerToNormalExpression(field.getInitializer(), field.getType());
if (initializer == null) {
return;
}
final String initializerText;
if (initializer instanceof PsiArrayInitializerExpression) {
final PsiType type = initializer.getType();
if (type == null) {
initializerText = initializer.getText();
}
else {
initializerText = "new " + type.getCanonicalText() +
initializer.getText();
}
}
else {
initializerText = initializer.getText();
}
final String initializerText = initializer.getText();
final PsiClass containingClass = field.getContainingClass();
if (containingClass == null) {
return;
@@ -0,0 +1,3 @@
class X {
String s <caret>= {};
}
@@ -0,0 +1,7 @@
class X {
String s;
{
s = {};
}
}
@@ -0,0 +1,38 @@
/*
* 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.siyeh.ipp.initialization;
import com.siyeh.IntentionPowerPackBundle;
import com.siyeh.ipp.IPPTestCase;
/**
* @see com.siyeh.ipp.initialization.SplitDeclarationAndInitializationIntention
* @author Bas Leijdekkers
*/
public class SplitDeclarationAndInitializationIntentionTest extends IPPTestCase {
public void testArrayInitializer() { doTest(); }
@Override
protected String getRelativePath() {
return "initialization";
}
@Override
protected String getIntentionName() {
return IntentionPowerPackBundle.message("split.declaration.and.initialization.intention.name");
}
}
@@ -20,9 +20,6 @@ import org.jetbrains.annotations.NotNull;
import java.awt.*;
/**
* User: lia
*/
class StudyEditorFactoryListener implements EditorFactoryListener {
@@ -73,6 +70,7 @@ class StudyEditorFactoryListener implements EditorFactoryListener {
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
TaskFile taskFile = taskManager.getTaskFile(openedFile);
if (taskFile != null) {
taskFile.navigateToFirstTaskWindow(editor);
editor.addEditorMouseListener(new WindowSelectionListener(taskFile));
StudyDocumentListener listener = new StudyDocumentListener(taskFile);
StudyEditor.addDocumentListener(document, listener);
@@ -11,9 +11,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.BalloonBuilder;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.edu.StudyDocumentListener;
import com.jetbrains.python.edu.StudyTaskManager;
@@ -33,7 +31,7 @@ public class StudyRefreshTaskAction extends DumbAwareAction {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
Editor editor = StudyEditor.getSelectedEditor(project);
final Editor editor = StudyEditor.getSelectedEditor(project);
assert editor != null;
final Document document = editor.getDocument();
StudyDocumentListener listener = StudyEditor.getListener(document);
@@ -57,7 +55,7 @@ public class StudyRefreshTaskAction extends DumbAwareAction {
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
VirtualFile openedFile = fileDocumentManager.getFile(document);
assert openedFile != null;
TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
final TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
assert selectedTaskFile != null;
Task currentTask = selectedTaskFile.getTask();
String lessonDir = Lesson.LESSON_DIR + String.valueOf(currentTask.getLesson().getIndex() + 1);
@@ -12,7 +12,6 @@ import com.intellij.openapi.ui.popup.BalloonBuilder;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.edu.StudyTaskManager;
import com.jetbrains.python.edu.StudyUtils;
import com.jetbrains.python.edu.course.Lesson;
import com.jetbrains.python.edu.course.Task;
import com.jetbrains.python.edu.course.TaskFile;
@@ -50,23 +49,28 @@ abstract public class StudyTaskNavigationAction extends DumbAwareAction {
}
int nextTaskIndex = nextTask.getIndex();
int lessonIndex = nextTask.getLesson().getIndex();
TaskFile nextFile = nextTask.getTaskFiles().values().iterator().next();
if (nextFile != null) {
VirtualFile projectDir = project.getBaseDir();
String lessonDirName = Lesson.LESSON_DIR + String.valueOf(lessonIndex + 1);
if (projectDir != null) {
VirtualFile lessonDir = projectDir.findChild(lessonDirName);
if (lessonDir != null) {
String taskDirName = Task.TASK_DIR + String.valueOf(nextTaskIndex + 1);
VirtualFile taskDir = lessonDir.findChild(taskDirName);
if (taskDir != null) {
Map.Entry<String, TaskFile> taskFile = StudyUtils.getFirst(nextTask.getTaskFiles().entrySet());
VirtualFile virtualFile = taskDir.findChild(taskFile.getKey());
if (virtualFile != null) {
FileEditorManager.getInstance(project).openFile(virtualFile, true);
}
}
}
Map<String, TaskFile> nextTaskFiles = nextTask.getTaskFiles();
if (nextTaskFiles.isEmpty()) {
return;
}
VirtualFile projectDir = project.getBaseDir();
String lessonDirName = Lesson.LESSON_DIR + String.valueOf(lessonIndex + 1);
if (projectDir == null) {
return;
}
VirtualFile lessonDir = projectDir.findChild(lessonDirName);
if (lessonDir == null) {
return;
}
String taskDirName = Task.TASK_DIR + String.valueOf(nextTaskIndex + 1);
VirtualFile taskDir = lessonDir.findChild(taskDirName);
if (taskDir == null) {
return;
}
for (String name : nextTaskFiles.keySet()) {
VirtualFile vf = taskDir.findChild(name);
if (vf != null) {
FileEditorManager.getInstance(project).openFile(vf, true);
}
}
}
@@ -6,6 +6,7 @@ import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.xmlb.annotations.Transient;
import com.jetbrains.python.edu.StudyUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -210,4 +211,15 @@ public class TaskFile implements Stateful{
public boolean isUserCreated() {
return myUserCreated;
}
public void navigateToFirstTaskWindow(@NotNull final Editor editor) {
if (!taskWindows.isEmpty()) {
TaskWindow firstTaskWindow = StudyUtils.getFirst(taskWindows);
LogicalPosition taskWindowStart = new LogicalPosition(firstTaskWindow.getLine(), firstTaskWindow.getStart());
editor.getCaretModel().moveToLogicalPosition(taskWindowStart);
int startOffset = firstTaskWindow.getRealStartOffset(editor.getDocument());
int endOffset = startOffset + firstTaskWindow.getLength();
editor.getSelectionModel().setSelection(startOffset, endOffset);
}
}
}
@@ -207,7 +207,7 @@ public class StudyEditor implements TextEditor {
@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
return myComponent;
return myDefaultEditor.getPreferredFocusedComponent();
}
@NotNull