Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -126,20 +126,25 @@ private String parseTopLevel(boolean stopAtQuote, boolean parseMetadata) {
}

private Optional<String> parseItem() {
if (nextChar() != '@') return Optional.empty();
if (nextChar() != '(') return Optional.empty();
if (nextChar() != '@' || nextChar() != '(') {
return Optional.empty();
}

skipWhitespace();
Optional<String> ident = parseIdentifier();
if (ident.isEmpty()) return Optional.empty();
if (ident.isEmpty()) {
return Optional.empty();
}
skipWhitespace();

Function<MSBuildItem, String> transform = MSBuildItem::getIdentity;
String separator = ";";

if (peekChar() == '-') {
var maybeTransform = parseItemTransform();
if (maybeTransform.isEmpty()) return Optional.empty();
if (maybeTransform.isEmpty()) {
return Optional.empty();
}
transform = maybeTransform.get();

skipWhitespace();
Expand All @@ -154,12 +159,16 @@ private Optional<String> parseItem() {
nextChar();
skipWhitespace();
var maybeSeparator = parseSimpleString();
if (maybeSeparator.isEmpty()) return Optional.empty();
if (maybeSeparator.isEmpty()) {
return Optional.empty();
}
separator = maybeSeparator.get();
skipWhitespace();
}

if (nextChar() != ')') return Optional.empty();
if (nextChar() != ')') {
return Optional.empty();
}

return Optional.of(concatItems(ident.get(), transform, separator));
}
Expand All @@ -170,8 +179,9 @@ private String concatItems(
}

private Optional<Function<MSBuildItem, String>> parseItemTransform() {
if (nextChar() != '-') return Optional.empty();
if (nextChar() != '>') return Optional.empty();
if (nextChar() != '-' || nextChar() != '>') {
return Optional.empty();
}

return parseItemTransformExpression();
}
Expand All @@ -182,9 +192,15 @@ private Optional<Function<MSBuildItem, String>> parseItemTransformExpression() {
return Optional.empty();
}

if (nextChar() != '\'') return Optional.empty();
if (nextChar() != '\'') {
return Optional.empty();
}

String expression = parseTopLevel(true, false);
if (nextChar() != '\'') return Optional.empty();

if (nextChar() != '\'') {
return Optional.empty();
}

return Optional.of(item -> expandMetadataValues(item, expression));
}
Expand All @@ -196,8 +212,10 @@ private String expandMetadataValues(MSBuildItem item, String expression) {
}

private Optional<String> parseProperty() {
if (nextChar() != '$') return Optional.empty();
if (nextChar() != '(') return Optional.empty();
if (nextChar() != '$' || nextChar() != '(') {
return Optional.empty();
}

if (peekChar() == '[') {
unsupportedFeature("static property function");
return Optional.empty();
Expand All @@ -215,32 +233,39 @@ private Optional<String> parseProperty() {
}

discard = skipWhitespace() || discard;
if (nextChar() != ')') return Optional.empty();
if (nextChar() != ')') {
return Optional.empty();
}

if (discard) {
// Whitespace is significant inside property expressions, but it's impossible to
// define properties with spaces, so expressions with spaces always evaluate to "".
// Whitespace is significant inside property expressions, but it's impossible to define
// properties with spaces, so expressions with spaces always evaluate to "".
return Optional.of("");
} else {
return Optional.of(state.getProperty(ident.get()));
}
}

private Optional<String> parseMetadata() {
if (nextChar() != '%') return Optional.empty();
if (nextChar() != '(') return Optional.empty();
if (nextChar() != '%' || nextChar() != '(') {
return Optional.empty();
}

var discard = skipWhitespace();
Optional<String> ident = parseIdentifier();
if (ident.isEmpty()) return Optional.empty();
if (ident.isEmpty()) {
return Optional.empty();
}

discard = skipWhitespace() || discard;

if (nextChar() != ')') return Optional.empty();
if (nextChar() != ')') {
return Optional.empty();
}

if (discard) {
// Whitespace is significant inside metadata expressions, but it's impossible to
// define metadata with spaces, so expressions with spaces always evaluate to "".
// Whitespace is significant inside metadata expressions, but it's impossible to define
// metadata with spaces, so expressions with spaces always evaluate to "".
return Optional.of("");
} else if (metadataProvider != null) {
return Optional.of(metadataProvider.apply(ident.get()));
Expand All @@ -258,7 +283,9 @@ private static boolean isSimpleStringChar(char character) {
}

private Optional<String> parseSimpleString() {
if (nextChar() != '\'') return Optional.empty();
if (nextChar() != '\'') {
return Optional.empty();
}

StringBuilder builder = new StringBuilder();

Expand All @@ -271,7 +298,9 @@ private Optional<String> parseSimpleString() {
}

private Optional<String> parseIdentifier() {
if (!isSimpleStringStart(peekChar())) return Optional.empty();
if (!isSimpleStringStart(peekChar())) {
return Optional.empty();
}

StringBuilder builder = new StringBuilder();

Expand All @@ -295,10 +324,9 @@ private boolean skipWhitespace() {

private void unsupportedFeature(String feature) {
// We don't know the relative importance of this expression - it could be an expression that
// SonarDelphi
// never needs to read. Making this a warning despite having a well-defined behaviour for when
// an unsupported
// feature is encountered (to interpret it literally) would probably be overkill.
// SonarDelphi never needs to read. Making this a warning despite having a well-defined
// behaviour for when an unsupported feature is encountered (to interpret it literally) would
// probably be overkill.
LOG.debug("Unsupported MSBuild feature '{}' ignored in expression: {}", feature, text);
}
}