# HG changeset patch # Parent 6d95d2a94e2147d945958562c5362c9671e92955 diff -r 6d95d2a94e21 apisupport.refactoring/nbproject/project.xml --- a/apisupport.refactoring/nbproject/project.xml Sat Mar 10 07:43:05 2012 +0100 +++ b/apisupport.refactoring/nbproject/project.xml Sat Mar 10 15:42:17 2012 +0100 @@ -125,7 +125,7 @@ - 0.67 + 0.97 diff -r 6d95d2a94e21 apisupport.refactoring/src/org/netbeans/modules/apisupport/hints/UseNbBundleMessages.java --- a/apisupport.refactoring/src/org/netbeans/modules/apisupport/hints/UseNbBundleMessages.java Sat Mar 10 07:43:05 2012 +0100 +++ b/apisupport.refactoring/src/org/netbeans/modules/apisupport/hints/UseNbBundleMessages.java Sat Mar 10 15:42:17 2012 +0100 @@ -243,21 +243,6 @@ wc.rewrite(mit, make.MethodInvocation(Collections.emptyList(), make.Identifier(toIdentifier(key)), params)); } // else annotation value, nothing to change if (!isAlreadyRegistered) { - Tree enclosing = findEnclosingElement(wc, treePath); - Tree modifiers; - switch (enclosing.getKind()) { - case METHOD: - modifiers = ((MethodTree) enclosing).getModifiers(); - break; - case VARIABLE: - modifiers = ((VariableTree) enclosing).getModifiers(); - break; - case COMPILATION_UNIT: - modifiers = enclosing; - break; - default: - modifiers = ((ClassTree) enclosing).getModifiers(); - } EditableProperties ep = new EditableProperties(true); InputStream is = ctx.getResourceContent(bundleProperties); try { @@ -270,7 +255,32 @@ lines.add(make.Literal(comment)); } lines.add(make.Literal(key + '=' + ep.remove(key))); - wc.rewrite(modifiers, addMessage(wc, modifiers, lines)); + TypeElement nbBundleMessages = wc.getElements().getTypeElement("org.openide.util.NbBundle.Messages"); + if (nbBundleMessages == null) { + throw new IllegalArgumentException("cannot resolve org.openide.util.NbBundle.Messages"); + } + GeneratorUtilities gu = GeneratorUtilities.get(wc); + Tree enclosing = findEnclosingElement(wc, treePath); + Tree modifiers; + Tree nueModifiers; + switch (enclosing.getKind()) { + case METHOD: + modifiers = ((MethodTree) enclosing).getModifiers(); + nueModifiers = gu.appendToAnnotationValue(((MethodTree) enclosing).getModifiers(), nbBundleMessages, "value", lines.toArray(new ExpressionTree[0])); + break; + case VARIABLE: + modifiers = ((VariableTree) enclosing).getModifiers(); + nueModifiers = gu.appendToAnnotationValue(((VariableTree) enclosing).getModifiers(), nbBundleMessages, "value", lines.toArray(new ExpressionTree[0])); + break; + case COMPILATION_UNIT: + modifiers = enclosing; + nueModifiers = gu.appendToAnnotationValue((CompilationUnitTree) enclosing, nbBundleMessages, "value", lines.toArray(new ExpressionTree[0])); + break; + default: + modifiers = ((ClassTree) enclosing).getModifiers(); + nueModifiers = gu.appendToAnnotationValue(((ClassTree) enclosing).getModifiers(), nbBundleMessages, "value", lines.toArray(new ExpressionTree[0])); + } + wc.rewrite(modifiers, nueModifiers); // XXX remove NbBundle import if now unused OutputStream os = ctx.getResourceOutput(bundleProperties); try { @@ -281,71 +291,6 @@ } // XXX after JavaFix rewrite, Savable.save (on DataObject.find(src)) no longer works (JG13 again) } - // borrowed from FindBugsHint: - private Tree addMessage(WorkingCopy wc, /*Modifiers|CompilationUnit*/Tree original, List lines) throws IllegalArgumentException { - TreeMaker make = wc.getTreeMaker(); - // First try to insert into a value list for an existing annotation: - List anns; - if (original.getKind() == Kind.COMPILATION_UNIT) { - anns = ((CompilationUnitTree) original).getPackageAnnotations(); - } else { - anns = ((ModifiersTree) original).getAnnotations(); - } - for (int i = 0; i < anns.size(); i++) { - AnnotationTree ann = anns.get(i); - Tree annotationType = ann.getAnnotationType(); - // XXX clumsy and imprecise, but how to find the FQN of the annotation type given a Tree? Want a TypeMirror for it. - if (annotationType.toString().matches("((org[.]openide[.]util[.])?NbBundle[.])?Messages")) { - List args = ann.getArguments(); - if (args.size() != 1) { - throw new IllegalArgumentException("expecting just one arg for @Messages"); - } - AssignmentTree assign = (AssignmentTree) args.get(0); - if (!assign.getVariable().toString().equals("value")) { - throw new IllegalArgumentException("expected value=... for @Messages"); - } - ExpressionTree arg = assign.getExpression(); - NewArrayTree arr; - if (arg.getKind() == Tree.Kind.STRING_LITERAL) { - arr = make.NewArray(null, Collections.emptyList(), Collections.singletonList(arg)); - } else if (arg.getKind() == Tree.Kind.NEW_ARRAY) { - arr = (NewArrayTree) arg; - } else { - throw new IllegalArgumentException("unknown arg kind " + arg.getKind() + ": " + arg); - } - for (ExpressionTree line : lines) { - arr = make.addNewArrayInitializer(arr, line); - } - ann = make.Annotation(annotationType, Collections.singletonList(arr)); - if (original.getKind() == Kind.COMPILATION_UNIT) { - CompilationUnitTree cut = (CompilationUnitTree) original; - List newAnns = new ArrayList(anns); - newAnns.set(i, ann); - return make.CompilationUnit(newAnns, cut.getPackageName(), cut.getImports(), cut.getTypeDecls(), cut.getSourceFile()); - } else { - return make.insertModifiersAnnotation(make.removeModifiersAnnotation((ModifiersTree) original, i), i, ann); - } - } - } - // Not found, so create a new annotation: - List values; - if (lines.size() > 1) { // @Messages({"# ...", "k=v"}) - values = Collections.singletonList(make.NewArray(null, Collections.emptyList(), lines)); - } else { // @Messages("k=v") - values = lines; - } - AnnotationTree atMessages = make.Annotation(make.QualIdent("org.openide.util.NbBundle.Messages"), values); - Tree result; - if (original.getKind() == Kind.COMPILATION_UNIT) { - CompilationUnitTree cut = (CompilationUnitTree) original; - List newAnns = new ArrayList(anns); - newAnns.add(atMessages); - result = make.CompilationUnit(newAnns, cut.getPackageName(), cut.getImports(), cut.getTypeDecls(), cut.getSourceFile()); - } else { - result = make.insertModifiersAnnotation((ModifiersTree) original, 0, atMessages); - } - return GeneratorUtilities.get(wc).importFQNs(result); - } private Tree findEnclosingElement(WorkingCopy wc, TreePath treePath) { Tree leaf = treePath.getLeaf(); Kind kind = leaf.getKind(); diff -r 6d95d2a94e21 java.source/apichanges.xml --- a/java.source/apichanges.xml Sat Mar 10 07:43:05 2012 +0100 +++ b/java.source/apichanges.xml Sat Mar 10 15:42:17 2012 +0100 @@ -108,6 +108,21 @@ + + + Added GeneratorUtilities.appendToAnnotationValue. + + + + + + Added two overloaded methods appendToAnnotationValue to class GeneratorUtilites, + which augment ModifiersTree or CompilationUnitTree with + annotation with the given attribute values. + + + + Added several methods to CodeStyle supporting customization of the generated class members order and other minor formatting enhancements. diff -r 6d95d2a94e21 java.source/manifest.mf --- a/java.source/manifest.mf Sat Mar 10 07:43:05 2012 +0100 +++ b/java.source/manifest.mf Sat Mar 10 15:42:17 2012 +0100 @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.java.source -OpenIDE-Module-Implementation-Version: 20 +OpenIDE-Module-Implementation-Version: 21 OpenIDE-Module-Install: org/netbeans/modules/java/source/JBrowseModule.class OpenIDE-Module-Layer: org/netbeans/modules/java/source/resources/layer.xml OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/java/source/Bundle.properties diff -r 6d95d2a94e21 java.source/nbproject/project.properties --- a/java.source/nbproject/project.properties Sat Mar 10 07:43:05 2012 +0100 +++ b/java.source/nbproject/project.properties Sat Mar 10 15:42:17 2012 +0100 @@ -46,7 +46,7 @@ javadoc.title=Java Source javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml -spec.version.base=0.96.0 +spec.version.base=0.97.0 test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/javac-api-nb-7.0-b07.jar test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\ ${o.n.core.dir}/lib/boot.jar:\ diff -r 6d95d2a94e21 java.source/src/org/netbeans/api/java/source/GeneratorUtilities.java --- a/java.source/src/org/netbeans/api/java/source/GeneratorUtilities.java Sat Mar 10 07:43:05 2012 +0100 +++ b/java.source/src/org/netbeans/api/java/source/GeneratorUtilities.java Sat Mar 10 15:42:17 2012 +0100 @@ -45,16 +45,20 @@ package org.netbeans.api.java.source; import com.sun.source.tree.AnnotationTree; +import com.sun.source.tree.ArrayTypeTree; +import com.sun.source.tree.AssignmentTree; import com.sun.source.tree.BlockTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.IdentifierTree; import com.sun.source.tree.ImportTree; +import com.sun.source.tree.LiteralTree; import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.MethodTree; import com.sun.source.tree.ModifiersTree; +import com.sun.source.tree.NewArrayTree; import com.sun.source.tree.NewClassTree; import com.sun.source.tree.PrimitiveTypeTree; import com.sun.source.tree.Scope; @@ -81,6 +85,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.EnumSet; @@ -93,6 +98,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; @@ -813,6 +820,201 @@ t.addComments(RelativePosition.TRAILING, s.getComments(RelativePosition.TRAILING)); } } + + /**Ensures that the given {@code modifiers} contains annotation of the given type, + * which has attribute name {@code attributeName}, which contains values {@code attributeValuesToAdd}. + * The annotation or the attribute will be added as needed, as will be the attribute value + * converted from a single value into an array. + * + * The typical trees passed as {@code attributeValuesToAdd} are: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
attribute typeexpected tree type
primitive type{@link LiteralTree} created by {@link TreeMaker#Literal(java.lang.Object) }
{@code java.lang.String}{@link LiteralTree} created by {@link TreeMaker#Literal(java.lang.Object) }
{@code java.lang.Class}{@link MemberSelectTree} created by {@link TreeMaker#MemberSelect(com.sun.source.tree.ExpressionTree, java.lang.CharSequence) }, + * with identifier {@code class} and expression created by {@link TreeMaker#QualIdent(javax.lang.model.element.Element) }
enum constant{@link MemberSelectTree}, with identifier representing the enum constant + * and expression created by {@link TreeMaker#QualIdent(javax.lang.model.element.Element) }
annotation type{@link AnnotationTree} created by {@link TreeMaker#Annotation(com.sun.source.tree.Tree, java.util.List) }
array (of a supported type){@link NewArrayTree} created by {@link TreeMaker#NewArray(com.sun.source.tree.Tree, java.util.List, java.util.List) }, + * where {@code elemtype} is {@code null}, {@code dimensions} is {@code Collections.emptyList()}, + * {@code initializers} should contain the elements that should appear in the array
+ * + * @param modifiers into which the values should be added + * @param annotation the annotation type that should be added or augmented + * @param attributeName the attribute that should be added or augmented + * @param attributeValuesToAdd values that should be added into the given attribute of the given annotation + * @return {@code modifiers} augmented in such a way that it contains the given annotation, with the given values + * @since 0.97 + */ + public ModifiersTree appendToAnnotationValue(ModifiersTree modifiers, TypeElement annotation, String attributeName, ExpressionTree... attributeValuesToAdd) { + return (ModifiersTree) appendToAnnotationValue((Tree) modifiers, annotation, attributeName, attributeValuesToAdd); + } + + /**Ensures that the given {@code compilationUnit} contains annotation of the given type, + * which has attribute name {@code attributeName}, which contains values {@code attributeValuesToAdd}. + * The annotation or the attribute will be added as needed, as will be the attribute value + * converted from a single value into an array. This method is intended to be called on + * {@link CompilationUnitTree} from {@code package-info.java}. + * + * The typical trees passed as {@code attributeValuesToAdd} are: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
attribute typeexpected tree type
primitive type{@link LiteralTree} created by {@link TreeMaker#Literal(java.lang.Object) }
{@code java.lang.String}{@link LiteralTree} created by {@link TreeMaker#Literal(java.lang.Object) }
{@code java.lang.Class}{@link MemberSelectTree} created by {@link TreeMaker#MemberSelect(com.sun.source.tree.ExpressionTree, java.lang.CharSequence) }, + * with identifier {@code class} and expression created by {@link TreeMaker#QualIdent(javax.lang.model.element.Element) }
enum constant{@link MemberSelectTree}, with identifier representing the enum constant + * and expression created by {@link TreeMaker#QualIdent(javax.lang.model.element.Element) }
annotation type{@link AnnotationTree} created by {@link TreeMaker#Annotation(com.sun.source.tree.Tree, java.util.List) }
array (of a supported type){@link NewArrayTree} created by {@link TreeMaker#NewArray(com.sun.source.tree.Tree, java.util.List, java.util.List) }, + * where {@code elemtype} is {@code null}, {@code dimensions} is {@code Collections.emptyList()}, + * {@code initializers} should contain the elements that should appear in the array
+ * + * @param compilationUnit into which the values should be added + * @param annotation the annotation type that should be added or augmented + * @param attributeName the attribute that should be added or augmented + * @param attributeValuesToAdd values that should be added into the given attribute of the given annotation + * @return {@code compilationUnit} augmented in such a way that it contains the given annotation, with the given values + * @since 0.97 + */ + public CompilationUnitTree appendToAnnotationValue(CompilationUnitTree compilationUnit, TypeElement annotation, String attributeName, ExpressionTree... attributeValuesToAdd) { + return (CompilationUnitTree) appendToAnnotationValue((Tree) compilationUnit, annotation, attributeName, attributeValuesToAdd); + } + + private Tree appendToAnnotationValue(Tree/*CompilationUnitTree|ModifiersTree*/ modifiers, TypeElement annotation, String attributeName, ExpressionTree... attributeValuesToAdd) { + TreeMaker make = copy.getTreeMaker(); + + //check for already existing SuppressWarnings annotation: + List annotations = null; + + if (modifiers.getKind() == Kind.MODIFIERS) { + annotations = ((ModifiersTree) modifiers).getAnnotations(); + } else if (modifiers.getKind() == Kind.COMPILATION_UNIT) { + annotations = ((CompilationUnitTree) modifiers).getPackageAnnotations(); + } else { + throw new IllegalStateException(); + } + + for (AnnotationTree at : annotations) { + TreePath tp = new TreePath(new TreePath(copy.getCompilationUnit()), at.getAnnotationType()); + Element e = copy.getTrees().getElement(tp); + + if (annotation.equals(e)) { + //found SuppressWarnings: + List arguments = at.getArguments(); + + for (ExpressionTree et : arguments) { + ExpressionTree expression; + + if (et.getKind() == Kind.ASSIGNMENT) { + AssignmentTree assignment = (AssignmentTree) et; + + if (!((IdentifierTree) assignment.getVariable()).getName().contentEquals(attributeName)) continue; + + expression = assignment.getExpression(); + } else if ("value".equals(attributeName)) { + expression = et; + } else { + continue; + } + + List currentValues; + + if (expression.getKind() == Kind.NEW_ARRAY) { + currentValues = ((NewArrayTree) expression).getInitializers(); + } else { + currentValues = Collections.singletonList(expression); + } + + assert currentValues != null; + + List values = new ArrayList(currentValues); + + values.addAll(Arrays.asList(attributeValuesToAdd)); + + NewArrayTree newAssignment = make.NewArray(null, Collections.emptyList(), values); + + return copy.getTreeUtilities().translate(modifiers, Collections.singletonMap(expression, newAssignment)); + } + + AnnotationTree newAnnotation = make.addAnnotationAttrValue(at, make.Assignment(make.Identifier(attributeName), make.NewArray(null, Collections.emptyList(), Arrays.asList(attributeValuesToAdd)))); + + return copy.getTreeUtilities().translate(modifiers, Collections.singletonMap(at, newAnnotation)); + } + } + + ExpressionTree attribute; + + if (attributeValuesToAdd.length > 1 ) { + attribute = make.NewArray(null, Collections.emptyList(), Arrays.asList(attributeValuesToAdd)); + } + else { + attribute = attributeValuesToAdd[0]; + } + + ExpressionTree attributeAssignmentTree; + + if ("value".equals(attributeName)) { + attributeAssignmentTree = attribute; + } else { + attributeAssignmentTree = make.Assignment(make.Identifier(attributeName), attribute); + } + + AnnotationTree newAnnotation = make.Annotation(make.QualIdent(annotation), Collections.singletonList(attributeAssignmentTree)); + + if (modifiers.getKind() == Kind.MODIFIERS) { + return make.addModifiersAnnotation((ModifiersTree) modifiers, newAnnotation); + } else if (modifiers.getKind() == Kind.COMPILATION_UNIT) { + return make.addPackageAnnotation((CompilationUnitTree) modifiers, newAnnotation); + } else { + throw new IllegalStateException(); + } + } // private implementation -------------------------------------------------- diff -r 6d95d2a94e21 java.source/test/unit/src/org/netbeans/api/java/source/GeneratorUtilitiesTest.java --- a/java.source/test/unit/src/org/netbeans/api/java/source/GeneratorUtilitiesTest.java Sat Mar 10 07:43:05 2012 +0100 +++ b/java.source/test/unit/src/org/netbeans/api/java/source/GeneratorUtilitiesTest.java Sat Mar 10 15:42:17 2012 +0100 @@ -49,11 +49,13 @@ import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.ImportTree; import com.sun.source.tree.MethodTree; +import com.sun.source.tree.ModifiersTree; import com.sun.source.tree.StatementTree; import com.sun.source.tree.Tree; import com.sun.source.tree.Tree.Kind; import com.sun.source.tree.TypeParameterTree; import com.sun.source.tree.VariableTree; +import com.sun.source.util.SourcePositions; import com.sun.source.util.TreePath; import java.beans.PropertyVetoException; import java.io.File; @@ -78,6 +80,7 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; +import org.netbeans.api.java.source.JavaSource.Phase; import org.netbeans.junit.NbTestCase; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; @@ -1155,13 +1158,17 @@ } private void performTest(String sourceCode, String sourceLevel, final Task task, final Validator validator, final boolean requireNoErrors) throws Exception { + performTest("test/Test.java", sourceCode, sourceLevel, task, validator, requireNoErrors); + } + + private void performTest(String filePath, String sourceCode, String sourceLevel, final Task task, final Validator validator, final boolean requireNoErrors) throws Exception { FileObject root = makeScratchDir(this); FileObject sourceDir = root.createFolder("src"); FileObject buildDir = root.createFolder("build"); FileObject cacheDir = root.createFolder("cache"); - FileObject source = sourceDir.createFolder("test").createData("Test.java"); + FileObject source = FileUtil.createData(sourceDir, filePath); writeIntoFile(source, sourceCode); @@ -1178,8 +1185,6 @@ public void cancel() { } public void run(CompilationController controller) throws Exception { - System.err.println("text:"); - System.err.println(controller.getText()); controller.toPhase(JavaSource.Phase.RESOLVED); if (requireNoErrors) { @@ -1339,4 +1344,104 @@ "}\n"; assertEquals(golden, actual); } + + public void testAddAnnotationAttributeValue1() throws Exception { + performTest("package test;\npublic class Test { }\n", + new AddAnnotationAttributeValue("java.lang.SuppressWarnings", "value", "\"foobar\""), + new ContentValidator("package test;\n@SuppressWarnings(\"foobar\")\npublic class Test { }\n")); + } + + public void testAddAnnotationAttributeValue2() throws Exception { + performTest("package test;\n@SuppressWarnings(\"w\")\npublic class Test { }\n", + new AddAnnotationAttributeValue("java.lang.SuppressWarnings", "value", "\"foobar\""), + new ContentValidator("package test;\n@SuppressWarnings({\"w\", \"foobar\"})\npublic class Test { }\n")); + } + + public void testAddAnnotationAttributeValue3() throws Exception { + performTest("package test;\n@SuppressWarnings({\"w1\", \"w2\"})\npublic class Test { }\n", + new AddAnnotationAttributeValue("java.lang.SuppressWarnings", "value", "\"foobar\""), + new ContentValidator("package test;\n@SuppressWarnings({\"w1\", \"w2\", \"foobar\"})\npublic class Test { }\n")); + } + + public void testAddAnnotationAttributeValue4() throws Exception { + performTest("package test;\npublic class Test { }\n", + new AddAnnotationAttributeValue("java.lang.SuppressWarnings", "value", "\"foo\"", "\"bar\""), + new ContentValidator("package test;\n@SuppressWarnings({\"foo\", \"bar\"})\npublic class Test { }\n")); + } + + public void testAddAnnotationAttributeValue5() throws Exception { + performTest("package test;\n@SuppressWarnings({\"w1\", \"w2\"})\npublic class Test { }\n", + new AddAnnotationAttributeValue("java.lang.SuppressWarnings", "value", "\"foo\"", "\"bar\""), + new ContentValidator("package test;\n@SuppressWarnings({\"w1\", \"w2\", \"foo\", \"bar\"})\npublic class Test { }\n")); + } + + public void testAddAnnotationAttributeValueCompilationUnit() throws Exception { + performTest("test/package-info.java", + "package test;\n", + "1.5", + new AddAnnotationAttributeValue("java.lang.SuppressWarnings", "value", "\"foo\"", "\"bar\""), + new ContentValidator("@SuppressWarnings({\"foo\", \"bar\"})\npackage test;\n"), + false);//@SuppressWarning is not application to package-info. + } + + private static final class AddAnnotationAttributeValue implements Task { + + private final String annotationType; + private final String attributeName; + private final String[] values; + + public AddAnnotationAttributeValue(String annotationType, String attributeName, String... values) { + this.annotationType = annotationType; + this.attributeName = attributeName; + this.values = values; + } + + @Override + public void run(WorkingCopy parameter) throws Exception { + parameter.toPhase(Phase.RESOLVED); + + if ("package-info.java".equals(parameter.getFileObject().getNameExt())) { + CompilationUnitTree newCUT = parameter.getCompilationUnit(); + TypeElement annotation = parameter.getElements().getTypeElement(annotationType); + + assertNotNull(annotation); + + for (int i = 0; i < values.length; i++) { + ExpressionTree value = parameter.getTreeUtilities().parseExpression(values[i], new SourcePositions[1]); + newCUT = GeneratorUtilities.get(parameter).appendToAnnotationValue(newCUT, annotation, attributeName, value); + } + + parameter.rewrite(parameter.getCompilationUnit(), newCUT); + } else { + ClassTree ct = (ClassTree) parameter.getCompilationUnit().getTypeDecls().get(0); + ModifiersTree newMods = ct.getModifiers(); + TypeElement annotation = parameter.getElements().getTypeElement(annotationType); + + assertNotNull(annotation); + + for (int i = 0; i < values.length; i++) { + ExpressionTree value = parameter.getTreeUtilities().parseExpression(values[i], new SourcePositions[1]); + newMods = GeneratorUtilities.get(parameter).appendToAnnotationValue(newMods, annotation, attributeName, value); + } + + parameter.rewrite(ct.getModifiers(), newMods); + } + } + } + + private static final class ContentValidator implements Validator { + + private final String expectedCode; + + public ContentValidator(String expectedCode) { + this.expectedCode = expectedCode; + } + + @Override + public void validate(CompilationInfo info) { + assertEquals(expectedCode, info.getText()); + } + + } + } diff -r 6d95d2a94e21 spi.java.hints/src/org/netbeans/spi/java/hints/ErrorDescriptionFactory.java --- a/spi.java.hints/src/org/netbeans/spi/java/hints/ErrorDescriptionFactory.java Sat Mar 10 07:43:05 2012 +0100 +++ b/spi.java.hints/src/org/netbeans/spi/java/hints/ErrorDescriptionFactory.java Sat Mar 10 15:42:17 2012 +0100 @@ -73,6 +73,7 @@ import javax.lang.model.element.TypeElement; import org.netbeans.api.annotations.common.NonNull; import org.netbeans.api.java.source.CompilationInfo; +import org.netbeans.api.java.source.GeneratorUtilities; import org.netbeans.api.java.source.JavaSource; import org.netbeans.api.java.source.JavaSource.Phase; import org.netbeans.api.java.source.Task; @@ -443,66 +444,14 @@ return ; } - //check for already existing SuppressWarnings annotation: - for (AnnotationTree at : modifiers.getAnnotations()) { - TreePath tp = new TreePath(new TreePath(path, at), at.getAnnotationType()); - Element e = copy.getTrees().getElement(tp); + LiteralTree[] keyLiterals = new LiteralTree[keys.length]; - if (el.equals(e)) { - //found SuppressWarnings: - List arguments = at.getArguments(); - - if (arguments.isEmpty() || arguments.size() > 1) { - Logger.getLogger(ErrorDescriptionFactory.class.getName()).log(Level.INFO, "SupressWarnings annotation has incorrect number of arguments - {0}.", arguments.size()); // NOI18N - return ; - } - - ExpressionTree et = at.getArguments().get(0); - - if (et.getKind() != Kind.ASSIGNMENT) { - Logger.getLogger(ErrorDescriptionFactory.class.getName()).log(Level.INFO, "SupressWarnings annotation's argument is not an assignment - {0}.", et.getKind()); // NOI18N - return ; - } - - AssignmentTree assignment = (AssignmentTree) et; - List currentValues = null; - - if (assignment.getExpression().getKind() == Kind.NEW_ARRAY) { - currentValues = ((NewArrayTree) assignment.getExpression()).getInitializers(); - } else { - currentValues = Collections.singletonList(assignment.getExpression()); - } - - assert currentValues != null; - - List values = new ArrayList(currentValues); - - for (String key : keys) { - values.add(copy.getTreeMaker().Literal(key)); - } - - - copy.rewrite(assignment.getExpression(), copy.getTreeMaker().NewArray(null, Collections.emptyList(), values)); - return ; - } + for (int i = 0; i < keys.length; i++) { + keyLiterals[i] = copy.getTreeMaker(). + Literal(keys[i]); } - List annotations = new ArrayList(modifiers.getAnnotations()); - - - if ( keys.length > 1 ) { - List keyLiterals = new ArrayList(keys.length); - for (String key : keys) { - keyLiterals.add(copy.getTreeMaker().Literal(key)); - } - annotations.add(copy.getTreeMaker().Annotation(copy.getTreeMaker().QualIdent(el), - Collections.singletonList( - copy.getTreeMaker().NewArray(null, Collections.emptyList(), keyLiterals)))); - } - else { - annotations.add(copy.getTreeMaker().Annotation(copy.getTreeMaker().QualIdent(el), Collections.singletonList(copy.getTreeMaker().Literal(keys[0])))); - } - ModifiersTree nueMods = copy.getTreeMaker().Modifiers(modifiers, annotations); + ModifiersTree nueMods = GeneratorUtilities.get(copy).appendToAnnotationValue(modifiers, el, "value", keyLiterals); copy.rewrite(modifiers, nueMods); }