rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java
branchclosure
changeset 1087 d868b5a67b9b
parent 1086 2ac4283ee209
child 1094 36961c9a009f
     1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Wed May 08 14:54:32 2013 +0200
     1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Wed May 08 17:47:47 2013 +0200
     1.3 @@ -115,7 +115,7 @@
     1.4      protected void declaredMethod(MethodData methodData,
     1.5                                    String destObject,
     1.6                                    String mangledName) throws IOException {
     1.7 -        if (exportedSymbols.isExported(methodData)) {
     1.8 +        if (isHierarchyExported(methodData)) {
     1.9              exportMember(destObject, mangledName);
    1.10          }
    1.11      }
    1.12 @@ -317,7 +317,7 @@
    1.13                  && (((method.access & ByteCodeParser.ACC_FINAL) != 0)
    1.14                          || ((referencedClass.getAccessFlags()
    1.15                                   & ByteCodeParser.ACC_FINAL) != 0)
    1.16 -                        || !exportedSymbols.isExported(method))) {
    1.17 +                        || !isHierarchyExported(method))) {
    1.18              return object + "." + mangledName;
    1.19          }
    1.20  
    1.21 @@ -331,6 +331,28 @@
    1.22          return "invoker." + mangledName + '(' + object + ')';
    1.23      }
    1.24  
    1.25 +    private boolean isHierarchyExported(final MethodData methodData)
    1.26 +            throws IOException {
    1.27 +        if (exportedSymbols.isExported(methodData)) {
    1.28 +            return true;
    1.29 +        }
    1.30 +        if ((methodData.access & (ByteCodeParser.ACC_PRIVATE
    1.31 +                                      | ByteCodeParser.ACC_STATIC)) != 0) {
    1.32 +            return false;
    1.33 +        }
    1.34 +
    1.35 +        final ExportedMethodFinder exportedMethodFinder =
    1.36 +                new ExportedMethodFinder(exportedSymbols);
    1.37 +
    1.38 +        classDataCache.findMethods(
    1.39 +                methodData.cls,
    1.40 +                methodData.getName(),
    1.41 +                methodData.getInternalSig(),
    1.42 +                exportedMethodFinder);
    1.43 +
    1.44 +        return (exportedMethodFinder.getFound() != null);
    1.45 +    }
    1.46 +
    1.47      private static String accessNonVirtualMember(String object,
    1.48                                                   String mangledName,
    1.49                                                   ClassData declaringClass) {
    1.50 @@ -338,6 +360,33 @@
    1.51                                          : object + "['" + mangledName + "']";
    1.52      }
    1.53  
    1.54 +    private static final class ExportedMethodFinder
    1.55 +            implements ClassDataCache.TraversalCallback<MethodData> {
    1.56 +        private final ExportedSymbols exportedSymbols;
    1.57 +        private MethodData found;
    1.58 +
    1.59 +        public ExportedMethodFinder(final ExportedSymbols exportedSymbols) {
    1.60 +            this.exportedSymbols = exportedSymbols;
    1.61 +        }
    1.62 +
    1.63 +        @Override
    1.64 +        public boolean traverse(final MethodData methodData) {
    1.65 +            try {
    1.66 +                if (exportedSymbols.isExported(methodData)) {
    1.67 +                    found = methodData;
    1.68 +                    return false;
    1.69 +                }
    1.70 +            } catch (final IOException e) {
    1.71 +            }
    1.72 +
    1.73 +            return true;
    1.74 +        }
    1.75 +
    1.76 +        public MethodData getFound() {
    1.77 +            return found;
    1.78 +        }
    1.79 +    }
    1.80 +
    1.81      private static final class Standalone extends VM {
    1.82          private Standalone(Appendable out, Bck2Brwsr.Resources resources) {
    1.83              super(out, resources);