mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 00:04:10 -08:00
Add annotations to mark classes and methods supported on some platforms
This commit is contained in:
parent
816434500c
commit
86b5daa3cf
|
@ -16,28 +16,28 @@
|
|||
package org.teavm.classlib;
|
||||
|
||||
import org.teavm.interop.PlatformMarker;
|
||||
import org.teavm.interop.PlatformMarkers;
|
||||
import org.teavm.interop.Platforms;
|
||||
|
||||
public final class PlatformDetector {
|
||||
private PlatformDetector() {
|
||||
}
|
||||
|
||||
@PlatformMarker(PlatformMarkers.WEBASSEMBLY)
|
||||
@PlatformMarker(Platforms.WEBASSEMBLY)
|
||||
public static boolean isWebAssembly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@PlatformMarker(PlatformMarkers.JAVASCRIPT)
|
||||
@PlatformMarker(Platforms.JAVASCRIPT)
|
||||
public static boolean isJavaScript() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@PlatformMarker(PlatformMarkers.C)
|
||||
@PlatformMarker(Platforms.C)
|
||||
public static boolean isC() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@PlatformMarker(PlatformMarkers.LOW_LEVEL)
|
||||
@PlatformMarker(Platforms.LOW_LEVEL)
|
||||
public static boolean isLowLevel() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ import org.teavm.dependency.ClassDependency;
|
|||
import org.teavm.dependency.DependencyAnalyzer;
|
||||
import org.teavm.dependency.DependencyListener;
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.interop.PlatformMarkers;
|
||||
import org.teavm.interop.Platforms;
|
||||
import org.teavm.interop.Structure;
|
||||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.ClassHierarchy;
|
||||
|
@ -775,7 +775,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
|||
|
||||
@Override
|
||||
public String[] getPlatformTags() {
|
||||
return new String[] { PlatformMarkers.C, PlatformMarkers.LOW_LEVEL };
|
||||
return new String[] { Platforms.C, Platforms.LOW_LEVEL };
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -72,7 +72,7 @@ import org.teavm.dependency.DependencyListener;
|
|||
import org.teavm.dependency.DependencyType;
|
||||
import org.teavm.dependency.MethodDependency;
|
||||
import org.teavm.interop.PlatformMarker;
|
||||
import org.teavm.interop.PlatformMarkers;
|
||||
import org.teavm.interop.Platforms;
|
||||
import org.teavm.model.AnnotationHolder;
|
||||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.CallLocation;
|
||||
|
@ -726,7 +726,7 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
|||
|
||||
@Override
|
||||
public String[] getPlatformTags() {
|
||||
return new String[] { PlatformMarkers.JAVASCRIPT };
|
||||
return new String[] { Platforms.JAVASCRIPT };
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -100,7 +100,7 @@ import org.teavm.diagnostics.Diagnostics;
|
|||
import org.teavm.interop.Address;
|
||||
import org.teavm.interop.DelegateTo;
|
||||
import org.teavm.interop.Import;
|
||||
import org.teavm.interop.PlatformMarkers;
|
||||
import org.teavm.interop.Platforms;
|
||||
import org.teavm.interop.StaticInit;
|
||||
import org.teavm.model.AnnotationHolder;
|
||||
import org.teavm.model.BasicBlock;
|
||||
|
@ -806,7 +806,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
|||
|
||||
@Override
|
||||
public String[] getPlatformTags() {
|
||||
return new String[] { PlatformMarkers.WEBASSEMBLY, PlatformMarkers.LOW_LEVEL };
|
||||
return new String[] { Platforms.WEBASSEMBLY, Platforms.LOW_LEVEL };
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,11 +16,16 @@
|
|||
package org.teavm.model.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.teavm.dependency.DependencyInfo;
|
||||
import org.teavm.dependency.MethodDependencyInfo;
|
||||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.interop.SupportedOn;
|
||||
import org.teavm.interop.UnsupportedOn;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.model.instructions.*;
|
||||
import org.teavm.model.optimization.UnreachableBasicBlockEliminator;
|
||||
|
@ -35,14 +40,17 @@ public class MissingItemsProcessor {
|
|||
private Collection<String> reachableClasses;
|
||||
private Collection<MethodReference> reachableMethods;
|
||||
private Collection<FieldReference> reachableFields;
|
||||
private Set<String> platformTags = new HashSet<>();
|
||||
|
||||
public MissingItemsProcessor(DependencyInfo dependencyInfo, ClassHierarchy hierarchy, Diagnostics diagnostics) {
|
||||
public MissingItemsProcessor(DependencyInfo dependencyInfo, ClassHierarchy hierarchy, Diagnostics diagnostics,
|
||||
String[] platformTags) {
|
||||
this.dependencyInfo = dependencyInfo;
|
||||
this.diagnostics = diagnostics;
|
||||
this.hierarchy = hierarchy;
|
||||
reachableClasses = dependencyInfo.getReachableClasses();
|
||||
reachableMethods = dependencyInfo.getReachableMethods();
|
||||
reachableFields = dependencyInfo.getReachableFields();
|
||||
this.platformTags.addAll(Arrays.asList(platformTags));
|
||||
}
|
||||
|
||||
public void processClass(ClassHolder cls) {
|
||||
|
@ -132,9 +140,21 @@ public class MissingItemsProcessor {
|
|||
}
|
||||
|
||||
private boolean checkClass(TextLocation location, String className) {
|
||||
if (!reachableClasses.contains(className) || !dependencyInfo.getClass(className).isMissing()) {
|
||||
if (!reachableClasses.contains(className)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dependencyInfo.getClass(className).isMissing()) {
|
||||
ClassReader cls = dependencyInfo.getClassSource().get(className);
|
||||
if (cls != null && !checkPlatformSupported(cls.getAnnotations())) {
|
||||
diagnostics.error(new CallLocation(methodRef, location), "Class {{c0}} is not supported on "
|
||||
+ "current target", className);
|
||||
emitExceptionThrow(location, NoClassDefFoundError.class.getName(), "Class not found: " + className);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
diagnostics.error(new CallLocation(methodRef, location), "Class {{c0}} was not found",
|
||||
className);
|
||||
emitExceptionThrow(location, NoClassDefFoundError.class.getName(), "Class not found: " + className);
|
||||
|
@ -159,14 +179,28 @@ public class MissingItemsProcessor {
|
|||
return true;
|
||||
}
|
||||
MethodDependencyInfo methodDep = dependencyInfo.getMethod(method);
|
||||
if (!methodDep.isMissing() || !methodDep.isUsed()) {
|
||||
if (!methodDep.isUsed()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!methodDep.isMissing()) {
|
||||
ClassReader cls = dependencyInfo.getClassSource().get(method.getClassName());
|
||||
if (cls != null) {
|
||||
MethodReader methodReader = cls.getMethod(method.getDescriptor());
|
||||
if (methodReader != null && !checkPlatformSupported(methodReader.getAnnotations())) {
|
||||
diagnostics.error(new CallLocation(methodRef, location), "Method {{m0}} is not supported on "
|
||||
+ "current target", method);
|
||||
emitExceptionThrow(location, NoSuchMethodError.class.getName(), "Method not found: " + method);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
diagnostics.error(new CallLocation(methodRef, location), "Method {{m0}} was not found",
|
||||
method);
|
||||
emitExceptionThrow(location, NoSuchMethodError.class.getName(), "Method not found: " + method);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkVirtualMethod(TextLocation location, MethodReference method) {
|
||||
|
@ -200,6 +234,28 @@ public class MissingItemsProcessor {
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean checkPlatformSupported(AnnotationContainerReader annotations) {
|
||||
AnnotationReader supportedAnnot = annotations.get(SupportedOn.class.getName());
|
||||
AnnotationReader unsupportedAnnot = annotations.get(UnsupportedOn.class.getName());
|
||||
if (supportedAnnot != null) {
|
||||
for (AnnotationValue value : supportedAnnot.getValue("value").getList()) {
|
||||
if (platformTags.contains(value.getString())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (unsupportedAnnot != null) {
|
||||
for (AnnotationValue value : unsupportedAnnot.getValue("value").getList()) {
|
||||
if (platformTags.contains(value.getString())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private InstructionVisitor instructionProcessor = new AbstractInstructionVisitor() {
|
||||
@Override
|
||||
public void visit(InitClassInstruction insn) {
|
||||
|
|
|
@ -551,7 +551,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
Linker linker = new Linker(dependency);
|
||||
MutableClassHolderSource cutClasses = new MutableClassHolderSource();
|
||||
MissingItemsProcessor missingItemsProcessor = new MissingItemsProcessor(dependency,
|
||||
dependency.getClassHierarchy(), diagnostics);
|
||||
dependency.getClassHierarchy(), diagnostics, target.getPlatformTags());
|
||||
if (wasCancelled()) {
|
||||
return cutClasses;
|
||||
}
|
||||
|
@ -913,7 +913,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
class PostProcessingClassHolderSource implements ListableClassHolderSource {
|
||||
private Linker linker = new Linker(dependencyAnalyzer);
|
||||
private MissingItemsProcessor missingItemsProcessor = new MissingItemsProcessor(dependencyAnalyzer,
|
||||
dependencyAnalyzer.getClassHierarchy(), diagnostics);
|
||||
dependencyAnalyzer.getClassHierarchy(), diagnostics, target.getPlatformTags());
|
||||
private Map<String, ClassHolder> cache = new HashMap<>();
|
||||
private Set<String> classNames = Collections.unmodifiableSet(new HashSet<>(
|
||||
dependencyAnalyzer.getReachableClasses().stream()
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
*/
|
||||
package org.teavm.interop;
|
||||
|
||||
public final class PlatformMarkers {
|
||||
private PlatformMarkers() {
|
||||
public final class Platforms {
|
||||
private Platforms() {
|
||||
}
|
||||
|
||||
public static final String JAVASCRIPT = "javascript";
|
|
@ -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.interop;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR})
|
||||
public @interface SupportedOn {
|
||||
String[] value();
|
||||
}
|
|
@ -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.interop;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR})
|
||||
public @interface UnsupportedOn {
|
||||
String[] value();
|
||||
}
|
|
@ -23,7 +23,7 @@ import org.teavm.interop.Address;
|
|||
import org.teavm.interop.DelegateTo;
|
||||
import org.teavm.interop.NoSideEffects;
|
||||
import org.teavm.interop.PlatformMarker;
|
||||
import org.teavm.interop.PlatformMarkers;
|
||||
import org.teavm.interop.Platforms;
|
||||
import org.teavm.interop.Unmanaged;
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSObject;
|
||||
|
@ -251,7 +251,7 @@ public final class Platform {
|
|||
return cls.getMetadata().getName();
|
||||
}
|
||||
|
||||
@PlatformMarker(PlatformMarkers.LOW_LEVEL)
|
||||
@PlatformMarker(Platforms.LOW_LEVEL)
|
||||
private static boolean isLowLevel() {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user