This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 130240
Collapse All | Expand All

(-)a/java.source/apichanges.xml (+12 lines)
Lines 105-110 is the proper place. Link Here
105
    <!-- ACTUAL CHANGES BEGIN HERE: -->
105
    <!-- ACTUAL CHANGES BEGIN HERE: -->
106
106
107
    <changes>
107
    <changes>
108
        <change id="GeneratorUtilities.createMethod">
109
             <api name="general"/>
110
             <summary>Added GeneratorUtilities.createMethod</summary>
111
             <version major="0" minor="34"/>
112
             <date day="25" month="3" year="2008"/>
113
             <author login="jlahoda"/>
114
             <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
115
             <description>
116
                 Added method to create a new method tree for given method element.
117
             </description>
118
            <issue number="999999"/>
119
        </change>
108
        <change id="CommitToGuards">
120
        <change id="CommitToGuards">
109
            <api name="general"/>
121
            <api name="general"/>
110
            <summary>Added ModificationResult.Difference.setCommitToGuards(boolean) and isCommitToGuards() methods permitting to write modifications even to guarded sections</summary>
122
            <summary>Added ModificationResult.Difference.setCommitToGuards(boolean) and isCommitToGuards() methods permitting to write modifications even to guarded sections</summary>
(-)a/java.source/nbproject/project.properties (-1 / +1 lines)
Lines 43-49 javadoc.title=Java Source Link Here
43
javadoc.title=Java Source
43
javadoc.title=Java Source
44
javadoc.arch=${basedir}/arch.xml
44
javadoc.arch=${basedir}/arch.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
45
javadoc.apichanges=${basedir}/apichanges.xml
46
spec.version.base=0.33.0
46
spec.version.base=0.34.0
47
test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/javac-api-nb-7.0-b07.jar
47
test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/javac-api-nb-7.0-b07.jar
48
test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
48
test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
49
    ${o.n.core.dir}/lib/boot.jar:\
49
    ${o.n.core.dir}/lib/boot.jar:\
(-)a/java.source/src/org/netbeans/api/java/source/GeneratorUtilities.java (-57 / +83 lines)
Lines 82-87 import javax.lang.model.type.TypeKind; Link Here
82
import javax.lang.model.type.TypeKind;
82
import javax.lang.model.type.TypeKind;
83
import javax.lang.model.type.TypeMirror;
83
import javax.lang.model.type.TypeMirror;
84
import javax.lang.model.type.TypeVariable;
84
import javax.lang.model.type.TypeVariable;
85
import javax.lang.model.util.Types;
85
import javax.swing.text.Document;
86
import javax.swing.text.Document;
86
87
87
import org.netbeans.api.java.lexer.JavaTokenId;
88
import org.netbeans.api.java.lexer.JavaTokenId;
Lines 242-247 public final class GeneratorUtilities { Link Here
242
        return createMethod(method, (DeclaredType)clazz.asType());
243
        return createMethod(method, (DeclaredType)clazz.asType());
243
    }
244
    }
244
245
246
    /**Create a new method tree for the given method element. The method will be created as if it were member of {@link asMemberOf} type
247
     * (see also {@link Types#asMemberOf(javax.lang.model.type.DeclaredType,javax.lang.model.element.Element)}).
248
     * The new method will have an empty body.
249
     * 
250
     * @param asMemberOf create the method as if it were member of this type
251
     * @param method method to create
252
     * @return a newly created method
253
     * @see Types#asMemberOf(javax.lang.model.type.DeclaredType,javax.lang.model.element.Element)
254
     * @since 0.34
255
     */
