comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java @ 8237:6b74ffe38183

Implemented support for executing nodes in @Children fields.
author Christian Humer <christian.humer@gmail.com>
date Fri, 01 Mar 2013 17:03:57 +0100
parents c17ee8823d72
children ac4e8c16ffdf
comparison
equal deleted inserted replaced
7860:dbbdc0a30a16 8237:6b74ffe38183
99 getContext().getLog().error(method, "Method must not be private."); 99 getContext().getLog().error(method, "Method must not be private.");
100 valid = false; 100 valid = false;
101 continue; 101 continue;
102 } 102 }
103 103
104 E parsedMethod = parse(method, mirror); 104 E parsedMethod = parseNew(method, mirror);
105 if (parsedMethod != null) { 105 if (parsedMethod != null) {
106 parsedMethods.add(parsedMethod); 106 parsedMethods.add(parsedMethod);
107 } else { 107 } else {
108 valid = false; 108 valid = false;
109 } 109 }
112 return null; 112 return null;
113 } 113 }
114 return parsedMethods; 114 return parsedMethods;
115 } 115 }
116 116
117 private E parse(ExecutableElement method, AnnotationMirror annotation) { 117 private E parseNew(ExecutableElement method, AnnotationMirror annotation) {
118 MethodSpec methodSpecification = createSpecification(method, annotation); 118 MethodSpec methodSpecification = createSpecification(method, annotation);
119 if (methodSpecification == null) { 119 if (methodSpecification == null) {
120 return null; 120 return null;
121 } 121 }
122 122
124 124
125 ParameterSpec returnTypeSpec = methodSpecification.getReturnType(); 125 ParameterSpec returnTypeSpec = methodSpecification.getReturnType();
126 List<ParameterSpec> parameterSpecs = new ArrayList<>(); 126 List<ParameterSpec> parameterSpecs = new ArrayList<>();
127 parameterSpecs.addAll(methodSpecification.getParameters()); 127 parameterSpecs.addAll(methodSpecification.getParameters());
128 128
129 ActualParameter returnTypeMirror = resolveTypeMirror(returnTypeSpec, method.getReturnType(), template); 129 ActualParameter returnTypeMirror = matchParameter(returnTypeSpec, method.getReturnType(), template, 0);
130 if (returnTypeMirror == null) { 130 if (returnTypeMirror == null) {
131 if (isEmitErrors()) { 131 if (isEmitErrors()) {
132 String expectedReturnType = createTypeSignature(returnTypeSpec, typeDefs, true); 132 String expectedReturnType = createTypeSignature(returnTypeSpec, typeDefs, true);
133 String actualReturnType = Utils.getSimpleName(method.getReturnType()); 133 String actualReturnType = Utils.getSimpleName(method.getReturnType());
134 134
138 context.getLog().error(method, annotation, message); 138 context.getLog().error(method, annotation, message);
139 } 139 }
140 return null; 140 return null;
141 } 141 }
142 142
143 Iterator<? extends VariableElement> variableIterator = method.getParameters().iterator(); 143 List<ActualParameter> parameters = parseParameters(method, parameterSpecs);
144 if (parameters == null) {
145 if (isEmitErrors()) {
146 String message = String.format("Method signature mismatch. Expected signature: \n%s",
147 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
148 context.getLog().error(method, annotation, message);
149 }
150 return null;
151 }
152 ActualParameter[] paramMirrors = parameters.toArray(new ActualParameter[parameters.size()]);
153 return create(new TemplateMethod(template, methodSpecification, method, annotation, returnTypeMirror, paramMirrors));
154 }
155
156 private List<ActualParameter> parseParameters(ExecutableElement method, List<ParameterSpec> parameterSpecs) {
157 Iterator<? extends VariableElement> parameterIterator = method.getParameters().iterator();
144 Iterator<? extends ParameterSpec> specificationIterator = parameterSpecs.iterator(); 158 Iterator<? extends ParameterSpec> specificationIterator = parameterSpecs.iterator();
145 159
146 List<ActualParameter> resolvedMirrors = new ArrayList<>(); 160 VariableElement parameter = parameterIterator.hasNext() ? parameterIterator.next() : null;
147 VariableElement parameter = null; 161 ParameterSpec specification = specificationIterator.hasNext() ? specificationIterator.next() : null;
148 ParameterSpec specification = null; 162
149 while (specificationIterator.hasNext() || specification != null) { 163 int specificationIndex = 0;
150 if (specification == null) { 164 List<ActualParameter> resolvedParameters = new ArrayList<>();
151 specification = specificationIterator.next(); 165 while (parameter != null || specification != null) {
152 } 166 if (parameter == null || specification == null) {
153 167 if (specification != null && (specification.isOptional() || specification.getCardinality() == Cardinality.MULTIPLE)) {
154 if (parameter == null && variableIterator.hasNext()) { 168 specification = specificationIterator.hasNext() ? specificationIterator.next() : null;
155 parameter = variableIterator.next(); 169 specificationIndex = 0;
156 }
157
158 if (parameter == null) {
159 if (specification.getCardinality() == Cardinality.MULTIPLE) {
160 specification = null;
161 continue; 170 continue;
162 } else if (!specification.isOptional()) { 171 }
163 if (isEmitErrors()) { 172 return null;
164 // non option type specification found -> argument missing 173 }
165 String expectedType = createTypeSignature(specification, typeDefs, false); 174
166 175 ActualParameter resolvedParameter = matchParameter(specification, parameter.asType(), template, specificationIndex);
167 String message = String.format("Missing argument \"%s\".\nExpected signature: \n %s", expectedType, 176 if (resolvedParameter == null) {
168 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs)); 177 // mismatch
169 178 if (specification.isOptional()) {
170 context.getLog().error(method, message); 179 specification = specificationIterator.hasNext() ? specificationIterator.next() : null;
171 } 180 specificationIndex = 0;
181 } else {
172 return null; 182 return null;
173 } else { 183 }
174 // specification is optional -> continue 184 } else {
175 specification = null; 185 resolvedParameters.add(resolvedParameter);
176 continue; 186
177 } 187 // match
178 } 188 if (specification.getCardinality() == Cardinality.ONE) {
179 189 parameter = parameterIterator.hasNext() ? parameterIterator.next() : null;
180 ActualParameter resolvedMirror = resolveTypeMirror(specification, parameter.asType(), template); 190 specification = specificationIterator.hasNext() ? specificationIterator.next() : null;
181 191 specificationIndex = 0;
182 if (resolvedMirror == null) { 192 } else if (specification.getCardinality() == Cardinality.MULTIPLE) {
183 if (specification.isOptional()) { 193 parameter = parameterIterator.hasNext() ? parameterIterator.next() : null;
184 specification = null; 194 specificationIndex++;
185 continue; 195 }
186 } 196 }
187 197 }
188 if (isEmitErrors()) { 198 return resolvedParameters;
189 String expectedReturnType = createTypeSignature(specification, typeDefs, false); 199 }
190 String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName(); 200
191 201 private ActualParameter matchParameter(ParameterSpec specification, TypeMirror mirror, Template typeSystem, int index) {
192 String message = String.format("The provided argument type \"%s\" does not match expected type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
193 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
194
195 context.getLog().error(parameter, message);
196 }
197 return null;
198 }
199
200 resolvedMirrors.add(resolvedMirror);
201 parameter = null; // consume parameter
202
203 if (specification.getCardinality() != Cardinality.MULTIPLE) {
204 specification = null;
205 }
206 }
207
208 if (variableIterator.hasNext()) {
209 parameter = variableIterator.next();
210 if (isEmitErrors()) {
211 String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
212 String message = String.format("No argument expected but found \"%s\".\nExpected signature: \n %s", actualReturnType,
213 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
214
215 context.getLog().error(parameter, message);
216 }
217 return null;
218 }
219
220 ActualParameter[] paramMirrors = resolvedMirrors.toArray(new ActualParameter[resolvedMirrors.size()]);
221 return create(new TemplateMethod(template, methodSpecification, method, annotation, returnTypeMirror, paramMirrors));
222 }
223
224 private ActualParameter resolveTypeMirror(ParameterSpec specification, TypeMirror mirror, Template typeSystem) {
225 TypeMirror resolvedType = mirror; 202 TypeMirror resolvedType = mirror;
226 if (hasError(resolvedType)) { 203 if (hasError(resolvedType)) {
227 resolvedType = context.resolveNotYetCompiledType(mirror, typeSystem); 204 resolvedType = context.resolveNotYetCompiledType(mirror, typeSystem);
228 } 205 }
229 206
230 if (!specification.matches(resolvedType)) { 207 if (!specification.matches(resolvedType)) {
231 return null; 208 return null;
232 } 209 }
233 return new ActualParameter(specification, resolvedType); 210 return new ActualParameter(specification, resolvedType, index);
234 } 211 }
235 212
236 protected List<TypeDef> createTypeDefinitions(ParameterSpec returnType, List<? extends ParameterSpec> parameters) { 213 protected List<TypeDef> createTypeDefinitions(ParameterSpec returnType, List<? extends ParameterSpec> parameters) {
237 List<TypeDef> typeDefs = new ArrayList<>(); 214 List<TypeDef> typeDefs = new ArrayList<>();
238 215