Skip to content

Commit

Permalink
Implement better support for ResourceDirective
Browse files Browse the repository at this point in the history
  • Loading branch information
Cirras authored and fourls committed Jan 28, 2024
1 parent b573b54 commit 919566b
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Support for the `LLVM` symbol, which is defined on LLVM-based toolchains from Delphi 12 onward.
- Support for the `IOSSIMULATOR` symbol, which is defined on the `DCCIOSSIMARM64` toolchain.
- **API:** `CompilerDirectiveParser` now returns a new `ResourceDirective` type when parsing
[resource directives](https://docwiki.embarcadero.com/RADStudio/en/Resource_file_(Delphi)).

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@
import au.com.integradev.delphi.preprocessor.directive.expression.ExpressionLexer.ExpressionLexerError;
import au.com.integradev.delphi.preprocessor.directive.expression.ExpressionParser;
import au.com.integradev.delphi.preprocessor.directive.expression.ExpressionParser.ExpressionParserError;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.sonar.plugins.communitydelphi.api.directive.CompilerDirective;
import org.sonar.plugins.communitydelphi.api.directive.CompilerDirectiveParser;
import org.sonar.plugins.communitydelphi.api.directive.ConditionalDirective.ConditionalKind;
import org.sonar.plugins.communitydelphi.api.directive.ParameterDirective.ParameterKind;
import org.sonar.plugins.communitydelphi.api.directive.ResourceDirective;
import org.sonar.plugins.communitydelphi.api.directive.SwitchDirective.SwitchKind;
import org.sonar.plugins.communitydelphi.api.directive.WarnDirective;
import org.sonar.plugins.communitydelphi.api.directive.WarnDirective.WarnParameterValue;
Expand Down Expand Up @@ -113,6 +117,8 @@ private CompilerDirective createDirective(String name) {
return new UndefineDirectiveImpl(token, readDirectiveParameter());
case INCLUDE:
return new IncludeDirectiveImpl(token, readDirectiveParameter());
case RESOURCE:
return createResourceDirective();
case WARN:
return createWarnDirective();
default:
Expand Down Expand Up @@ -159,6 +165,31 @@ private static boolean isMinEnumSize(SwitchKind switchKind) {
|| switchKind == SwitchKind.MINENUMSIZE4;
}

private ResourceDirective createResourceDirective() {
String resourceFile = readDirectiveParameter();
String resourceScriptFile = null;
List<String> predicates = new ArrayList<>();

char character = currentChar();
while (Character.isWhitespace(character)) {
character = nextChar();
}

if (character == '\'') {
resourceScriptFile = StringUtils.stripToNull(readDirectiveParameter());
} else {
while (true) {
String predicate = StringUtils.stripToNull(readDirectiveParameter());
if (predicate == null) {
break;
}
predicates.add(predicate);
}
}

return new ResourceDirectiveImpl(token, resourceFile, resourceScriptFile, predicates);
}

private WarnDirective createWarnDirective() {
String identifier = readDirectiveParameter();
String parameter = readDirectiveParameter();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Sonar Delphi Plugin
* Copyright (C) 2024 Integrated Application Development
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package au.com.integradev.delphi.preprocessor.directive;

import java.util.List;
import javax.annotation.Nullable;
import org.sonar.plugins.communitydelphi.api.directive.ResourceDirective;
import org.sonar.plugins.communitydelphi.api.token.DelphiToken;

class ResourceDirectiveImpl extends ParameterDirectiveImpl implements ResourceDirective {
private final String resourceFile;
private final String resourceScriptFile;
private final List<String> predicates;

ResourceDirectiveImpl(
DelphiToken token,
String resourceFile,
@Nullable String resourceScriptFile,
List<String> predicates) {
super(token, ParameterKind.RESOURCE);
this.resourceFile = resourceFile;
this.resourceScriptFile = resourceScriptFile;
this.predicates = predicates;
}

@Override
public String getResourceFile() {
return resourceFile;
}

@Nullable
@Override
public String getResourceScriptFile() {
return resourceScriptFile;
}

@Override
public List<String> getPredicates() {
return predicates;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Sonar Delphi Plugin
* Copyright (C) 2024 Integrated Application Development
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.communitydelphi.api.directive;

import java.util.List;
import javax.annotation.Nullable;

public interface ResourceDirective extends CompilerDirective {
String getResourceFile();

@Nullable
String getResourceScriptFile();

List<String> getPredicates();
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.sonar.plugins.communitydelphi.api.directive.IncludeDirective;
import org.sonar.plugins.communitydelphi.api.directive.ParameterDirective;
import org.sonar.plugins.communitydelphi.api.directive.ParameterDirective.ParameterKind;
import org.sonar.plugins.communitydelphi.api.directive.ResourceDirective;
import org.sonar.plugins.communitydelphi.api.directive.SwitchDirective;
import org.sonar.plugins.communitydelphi.api.directive.SwitchDirective.SwitchKind;
import org.sonar.plugins.communitydelphi.api.directive.UndefineDirective;
Expand All @@ -62,6 +63,31 @@ void testCreateIncludeDirective() {
assertThat(directive).isInstanceOf(IncludeDirective.class);
}

@Test
void testCreateResourceDirective() {
CompilerDirective directive = parse("{$RESOURCE file.res}");
assertThat(directive).isInstanceOf(ResourceDirective.class);
assertThat(((ResourceDirective) directive).getResourceFile()).isEqualTo("file.res");
assertThat(((ResourceDirective) directive).getResourceScriptFile()).isNull();

directive = parse("{$R 'file.res' 'script.rc'}");
assertThat(directive).isInstanceOf(ResourceDirective.class);
assertThat(((ResourceDirective) directive).getResourceFile()).isEqualTo("file.res");
assertThat(((ResourceDirective) directive).getResourceScriptFile()).isEqualTo("script.rc");

directive = parse("{$R 'file.res' foo}");
assertThat(directive).isInstanceOf(ResourceDirective.class);
assertThat(((ResourceDirective) directive).getResourceFile()).isEqualTo("file.res");
assertThat(((ResourceDirective) directive).getResourceScriptFile()).isNull();
assertThat(((ResourceDirective) directive).getPredicates()).containsExactly("foo");

directive = parse("{$R 'file.res' foo bar}");
assertThat(directive).isInstanceOf(ResourceDirective.class);
assertThat(((ResourceDirective) directive).getResourceFile()).isEqualTo("file.res");
assertThat(((ResourceDirective) directive).getResourceScriptFile()).isNull();
assertThat(((ResourceDirective) directive).getPredicates()).containsExactly("foo", "bar");
}

@Test
void testCreateIfDirective() {
CompilerDirective directive = parse("{$if True}");
Expand Down

0 comments on commit 919566b

Please sign in to comment.