Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.netbeans.modules.java.hints.errors;

import com.sun.source.tree.BreakTree;
import com.sun.source.tree.CaseTree;
import com.sun.source.tree.CaseTree.CaseKind;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.ParenthesizedTree;
import com.sun.source.tree.StatementTree;
import com.sun.source.tree.SwitchExpressionTree;
import com.sun.source.tree.SwitchTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.SourcePositions;
import com.sun.source.util.TreePath;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.netbeans.api.java.source.CompilationInfo;
import org.netbeans.api.java.source.TreeMaker;
import org.netbeans.api.java.source.WorkingCopy;
import org.netbeans.modules.java.hints.spi.ErrorRule;
import org.netbeans.spi.editor.hints.Fix;
import org.netbeans.spi.java.hints.JavaFix;
import org.openide.util.NbBundle;

/**
* Resolves javac error by adding a missing default case to a switch.
*
* @author SANDEEMI
*/
@NbBundle.Messages("FIX_Add_Default_Case=Add Default Case")
public class AddDefaultCase implements ErrorRule<Void> {

private static final Set<String> CODES = Set.of(
"compiler.err.not.exhaustive",
"compiler.err.not.exhaustive.statement"
);

private static final String THROW_ISE = "throw new IllegalStateException(\"Unexpected value: \" + %1$s);";

@Override
public Set<String> getCodes() {
return CODES;
}

@Override
public List<Fix> run(CompilationInfo info, String diagnosticKey, int offset, TreePath treePath, Data<Void> data) {
return List.of(new AddDefaultCaseFix(info, treePath).toEditorFix());
}

@Override
public String getId() {
return AddDefaultCase.class.getName();
}

@Override
public String getDisplayName() {
return Bundle.FIX_Add_Default_Case();
}

@Override
public void cancel() {

}

private static final class AddDefaultCaseFix extends JavaFix {

public AddDefaultCaseFix(CompilationInfo info, TreePath path) {
super(info, path);
}

@Override
protected String getText() {
return Bundle.FIX_Add_Default_Case();
}

@Override
protected void performRewrite(TransformationContext ctx) throws Exception {
WorkingCopy wc = ctx.getWorkingCopy();
TreeMaker make = wc.getTreeMaker();
TreePath path = ctx.getPath();

switch (path.getLeaf().getKind()) {
case SWITCH_EXPRESSION -> {
SwitchExpressionTree expTree = (SwitchExpressionTree) path.getLeaf();
List<? extends CaseTree> cases = expTree.getCases();
if (cases.isEmpty()) {
return;
}
ParenthesizedTree expression = (ParenthesizedTree) expTree.getExpression();

String text = THROW_ISE.formatted(expression.toString());
StatementTree parseStatement = wc.getTreeUtilities().parseStatement(text, new SourcePositions[1]);
CaseTree caseSwitchPatterns;
if (cases.get(0).getCaseKind() == CaseKind.RULE) {
caseSwitchPatterns = make.CasePatterns(List.of(), parseStatement);
} else {
caseSwitchPatterns = make.CasePatterns(List.of(), List.of(parseStatement));
}

List<CaseTree> newCases = new ArrayList<>(cases.size() + 1);
newCases.addAll(cases);
newCases.add(caseSwitchPatterns);
Tree switchExpression = make.SwitchExpression(expression, newCases);
wc.rewrite(expTree, switchExpression);
}
case SWITCH -> {
SwitchTree switchTree = (SwitchTree) path.getLeaf();
List<? extends CaseTree> cases = switchTree.getCases();
if (cases.isEmpty()) {
return;
}
ExpressionTree expression = ((ParenthesizedTree) switchTree.getExpression()).getExpression();

String text = THROW_ISE.formatted(expression.toString());
StatementTree parseStatement = wc.getTreeUtilities().parseStatement(text, new SourcePositions[1]);
CaseTree caseSwitchPatterns;
if (cases.get(0).getCaseKind() == CaseKind.RULE) {
caseSwitchPatterns = make.CasePatterns(List.of(), parseStatement);
} else {
handleLastCase(cases.get(cases.size() - 1), wc, make);
caseSwitchPatterns = make.CasePatterns(List.of(), List.of(parseStatement));
}

SwitchTree insertSwitchCase = make.addSwitchCase(switchTree, caseSwitchPatterns);
wc.rewrite(switchTree, insertSwitchCase);
}
default -> throw new UnsupportedOperationException(path.getLeaf().getKind() + " not implemented");
}
}

private static void handleLastCase(CaseTree lastCase, WorkingCopy wc, TreeMaker make) {
List<? extends StatementTree> statements = lastCase.getStatements();
if (statements.isEmpty() || !(statements.get(statements.size() - 1) instanceof BreakTree)) {
List<StatementTree> expanded = new ArrayList<>(statements.size() + 1);
expanded.addAll(statements);
expanded.add(make.Break(null));
wc.rewrite(lastCase, make.CasePatterns(lastCase.getLabels(), expanded));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,8 @@ public void cancel() {

private static final class FixImpl extends JavaFix {

CompilationInfo info;
TreePath path;

public FixImpl(CompilationInfo info, TreePath path) {
super(info, path);
this.info = info;
this.path = path;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,10 @@ public void cancel() {
private static final class FixImpl extends JavaFix {

CompilationInfo info;
TreePath path;

public FixImpl(CompilationInfo info, TreePath path) {
super(info, path);
this.info = info;
this.path = path;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
<file name="org-netbeans-modules-java-hints-errors-RemoveFinalModifierFromVariable.instance">
<attr name="instanceCreate" methodvalue="org.netbeans.modules.java.hints.errors.AddOrRemoveFinalModifier.createRemoveFinalFromVariable"/>
</file>
<file name="org-netbeans-modules-java-hints-errors-AddDefaultCase.instance"/>
<file name="org-netbeans-modules-java-hints-errors-RemoveInvalidModifier.instance"/>
<file name="org-netbeans-modules-java-hints-errors-RemoveUselessCast.instance"/>
<file name="org-netbeans-modules-java-hints-errors-SuppressWarningsFixer.instance"/>
Expand Down Expand Up @@ -327,7 +328,7 @@

<folder name="bugs">
<attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.java.hints.resources.Bundle"/>
<file name="org-netbeans-modules-java-hints-SuspiciousNamesCombination.instance" />
<file name="org-netbeans-modules-java-hints-SuspiciousNamesCombination.instance"/>
</folder>

<folder name="thread">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,7 @@
*/
package org.netbeans.modules.java.hints.errors;

import com.sun.source.util.TreePath;
import java.util.List;
import java.util.Set;
import org.netbeans.api.java.source.CompilationInfo;
import org.netbeans.modules.java.hints.infrastructure.ErrorHintsTestBase;
import org.netbeans.spi.editor.hints.Fix;
import org.openide.util.NbBundle;

/**
Expand All @@ -33,7 +28,7 @@
public class AccessErrorTest extends ErrorHintsTestBase {

public AccessErrorTest(String name) {
super(name);
super(name, AccessError.class);
}

public void testSimple() throws Exception {
Expand Down Expand Up @@ -61,21 +56,6 @@ public void testSimple() throws Exception {
"}\n").replaceAll("[\\s]+", " "));
}

@Override
protected List<Fix> computeFixes(CompilationInfo info, int pos, TreePath path) throws Exception {
return new AccessError().run(info, null, pos, path, null);
}

@Override
protected String toDebugString(CompilationInfo info, Fix f) {
return f.getText();
}

@Override
protected Set<String> getSupportedErrorKeys() {
return new AccessError().getCodes();
}

static {
NbBundle.setBranding("test");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,7 @@

package org.netbeans.modules.java.hints.errors;

import com.sun.source.util.TreePath;
import java.util.List;
import java.util.Set;
import org.netbeans.api.java.source.CompilationInfo;
import org.netbeans.modules.java.hints.infrastructure.ErrorHintsTestBase;
import org.netbeans.spi.editor.hints.Fix;
import org.openide.util.NbBundle;

/**
Expand All @@ -34,7 +29,7 @@
public class AddCastTest extends ErrorHintsTestBase {

public AddCastTest(String testName) {
super(testName);
super(testName, AddCast.class);
}

public void test117868() throws Exception {
Expand Down Expand Up @@ -157,21 +152,6 @@ public void test214835b() throws Exception {
"package test; public class Test { private static void x(long l) { t((byte) l); } void t(byte b) {} void t(int i) {} void t(String s) {} }");
}

@Override
protected List<Fix> computeFixes(CompilationInfo info, int pos, TreePath path) throws Exception {
return new AddCast().run(info, null, pos, path, null);
}

@Override
protected String toDebugString(CompilationInfo info, Fix f) {
return f.getText();
}

@Override
protected Set<String> getSupportedErrorKeys() {
return new AddCast().getCodes();
}

static {
NbBundle.setBranding("test");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,7 @@
*/
package org.netbeans.modules.java.hints.errors;

import com.sun.source.util.TreePath;
import java.util.List;
import java.util.Set;
import org.netbeans.api.java.source.CompilationInfo;
import org.netbeans.modules.java.hints.infrastructure.ErrorHintsTestBase;
import org.netbeans.spi.editor.hints.Fix;
import org.openide.util.NbBundle;

/**
Expand All @@ -33,7 +28,7 @@
public class AddCatchFixTest extends ErrorHintsTestBase {

public AddCatchFixTest(String testName) {
super(testName);
super(testName, UncaughtException.class);
}

public void test207480a() throws Exception {
Expand All @@ -44,20 +39,6 @@ public void test207480a() throws Exception {
"package test; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; public class Test {public void test() {try { test2(); } catch (IOException ex) { Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); } finally{ } } private void test2() throws IOException {} }");
}

protected List<Fix> computeFixes(CompilationInfo info, int pos, TreePath path) throws Exception {
return new UncaughtException().run(info, null, pos, path, null);
}

@Override
protected Set<String> getSupportedErrorKeys() {
return new UncaughtException().getCodes();
}

@Override
protected String toDebugString(CompilationInfo info, Fix f) {
return f.getText();
}

static {
NbBundle.setBranding("test");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,7 @@
*/
package org.netbeans.modules.java.hints.errors;

import org.netbeans.modules.java.hints.errors.AddConstructor;
import com.sun.source.util.TreePath;
import java.util.List;
import java.util.Set;
import org.netbeans.api.java.source.CompilationInfo;
import org.netbeans.modules.java.hints.infrastructure.ErrorHintsTestBase;
import org.netbeans.spi.editor.hints.Fix;
import org.openide.util.NbBundle;

/**
Expand Down
Loading
Loading