256
    public MethodTree createMethod(DeclaredType asMemberOf, ExecutableElement method) {
257
        TreeMaker make = copy.getTreeMaker();
258
        Set<Modifier> mods = method.getModifiers();
259
        Set<Modifier> flags = mods.isEmpty() ? EnumSet.noneOf(Modifier.class) : EnumSet.copyOf(mods);
260
        flags.remove(Modifier.ABSTRACT);
261
        flags.remove(Modifier.NATIVE);
262
263
        ExecutableType et = (ExecutableType) method.asType();
264
        try {
265
            et = (ExecutableType) copy.getTypes().asMemberOf(asMemberOf, method);
266
        } catch (IllegalArgumentException iae) {
267
        }
268
        List<TypeParameterTree> typeParams = new ArrayList<TypeParameterTree>();
269
        for (TypeVariable typeVariable : et.getTypeVariables()) {
270
            List<ExpressionTree> bounds = new ArrayList<ExpressionTree>();
271
            TypeMirror bound = typeVariable.getUpperBound();
272
            if (bound.getKind() != TypeKind.NULL) {
273
                if (bound.getKind() == TypeKind.DECLARED) {
274
                    ClassSymbol boundSymbol = (ClassSymbol) ((DeclaredType) bound).asElement();
275
                    if (boundSymbol.getSimpleName().length() == 0 && (boundSymbol.flags() & Flags.COMPOUND) != 0) {
276
                        bounds.add((ExpressionTree) make.Type(boundSymbol.getSuperclass()));
277
                        for (Type iface : boundSymbol.getInterfaces()) {
278
                            bounds.add((ExpressionTree) make.Type(iface));
279
                        }
280
                    } else if (!boundSymbol.getQualifiedName().contentEquals("java.lang.Object")) { //NOI18N
281
                        //if the bound is java.lang.Object, do not generate the extends clause:
282
283
                        bounds.add((ExpressionTree) make.Type(bound));
284
                    }
285
                } else {
286
                    bounds.add((ExpressionTree) make.Type(bound));
287
                }
288
            }
289
            typeParams.add(make.TypeParameter(typeVariable.asElement().getSimpleName(), bounds));
290
        }
291
292
        Tree returnType = make.Type(et.getReturnType());
293
294
        List<VariableTree> params = new ArrayList<VariableTree>();
295
        boolean isVarArgs = method.isVarArgs();
296
        Iterator<? extends VariableElement> formArgNames = method.getParameters().iterator();
297
        Iterator<? extends TypeMirror> formArgTypes = et.getParameterTypes().iterator();
298
        ModifiersTree parameterModifiers = make.Modifiers(EnumSet.noneOf(Modifier.class));
299
        while (formArgNames.hasNext() && formArgTypes.hasNext()) {
300
            VariableElement formArgName = formArgNames.next();
301
            TypeMirror formArgType = formArgTypes.next();
302
            if (isVarArgs && !formArgNames.hasNext()) {
303
                parameterModifiers = make.Modifiers(1L << 34,
304
                        Collections.<AnnotationTree>emptyList());
305
            }
306
            params.add(make.Variable(parameterModifiers, formArgName.getSimpleName(), make.Type(formArgType), null));
307
        }
308
309
        List<ExpressionTree> throwsList = new ArrayList<ExpressionTree>();
310
        for (TypeMirror tm : et.getThrownTypes()) {
311
            throwsList.add((ExpressionTree) make.Type(tm));
312
        }
313
314
        ModifiersTree mt = make.Modifiers(flags, Collections.<AnnotationTree>emptyList());
315
316
        return make.Method(mt, method.getSimpleName(), returnType, typeParams, params, throwsList, "{}", null);
317
    }
318
    
