001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * Portions Copyrighted 2007 Sun Microsystems, Inc.
027: */
028: package org.netbeans.modules.java.hints.errors;
029:
030: import com.sun.source.tree.ExpressionTree;
031: import com.sun.source.tree.VariableTree;
032: import com.sun.source.util.TreePath;
033: import com.sun.source.util.Trees;
034: import java.util.ArrayList;
035: import java.util.Collections;
036: import java.util.List;
037: import java.util.Set;
038: import javax.lang.model.element.Element;
039: import javax.lang.model.element.ElementKind;
040: import javax.lang.model.type.TypeKind;
041: import javax.lang.model.type.TypeMirror;
042: import org.netbeans.api.java.source.CompilationInfo;
043: import org.netbeans.api.java.source.JavaSource;
044: import org.netbeans.api.java.source.JavaSource.Phase;
045: import org.netbeans.api.java.source.Task;
046: import org.netbeans.api.java.source.TreePathHandle;
047: import org.netbeans.api.java.source.WorkingCopy;
048: import org.netbeans.modules.java.hints.spi.ErrorRule;
049: import org.netbeans.modules.java.hints.spi.ErrorRule.Data;
050: import org.netbeans.spi.editor.hints.ChangeInfo;
051: import org.netbeans.spi.editor.hints.Fix;
052: import org.openide.filesystems.FileObject;
053: import org.openide.util.NbBundle;
054:
055: /**
056: *
057: * @author Tomas Zezula
058: */
059: public class NotInitializedVariable implements ErrorRule<Void> {
060:
061: private static final String DIAGNOSTIC_KEY = "compiler.err.var.might.not.have.been.initialized";
062: private volatile boolean canceled;
063:
064: public NotInitializedVariable() {
065: }
066:
067: public Set<String> getCodes() {
068: return Collections.<String> singleton(DIAGNOSTIC_KEY);
069: }
070:
071: public List<Fix> run(CompilationInfo compilationInfo,
072: String diagnosticKey, int offset, TreePath treePath,
073: Data<Void> data) {
074: assert DIAGNOSTIC_KEY.equals(diagnosticKey);
075: final List<Fix> result = new ArrayList<Fix>();
076: if (!canceled) {
077: final Trees t = compilationInfo.getTrees();
078: final Element e = t.getElement(treePath);
079: if (!canceled && e != null
080: && e.getKind() == ElementKind.LOCAL_VARIABLE) {
081: TreePath declaration = t.getPath(e);
082: if (!canceled && declaration != null) {
083: result.add(new NIVFix(compilationInfo
084: .getFileObject(), e.getSimpleName()
085: .toString(), TreePathHandle.create(
086: declaration, compilationInfo)));
087: }
088: }
089: }
090: return Collections.unmodifiableList(result);
091: }
092:
093: public String getId() {
094: return "NotInitializedVariable"; //NOI18N
095: }
096:
097: public String getDisplayName() {
098: return NbBundle.getMessage(NotInitializedVariable.class,
099: "LBL_NotInitializedVariable");
100: }
101:
102: public void cancel() {
103: this .canceled = true;
104: }
105:
106: private static class NIVFix implements Fix {
107:
108: private final FileObject file;
109: private final String variableName;
110: private final TreePathHandle variable;
111:
112: public NIVFix(final FileObject file, final String variableName,
113: final TreePathHandle variable) {
114: assert file != null;
115: assert variableName != null;
116: assert variable != null;
117: this .file = file;
118: this .variableName = variableName;
119: this .variable = variable;
120: }
121:
122: public String getText() {
123: return NbBundle.getMessage(NotInitializedVariable.class,
124: "LBL_NotInitializedVariable_fix", variableName); //NOI18N
125: }
126:
127: public ChangeInfo implement() throws Exception {
128: final JavaSource js = JavaSource.forFileObject(this .file);
129: if (js != null) {
130: js.runModificationTask(new Task<WorkingCopy>() {
131: public void run(final WorkingCopy wc)
132: throws Exception {
133: wc.toPhase(Phase.RESOLVED);
134: TreePath tp = variable.resolve(wc);
135: if (tp == null)
136: return;
137: VariableTree vt = (VariableTree) tp.getLeaf();
138: ExpressionTree init = vt.getInitializer();
139: if (init != null) {
140: return;
141: }
142: Element decl = wc.getTrees().getElement(tp);
143: if (decl == null) {
144: return;
145: }
146: TypeMirror type = decl.asType();
147: TypeKind kind = type.getKind();
148: Object value;
149: if (kind.isPrimitive()) {
150: if (kind == TypeKind.BOOLEAN) {
151: value = false;
152: } else {
153: value = 0;
154: }
155: } else {
156: value = null;
157: }
158: ExpressionTree newInit = wc.getTreeMaker()
159: .Literal(value);
160: VariableTree newVt = wc.getTreeMaker()
161: .Variable(vt.getModifiers(),
162: vt.getName(), vt.getType(),
163: newInit);
164: wc.rewrite(vt, newVt);
165: }
166: }).commit();
167: }
168: return null;
169: }
170:
171: }
172:
173: }
|