From 1842c4c38788a752bf9a7a4dca456b176a2d07c4 Mon Sep 17 00:00:00 2001 From: Victor Date: Sun, 24 Jul 2016 14:30:55 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=81=D1=82=D1=80=D0=B0=D0=B8=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=BD=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D0=BD=D1=82=20=D0=B8=D0=B7=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB?= =?UTF-8?q?=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + ...onstantInitializerAnnotationProcessor.java | 59 ------------------- .../annimon/ownlang/lib/modules/canvasfx.java | 6 +- .../ownlang/parser/ast/UseStatement.java | 14 +++++ .../optimization/ConstantPropagation.java | 2 +- .../parser/optimization/VariablesGrabber.java | 40 ++++++++++++- 6 files changed, 58 insertions(+), 64 deletions(-) delete mode 100644 src/main/java/com/annimon/ownlang/annotations/ConstantInitializerAnnotationProcessor.java diff --git a/build.gradle b/build.gradle index 6bbfc05..02e8725 100644 --- a/build.gradle +++ b/build.gradle @@ -31,6 +31,7 @@ task runOptimizing(dependsOn: classes, type: JavaExec) { main = project.mainClass classpath = sourceSets.main.runtimeClasspath ignoreExitValue = true + // args '-o 9 -m -a -f examples/game/minesweeper.own'.split(' ') args '-o 9 -m -a -f program.own'.split(' ') } diff --git a/src/main/java/com/annimon/ownlang/annotations/ConstantInitializerAnnotationProcessor.java b/src/main/java/com/annimon/ownlang/annotations/ConstantInitializerAnnotationProcessor.java deleted file mode 100644 index 3293f44..0000000 --- a/src/main/java/com/annimon/ownlang/annotations/ConstantInitializerAnnotationProcessor.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.annimon.ownlang.annotations; - -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.Optional; -import java.util.Set; -import javax.annotation.processing.AbstractProcessor; -import javax.annotation.processing.RoundEnvironment; -import javax.annotation.processing.SupportedAnnotationTypes; -import javax.annotation.processing.SupportedSourceVersion; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.ExecutableType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.util.SimpleTypeVisitor6; -import javax.tools.Diagnostic.Kind; - -@SupportedAnnotationTypes("com.annimon.ownlang.annotations.ConstantInitializer") -@SupportedSourceVersion(SourceVersion.RELEASE_6) -public class ConstantInitializerAnnotationProcessor extends AbstractProcessor { - - // https://github.com/corgrath/abandoned-Requires-Static-Method-Annotation - private static final String METHOD_NAME = "initConstants"; - - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) { - Set elements = roundEnv.getElementsAnnotatedWith(ConstantInitializer.class); - for (Element element : elements) { - final Optional result = element.getEnclosedElements().stream() - .filter(e -> e.getKind() == ElementKind.METHOD) - .filter(m -> m.getSimpleName().contentEquals(METHOD_NAME)) - .filter(m -> m.getModifiers().containsAll(Arrays.asList(Modifier.PUBLIC, Modifier.STATIC))) - .filter(m -> m.asType().accept(visitor, null)) - .findFirst(); - if (result.isPresent()) { - showError(element); - return true; - } - } - return true; - } - - private void showError(Element element) { - final String message = String.format("Class %s requires a method" - + " `public static void %s() {}`", element.getSimpleName(), METHOD_NAME); - processingEnv.getMessager().printMessage(Kind.ERROR, message, element); - } - - private final SimpleTypeVisitor6 visitor = new SimpleTypeVisitor6() { - @Override - public Boolean visitExecutable(ExecutableType t, Void v) { - if (t.getReturnType().getKind() != TypeKind.VOID) return false; - if (!t.getParameterTypes().isEmpty()) return false; - return true; - } - }; -} diff --git a/src/main/java/com/annimon/ownlang/lib/modules/canvasfx.java b/src/main/java/com/annimon/ownlang/lib/modules/canvasfx.java index c8fb30a..1b129eb 100644 --- a/src/main/java/com/annimon/ownlang/lib/modules/canvasfx.java +++ b/src/main/java/com/annimon/ownlang/lib/modules/canvasfx.java @@ -207,9 +207,9 @@ public final class canvasfx implements Module { @Override public int asInt() { final int a = (int) (color.getOpacity() * 255) & 0xFF; - final int r = (int) (color.getRed()* 255) & 0xFF; - final int g = (int) (color.getGreen()* 255) & 0xFF; - final int b = (int) (color.getBlue()* 255) & 0xFF; + final int r = (int) (color.getRed() * 255) & 0xFF; + final int g = (int) (color.getGreen() * 255) & 0xFF; + final int b = (int) (color.getBlue() * 255) & 0xFF; return ((a << 24) | (r << 16) | (g << 8) | b); } diff --git a/src/main/java/com/annimon/ownlang/parser/ast/UseStatement.java b/src/main/java/com/annimon/ownlang/parser/ast/UseStatement.java index 1fcd841..095d53a 100644 --- a/src/main/java/com/annimon/ownlang/parser/ast/UseStatement.java +++ b/src/main/java/com/annimon/ownlang/parser/ast/UseStatement.java @@ -1,6 +1,7 @@ package com.annimon.ownlang.parser.ast; import com.annimon.ownlang.lib.modules.Module; +import java.lang.reflect.Method; /** * @@ -9,6 +10,7 @@ import com.annimon.ownlang.lib.modules.Module; public final class UseStatement extends InterruptableNode implements Statement { private static final String PACKAGE = "com.annimon.ownlang.lib.modules."; + private static final String INIT_CONSTANTS_METHOD = "initConstants"; public final Expression expression; @@ -27,6 +29,18 @@ public final class UseStatement extends InterruptableNode implements Statement { throw new RuntimeException(ex); } } + + public void loadConstants() { + try { + final String moduleName = expression.eval().asString(); + final Class moduleClass = Class.forName(PACKAGE + moduleName); + final Method method = moduleClass.getMethod(INIT_CONSTANTS_METHOD); + if (method != null) { + method.invoke(this); + } + } catch (Exception ex) { + } + } @Override public void accept(Visitor visitor) { diff --git a/src/main/java/com/annimon/ownlang/parser/optimization/ConstantPropagation.java b/src/main/java/com/annimon/ownlang/parser/optimization/ConstantPropagation.java index f42435c..7a2b00c 100644 --- a/src/main/java/com/annimon/ownlang/parser/optimization/ConstantPropagation.java +++ b/src/main/java/com/annimon/ownlang/parser/optimization/ConstantPropagation.java @@ -23,7 +23,7 @@ public class ConstantPropagation extends OptimizationVisitor> public Node optimize(Node node) { final Map variables = new HashMap<>(); // Find variables - node.accept(new VariablesGrabber(), variables); + node.accept(new VariablesGrabber(true), variables); // Filter only string/number values with 1 modification final Map candidates = new HashMap<>(); for (Map.Entry e : variables.entrySet()) { diff --git a/src/main/java/com/annimon/ownlang/parser/optimization/VariablesGrabber.java b/src/main/java/com/annimon/ownlang/parser/optimization/VariablesGrabber.java index e980f68..8fab658 100644 --- a/src/main/java/com/annimon/ownlang/parser/optimization/VariablesGrabber.java +++ b/src/main/java/com/annimon/ownlang/parser/optimization/VariablesGrabber.java @@ -1,5 +1,7 @@ package com.annimon.ownlang.parser.optimization; +import com.annimon.ownlang.lib.Value; +import com.annimon.ownlang.lib.Variables; import com.annimon.ownlang.parser.ast.Accessible; import com.annimon.ownlang.parser.ast.Argument; import com.annimon.ownlang.parser.ast.AssignmentExpression; @@ -11,6 +13,7 @@ import com.annimon.ownlang.parser.ast.FunctionDefineStatement; import com.annimon.ownlang.parser.ast.MatchExpression; import com.annimon.ownlang.parser.ast.Node; import com.annimon.ownlang.parser.ast.UnaryExpression; +import com.annimon.ownlang.parser.ast.UseStatement; import com.annimon.ownlang.parser.ast.ValueExpression; import com.annimon.ownlang.parser.ast.VariableExpression; import static com.annimon.ownlang.parser.visitors.VisitorUtils.isValue; @@ -21,11 +24,25 @@ import java.util.Map; public class VariablesGrabber extends OptimizationVisitor> { public static Map getInfo(Node node) { + return getInfo(node, false); + } + + public static Map getInfo(Node node, boolean grabModuleConstants) { Map variableInfos = new HashMap<>(); - node.accept(new VariablesGrabber(), variableInfos); + node.accept(new VariablesGrabber(grabModuleConstants), variableInfos); return variableInfos; } + private final boolean grabModuleConstants; + + public VariablesGrabber() { + this(false); + } + + public VariablesGrabber(boolean grabModuleConstants) { + this.grabModuleConstants = grabModuleConstants; + } + @Override public Node visit(AssignmentExpression s, Map t) { if (!isVariable((Node)s.target)) { @@ -99,6 +116,27 @@ public class VariablesGrabber extends OptimizationVisitor t) { + if (grabModuleConstants) { + // To get module variables we need to store current variables, clear all, then load module. + final Map currentVariables = new HashMap<>(Variables.variables()); + Variables.variables().clear(); + if (isValue(s.expression)) { + s.loadConstants(); + } + // Grab module variables + for (Map.Entry entry : Variables.variables().entrySet()) { + final VariableInfo var = variableInfo(t, entry.getKey()); + var.value = entry.getValue(); + t.put(entry.getKey(), var); + } + // Restore previous variables + Variables.variables().putAll(currentVariables); + } + return super.visit(s, t); + } + private VariableInfo variableInfo(Map t, final String variableName) {