From f664d94d74cdc0135afe96a336a4e07c36772457 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 21 Mar 2019 17:00:22 +0300 Subject: [PATCH] Allow to exclude certain classes, fields and methods from compilation --- .../parsing/ClasspathResourceMapper.java | 41 +++++++++++++++++++ .../java/org/teavm/vm/spi/ElementFilter.java | 27 ++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 core/src/main/java/org/teavm/vm/spi/ElementFilter.java diff --git a/core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java b/core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java index b871f1582..82387ce5f 100644 --- a/core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java +++ b/core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java @@ -24,7 +24,10 @@ import java.util.*; import java.util.function.Function; import org.teavm.common.CachedFunction; import org.teavm.model.ClassHolder; +import org.teavm.model.FieldHolder; +import org.teavm.model.MethodHolder; import org.teavm.model.ReferenceCache; +import org.teavm.vm.spi.ElementFilter; public class ClasspathResourceMapper implements Function, ClassDateProvider { private static final String PACKAGE_PREFIX = "packagePrefix."; @@ -35,6 +38,7 @@ public class ClasspathResourceMapper implements Function, C private ClassLoader classLoader; private Map modificationDates = new HashMap<>(); private ReferenceCache referenceCache; + private List elementFilters = new ArrayList<>(); private static class Transformation { String packageName; @@ -63,6 +67,11 @@ public class ClasspathResourceMapper implements Function, C throw new RuntimeException("Error reading resources", e); } renamer = new ClassRefsRenamer(referenceCache, new CachedFunction<>(classNameMapper)); + + for (ElementFilter elementFilter : ServiceLoader.load(ElementFilter.class)) { + elementFilters.add(elementFilter); + } + this.classLoader = classLoader; } @@ -104,6 +113,38 @@ public class ClasspathResourceMapper implements Function, C @Override public ClassHolder apply(String name) { + for (ElementFilter filter : elementFilters) { + if (!filter.acceptClass(name)) { + return null; + } + } + + ClassHolder cls = find(name); + + if (cls != null) { + for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) { + for (ElementFilter filter : elementFilters) { + if (!filter.acceptMethod(method.getReference())) { + cls.removeMethod(method); + break; + } + } + } + + for (FieldHolder field : cls.getFields().toArray(new FieldHolder[0])) { + for (ElementFilter filter : elementFilters) { + if (!filter.acceptField(field.getReference())) { + cls.removeField(field); + break; + } + } + } + } + + return cls; + } + + private ClassHolder find(String name) { for (Transformation transformation : transformations) { if (name.startsWith(transformation.packageName)) { int index = name.lastIndexOf('.'); diff --git a/core/src/main/java/org/teavm/vm/spi/ElementFilter.java b/core/src/main/java/org/teavm/vm/spi/ElementFilter.java new file mode 100644 index 000000000..01b189fbe --- /dev/null +++ b/core/src/main/java/org/teavm/vm/spi/ElementFilter.java @@ -0,0 +1,27 @@ +/* + * Copyright 2019 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.vm.spi; + +import org.teavm.model.FieldReference; +import org.teavm.model.MethodReference; + +public interface ElementFilter { + boolean acceptClass(String className); + + boolean acceptMethod(MethodReference method); + + boolean acceptField(FieldReference field); +}