blob: 9706480ede97f2fda7976e3c244143db10769783 [file] [log] [blame]
/*
* 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.BlockTree;
import com.sun.source.tree.CaseTree;
import com.sun.source.tree.StatementTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.VariableTree;
import com.sun.source.util.TreePath;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
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;
/**
* Handle error rule "compiler.err.var.not.allowed.compound"
* and provide the fix.
* @author vkprabha
*/
public class VarCompDeclaration implements ErrorRule<Void> {
private static final Set<String> ERROR_CODES = new HashSet<String>(Arrays.asList(
"compiler.err.var.not.allowed.compound")); // NOI18N
@Override
public Set<String> getCodes() {
return Collections.unmodifiableSet(ERROR_CODES);
}
@Override
public List<Fix> run(CompilationInfo info, String diagnosticKey, int offset, TreePath treePath, Data<Void> data) {
Tree.Kind parentKind = treePath.getParentPath().getLeaf().getKind();
if (parentKind != Tree.Kind.BLOCK && parentKind != Tree.Kind.CASE) {
return null;
}
return Collections.<Fix>singletonList(new VarCompDeclaration.FixImpl(info, treePath).toEditorFix());
}
@Override
public String getId() {
return VarCompDeclaration.class.getName();
}
@Override
public String getDisplayName() {
return NbBundle.getMessage(VarCompDeclaration.class, "FIX_VarCompDeclaration"); // NOI18N
}
public String getDescription() {
return NbBundle.getMessage(VarCompDeclaration.class, "FIX_VarCompDeclaration"); // NOI18N
}
@Override
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
protected String getText() {
return NbBundle.getMessage(VarCompDeclaration.class, "FIX_VarCompDeclaration"); // NOI18N
}
public String toDebugString() {
return NbBundle.getMessage(VarCompDeclaration.class, "FIX_VarCompDeclaration"); // NOI18N
}
@Override
protected void performRewrite(TransformationContext ctx) throws Exception {
TreePath statementPath = ctx.getPath();
Tree parent = statementPath.getParentPath().getLeaf();
List<? extends StatementTree> statements = null;
switch (parent.getKind()) {
case BLOCK:
statements = ((BlockTree) parent).getStatements();
break;
case CASE:
statements = ((CaseTree) parent).getStatements();
break;
default:
// Ignore other scenario
break;
}
WorkingCopy wc = ctx.getWorkingCopy();
TreeMaker make = wc.getTreeMaker();
int pos = statements.indexOf(statementPath.getLeaf());
List<StatementTree> newStatements = new ArrayList<>();
if (pos > 0) {
newStatements.addAll(statements.subList(0, pos));
}
int current = 0;
for (current = pos; current < statements.size(); current++) {
StatementTree t = (StatementTree) statements.get(current);
if (t instanceof VariableTree) {
VariableTree oldVariableTree = (VariableTree) t;
VariableTree newVariableTree = make.Variable(
oldVariableTree.getModifiers(),
oldVariableTree.getName(),
make.Type("var"), // NOI18N
oldVariableTree.getInitializer()
);
newStatements.add(make.asReplacementOf(newVariableTree, oldVariableTree));
// Check variable tree seperated with ","
if(info.getTreeUtilities().isEndOfCompoundVariableDeclaration(t)) break;
}
}
if (current + 1 < statements.size()) {
newStatements.addAll(statements.subList(current + 1, statements.size()));
}
Tree target = null;
switch (parent.getKind()) {
case BLOCK:
target = make.Block(newStatements, ((BlockTree) parent).isStatic());
break;
case CASE:
target = make.Case(((CaseTree) parent).getExpression(), newStatements);
break;
default:
// Ignore other scenario
break;
}
wc.rewrite(parent, target);
}
}
}