View Javadoc
Minimize
Table

Bug Overview

linebug prioritybugbug descriptionexisting sinceauthor
58mediumTODODer Code ist an dieser Stelle eventuell unfertig oder fehlerhaft. Bitte überprüfen!18.06.2012-10:31Unbekannt

1   /*
2    * Copyright 2003-2007 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.codehaus.groovy.ast.expr;
17  
18  import org.codehaus.groovy.ast.ClassHelper;
19  import org.codehaus.groovy.ast.GenericsType;
20  import org.codehaus.groovy.ast.GroovyCodeVisitor;
21  import org.codehaus.groovy.ast.MethodNode;
22  
23  /**
24   * A method call on an object or class
25   * 
26   * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
27   * @version $Revision: 21774 $
28   */
29  public class MethodCallExpression extends Expression {
30  
31      private Expression objectExpression;
32      private Expression method;
33      private Expression arguments;
34      private boolean spreadSafe = false;
35      private boolean safe = false;
36      private boolean implicitThis;
37  
38      // type spec for generics
39      private GenericsType[] genericsTypes = null;
40      private boolean usesGenerics = false;
41  
42      private MethodNode target;
43      
44      public static final Expression NO_ARGUMENTS = new TupleExpression();
45  
46      public MethodCallExpression(Expression objectExpression, String method, Expression arguments) {
47          this(objectExpression,new ConstantExpression(method),arguments);
48      }
49      
50      public MethodCallExpression(Expression objectExpression, Expression method, Expression arguments) {
51          this.objectExpression = objectExpression;
52          this.method = method;
53          if (!(arguments instanceof TupleExpression)){
54              this.arguments = new TupleExpression(arguments);
55          } else {
56              this.arguments = arguments;
57          }
58 bug overview            //TODO: set correct type here 
59          // if setting type and a methodcall is the last expression in a method,
60          // then the method will return null if the method itself is not void too!
61          // (in bytecode after call: aconst_null, areturn)
62          this.setType(ClassHelper.DYNAMIC_TYPE);
63          this.setImplicitThis(true);
64      }
65  
66      public void visit(GroovyCodeVisitor visitor) {
67          visitor.visitMethodCallExpression(this);
68      }
69  
70      public Expression transformExpression(ExpressionTransformer transformer) {
71          MethodCallExpression answer =
72              new MethodCallExpression(transformer.transform(objectExpression), transformer.transform(method), transformer.transform(arguments));
73          answer.setSafe(safe);
74          answer.setSpreadSafe(spreadSafe);
75          answer.setImplicitThis(implicitThis);
76          answer.setSourcePosition(this);
77          answer.setMethodTarget(target);
78          return answer;
79      }
80  
81      public Expression getArguments() {
82          return arguments;
83      }
84  
85      public void setArguments(Expression arguments) {
86          if (!(arguments instanceof TupleExpression)){
87              this.arguments = new TupleExpression(arguments);
88          } else {
89              this.arguments = arguments;
90          }
91      }
92  
93      public Expression getMethod() {
94          return method;
95      }
96  
97      public void setMethod(Expression method) {
98        this.method = method;
99      }
100 
101     /**
102      * This method returns the method name as String if it is no dynamic
103      * calculated method name, but a constant.
104      */
105     public String getMethodAsString() {
106         if (! (method instanceof ConstantExpression)) return null;
107         ConstantExpression constant = (ConstantExpression) method;
108         return constant.getText();
109     }
110 
111     public void setObjectExpression(Expression objectExpression) {
112       this.objectExpression = objectExpression;
113     }
114 
115     public Expression getObjectExpression() {
116         return objectExpression;
117     }
118 
119     public String getText() {
120         String object = objectExpression.getText();
121         String meth = method.getText();
122         String args = arguments.getText();
123         String spread = spreadSafe ? "*" : "";
124         String dereference = safe ? "?" : "";
125         return object + spread + dereference + "." + meth + args;
126     }
127 
128     /**
129      * @return is this a safe method call, i.e. if true then if the source object is null
130      * then this method call will return null rather than throwing a null pointer exception
131      */
132     public boolean isSafe() {
133         return safe;
134     }
135 
136     public void setSafe(boolean safe) {
137         this.safe = safe;
138     }
139 
140     public boolean isSpreadSafe() {
141         return spreadSafe;
142     }
143 
144     public void setSpreadSafe(boolean value) {
145         spreadSafe = value;
146     }
147 
148     /**
149      * @return true if no object expression was specified otherwise if 
150      * some expression was specified for the object on which to evaluate
151      * the method then return false
152      */
153     public boolean isImplicitThis() {
154         return implicitThis;
155     }
156 
157     public void setImplicitThis(boolean implicitThis) {
158         this.implicitThis = implicitThis;
159     }
160 
161     public String toString() {
162         return super.toString()
163             + "[object: "
164             + objectExpression
165             + " method: "
166             + method
167             + " arguments: "
168             + arguments
169             + "]";
170     }
171 
172     public GenericsType[] getGenericsTypes() {
173         return genericsTypes;
174     }
175 
176     public void setGenericsTypes(GenericsType[] genericsTypes) {
177         usesGenerics = usesGenerics || genericsTypes != null;
178         this.genericsTypes = genericsTypes;
179     }
180 
181     public boolean isUsingGenerics() {
182         return usesGenerics;
183 	}
184 
185     /**
186      * Sets a method call target for a direct method call. 
187      * WARNING: A method call made this way will run outside of the MOP! 
188      * @param mn the target as MethodNode, mn==null means no target
189      */
190     public void setMethodTarget(MethodNode mn) {
191         this.target = mn;
192         if (mn!=null) {
193             setType(target.getReturnType());
194         } else {
195             setType(ClassHelper.OBJECT_TYPE);
196         }
197     }
198     
199     /**
200      * @return the target as method node if set
201      */
202     public MethodNode getMethodTarget() {
203         return target;
204     }
205 }