diff --git a/teavm-core/src/main/java/org/teavm/common/ServiceRepository.java b/teavm-core/src/main/java/org/teavm/common/ServiceRepository.java new file mode 100644 index 000000000..03f706295 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/common/ServiceRepository.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.common; + +/** + * + * @author Alexey Andreev + */ +public interface ServiceRepository { + T getService(Class type); +} diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java index 2062ef039..c9a7ae198 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java @@ -15,6 +15,7 @@ */ package org.teavm.dependency; +import org.teavm.common.ServiceRepository; import org.teavm.model.ClassHolder; import org.teavm.model.FieldReference; import org.teavm.model.MethodReference; @@ -23,7 +24,7 @@ import org.teavm.model.MethodReference; * * @author Alexey Andreev */ -public interface DependencyAgent extends DependencyInfo { +public interface DependencyAgent extends DependencyInfo, ServiceRepository { DependencyNode createNode(); String generateClassName(); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index 4258d3f08..7f3c52976 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -45,18 +45,21 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { private ConcurrentMap achievableClasses = new ConcurrentHashMap<>(); private ConcurrentMap initializedClasses = new ConcurrentHashMap<>(); private List listeners = new ArrayList<>(); + private ServiceRepository services; ConcurrentMap missingMethods = new ConcurrentHashMap<>(); ConcurrentMap missingClasses = new ConcurrentHashMap<>(); ConcurrentMap missingFields = new ConcurrentHashMap<>(); - public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader) { - this(classSource, classLoader, new SimpleFiniteExecutor()); + public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services) { + this(classSource, classLoader, services, new SimpleFiniteExecutor()); } - public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, FiniteExecutor executor) { + public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, + FiniteExecutor executor) { this.classSource = new DependencyClassSource(classSource); this.classLoader = classLoader; this.executor = executor; + this.services = services; methodReaderCache = new ConcurrentCachedMapper<>(new Mapper() { @Override public MethodReader map(MethodReference preimage) { return findMethodReader(preimage); @@ -447,4 +450,9 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { sb.append('\n'); } } + + @Override + public T getService(Class type) { + return services.getService(type); + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index 1006a503b..ce4d2691e 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -22,6 +22,7 @@ import java.util.*; import org.teavm.codegen.NamingException; import org.teavm.codegen.NamingStrategy; import org.teavm.codegen.SourceWriter; +import org.teavm.common.ServiceRepository; import org.teavm.javascript.ast.*; import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.ni.InjectedBy; @@ -44,6 +45,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext private boolean minifying; private Map injectorMap = new HashMap<>(); private Properties properties = new Properties(); + private ServiceRepository services; private static class InjectorHolder { public final Injector injector; @@ -57,11 +59,13 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext injectorMap.put(method, new InjectorHolder(injector)); } - public Renderer(SourceWriter writer, ListableClassHolderSource classSource, ClassLoader classLoader) { + public Renderer(SourceWriter writer, ListableClassHolderSource classSource, ClassLoader classLoader, + ServiceRepository services) { this.naming = writer.getNaming(); this.writer = writer; this.classSource = classSource; this.classLoader = classLoader; + this.services = services; } @Override @@ -506,7 +510,12 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext @Override public Properties getProperties() { - return null; + return new Properties(properties); + } + + @Override + public T getService(Class type) { + return services.getService(type); } } @@ -1429,5 +1438,20 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext public int argumentCount() { return arguments.size(); } + + @Override + public T getService(Class type) { + return services.getService(type); + } + + @Override + public Properties getProperties() { + return new Properties(properties); + } + } + + @Override + public T getService(Class type) { + return services.getService(type); } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/RenderingContext.java b/teavm-core/src/main/java/org/teavm/javascript/RenderingContext.java index 48e2b6cae..70c374f53 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/RenderingContext.java +++ b/teavm-core/src/main/java/org/teavm/javascript/RenderingContext.java @@ -18,13 +18,14 @@ package org.teavm.javascript; import java.util.Properties; import org.teavm.codegen.NamingStrategy; import org.teavm.codegen.SourceWriter; +import org.teavm.common.ServiceRepository; import org.teavm.model.ListableClassReaderSource; /** * * @author Alexey Andreev */ -public interface RenderingContext { +public interface RenderingContext extends ServiceRepository { NamingStrategy getNaming(); SourceWriter getWriter(); diff --git a/teavm-core/src/main/java/org/teavm/javascript/ni/GeneratorContext.java b/teavm-core/src/main/java/org/teavm/javascript/ni/GeneratorContext.java index d54363239..985727a90 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ni/GeneratorContext.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ni/GeneratorContext.java @@ -16,13 +16,14 @@ package org.teavm.javascript.ni; import java.util.Properties; +import org.teavm.common.ServiceRepository; import org.teavm.model.ListableClassReaderSource; /** * * @author Alexey Andreev */ -public interface GeneratorContext { +public interface GeneratorContext extends ServiceRepository { String getParameterName(int index); ListableClassReaderSource getClassSource(); diff --git a/teavm-core/src/main/java/org/teavm/javascript/ni/InjectorContext.java b/teavm-core/src/main/java/org/teavm/javascript/ni/InjectorContext.java index 95cf19776..71db4a2e9 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ni/InjectorContext.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ni/InjectorContext.java @@ -16,7 +16,9 @@ package org.teavm.javascript.ni; import java.io.IOException; +import java.util.Properties; import org.teavm.codegen.SourceWriter; +import org.teavm.common.ServiceRepository; import org.teavm.javascript.ast.Expr; import org.teavm.model.ValueType; @@ -24,7 +26,7 @@ import org.teavm.model.ValueType; * * @author Alexey Andreev */ -public interface InjectorContext { +public interface InjectorContext extends ServiceRepository { Expr getArgument(int index); int argumentCount(); @@ -33,6 +35,8 @@ public interface InjectorContext { SourceWriter getWriter(); + Properties getProperties(); + void writeEscaped(String str) throws IOException; void writeType(ValueType type) throws IOException; diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index 8eba7ff75..3a9c78e2a 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -19,6 +19,7 @@ import java.io.*; import java.util.*; import org.teavm.codegen.*; import org.teavm.common.FiniteExecutor; +import org.teavm.common.ServiceRepository; import org.teavm.dependency.*; import org.teavm.javascript.Decompiler; import org.teavm.javascript.Renderer; @@ -65,7 +66,7 @@ import org.teavm.vm.spi.TeaVMPlugin; * * @author Alexey Andreev */ -public class TeaVM implements TeaVMHost { +public class TeaVM implements TeaVMHost, ServiceRepository { private ClassReaderSource classSource; private DependencyChecker dependencyChecker; private FiniteExecutor executor; @@ -78,12 +79,13 @@ public class TeaVM implements TeaVMHost { private Map methodGenerators = new HashMap<>(); private Map methodInjectors = new HashMap<>(); private List rendererListeners = new ArrayList<>(); + private Map, Object> services = new HashMap<>(); private Properties properties = new Properties(); TeaVM(ClassReaderSource classSource, ClassLoader classLoader, FiniteExecutor executor) { this.classSource = classSource; this.classLoader = classLoader; - dependencyChecker = new DependencyChecker(this.classSource, classLoader, executor); + dependencyChecker = new DependencyChecker(this.classSource, classLoader, this, executor); this.executor = executor; } @@ -335,7 +337,7 @@ public class TeaVM implements TeaVMHost { SourceWriterBuilder builder = new SourceWriterBuilder(naming); builder.setMinified(minifying); SourceWriter sourceWriter = builder.build(writer); - Renderer renderer = new Renderer(sourceWriter, classSet, classLoader); + Renderer renderer = new Renderer(sourceWriter, classSet, classLoader, this); for (Map.Entry entry : methodInjectors.entrySet()) { renderer.addInjector(entry.getKey(), entry.getValue()); } @@ -529,4 +531,18 @@ public class TeaVM implements TeaVMHost { plugin.install(this); } } + + @Override + public T getService(Class type) { + Object service = services.get(type); + if (service == null) { + throw new IllegalArgumentException("Service not registered: " + type.getName()); + } + return type.cast(service); + } + + @Override + public void registerService(Class type, T instance) { + services.put(type, instance); + } } diff --git a/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java b/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java index 2acbda0af..59a38ab52 100644 --- a/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java +++ b/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java @@ -41,6 +41,8 @@ public interface TeaVMHost { void add(RendererListener listener); + void registerService(Class type, T instance); + /** * Gets class loaded that is used by TeaVM. This class loader is usually specified by * {@link TeaVMBuilder#setClassLoader(ClassLoader)}