Skip to content

Commit 2a5b76b

Browse files
committed
Optimize imports on the fly
1 parent dd4ec66 commit 2a5b76b

File tree

12 files changed

+236
-0
lines changed

12 files changed

+236
-0
lines changed

src/META-INF/plugin.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@
5252
</component>
5353
</module-components>
5454

55+
<project-components>
56+
<component>
57+
<implementation-class>com.goide.codeInsight.imports.GoOptimizeImportsPassFactory</implementation-class>
58+
<skipForDefaultProject/>
59+
</component>
60+
</project-components>
61+
5562
<extensions defaultExtensionNs="com.intellij">
5663
<stubIndex implementation="com.goide.stubs.index.GoAllPublicNamesIndex"/>
5764
<stubIndex implementation="com.goide.stubs.index.GoAllPrivateNamesIndex"/>

src/com/goide/codeInsight/imports/GoAutoImportConfigurable.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
public class GoAutoImportConfigurable implements SearchableConfigurable {
3939
private JCheckBox myCbShowImportPopup;
40+
private JCheckBox myCbOptimizeImportsOnTheFly;
4041
private JCheckBox myCbAddUnambiguousImports;
4142
private JBList myExcludePackagesList;
4243
private DefaultListModel myExcludePackagesModel;
@@ -58,8 +59,10 @@ public GoAutoImportConfigurable(@NotNull Project project, boolean dialogMode) {
5859
public JComponent createComponent() {
5960
FormBuilder builder = FormBuilder.createFormBuilder();
6061
myCbShowImportPopup = new JCheckBox(ApplicationBundle.message("checkbox.show.import.popup"));
62+
myCbOptimizeImportsOnTheFly = new JCheckBox(ApplicationBundle.message("checkbox.optimize.imports.on.the.fly"));
6163
myCbAddUnambiguousImports = new JCheckBox(ApplicationBundle.message("checkbox.add.unambiguous.imports.on.the.fly"));
6264
builder.addComponent(myCbShowImportPopup);
65+
builder.addComponent(myCbOptimizeImportsOnTheFly);
6366
builder.addComponent(myCbAddUnambiguousImports);
6467

6568
myExcludePackagesList = new JBList();
@@ -94,20 +97,23 @@ private String[] getExcludedPackages() {
9497
@Override
9598
public boolean isModified() {
9699
return myCodeInsightSettings.isShowImportPopup() != myCbShowImportPopup.isSelected() ||
100+
myCodeInsightSettings.isOptimizeImportsOnTheFly() != myCbOptimizeImportsOnTheFly.isSelected() ||
97101
myCodeInsightSettings.isAddUnambiguousImportsOnTheFly() != myCbAddUnambiguousImports.isSelected() ||
98102
!Arrays.equals(getExcludedPackages(), myExcludedSettings.getExcludedPackages());
99103
}
100104

101105
@Override
102106
public void apply() throws ConfigurationException {
103107
myCodeInsightSettings.setShowImportPopup(myCbShowImportPopup.isSelected());
108+
myCodeInsightSettings.setOptimizeImportsOnTheFly(myCbOptimizeImportsOnTheFly.isSelected());
104109
myCodeInsightSettings.setAddUnambiguousImportsOnTheFly(myCbAddUnambiguousImports.isSelected());
105110
myExcludedSettings.setExcludedPackages(getExcludedPackages());
106111
}
107112

108113
@Override
109114
public void reset() {
110115
myCbShowImportPopup.setSelected(myCodeInsightSettings.isShowImportPopup());
116+
myCbOptimizeImportsOnTheFly.setSelected(myCodeInsightSettings.isOptimizeImportsOnTheFly());
111117
myCbAddUnambiguousImports.setSelected(myCodeInsightSettings.isAddUnambiguousImportsOnTheFly());
112118

113119
myExcludePackagesModel = new DefaultListModel();

src/com/goide/codeInsight/imports/GoCodeInsightSettings.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
)
2727
public class GoCodeInsightSettings implements PersistentStateComponent<GoCodeInsightSettings> {
2828
private boolean myShowImportPopup = true;
29+
private boolean myOptimizeImportsOnTheFly = false;
2930
private boolean myAddUnambiguousImportsOnTheFly = true;
3031

3132
public static GoCodeInsightSettings getInstance() {
@@ -51,6 +52,14 @@ public void setShowImportPopup(boolean showImportPopup) {
5152
myShowImportPopup = showImportPopup;
5253
}
5354

55+
public boolean isOptimizeImportsOnTheFly() {
56+
return myOptimizeImportsOnTheFly;
57+
}
58+
59+
public void setOptimizeImportsOnTheFly(boolean optimizeImportsOnTheFly) {
60+
myOptimizeImportsOnTheFly = optimizeImportsOnTheFly;
61+
}
62+
5463
public boolean isAddUnambiguousImportsOnTheFly() {
5564
return myAddUnambiguousImportsOnTheFly;
5665
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2013-2015 Sergey Ignatov, Alexander Zolotov, Mihai Toader, Florin Patan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.goide.codeInsight.imports;
18+
19+
import com.intellij.codeInsight.daemon.impl.DefaultHighlightInfoProcessor;
20+
import com.intellij.codeInsight.daemon.impl.ProgressableTextEditorHighlightingPass;
21+
import com.intellij.openapi.editor.Editor;
22+
import com.intellij.openapi.progress.ProgressIndicator;
23+
import com.intellij.openapi.project.Project;
24+
import com.intellij.psi.PsiFile;
25+
import com.intellij.util.DocumentUtil;
26+
import org.jetbrains.annotations.NotNull;
27+
28+
public class GoOptimizeImportsPass extends ProgressableTextEditorHighlightingPass {
29+
@NotNull private final PsiFile myFile;
30+
31+
public GoOptimizeImportsPass(@NotNull Project project, @NotNull PsiFile file, @NotNull Editor editor) {
32+
super(project, editor.getDocument(), "Go Optimize Imports Pass", file, editor, file.getTextRange(), false,
33+
new DefaultHighlightInfoProcessor());
34+
myFile = file;
35+
}
36+
37+
@Override
38+
protected void collectInformationWithProgress(@NotNull ProgressIndicator progress) {
39+
progress.checkCanceled();
40+
}
41+
42+
@Override
43+
protected void applyInformationWithProgress() {
44+
final Runnable runnable = new GoImportOptimizer().processFile(myFile);
45+
DocumentUtil.writeInRunUndoTransparentAction(runnable);
46+
}
47+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2013-2015 Sergey Ignatov, Alexander Zolotov, Mihai Toader, Florin Patan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.goide.codeInsight.imports;
18+
19+
import com.goide.psi.GoFile;
20+
import com.intellij.codeHighlighting.Pass;
21+
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
22+
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory;
23+
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
24+
import com.intellij.codeInsight.daemon.impl.FileStatusMap;
25+
import com.intellij.openapi.components.AbstractProjectComponent;
26+
import com.intellij.openapi.editor.Editor;
27+
import com.intellij.openapi.project.Project;
28+
import com.intellij.openapi.util.TextRange;
29+
import com.intellij.psi.PsiFile;
30+
import org.jetbrains.annotations.NotNull;
31+
import org.jetbrains.annotations.Nullable;
32+
33+
public class GoOptimizeImportsPassFactory extends AbstractProjectComponent implements TextEditorHighlightingPassFactory {
34+
protected GoOptimizeImportsPassFactory(Project project, TextEditorHighlightingPassRegistrar highlightingPassRegistrar) {
35+
super(project);
36+
highlightingPassRegistrar.registerTextEditorHighlightingPass(this, new int[]{Pass.UPDATE_ALL}, null, false, -1);
37+
}
38+
39+
@Nullable
40+
@Override
41+
public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull Editor editor) {
42+
TextRange range = FileStatusMap.getDirtyTextRange(editor, Pass.UPDATE_ALL);
43+
if (range != null && file instanceof GoFile && GoCodeInsightSettings.getInstance().isOptimizeImportsOnTheFly()) {
44+
return new GoOptimizeImportsPass(file.getProject(), file, editor);
45+
}
46+
return null;
47+
}
48+
49+
@NotNull
50+
@Override
51+
public String getComponentName() {
52+
return "OptimizeImportsPassFactory";
53+
}
54+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package a
2+
import (
3+
"fmt"
4+
"http"
5+
)
6+
7+
func b() {
8+
http.get("123")
9+
fmt.Println()
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package a
2+
import (
3+
fmt "fmt"
4+
"fmt"
5+
"http"
6+
)
7+
8+
func b() {
9+
http.get("123")
10+
fmt.Println()
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package a
2+
import (
3+
"fmt"
4+
"http"
5+
)
6+
7+
func b() {
8+
http.get("123")
9+
fmt.Println()
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package a
2+
import (
3+
fmt "fmt"
4+
"http"
5+
)
6+
7+
func b() {
8+
http.get("123")
9+
fmt.Println()
10+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package a
2+
3+
func b() {
4+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package a
2+
import "fmt"
3+
4+
func b() {
5+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2013-2015 Sergey Ignatov, Alexander Zolotov, Mihai Toader, Florin Patan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.goide.codeInsight.imports;
18+
19+
import com.goide.GoCodeInsightFixtureTestCase;
20+
import com.intellij.testFramework.LightProjectDescriptor;
21+
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
22+
23+
public class GoOptimizeImportsOnTheFlyTest extends GoCodeInsightFixtureTestCase {
24+
@Override
25+
public void setUp() throws Exception {
26+
super.setUp();
27+
setUpProjectSdk();
28+
((CodeInsightTestFixtureImpl)myFixture).canChangeDocumentDuringHighlighting(true);
29+
GoCodeInsightSettings.getInstance().setOptimizeImportsOnTheFly(true);
30+
}
31+
32+
@Override
33+
protected void tearDown() throws Exception {
34+
GoCodeInsightSettings.getInstance().setOptimizeImportsOnTheFly(false);
35+
super.tearDown();
36+
}
37+
38+
@Override
39+
protected String getBasePath() {
40+
return "imports/optimize/on-the-fly";
41+
}
42+
43+
@Override
44+
protected LightProjectDescriptor getProjectDescriptor() {
45+
return createMockProjectDescriptor();
46+
}
47+
48+
@Override
49+
protected boolean isWriteActionRequired() {
50+
return false;
51+
}
52+
53+
private void doTest() {
54+
String testName = getTestName(true);
55+
myFixture.configureByFile(testName + ".go");
56+
myFixture.doHighlighting();
57+
myFixture.checkResultByFile(testName + "-after.go");
58+
}
59+
60+
public void testUnusedImport() { doTest(); }
61+
public void testRedundantImport() { doTest(); }
62+
public void testRedeclaredImport() { doTest(); }
63+
}

0 commit comments

Comments
 (0)