| /* |
| * Copyright 2008 Google Inc. |
| * |
| * 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 com.google.gwt.dev.jjs.impl; |
| |
| import com.google.gwt.core.ext.UnableToCompleteException; |
| import com.google.gwt.dev.javac.testing.impl.MockJavaResource; |
| import com.google.gwt.dev.jjs.ast.JMethod; |
| import com.google.gwt.dev.jjs.ast.JMethodBody; |
| import com.google.gwt.dev.jjs.ast.JProgram; |
| import com.google.gwt.dev.jjs.ast.JReturnStatement; |
| |
| /** |
| * Tests {@link ExpressionAnalyzer}. |
| */ |
| public class ExpressionAnalyzerTest extends JJSTestBase { |
| |
| private static class Result { |
| private final ExpressionAnalyzer ea; |
| private boolean accessesField; |
| private boolean accessesFieldNonFinal; |
| private boolean accessesLocal; |
| private boolean accessesParameter; |
| private boolean canThrowException; |
| private boolean createsObject; |
| private boolean hasAssignment; |
| private boolean hasAssignmentToField; |
| private boolean hasAssignmentToLocal; |
| private boolean hasAssignmentToParameter; |
| |
| public Result(ExpressionAnalyzer ea) { |
| this.ea = ea; |
| } |
| |
| public Result accessesField() { |
| accessesField = true; |
| return this; |
| } |
| |
| public Result accessesFieldNonFinal() { |
| accessesField = true; |
| accessesFieldNonFinal = true; |
| return this; |
| } |
| |
| public Result accessesLocal() { |
| accessesLocal = true; |
| return this; |
| } |
| |
| public Result accessesParameter() { |
| accessesParameter = true; |
| return this; |
| } |
| |
| public Result canThrowException() { |
| canThrowException = true; |
| return this; |
| } |
| |
| public Result createsObject() { |
| createsObject = true; |
| return this; |
| } |
| |
| public Result hasAssignment() { |
| hasAssignment = true; |
| return this; |
| } |
| |
| public Result hasAssignmentToField() { |
| hasAssignment = true; |
| hasAssignmentToField = true; |
| return this; |
| } |
| |
| public Result hasAssignmentToLocal() { |
| hasAssignment = true; |
| hasAssignmentToLocal = true; |
| return this; |
| } |
| |
| public Result hasAssignmentToParameter() { |
| hasAssignment = true; |
| hasAssignmentToParameter = true; |
| return this; |
| } |
| |
| public void check() { |
| assertEquals(accessesField, ea.accessesField()); |
| assertEquals(accessesFieldNonFinal, ea.accessesFieldNonFinal()); |
| assertEquals(accessesLocal, ea.accessesLocal()); |
| assertEquals(accessesParameter, ea.accessesParameter()); |
| assertEquals(canThrowException, ea.canThrowException()); |
| assertEquals(createsObject, ea.createsObject()); |
| assertEquals(hasAssignment, ea.hasAssignment()); |
| assertEquals(hasAssignmentToField, ea.hasAssignmentToField()); |
| assertEquals(hasAssignmentToLocal, ea.hasAssignmentToLocal()); |
| assertEquals(hasAssignmentToParameter, ea.hasAssignmentToParameter()); |
| } |
| } |
| |
| public void testEmpty() throws Exception { |
| analyzeExpression("int", "0").check(); |
| } |
| |
| public void testFieldAccessClinit() throws Exception { |
| sourceOracle.addOrReplace(new MockJavaResource("test.Foo") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package test;\n"); |
| code.append("public class Foo {\n"); |
| code.append(" static final boolean value = trueMethod();"); |
| code.append(" static boolean trueMethod() { return true; }"); |
| code.append("}\n"); |
| return code; |
| } |
| }); |
| analyzeExpression("boolean", "Foo.value").accessesFieldNonFinal().canThrowException().createsObject().hasAssignmentToField().check(); |
| } |
| |
| public void testFieldAccessInstance() throws Exception { |
| sourceOracle.addOrReplace(new MockJavaResource("test.Foo") { |
| @Override |
| public CharSequence getContent() { |
| StringBuilder code = new StringBuilder(); |
| code.append("package test;\n"); |
| code.append("import com.google.gwt.core.client.JavaScriptObject;\n"); |
| code.append("public class Foo {\n"); |
| code.append(" public final boolean BOOL_CONST = true;\n"); |
| code.append(" public boolean FOO = true;\n"); |
| code.append("}\n"); |
| return code; |
| } |
| }); |
| addSnippetImport("test.Foo"); |
| addSnippetClassDecl("static final Foo f = new Foo();"); |
| |
| analyzeExpression("boolean", "f.BOOL_CONST").accessesField().canThrowException().check(); |
| |
| analyzeExpression("boolean", "f.FOO").accessesFieldNonFinal().canThrowException().check(); |
| |
| analyzeExpression("boolean", "f.FOO = false").accessesFieldNonFinal().canThrowException().hasAssignment().hasAssignmentToField().check(); |
| } |
| |
| public void testFieldAccessStatic() throws Exception { |
| addSnippetClassDecl("static boolean trueMethod() { return true; }"); |
| addSnippetClassDecl("static final boolean BOOL_CONST = trueMethod();"); |
| addSnippetClassDecl("static volatile boolean FOO;"); |
| |
| analyzeExpression("boolean", "BOOL_CONST").accessesField().check(); |
| |
| analyzeExpression("boolean", "FOO").accessesFieldNonFinal().check(); |
| |
| analyzeExpression("boolean", "FOO = false").accessesFieldNonFinal().hasAssignmentToField().check(); |
| } |
| |
| public void testNewArray() throws Exception { |
| analyzeExpression("float[]", "new float[3]").createsObject().check(); |
| } |
| |
| private Result analyzeExpression(String type, String expression) |
| throws UnableToCompleteException { |
| JProgram program = compileSnippet(type, "return " + expression + ";", true); |
| ExpressionAnalyzer ea = new ExpressionAnalyzer(); |
| JMethod mainMethod = findMainMethod(program); |
| JMethodBody body = (JMethodBody) mainMethod.getBody(); |
| JReturnStatement returnStmt = (JReturnStatement) body.getStatements().get(0); |
| ea.accept(returnStmt.getExpr()); |
| return new Result(ea); |
| } |
| } |