Mercurial > hg > truffle
diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/MethodSpecParser.java @ 19289:62c43fcf5be2
Truffle-DSL: implement @Cached and fixes for the new guard expression syntax.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Tue, 03 Feb 2015 15:07:07 +0100 |
parents | 08aa0372dad4 |
children | 18c0f02fa4d2 |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/MethodSpecParser.java Mon Dec 29 18:32:03 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/MethodSpecParser.java Tue Feb 03 15:07:07 2015 +0100 @@ -30,6 +30,7 @@ import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; +import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.model.*; public final class MethodSpecParser { @@ -76,26 +77,13 @@ String id = method.getSimpleName().toString(); TypeMirror returnType = method.getReturnType(); - List<TypeMirror> parameterTypes = new ArrayList<>(); - for (VariableElement var : method.getParameters()) { - parameterTypes.add(var.asType()); - } - - TemplateMethod templateMethod = parseImpl(methodSpecification, naturalOrder, id, method, annotation, returnType, parameterTypes); - if (templateMethod != null) { - for (int i = 0; i < templateMethod.getParameters().size(); i++) { - if (i < method.getParameters().size()) { - templateMethod.getParameters().get(i).setVariableElement(method.getParameters().get(i)); - } - } - } - return templateMethod; + return parseImpl(methodSpecification, naturalOrder, id, method, annotation, returnType, method.getParameters()); } public TemplateMethod parseImpl(MethodSpec methodSpecification, int naturalOrder, String id, ExecutableElement method, AnnotationMirror annotation, TypeMirror returnType, - List<TypeMirror> parameterTypes) { + List<? extends VariableElement> parameterTypes) { ParameterSpec returnTypeSpec = methodSpecification.getReturnType(); - Parameter returnTypeMirror = matchParameter(returnTypeSpec, returnType, -1, -1); + Parameter returnTypeMirror = matchParameter(returnTypeSpec, new CodeVariableElement(returnType, "returnType"), -1, -1); if (returnTypeMirror == null) { if (emitErrors) { TemplateMethod invalidMethod = new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<Parameter> emptyList()); @@ -147,11 +135,11 @@ * end matching the required arguments, parsing fails. Parameters prior to the parsed required * ones are cut and used to parse the optional parameters. */ - private List<Parameter> parseParameters(MethodSpec spec, List<TypeMirror> parameterTypes, boolean varArgs) { + private List<Parameter> parseParameters(MethodSpec spec, List<? extends VariableElement> parameterTypes, boolean varArgs) { List<Parameter> parsedRequired = null; int offset = 0; for (; offset <= parameterTypes.size(); offset++) { - List<TypeMirror> parameters = new ArrayList<>(); + List<VariableElement> parameters = new ArrayList<>(); parameters.addAll(parameterTypes.subList(offset, parameterTypes.size())); parsedRequired = parseParametersRequired(spec, parameters, varArgs); if (parsedRequired != null) { @@ -166,7 +154,7 @@ if (parsedRequired.isEmpty() && offset == 0) { offset = parameterTypes.size(); } - List<TypeMirror> potentialOptionals = parameterTypes.subList(0, offset); + List<? extends VariableElement> potentialOptionals = parameterTypes.subList(0, offset); List<Parameter> parsedOptionals = parseParametersOptional(spec, potentialOptionals); if (parsedOptionals == null) { return null; @@ -178,7 +166,7 @@ return finalParameters; } - private List<Parameter> parseParametersOptional(MethodSpec spec, List<TypeMirror> types) { + private List<Parameter> parseParametersOptional(MethodSpec spec, List<? extends VariableElement> types) { List<Parameter> parsedParams = new ArrayList<>(); int typeStartIndex = 0; @@ -186,8 +174,8 @@ outer: for (int specIndex = 0; specIndex < specifications.size(); specIndex++) { ParameterSpec specification = specifications.get(specIndex); for (int typeIndex = typeStartIndex; typeIndex < types.size(); typeIndex++) { - TypeMirror actualType = types.get(typeIndex); - Parameter optionalParam = matchParameter(specification, actualType, -1, -1); + VariableElement variable = types.get(typeIndex); + Parameter optionalParam = matchParameter(specification, variable, -1, -1); if (optionalParam != null) { parsedParams.add(optionalParam); typeStartIndex = typeIndex + 1; @@ -203,7 +191,7 @@ return parsedParams; } - private List<Parameter> parseParametersRequired(MethodSpec spec, List<TypeMirror> types, boolean typeVarArgs) { + private List<Parameter> parseParametersRequired(MethodSpec spec, List<VariableElement> types, boolean typeVarArgs) { List<Parameter> parsedParams = new ArrayList<>(); List<ParameterSpec> specifications = spec.getRequired(); boolean specVarArgs = spec.isVariableRequiredParameters(); @@ -212,7 +200,7 @@ ParameterSpec specification; while ((specification = nextSpecification(specifications, specificationIndex, specVarArgs)) != null) { - TypeMirror actualType = nextActualType(types, typeIndex, typeVarArgs); + VariableElement actualType = nextActualType(types, typeIndex, typeVarArgs); if (actualType == null) { if (spec.isIgnoreAdditionalSpecifications()) { break; @@ -238,8 +226,18 @@ specificationIndex++; } + // consume randomly ordered annotated parameters + VariableElement variable; + while ((variable = nextActualType(types, typeIndex, typeVarArgs)) != null) { + Parameter matchedParamter = matchAnnotatedParameter(spec, variable); + if (matchedParamter == null) { + break; + } + parsedParams.add(matchedParamter); + typeIndex++; + } + if (typeIndex < types.size()) { - // additional types available if (spec.isIgnoreAdditionalParameters()) { return parsedParams; } else { @@ -250,6 +248,19 @@ return parsedParams; } + private Parameter matchAnnotatedParameter(MethodSpec spec, VariableElement variable) { + for (ParameterSpec parameterSpec : spec.getAnnotations()) { + if (parameterSpec.matches(variable)) { + Parameter matchedParameter = matchParameter(parameterSpec, variable, -1, -1); + if (matchedParameter != null) { + matchedParameter.setLocalName(variable.getSimpleName().toString()); + return matchedParameter; + } + } + } + return null; + } + private static ParameterSpec nextSpecification(List<ParameterSpec> specifications, int specIndex, boolean varArgs) { if (varArgs && specIndex >= specifications.size() - 1 && !specifications.isEmpty()) { return specifications.get(specifications.size() - 1); @@ -260,12 +271,12 @@ } } - private static TypeMirror nextActualType(List<TypeMirror> types, int typeIndex, boolean varArgs) { + private static VariableElement nextActualType(List<VariableElement> types, int typeIndex, boolean varArgs) { if (varArgs && typeIndex >= types.size() - 1 && !types.isEmpty()) { // unpack varargs array argument - TypeMirror actualType = types.get(types.size() - 1); - if (actualType.getKind() == TypeKind.ARRAY) { - actualType = ((ArrayType) actualType).getComponentType(); + VariableElement actualType = types.get(types.size() - 1); + if (actualType.asType().getKind() == TypeKind.ARRAY) { + actualType = new CodeVariableElement(((ArrayType) actualType.asType()).getComponentType(), actualType.getSimpleName().toString()); } return actualType; } else if (typeIndex < types.size()) { @@ -275,21 +286,21 @@ } } - private Parameter matchParameter(ParameterSpec specification, TypeMirror mirror, int specificationIndex, int varArgsIndex) { - TypeMirror resolvedType = mirror; + private Parameter matchParameter(ParameterSpec specification, VariableElement variable, int specificationIndex, int varArgsIndex) { + TypeMirror resolvedType = variable.asType(); if (hasError(resolvedType)) { return null; } - if (!specification.matches(resolvedType)) { + if (!specification.matches(variable)) { return null; } TypeData resolvedTypeData = getTypeSystem().findTypeData(resolvedType); if (resolvedTypeData != null) { - return new Parameter(specification, resolvedTypeData, specificationIndex, varArgsIndex); + return new Parameter(specification, resolvedTypeData, variable, specificationIndex, varArgsIndex); } else { - return new Parameter(specification, resolvedType, specificationIndex, varArgsIndex); + return new Parameter(specification, variable, specificationIndex, varArgsIndex); } }