use of org.gradle.language.nativeplatform.internal.Expression in project gradle by gradle.
the class DefaultSourceIncludesResolver method resolveTokenConcatenationToTokens.
private Collection<Expression> resolveTokenConcatenationToTokens(MacroLookup visibleMacros, Expression expression, ExpressionVisitor visitor, TokenLookup tokenLookup) {
Expression left = expression.getArguments().get(0);
Expression right = expression.getArguments().get(1);
Collection<Expression> leftValues = resolveExpressionToTokens(visibleMacros, left, visitor, tokenLookup);
Collection<Expression> rightValues = resolveExpressionToTokens(visibleMacros, right, visitor, tokenLookup);
if (leftValues.isEmpty() || rightValues.isEmpty()) {
return Collections.emptyList();
}
List<Expression> expressions = new ArrayList<Expression>(leftValues.size() * rightValues.size());
for (Expression leftValue : leftValues) {
if (leftValue.getType() != IncludeType.IDENTIFIER) {
if (rightValues.size() == 1) {
Expression rightValue = rightValues.iterator().next();
if (rightValue.getType() == IncludeType.EXPRESSIONS && rightValue.getArguments().isEmpty()) {
// Empty RHS
expressions.add(leftValue);
continue;
}
}
// Not supported for now
visitor.visitUnresolved();
continue;
}
String leftString = leftValue.getValue();
for (Expression rightValue : rightValues) {
// Handle just empty string, single identifier or '(' params? ')', should handle more by parsing the tokens into an expression
if (rightValue.getType() == IncludeType.IDENTIFIER) {
expressions.add(new SimpleExpression(leftString + rightValue.getValue(), IncludeType.IDENTIFIER));
continue;
}
if (rightValue.getType() == IncludeType.ARGS_LIST) {
expressions.add(new ComplexExpression(IncludeType.MACRO_FUNCTION, leftString, rightValue.getArguments()));
continue;
}
if (rightValue.getType() == IncludeType.EXPRESSIONS && rightValue.getArguments().isEmpty()) {
expressions.add(new SimpleExpression(leftString, IncludeType.IDENTIFIER));
continue;
}
visitor.visitUnresolved();
}
}
return expressions;
}
use of org.gradle.language.nativeplatform.internal.Expression in project gradle by gradle.
the class DefaultSourceIncludesResolver method resolveExpressionSequence.
private void resolveExpressionSequence(MacroLookup visibleMacros, Expression expression, ExpressionVisitor visitor, TokenLookup tokenLookup) {
List<Expression> expressions = expression.getArguments();
// Only <function-call>+ <args-list> supported
if (expressions.size() < 2) {
visitor.visitUnresolved();
return;
}
Expression argListExpression = expressions.get(expressions.size() - 1);
List<Expression> headExpressions = expressions.subList(0, expressions.size() - 1);
Collection<Expression> args = resolveExpressionToTokens(visibleMacros, argListExpression, visitor, tokenLookup);
for (Expression value : args) {
resolveExpressionSequenceForArgs(visibleMacros, headExpressions, value, visitor, tokenLookup);
}
}
use of org.gradle.language.nativeplatform.internal.Expression in project gradle by gradle.
the class RegexBackedCSourceParser method parseMacroFunctionDirectiveBody.
/**
* Parse a "function-like" macro directive body. Consumes all input.
*/
private void parseMacroFunctionDirectiveBody(Buffer buffer, String macroName, Collection<MacroFunction> macroFunctions) {
buffer.consumeWhitespace();
List<String> paramNames = new ArrayList<String>();
consumeParameterList(buffer, paramNames);
if (!buffer.consume(')')) {
// Badly form args list
return;
}
Expression expression = parseDirectiveBodyExpression(buffer);
if (expression.getType() == IncludeType.QUOTED || expression.getType() == IncludeType.SYSTEM) {
// Returns a fixed value expression
macroFunctions.add(new ReturnFixedValueMacroFunction(macroName, paramNames.size(), expression.getType(), expression.getValue(), Collections.<Expression>emptyList()));
return;
}
if (expression.getType() == IncludeType.IDENTIFIER) {
for (int i = 0; i < paramNames.size(); i++) {
String name = paramNames.get(i);
if (name.equals(expression.getValue())) {
// Returns a parameter
macroFunctions.add(new ReturnParameterMacroFunction(macroName, paramNames.size(), i));
return;
}
}
// References some fixed value expression, return it after macro expanding
macroFunctions.add(new ReturnFixedValueMacroFunction(macroName, paramNames.size(), IncludeType.MACRO, expression.getValue(), Collections.<Expression>emptyList()));
return;
}
if (expression.getType() != IncludeType.OTHER) {
// Look for parameter substitutions
if (paramNames.isEmpty() || expression.getArguments().isEmpty()) {
// When this function has no parameters, we don't need to substitute parameters, so return the expression after macro expanding it
// Also handle calling a zero args function, as we also don't need to substitute parameters
expression = expression.asMacroExpansion();
macroFunctions.add(new ReturnFixedValueMacroFunction(macroName, paramNames.size(), expression.getType(), expression.getValue(), expression.getArguments()));
return;
}
List<Integer> argsMap = new ArrayList<Integer>(expression.getArguments().size());
boolean usesArgs = mapArgs(paramNames, expression, argsMap);
if (!usesArgs) {
// Don't need to do parameter substitution, return the value of the expression after macro expanding it
expression = expression.asMacroExpansion();
macroFunctions.add(new ReturnFixedValueMacroFunction(macroName, paramNames.size(), expression.getType(), expression.getValue(), expression.getArguments()));
} else {
// Need to do parameter substitution, return the value of the expression after parameter substitutions and macro expanding the result
int[] argsMapArray = new int[argsMap.size()];
for (int i = 0; i < argsMap.size(); i++) {
argsMapArray[i] = argsMap.get(i);
}
expression = expression.asMacroExpansion();
macroFunctions.add(new ArgsMappingMacroFunction(macroName, paramNames.size(), argsMapArray, expression.getType(), expression.getValue(), expression.getArguments()));
}
return;
}
// Not resolvable. Discard the body when the expression is not resolvable
macroFunctions.add(new UnresolveableMacroFunction(macroName, paramNames.size()));
}
use of org.gradle.language.nativeplatform.internal.Expression in project gradle by gradle.
the class RegexBackedCSourceParser method mapArgs.
private boolean mapArgs(List<String> paramNames, Expression expression, List<Integer> argsMap) {
boolean usesParameters = false;
for (int i = 0; i < expression.getArguments().size(); i++) {
Expression argument = expression.getArguments().get(i);
if (argument.getType() == IncludeType.IDENTIFIER) {
boolean matches = false;
for (int j = 0; j < paramNames.size(); j++) {
String paramName = paramNames.get(j);
if (argument.getValue().equals(paramName)) {
argsMap.add(j);
usesParameters = true;
matches = true;
break;
}
}
if (matches) {
continue;
}
}
if (argument.getArguments().isEmpty()) {
// Don't map
argsMap.add(ArgsMappingMacroFunction.KEEP);
continue;
}
List<Integer> nestedMap = new ArrayList<Integer>(argument.getArguments().size());
boolean argUsesParameters = mapArgs(paramNames, argument, nestedMap);
if (argUsesParameters) {
argsMap.add(ArgsMappingMacroFunction.REPLACE_ARGS);
argsMap.addAll(nestedMap);
} else {
argsMap.add(ArgsMappingMacroFunction.KEEP);
}
usesParameters |= argUsesParameters;
}
return usesParameters;
}
use of org.gradle.language.nativeplatform.internal.Expression in project gradle by gradle.
the class RegexBackedCSourceParser method parseIncludeOrImportDirectiveBody.
/**
* Parses an #include/#import directive body. Consumes all input.
*/
private void parseIncludeOrImportDirectiveBody(Buffer buffer, boolean isImport, Collection<Include> includes) {
if (!buffer.hasAny()) {
// No include expression, ignore
return;
}
if (buffer.hasIdentifierChar()) {
// An identifier with no separator, so this is not an #include or #import directive, it is some other directive
return;
}
Expression expression = parseDirectiveBodyExpression(buffer);
if (expression.getType() == IncludeType.TOKEN_CONCATENATION || expression.getType() == IncludeType.ARGS_LIST || expression.getType() == IncludeType.EXPRESSIONS) {
// Token concatenation is only allowed inside a #define body
// Arbitrary tokens won't resolve to an include path
// Treat both these cases as an unresolvable include directive
expression = new SimpleExpression(expression.getAsSourceText(), IncludeType.OTHER);
}
expression = expression.asMacroExpansion();
if (expression.getType() != IncludeType.OTHER || !expression.getValue().isEmpty()) {
// Either a resolvable expression or a non-empty unresolvable expression, collect. Ignore includes with no value
includes.add(IncludeWithSimpleExpression.create(expression, isImport));
}
}
Aggregations