001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.dev.jjs.ast;
017:
018: import com.google.gwt.dev.jjs.SourceInfo;
019:
020: import java.util.ArrayList;
021:
022: /**
023: * Java method call expression.
024: */
025: public class JMethodCall extends JExpression {
026:
027: private ArrayList<JExpression> args = new ArrayList<JExpression>();
028: private JExpression instance;
029: private final JMethod method;
030: private final JType overrideReturnType;
031: private boolean staticDispatchOnly = false;
032:
033: public JMethodCall(JProgram program, SourceInfo info,
034: JExpression instance, JMethod method) {
035: super (program, info);
036: assert (method != null);
037: assert (instance != null || method.isStatic());
038: this .instance = instance;
039: this .method = method;
040: this .staticDispatchOnly = false;
041: this .overrideReturnType = null;
042: }
043:
044: /**
045: * Create a method call whose type is overridden to the specified type,
046: * ignoring the return type of the target method. This constructor is used
047: * during normalizing transformations to preserve type semantics when calling
048: * externally-defined compiler implementation methods.
049: *
050: * For example, Cast.dynamicCast() returns Object but that method is used to
051: * implement the cast operation. Using a stronger type on the call expression
052: * allows us to preserve type information during the latter phases of
053: * compilation.
054: */
055: public JMethodCall(JProgram program, SourceInfo info,
056: JExpression instance, JMethod method,
057: JType overrideReturnType) {
058: super (program, info);
059: this .instance = instance;
060: this .method = method;
061: assert (overrideReturnType != null);
062: this .overrideReturnType = overrideReturnType;
063: }
064:
065: public JMethodCall(JProgram program, SourceInfo info,
066: JExpression instance, JMethod method,
067: boolean staticDispatchOnly) {
068: super (program, info);
069: this .instance = instance;
070: this .method = method;
071: this .staticDispatchOnly = staticDispatchOnly;
072: this .overrideReturnType = null;
073: }
074:
075: public boolean canBePolymorphic() {
076: return !staticDispatchOnly && !method.isFinal()
077: && !method.isStatic();
078: }
079:
080: public ArrayList<JExpression> getArgs() {
081: return args;
082: }
083:
084: public JExpression getInstance() {
085: return instance;
086: }
087:
088: public JMethod getTarget() {
089: return method;
090: }
091:
092: public JType getType() {
093: if (overrideReturnType != null) {
094: return overrideReturnType;
095: } else {
096: return method.getType();
097: }
098: }
099:
100: @Override
101: public boolean hasSideEffects() {
102: // TODO(later): optimize? Be sure to check for clinit when we do.
103: return true;
104: }
105:
106: public boolean isStaticDispatchOnly() {
107: return staticDispatchOnly;
108: }
109:
110: public void setStaticDispatchOnly() {
111: this .staticDispatchOnly = true;
112: }
113:
114: public void traverse(JVisitor visitor, Context ctx) {
115: if (visitor.visit(this, ctx)) {
116: if (instance != null) {
117: instance = visitor.accept(instance);
118: }
119: visitor.accept(args);
120: }
121: visitor.endVisit(this, ctx);
122: }
123:
124: }
|