| /* |
| * 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); |
| } |
| |
| } |
| |
| } |