Mercurial > hg > graal-jvmci-8
diff graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java @ 8595:8a1115c92271
Implemented codegen guard definitions can now omit unused parameters.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 01 Apr 2013 21:43:20 +0200 |
parents | 2be3865d9ea0 |
children | 61ba6fc21ba4 |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java Mon Apr 01 12:19:15 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java Mon Apr 01 21:43:20 2013 +0200 @@ -110,13 +110,7 @@ valid = false; } } - Collections.sort(parsedMethods, new Comparator<TemplateMethod>() { - - @Override - public int compare(TemplateMethod o1, TemplateMethod o2) { - return o1.getMethodName().compareTo(o2.getMethodName()); - } - }); + Collections.sort(parsedMethods); if (!valid && parseNullOnError) { return null; @@ -130,27 +124,25 @@ return null; } + methodSpecification.applyTypeDefinitions("types"); + String id = method.getSimpleName().toString(); AnnotationMirror idAnnotation = Utils.findAnnotationMirror(context.getEnvironment(), method, NodeId.class); if (idAnnotation != null) { id = Utils.getAnnotationValue(String.class, idAnnotation, "value"); } - List<TypeDef> typeDefs = createTypeDefinitions(methodSpecification.getReturnType(), methodSpecification.getParameters()); - ParameterSpec returnTypeSpec = methodSpecification.getReturnType(); - List<ParameterSpec> parameterSpecs = new ArrayList<>(); - parameterSpecs.addAll(methodSpecification.getParameters()); ActualParameter returnTypeMirror = matchParameter(returnTypeSpec, method.getReturnType(), template, 0, false); if (returnTypeMirror == null) { if (emitErrors) { E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<ActualParameter> emptyList())); - String expectedReturnType = createTypeSignature(returnTypeSpec, typeDefs, true); + String expectedReturnType = returnTypeSpec.toSignatureString(true); String actualReturnType = Utils.getSimpleName(method.getReturnType()); String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType, - createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs)); + methodSpecification.toSignatureString(method.getSimpleName().toString())); invalidMethod.addError(message); return invalidMethod; } else { @@ -163,12 +155,12 @@ parameterTypes.add(var.asType()); } - List<ActualParameter> parameters = parseParameters(parameterTypes, methodSpecification.getImplicitTypes(), parameterSpecs); + List<ActualParameter> parameters = parseParameters(methodSpecification, parameterTypes); if (parameters == null) { if (isEmitErrors()) { E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<ActualParameter> emptyList())); String message = String.format("Method signature %s does not match to the expected signature: \n%s", createActualSignature(methodSpecification, method), - createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs)); + methodSpecification.toSignatureString(method.getSimpleName().toString())); invalidMethod.addError(message); return invalidMethod; } else { @@ -180,87 +172,95 @@ } private static String createActualSignature(MethodSpec spec, ExecutableElement method) { - List<String> types = new ArrayList<>(); - for (TypeMirror implicitType : spec.getImplicitTypes()) { - types.add("implicit " + Utils.getSimpleName(implicitType)); + StringBuilder b = new StringBuilder("("); + String sep = ""; + for (TypeMirror implicitType : spec.getImplicitRequiredTypes()) { + b.append(sep); + b.append("implicit " + Utils.getSimpleName(implicitType)); + sep = ", "; } for (VariableElement var : method.getParameters()) { - types.add(Utils.getSimpleName(var.asType())); - } - - StringBuilder b = new StringBuilder("("); - for (Iterator<String> iterator = types.iterator(); iterator.hasNext();) { - b.append(iterator.next()); - if (iterator.hasNext()) { - b.append(", "); - } + b.append(sep); + b.append(Utils.getSimpleName(var.asType())); + sep = ", "; } b.append(")"); return b.toString(); } - private List<ActualParameter> parseParameters(List<TypeMirror> types, List<TypeMirror> implicitTypes, List<ParameterSpec> parameterSpecs) { - Iterator<? extends TypeMirror> parameterIterator = types.iterator(); - Iterator<? extends TypeMirror> implicitParametersIterator = implicitTypes.iterator(); - Iterator<? extends ParameterSpec> specificationIterator = parameterSpecs.iterator(); + private List<ActualParameter> parseParameters(MethodSpec spec, List<TypeMirror> parameterTypes) { + List<ActualParameter> parsedParams = new ArrayList<>(); + ConsumableListIterator<TypeMirror> types = new ConsumableListIterator<>(parameterTypes); - TypeMirror parameter = parameterIterator.hasNext() ? parameterIterator.next() : null; - TypeMirror implicitParameter = implicitParametersIterator.hasNext() ? implicitParametersIterator.next() : null; - ParameterSpec specification = specificationIterator.hasNext() ? specificationIterator.next() : null; + // parse optional parameters + ConsumableListIterator<ParameterSpec> optionals = new ConsumableListIterator<>(spec.getOptional()); + for (TypeMirror type : types) { + int oldIndex = types.getIndex(); + int optionalCount = 1; + for (ParameterSpec paramspec : optionals) { + ActualParameter optionalParam = matchParameter(paramspec, type, template, 0, false); + if (optionalParam != null) { + optionals.consume(optionalCount); + types.consume(); + parsedParams.add(optionalParam); + break; + } + optionalCount++; + } + if (oldIndex == types.getIndex()) { + // nothing found anymore skip optional + break; + } + } + + List<TypeMirror> typesWithImplicit = new ArrayList<>(spec.getImplicitRequiredTypes()); + typesWithImplicit.addAll(types.toList()); + types = new ConsumableListIterator<>(typesWithImplicit); int specificationParameterIndex = 0; - List<ActualParameter> resolvedParameters = new ArrayList<>(); - while (parameter != null || specification != null || implicitParameter != null) { - if (parameter == null || specification == null) { - if (specification != null && (specification.isOptional() || specification.getCardinality() == Cardinality.MULTIPLE)) { - specification = specificationIterator.hasNext() ? specificationIterator.next() : null; + ConsumableListIterator<ParameterSpec> required = new ConsumableListIterator<>(spec.getRequired()); + while (required.get() != null || types.get() != null) { + if (required.get() == null || types.get() == null) { + if (required.get() != null && required.get().getCardinality() == Cardinality.MULTIPLE) { + required.consume(); specificationParameterIndex = 0; continue; } - return null; + break; } - - ActualParameter resolvedParameter = null; - - boolean implicit = false; - if (implicitParameter != null) { - resolvedParameter = matchParameter(specification, implicitParameter, template, specificationParameterIndex, true); - if (resolvedParameter != null) { - implicit = true; - } - } - - if (resolvedParameter == null) { - resolvedParameter = matchParameter(specification, parameter, template, specificationParameterIndex, false); - } - + boolean implicit = types.getIndex() < spec.getImplicitRequiredTypes().size(); + ActualParameter resolvedParameter = matchParameter(required.get(), types.get(), template, specificationParameterIndex, implicit); if (resolvedParameter == null) { - // mismatch - if (specification.isOptional()) { - specification = specificationIterator.hasNext() ? specificationIterator.next() : null; - specificationParameterIndex = 0; - } else { - return null; + if (required.get().getCardinality() == Cardinality.MULTIPLE) { + required.consume(); + continue; } + // direct mismatch but required -> error + return null; } else { - resolvedParameters.add(resolvedParameter); - - // match - if (implicit) { - implicitParameter = implicitParametersIterator.hasNext() ? implicitParametersIterator.next() : null; - } else { - parameter = parameterIterator.hasNext() ? parameterIterator.next() : null; - } - - if (specification.getCardinality() == Cardinality.ONE) { - specification = specificationIterator.hasNext() ? specificationIterator.next() : null; + parsedParams.add(resolvedParameter); + types.consume(); + if (required.get().getCardinality() == Cardinality.ONE) { + required.consume(); specificationParameterIndex = 0; - } else if (specification.getCardinality() == Cardinality.MULTIPLE) { + } else if (required.get().getCardinality() == Cardinality.MULTIPLE) { specificationParameterIndex++; } } } - return resolvedParameters; + + if (!types.toList().isEmpty()) { + // additional types -> error + return null; + } + + if (!required.toList().isEmpty() && !spec.isVariableRequiredArguments()) { + // additional specifications -> error + return null; + } + + // success! + return parsedParams; } private ActualParameter matchParameter(ParameterSpec specification, TypeMirror mirror, Template typeSystem, int index, boolean implicit) { @@ -275,143 +275,53 @@ return new ActualParameter(specification, resolvedType, index, implicit); } - protected List<TypeDef> createTypeDefinitions(ParameterSpec returnType, List<? extends ParameterSpec> parameters) { - List<TypeDef> typeDefs = new ArrayList<>(); + /* Helper class for parsing. */ + private static class ConsumableListIterator<E> implements Iterable<E> { - List<ParameterSpec> allParams = new ArrayList<>(); - allParams.add(returnType); - allParams.addAll(parameters); + private final List<E> data; + private int index; + + public ConsumableListIterator(List<E> data) { + this.data = data; + } - int defIndex = 0; - for (ParameterSpec spec : allParams) { - List<TypeMirror> allowedTypes = spec.getAllowedTypes(); - List<TypeMirror> types = spec.getAllowedTypes(); - if (types != null && allowedTypes.size() > 1) { - TypeDef foundDef = null; - for (TypeDef def : typeDefs) { - if (allowedTypes.equals(def.getTypes())) { - foundDef = def; - break; - } - } - if (foundDef == null) { - foundDef = new TypeDef(types, "Types" + defIndex); - typeDefs.add(foundDef); - defIndex++; - } + public E get() { + if (index >= data.size()) { + return null; + } + return data.get(index); + } - foundDef.getParameters().add(spec); + public E consume() { + return consume(1); + } + + public E consume(int count) { + if (index + count <= data.size()) { + index += count; + return get(); + } else { + throw new ArrayIndexOutOfBoundsException(count + 1); } } - return typeDefs; - } - - protected static class TypeDef { - - private final List<TypeMirror> types; - private final String name; - private final List<ParameterSpec> parameters = new ArrayList<>(); - - public TypeDef(List<TypeMirror> types, String name) { - this.types = types; - this.name = name; + public int getIndex() { + return index; } - public List<ParameterSpec> getParameters() { - return parameters; - } - - public List<TypeMirror> getTypes() { - return types; + @Override + public Iterator<E> iterator() { + return toList().iterator(); } - public String getName() { - return name; - } - } - - public static String createExpectedSignature(String methodName, ParameterSpec returnType, List<? extends ParameterSpec> parameters, List<TypeDef> typeDefs) { - StringBuilder b = new StringBuilder(); - - b.append(" "); - b.append(createTypeSignature(returnType, typeDefs, true)); - - b.append(" "); - b.append(methodName); - b.append("("); - - for (int i = 0; i < parameters.size(); i++) { - ParameterSpec specification = parameters.get(i); - if (specification.isOptional()) { - b.append("["); + public List<E> toList() { + if (index < data.size()) { + return data.subList(index, data.size()); + } else { + return Collections.<E> emptyList(); } - if (specification.getCardinality() == Cardinality.MULTIPLE) { - b.append("{"); - } - - b.append(createTypeSignature(specification, typeDefs, false)); - - if (specification.isOptional()) { - b.append("]"); - } - - if (specification.getCardinality() == Cardinality.MULTIPLE) { - b.append("}"); - } - - if (i < parameters.size() - 1) { - b.append(", "); - } - } - b.append(")"); - - if (!typeDefs.isEmpty()) { - b.append("\n\n"); - - String lineSep = ""; - for (TypeDef def : typeDefs) { - b.append(lineSep); - b.append(" <").append(def.getName()).append(">"); - b.append(" = {"); - String separator = ""; - for (TypeMirror type : def.getTypes()) { - b.append(separator).append(Utils.getSimpleName(type)); - separator = ", "; - } - b.append("}"); - lineSep = "\n"; - - } - } - return b.toString(); - } - - private static String createTypeSignature(ParameterSpec spec, List<TypeDef> typeDefs, boolean typeOnly) { - StringBuilder builder = new StringBuilder(); - if (spec.getAllowedTypes().size() > 1) { - TypeDef foundTypeDef = null; - for (TypeDef typeDef : typeDefs) { - if (typeDef.getParameters().contains(spec)) { - foundTypeDef = typeDef; - break; - } - } - if (foundTypeDef != null) { - builder.append("<" + foundTypeDef.getName() + ">"); - } - } else if (spec.getAllowedTypes().size() == 1) { - builder.append(Utils.getSimpleName(spec.getAllowedTypes().get(0))); - } else { - builder.append("void"); - } - if (!typeOnly) { - builder.append(" "); - builder.append(spec.getName()); - } - return builder.toString(); } }