245
    /**
319
    /**
246
     * Creates a class constructor.
320
     * Creates a class constructor.
247
     * 
321
     * 
Lines 428-487 public final class GeneratorUtilities { Link Here
428
    
502
    
429
    private MethodTree createMethod(ExecutableElement element, DeclaredType type) {
503
    private MethodTree createMethod(ExecutableElement element, DeclaredType type) {
430
        TreeMaker make = copy.getTreeMaker();
504
        TreeMaker make = copy.getTreeMaker();
431
        Set<Modifier> mods = element.getModifiers();
505
        boolean isAbstract = element.getModifiers().contains(Modifier.ABSTRACT);
432
        Set<Modifier> flags = mods.isEmpty() ? EnumSet.noneOf(Modifier.class) : EnumSet.copyOf(mods);
433
        boolean isAbstract = flags.remove(Modifier.ABSTRACT);
434
        flags.remove(Modifier.NATIVE);
435
        
436
        ExecutableType et = (ExecutableType)element.asType();
437
        try {
438
            et = (ExecutableType)copy.getTypes().asMemberOf(type, element);
439
        } catch (IllegalArgumentException iae) {}
440
        List<TypeParameterTree> typeParams = new ArrayList<TypeParameterTree>();
441
        for (TypeVariable typeVariable : et.getTypeVariables()) {
442
            List<ExpressionTree> bounds = new ArrayList<ExpressionTree>();
443
            TypeMirror bound = typeVariable.getUpperBound();
444
            if (bound.getKind() != TypeKind.NULL) {
445
                if (bound.getKind() == TypeKind.DECLARED) {
446
                    ClassSymbol boundSymbol = (ClassSymbol)((DeclaredType)bound).asElement();
447
                    if (boundSymbol.getSimpleName().length() == 0 && (boundSymbol.flags() & Flags.COMPOUND) != 0) {
448
                        bounds.add((ExpressionTree)make.Type(boundSymbol.getSuperclass()));
449
                        for (Type iface : boundSymbol.getInterfaces()) {
450
                            bounds.add((ExpressionTree)make.Type(iface));
451
                        }
452
                    } else if (!boundSymbol.getQualifiedName().contentEquals("java.lang.Object")) { //NOI18N
453
                        //if the bound is java.lang.Object, do not generate the extends clause:
454
                        bounds.add((ExpressionTree)make.Type(bound));
455
                    }
456
                } else {
457
                    bounds.add((ExpressionTree)make.Type(bound));
458
                }
459
            }
460
            typeParams.add(make.TypeParameter(typeVariable.asElement().getSimpleName(), bounds));
461
        }
462
463
        Tree returnType = make.Type(et.getReturnType());
464
465
        List<VariableTree> params = new ArrayList<VariableTree>();        
466
        boolean isVarArgs = element.isVarArgs();
467
        Iterator<? extends VariableElement> formArgNames = element.getParameters().iterator();
468
        Iterator<? extends TypeMirror> formArgTypes = et.getParameterTypes().iterator();
469
        ModifiersTree parameterModifiers = make.Modifiers(EnumSet.noneOf(Modifier.class));
470
        while (formArgNames.hasNext() && formArgTypes.hasNext()) {
471
            VariableElement formArgName = formArgNames.next();
472
            TypeMirror formArgType = formArgTypes.next();
473
            if (isVarArgs && !formArgNames.hasNext())
474
                parameterModifiers = make.Modifiers(1L<<34, Collections.<AnnotationTree>emptyList());
475
            params.add(make.Variable(parameterModifiers, formArgName.getSimpleName(), make.Type(formArgType), null));
476
        }
477
478
        List<ExpressionTree> throwsList = new ArrayList<ExpressionTree>();
479
        for (TypeMirror tm : et.getThrownTypes()) {
480
            throwsList.add((ExpressionTree)make.Type(tm));
481
        }
482
        
506
        
483
        BlockTree body;
507
        BlockTree body;
484
        List<AnnotationTree> annotations = new ArrayList<AnnotationTree>();
485
        if (isAbstract) {
508
        if (isAbstract) {
486
            List<StatementTree> blockStatements = new ArrayList<StatementTree>();
509
            List<StatementTree> blockStatements = new ArrayList<StatementTree>();
487
            TypeElement uoe = copy.getElements().getTypeElement("java.lang.UnsupportedOperationException"); //NOI18N
510
            TypeElement uoe = copy.getElements().getTypeElement("java.lang.UnsupportedOperationException"); //NOI18N
Lines 502-524 public final class GeneratorUtilities { Link Here
502
            body = make.Block(Collections.singletonList(statement), false);
525
            body = make.Block(Collections.singletonList(statement), false);
503
        }
526
        }
504
527
528
        MethodTree prototype = createMethod(type, element);
529
        ModifiersTree mt = prototype.getModifiers();
530
        
505
        //add @Override annotation:
531
        //add @Override annotation:
506
        SpecificationVersion thisFOVersion = new SpecificationVersion(SourceLevelQuery.getSourceLevel(copy.getFileObject()));
532
        SpecificationVersion thisFOVersion = new SpecificationVersion(SourceLevelQuery.getSourceLevel(copy.getFileObject()));
507
        SpecificationVersion version15 = new SpecificationVersion("1.5"); //NOI18N
533
        SpecificationVersion version15 = new SpecificationVersion("1.5"); //NOI18N
508
534
509
        if (thisFOVersion.compareTo(version15) >= 0) {
535
        if (thisFOVersion.compareTo(version15) >= 0) {
510
            boolean generate = true;
536
            boolean generate = true;
511
            
537
512
            if (thisFOVersion.compareTo(version15) == 0) {
538
            if (thisFOVersion.compareTo(version15) == 0) {
513
                generate = !element.getEnclosingElement().getKind().isInterface();
539
                generate = !element.getEnclosingElement().getKind().isInterface();
514
            }
540
            }
515
            
541
516
            if (generate) {
542
            if (generate) {
517
                annotations.add(make.Annotation(make.Identifier("Override"), Collections.<ExpressionTree>emptyList())); //NOI18N
543
               mt = make.addModifiersAnnotation(prototype.getModifiers(), make.Annotation(make.Identifier("Override"), Collections.<ExpressionTree>emptyList()));
518
            }
544
            }
519
        }
545
        }
520
        
546
521
        return make.Method(make.Modifiers(flags, annotations), element.getSimpleName(), returnType, typeParams, params, throwsList, body, null);
547
        return make.Method(mt, prototype.getName(), prototype.getReturnType(), prototype.getTypeParameters(), prototype.getParameters(), prototype.getThrows(), body, null);
522
    }
548
    }
523
    
549
    
524
    private static class ClassMemberComparator {
550
    private static class ClassMemberComparator {
(-)a/java.source/test/unit/src/org/netbeans/api/java/source/GeneratorUtilitiesTest.java (-1 / +56 lines)
Lines 360-365 public class GeneratorUtilitiesTest exte Link Here
360
360
361
    public void testStaticBooleanSetter() throws Exception {
361
    public void testStaticBooleanSetter() throws Exception {
362
        performTest("package test;\npublic class Test {\nprivate static boolean test;\npublic Test(){\n}\n }\n", new GetterSetterTask(34, false), new GetterSetterValidator(false));
362
        performTest("package test;\npublic class Test {\nprivate static boolean test;\npublic Test(){\n}\n }\n", new GetterSetterTask(34, false), new GetterSetterValidator(false));
363
    }
364
    
365
    public void testCreateMethod() throws Exception {
366
        performTest("package test;\npublic class Test { }\n", "1.5", new CreateMethodTask(34), new Validator() {
367
            public void validate(CompilationInfo info) {
368
                assertEquals(1, info.getDiagnostics().size());
369
                
370
                for (ExecutableElement ee : ElementFilter.methodsIn(info.getElements().getTypeElement("test.Test").getEnclosedElements())) {
371
                    assertEquals("toArray", ee.getSimpleName().toString());
372
                    assertEquals(1, ee.getTypeParameters().size());
373
                    return ;
374
                }
375
                
376
                fail("toArray method not found");
377
            }
378
        }, false);
363
    }
379
    }
364
    
380
    
365
    public static interface Validator {
381
    public static interface Validator {
Lines 804-814 public class GeneratorUtilitiesTest exte Link Here
804
        
820
        
805
    }
821
    }
806
    
822
    
823
    private static class CreateMethodTask implements CancellableTask<WorkingCopy> {        
824
    
825
        private int offset;
826
        
827
        public CreateMethodTask(int offset) {
828
            this.offset = offset;
829
        }
830
831
        public void cancel() {
832
        }
833
    
834
        public void run(WorkingCopy copy) throws Exception {
835
            copy.toPhase(JavaSource.Phase.RESOLVED);
836
            TreePath tp = copy.getTreeUtilities().pathFor(offset);
837
            assertTrue(tp.getLeaf().getKind() == Tree.Kind.CLASS);
838
            ClassTree ct = (ClassTree)tp.getLeaf();
839
            TypeElement te = (TypeElement)copy.getTrees().getElement(tp);
840
            DeclaredType dt = (DeclaredType) copy.getTreeUtilities().parseType("java.util.List<java.lang.String>", te);
841
            TypeElement list = copy.getElements().getTypeElement("java.util.List");
842
            ExecutableElement ee = null;
843
            for (ExecutableElement m : ElementFilter.methodsIn(list.getEnclosedElements())) {
844
                if (m.getSimpleName().contentEquals("toArray") && !m.getTypeParameters().isEmpty()) {
845
                    ee = m;
846
                }
847
            }
848
            assertNotNull(ee);
849
            GeneratorUtilities utilities = GeneratorUtilities.get(copy);
850
            assertNotNull(utilities);
851
            ClassTree newCt = utilities.insertClassMembers(ct, Collections.singletonList(utilities.createMethod(dt, ee)));
852
            copy.rewrite(ct, newCt);
853
        }
854
    }
855
    
807
    private void performTest(String sourceCode, final Task<WorkingCopy> task, final Validator validator) throws Exception {
856
    private void performTest(String sourceCode, final Task<WorkingCopy> task, final Validator validator) throws Exception {
808
        performTest(sourceCode, "1.5", task, validator);
857
        performTest(sourceCode, "1.5", task, validator);
809
    }
858
    }
810
    
859
    
811
    private void performTest(String sourceCode, String sourceLevel, final Task<WorkingCopy> task, final Validator validator) throws Exception {
860
    private void performTest(String sourceCode, String sourceLevel, final Task<WorkingCopy> task, final Validator validator) throws Exception {
861
        performTest(sourceCode, sourceLevel, task, validator, true);
862
    }
863
    
864
    private void performTest(String sourceCode, String sourceLevel, final Task<WorkingCopy> task, final Validator validator, final boolean requireNoErrors) throws Exception {
812
        FileObject root = makeScratchDir(this);
865
        FileObject root = makeScratchDir(this);
813
        
866
        
814
        FileObject sourceDir = root.createFolder("src");
867
        FileObject sourceDir = root.createFolder("src");
Lines 836-842 public class GeneratorUtilitiesTest exte Link Here
836
                System.err.println(controller.getText());
889
                System.err.println(controller.getText());
837
                controller.toPhase(JavaSource.Phase.RESOLVED);
890
                controller.toPhase(JavaSource.Phase.RESOLVED);
838
                
891
                
839
                assertEquals(controller.getDiagnostics().toString(), 0, controller.getDiagnostics().size());
892
                if (requireNoErrors) {
893
                    assertEquals(controller.getDiagnostics().toString(), 0, controller.getDiagnostics().size());
894
                }
840
                
895
                
841
                if (validator != null)
896
                if (validator != null)
842
                    validator.validate(controller);
897
                    validator.validate(controller);

Return to bug 130240