Allow to exclude certain classes, fields and methods from compilation

This commit is contained in:
Alexey Andreev 2019-03-21 17:00:22 +03:00
parent 36041b4107
commit f664d94d74
2 changed files with 68 additions and 0 deletions

View File

@ -24,7 +24,10 @@ import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import org.teavm.common.CachedFunction; import org.teavm.common.CachedFunction;
import org.teavm.model.ClassHolder; import org.teavm.model.ClassHolder;
import org.teavm.model.FieldHolder;
import org.teavm.model.MethodHolder;
import org.teavm.model.ReferenceCache; import org.teavm.model.ReferenceCache;
import org.teavm.vm.spi.ElementFilter;
public class ClasspathResourceMapper implements Function<String, ClassHolder>, ClassDateProvider { public class ClasspathResourceMapper implements Function<String, ClassHolder>, ClassDateProvider {
private static final String PACKAGE_PREFIX = "packagePrefix."; private static final String PACKAGE_PREFIX = "packagePrefix.";
@ -35,6 +38,7 @@ public class ClasspathResourceMapper implements Function<String, ClassHolder>, C
private ClassLoader classLoader; private ClassLoader classLoader;
private Map<String, ModificationDate> modificationDates = new HashMap<>(); private Map<String, ModificationDate> modificationDates = new HashMap<>();
private ReferenceCache referenceCache; private ReferenceCache referenceCache;
private List<ElementFilter> elementFilters = new ArrayList<>();
private static class Transformation { private static class Transformation {
String packageName; String packageName;
@ -63,6 +67,11 @@ public class ClasspathResourceMapper implements Function<String, ClassHolder>, C
throw new RuntimeException("Error reading resources", e); throw new RuntimeException("Error reading resources", e);
} }
renamer = new ClassRefsRenamer(referenceCache, new CachedFunction<>(classNameMapper)); renamer = new ClassRefsRenamer(referenceCache, new CachedFunction<>(classNameMapper));
for (ElementFilter elementFilter : ServiceLoader.load(ElementFilter.class)) {
elementFilters.add(elementFilter);
}
this.classLoader = classLoader; this.classLoader = classLoader;
} }
@ -104,6 +113,38 @@ public class ClasspathResourceMapper implements Function<String, ClassHolder>, C
@Override @Override
public ClassHolder apply(String name) { 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) { for (Transformation transformation : transformations) {
if (name.startsWith(transformation.packageName)) { if (name.startsWith(transformation.packageName)) {
int index = name.lastIndexOf('.'); int index = name.lastIndexOf('.');

View File

@ -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);
}