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 258981
Collapse All | Expand All

(-)a/java.source.base/apichanges.xml (+22 lines)
Lines 49-54 Link Here
49
    <apidef name="javasource_base">Java Source API</apidef>
49
    <apidef name="javasource_base">Java Source API</apidef>
50
</apidefs>
50
</apidefs>
51
<changes>
51
<changes>
52
    <change id="utilities.implementAndOverride.defaultMethods">
53
        <api name="javasource_base"/>
54
        <summary>Allow to return also unimplemented default methods</summary>
55
        <version major="1" minor="2.15"/>
56
        <date day="25" month="4" year="2015"/>
57
        <author login="sdedic"/>
58
        <compatibility addition="yes" binary="compatible" source="compatible"/>
59
        <description>
60
            <p>
61
                <code>findUnimplementedMethods</code> and <code>findOverridableMethods</code>
62
                work better with interface default methods: they are treated as implemented,
63
                but overridable.
64
            </p>
65
            <p>
66
                Allow <code>ElementUtilities.findUnimplementedMethods</code> enumerate
67
                also default methods whose implementations are not provided by class or
68
                superclasses.
69
            </p>
70
        </description>
71
        <class name="ElementUtilities" package="org.netbeans.api.java.source"/>
72
        <issue number=""/>
73
    </change>
52
    <change id="generator.insert.caretlocation">
74
    <change id="generator.insert.caretlocation">
53
        <api name="javasource_base"/>
75
        <api name="javasource_base"/>
54
        <summary>Code Generator uses caret location to insert members</summary>
76
        <summary>Code Generator uses caret location to insert members</summary>
(-)a/java.source.base/nbproject/project.properties (-1 / +1 lines)
Lines 47-53 Link Here
47
javadoc.title=Java Source Base
47
javadoc.title=Java Source Base
48
javadoc.arch=${basedir}/arch.xml
48
javadoc.arch=${basedir}/arch.xml
49
javadoc.apichanges=${basedir}/apichanges.xml
49
javadoc.apichanges=${basedir}/apichanges.xml
50
spec.version.base=2.14.0
50
spec.version.base=2.15.0
51
test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/nb-javac-api.jar
51
test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/nb-javac-api.jar
52
test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
52
test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
53
    ${o.n.core.dir}/lib/boot.jar:\
53
    ${o.n.core.dir}/lib/boot.jar:\
(-)a/java.source.base/src/org/netbeans/api/java/source/ElementUtilities.java (-8 / +45 lines)
Lines 74-79 Link Here
74
import com.sun.tools.javadoc.DocEnv;
74
import com.sun.tools.javadoc.DocEnv;
75
75
76
import java.util.ArrayList;
76
import java.util.ArrayList;
77
import java.util.Collection;
77
import java.util.Collections;
78
import java.util.Collections;
78
import java.util.EnumSet;
79
import java.util.EnumSet;
79
import java.util.HashMap;
80
import java.util.HashMap;
Lines 567-573 Link Here
567
     * @since 0.20
568
     * @since 0.20
568
     */
569
     */
569
    public List<? extends ExecutableElement> findUnimplementedMethods(TypeElement impl) {
570
    public List<? extends ExecutableElement> findUnimplementedMethods(TypeElement impl) {
570
        return findUnimplementedMethods(impl, impl);
571
        return findUnimplementedMethods(impl, impl, true);
572
    }
573
    
574
    /**
575
     * Finds all unimplemented methods in the given type and supertypes, bud include
576
     * also interface default methods.
577
     * <p/>
578
     * If the platform configured for the type is older than JDK8, the method is equivalent
579
     * to {@link #findUnimplementedMethods(javax.lang.model.element.TypeElement)}.
580
     * 
581
     * @param impl the implementation type
582
     * @param includeDefaults if true, will also return interface default methods, which
583
     * are not overriden in supertypes.
584
     * @return unimplemented (and/or default) methods.
585
     * @since 2.15
586
     */
587
    public List<? extends ExecutableElement> findUnimplementedMethods(TypeElement impl, boolean includeDefaults) {
588
        return findUnimplementedMethods(impl, impl, true);
571
    }
589
    }
