# HG changeset patch # User Christian Humer # Date 1377706720 -7200 # Node ID 89febfdb81d2d4a39893db0c23d3866184034c5f # Parent b33783cbd8ceb8f71237cffeffd6c87bc9206e2a Truffle-DSL: fixed a bug in parameter parsing where optional parameters were priorized to required ones. diff -r b33783cbd8ce -r 89febfdb81d2 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java Wed Aug 28 11:41:10 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java Wed Aug 28 18:18:40 2013 +0200 @@ -193,10 +193,50 @@ return b.toString(); } + /* + * Parameter parsing tries to parse required arguments starting from offset 0 with increasing + * offset until it finds a signature end that matches the required specification. If there is no + * end matching the required arguments, parsing fails. Parameters prior to the parsed required + * ones are cut and used to parse the optional parameters. All those remaining parameters must + * be consumed otherwise its an error. + */ private List parseParameters(MethodSpec spec, List parameterTypes) { + List implicitTypes = spec.getImplicitRequiredTypes(); + + int offset = -1; + List parsedRequired = null; + ConsumableListIterator types = null; + while (parsedRequired == null && offset < parameterTypes.size()) { + offset++; + types = new ConsumableListIterator<>(new ArrayList<>(implicitTypes)); + types.data.addAll(parameterTypes.subList(offset, parameterTypes.size())); + parsedRequired = parseParametersRequired(spec, types); + } + + if (parsedRequired == null && offset >= 0) { + return null; + } + + List potentialOptionals; + if (offset == -1) { + potentialOptionals = parameterTypes; + } else { + potentialOptionals = parameterTypes.subList(0, offset); + } + types = new ConsumableListIterator<>(potentialOptionals); + List parsedOptionals = parseParametersOptional(spec, types); + if (parsedOptionals == null) { + return null; + } + + List finalParameters = new ArrayList<>(); + finalParameters.addAll(parsedOptionals); + finalParameters.addAll(parsedRequired); + return finalParameters; + } + + private List parseParametersOptional(MethodSpec spec, ConsumableListIterator types) { List parsedParams = new ArrayList<>(); - ConsumableListIterator types = new ConsumableListIterator<>(parameterTypes); - // parse optional parameters ConsumableListIterator optionals = new ConsumableListIterator<>(spec.getOptional()); for (TypeMirror type : types) { @@ -217,10 +257,14 @@ break; } } + if (types.getIndex() <= types.data.size() - 1) { + return null; + } + return parsedParams; + } - List typesWithImplicit = new ArrayList<>(spec.getImplicitRequiredTypes()); - typesWithImplicit.addAll(types.toList()); - types = new ConsumableListIterator<>(typesWithImplicit); + private List parseParametersRequired(MethodSpec spec, ConsumableListIterator types) { + List parsedParams = new ArrayList<>(); int specificationParameterIndex = 0; ConsumableListIterator required = new ConsumableListIterator<>(spec.getRequired()); @@ -263,8 +307,6 @@ // additional specifications -> error return null; } - - // success! return parsedParams; }