572
590
573
    /**Find all methods in given type and its supertypes, which are overridable.
591
    /**Find all methods in given type and its supertypes, which are overridable.
Lines 786-809 Link Here
786
    // private implementation --------------------------------------------------
804
    // private implementation --------------------------------------------------
787
805
788
    private static final Set<Modifier> NOT_OVERRIDABLE = EnumSet.of(Modifier.STATIC, Modifier.FINAL, Modifier.PRIVATE);
806
    private static final Set<Modifier> NOT_OVERRIDABLE = EnumSet.of(Modifier.STATIC, Modifier.FINAL, Modifier.PRIVATE);
789
807
    
790
    private List<? extends ExecutableElement> findUnimplementedMethods(TypeElement impl, TypeElement element) {
808
    private List<? extends ExecutableElement> findUnimplementedMethods(TypeElement impl, TypeElement element, boolean includeDefaults) {
791
        List<ExecutableElement> undef = new ArrayList<ExecutableElement>();
809
        List<ExecutableElement> undef = new ArrayList<ExecutableElement>();
792
        Types types = JavacTypes.instance(ctx);
810
        Types types = JavacTypes.instance(ctx);
793
        com.sun.tools.javac.code.Types implTypes = com.sun.tools.javac.code.Types.instance(ctx);
811
        com.sun.tools.javac.code.Types implTypes = com.sun.tools.javac.code.Types.instance(ctx);
794
        DeclaredType implType = (DeclaredType)impl.asType();
812
        DeclaredType implType = (DeclaredType)impl.asType();
795
        if (element.getKind().isInterface() || element.getModifiers().contains(Modifier.ABSTRACT)) {
813
        if (element.getKind().isInterface() || element.getModifiers().contains(Modifier.ABSTRACT)) {
796
            for (Element e : element.getEnclosedElements()) {
814
            for (Element e : element.getEnclosedElements()) {
797
                if (e.getKind() == ElementKind.METHOD && e.getModifiers().contains(Modifier.ABSTRACT)) {
815
                if (e.getKind() != ElementKind.METHOD) {
798
                    ExecutableElement ee = (ExecutableElement)e;
816
                    continue;
799
                    Element eeImpl = getImplementationOf(ee, impl);
817
                }
800
                    if ((eeImpl == null || (eeImpl == ee && impl != element)) && implTypes.asSuper((Type)implType, (Symbol)ee.getEnclosingElement()) != null)
818
                if (element.getKind().isInterface()) {
819
                    if (e.getModifiers().contains(Modifier.STATIC)) {
820
                        continue;
821
                    } else if (e.getModifiers().contains(Modifier.DEFAULT) && !includeDefaults) {
822
                        continue;
823
                    }
824
                } else if (!e.getModifiers().contains(Modifier.ABSTRACT)) {
825
                    continue;
826
                }
827
                ExecutableElement ee = (ExecutableElement)e;
828
                ExecutableElement eeImpl = (ExecutableElement)getImplementationOf(ee, impl);
829
                if (eeImpl == null) {
830
                    if (implTypes.asSuper((Type)implType, (Symbol)ee.getEnclosingElement()) != null) {
801
                        undef.add(ee);
831
                        undef.add(ee);
832
                    }
833
                } else if (impl != element && implTypes.asSuper((Type)implType, (Symbol)ee.getEnclosingElement()) != null) {
834
                    if (eeImpl == ee) {
835
                        undef.add(ee);
836
                    } else if (includeDefaults && eeImpl.getModifiers().contains(Modifier.DEFAULT)) {
837
                        undef.add((ExecutableElement)eeImpl);
838
                    }
802
                }
839
                }
803
            }
840
            }
804
        }
841
        }
805
        for (TypeMirror t : types.directSupertypes(element.asType())) {
842
        for (TypeMirror t : types.directSupertypes(element.asType())) {
806
            for (ExecutableElement ee : findUnimplementedMethods(impl, (TypeElement) ((DeclaredType) t).asElement())) {
843
            for (ExecutableElement ee : findUnimplementedMethods(impl, (TypeElement) ((DeclaredType) t).asElement(), includeDefaults)) {
807
                //check if "the same" method has already been added:
844
                //check if "the same" method has already been added:
808
                boolean exists = false;
845
                boolean exists = false;
809
                ExecutableType eeType = (ExecutableType)types.asMemberOf(implType, ee);
846
                ExecutableType eeType = (ExecutableType)types.asMemberOf(implType, ee);
(-)a/java.source.base/src/org/netbeans/modules/java/source/builder/ElementsService.java (-6 / +34 lines)
Lines 49-54 Link Here
49
import com.sun.tools.javac.util.Name;
49
import com.sun.tools.javac.util.Name;
50
import com.sun.tools.javac.util.Names;
50
import com.sun.tools.javac.util.Names;
51
import com.sun.tools.javac.code.Scope;
51
import com.sun.tools.javac.code.Scope;
52
import com.sun.tools.javac.code.Source;
52
import com.sun.tools.javac.code.Symbol;
53
import com.sun.tools.javac.code.Symbol;
53
import com.sun.tools.javac.code.Symbol.ClassSymbol;
54
import com.sun.tools.javac.code.Symbol.ClassSymbol;
54
import com.sun.tools.javac.code.Symbol.MethodSymbol;
55
import com.sun.tools.javac.code.Symbol.MethodSymbol;
Lines 58-63 Link Here
58
import com.sun.tools.javac.model.JavacTypes;
59
import com.sun.tools.javac.model.JavacTypes;
59
import com.sun.tools.javac.util.Context;
60
import com.sun.tools.javac.util.Context;
60
import com.sun.tools.javac.util.ListBuffer;
61
import com.sun.tools.javac.util.ListBuffer;
62
import java.util.ArrayList;
63
import java.util.Collection;
64
import java.util.Collections;
61
import javax.lang.model.element.*;
65
import javax.lang.model.element.*;
62
import static javax.lang.model.element.ElementKind.*;
66
import static javax.lang.model.element.ElementKind.*;
63
import javax.lang.model.type.*;
67
import javax.lang.model.type.*;
Lines 70-75 Link Here
70
    private com.sun.tools.javac.code.Types jctypes;
74
    private com.sun.tools.javac.code.Types jctypes;
71
    private Names names;
75
    private Names names;
72
    private Types types;
76
    private Types types;
77
    private final boolean allowDefaultMethods;
73
    
78
    
74
    private static final Context.Key<ElementsService> KEY =
79
    private static final Context.Key<ElementsService> KEY =
75
	    new Context.Key<ElementsService>();
80
	    new Context.Key<ElementsService>();
Lines 86-91 Link Here
86
        jctypes = com.sun.tools.javac.code.Types.instance(context);
91
        jctypes = com.sun.tools.javac.code.Types.instance(context);
87
        names = Names.instance(context);
92
        names = Names.instance(context);
88
        types = JavacTypes.instance(context);
93
        types = JavacTypes.instance(context);
94
        allowDefaultMethods = Source.instance(context).allowDefaultMethods();
89
    }
95
    }
90
96
91
    /** 
97
    /** 
Lines 214-220 Link Here
214
    }
220
    }
215
221
216
    public Element getImplementationOf(ExecutableElement method, TypeElement origin) {
222
    public Element getImplementationOf(ExecutableElement method, TypeElement origin) {
217
        return ((MethodSymbol)method).implementation((TypeSymbol)origin, jctypes, true);
223
        MethodSymbol implmethod = ((MethodSymbol)method).implementation((TypeSymbol)origin, jctypes, true);
224
        if (implmethod == null || implmethod == method) {
225
            //look for default implementations
226
            if (allowDefaultMethods) {
227
                MethodSymbol prov = jctypes.interfaceCandidates(((TypeSymbol) origin).type, (MethodSymbol) method).head;
228
                if (prov != null && prov.overrides((MethodSymbol) method, (TypeSymbol) origin, jctypes, true)) {
229
                    implmethod = prov;
230
                }
231
            }
232
        }
233
        return implmethod;
218
    }
234
    }
219
235
220
    public boolean isSynthetic(Element e) {
236
    public boolean isSynthetic(Element e) {
Lines 225-234 Link Here
225
        MethodSymbol m = (MethodSymbol)method;
241
        MethodSymbol m = (MethodSymbol)method;
226
	ClassSymbol origin = (ClassSymbol)m.owner;
242
	ClassSymbol origin = (ClassSymbol)m.owner;
227
        MethodSymbol bridgeCandidate = null;
243
        MethodSymbol bridgeCandidate = null;
228
	for (Type t = jctypes.supertype(origin.type); t.hasTag(TypeTag.CLASS); t = jctypes.supertype(t)) {
244
        for (Type t = jctypes.supertype(origin.type); t.hasTag(TypeTag.CLASS); t = jctypes.supertype(t)) {
229
	    TypeSymbol c = t.tsym;
245
            TypeSymbol c = t.tsym;
230
            for (Symbol sym : c.members().getSymbolsByName(m.name)) {
246
            for (Symbol sym : c.members().getSymbolsByName(m.name)) {
231
		if (m.overrides(sym, origin, jctypes, false)) {
247
                if (m.overrides(sym, origin, jctypes, false)) {
232
                    if ((sym.flags() & Flags.BRIDGE) > 0) {
248
                    if ((sym.flags() & Flags.BRIDGE) > 0) {
233
                        if (bridgeCandidate == null) {
249
                        if (bridgeCandidate == null) {
234
                            bridgeCandidate = (MethodSymbol)sym;
250
                            bridgeCandidate = (MethodSymbol)sym;
Lines 237-244 Link Here
237
                        return (MethodSymbol)sym;
253
                        return (MethodSymbol)sym;
238
                    }
254
                    }
239
                }
255
                }
240
	    }
256
            }
241
	}
257
        }
258
        if (allowDefaultMethods) {
259
                MethodSymbol prov = jctypes.interfaceCandidates(((TypeSymbol) origin).type, (MethodSymbol) method).head;
260
                if (prov != null && m.overrides(prov, origin, jctypes, true)) {
261
                    if ((prov.flags() & Flags.BRIDGE) > 0) {
262
                        if (bridgeCandidate == null) {
263
                            bridgeCandidate = (MethodSymbol)prov;
264
                        }
265
                    } else {
266
                        return (MethodSymbol)prov;
267
                    }
268
                }
269
        }
242
        return bridgeCandidate;
270
        return bridgeCandidate;
243
    }
271
    }
244
}
272
}

Return to bug 258981