Skip to content

Commit b523887

Browse files
cirrasfourls
authored andcommitted
Implement support for assembly attributes
1 parent b618c26 commit b523887

File tree

9 files changed

+152
-7
lines changed

9 files changed

+152
-7
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Support for multiline string literals within compiler directives.
1313
- Support for the `TEXTBLOCK` directive.
1414
- Support for named arguments.
15+
- Support for `assembly` attributes.
1516
- **API:** `CompilerDirectiveParser` can now return a new `TextBlockDirective` type.
1617
- **API:** `CheckVerifier::withCompilerVersion` method.
1718
- **API:** `CheckVerifier::withToolchain` method.
1819
- **API:** `DelphiTokenType.ARGUMENT` token type.
20+
- **API:** `DelphiTokenType.ASSEMBLY` token type.
1921
- **API:** `ArgumentNode` node type.
2022
- **API:** `ArgumentListNode::getArgumentNodes` method.
23+
- **API:** `AttributeNode::isAssembly` method.
2124

2225
### Changed
2326

delphi-frontend/src/main/antlr3/au/com/integradev/delphi/antlr/Delphi.g

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ library : libraryHead usesFileClause? programBody '.'
265265
;
266266
libraryHead : LIBRARY<LibraryDeclarationNodeImpl>^ qualifiedNameDeclaration (portabilityDirective!)* ';'!
267267
;
268-
package_ : packageHead requiresClause? containsClause END '.'
268+
package_ : packageHead requiresClause? containsClause? attributeList* END '.'
269269
;
270270
packageHead : PACKAGE<PackageDeclarationNodeImpl>^ qualifiedNameDeclaration ';'!
271271
;
@@ -327,12 +327,14 @@ declSection : labelDeclSection
327327
| varSection
328328
| routineImplementation
329329
| exportsSection
330+
| attributeList
330331
;
331332
interfaceDecl : constSection
332333
| typeSection
333334
| varSection
334335
| exportsSection
335336
| routineInterface
337+
| attributeList
336338
;
337339
labelDeclSection : LABEL (label (','!)?)+ ';'
338340
;
@@ -687,8 +689,8 @@ attributeList : attributeGroup+
687689
attributeGroup : lbrack (attribute ','?)+ rbrack
688690
-> ^(TkAttributeGroup<AttributeGroupNodeImpl> attribute+)
689691
;
690-
attribute : nameReference argumentList?
691-
-> ^(TkAttribute<AttributeNodeImpl> nameReference argumentList?)
692+
attribute : (ASSEMBLY ':')? nameReference argumentList? (':' nameReference argumentList?)*
693+
-> ^(TkAttribute<AttributeNodeImpl> ASSEMBLY? nameReference argumentList? (':' nameReference argumentList?)*)
692694
;
693695

694696
//----------------------------------------------------------------------------
@@ -979,15 +981,15 @@ dispIDDirective : DISPID expression
979981
ident : TkIdentifier
980982
| keywordsUsedAsNames -> ^({changeTokenType(TkIdentifier)})
981983
;
982-
keywordsUsedAsNames : (ABSOLUTE | ABSTRACT | ALIGN | ASSEMBLER | AT | AUTOMATED | CDECL)
984+
keywordsUsedAsNames : (ABSOLUTE | ABSTRACT | ALIGN | ASSEMBLER | ASSEMBLY | AT | AUTOMATED | CDECL)
983985
| (CONTAINS | DEFAULT | DELAYED | DEPRECATED | DISPID | DYNAMIC | EXPERIMENTAL | EXPORT)
984986
| (EXTERNAL | FAR | FINAL | FORWARD | HELPER | IMPLEMENTS | INDEX | LOCAL | MESSAGE | NAME)
985987
| (NEAR | NODEFAULT | ON | OPERATOR | OUT | OVERLOAD | OVERRIDE | PACKAGE | PASCAL | PLATFORM)
986988
| (PRIVATE | PROTECTED | PUBLIC | PUBLISHED | READ | READONLY | REFERENCE | REGISTER | REINTRODUCE)
987989
| (REQUIRES | RESIDENT | SAFECALL | SEALED | STATIC | STDCALL | STORED | STRICT | UNSAFE)
988990
| (VARARGS | VIRTUAL | WRITE | WRITEONLY)
989991
;
990-
keywords : (ABSOLUTE | ABSTRACT | AND | ALIGN | ARRAY | AS | ASM | ASSEMBLER)
992+
keywords : (ABSOLUTE | ABSTRACT | AND | ALIGN | ARRAY | AS | ASM | ASSEMBLER | ASSEMBLY)
991993
| (AT | AUTOMATED | BEGIN | CASE | CDECL | CLASS | CONST | CONSTRUCTOR | CONTAINS| DEFAULT)
992994
| (DELAYED | DEPRECATED | DESTRUCTOR | DISPID | DISPINTERFACE | DIV | DO | DOWNTO | DYNAMIC)
993995
| (ELSE | END | EXCEPT | EXPERIMENTAL | EXPORT | EXPORTS | EXTERNAL | FAR | FILE | FINAL)
@@ -1052,6 +1054,7 @@ ARRAY : A R R A Y ;
10521054
AS : A S ;
10531055
ASM : A S M { asmMode = true; } ;
10541056
ASSEMBLER : A S S E M B L E R ;
1057+
ASSEMBLY : A S S E M B L Y ;
10551058
AT : A T ;
10561059
AUTOMATED : A U T O M A T E D ;
10571060
BEGIN : B E G I N ;

delphi-frontend/src/main/java/au/com/integradev/delphi/antlr/ast/node/AttributeNodeImpl.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
import org.antlr.runtime.Token;
2424
import org.sonar.plugins.communitydelphi.api.ast.ArgumentListNode;
2525
import org.sonar.plugins.communitydelphi.api.ast.AttributeNode;
26+
import org.sonar.plugins.communitydelphi.api.ast.DelphiNode;
2627
import org.sonar.plugins.communitydelphi.api.ast.NameReferenceNode;
2728
import org.sonar.plugins.communitydelphi.api.symbol.NameOccurrence;
29+
import org.sonar.plugins.communitydelphi.api.token.DelphiTokenType;
2830

2931
public final class AttributeNodeImpl extends DelphiNodeImpl implements AttributeNode {
3032
public AttributeNodeImpl(Token token) {
@@ -35,9 +37,14 @@ public AttributeNodeImpl(int tokenType) {
3537
super(tokenType);
3638
}
3739

40+
@Override
41+
public boolean isAssembly() {
42+
return getChild(0).getTokenType() == DelphiTokenType.ASSEMBLY;
43+
}
44+
3845
@Override
3946
public NameReferenceNode getNameReference() {
40-
return (NameReferenceNode) getChild(0);
47+
return (NameReferenceNode) getChild(isAssembly() ? 1 : 0);
4148
}
4249

4350
@Override
@@ -56,7 +63,11 @@ public NameOccurrence getConstructorNameOccurrence() {
5663

5764
@Override
5865
public ArgumentListNode getArgumentList() {
59-
return (ArgumentListNode) getChild(1);
66+
DelphiNode node = getChild(isAssembly() ? 2 : 1);
67+
if (node instanceof ArgumentListNode) {
68+
return (ArgumentListNode) node;
69+
}
70+
return null;
6071
}
6172

6273
@Override

delphi-frontend/src/main/java/org/sonar/plugins/communitydelphi/api/ast/AttributeNode.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@
2222
import org.sonar.plugins.communitydelphi.api.symbol.NameOccurrence;
2323

2424
public interface AttributeNode extends DelphiNode {
25+
26+
/**
27+
* Returns whether this is an {@code assembly} attribute.
28+
*
29+
* @return true if this is an {@code assembly} attribute
30+
* @see <a href="https://learn.microsoft.com/en-us/dotnet/standard/assembly/set-attributes">Set
31+
* assembly attributes in code</a>
32+
*/
33+
boolean isAssembly();
34+
2535
NameReferenceNode getNameReference();
2636

2737
@Nullable

delphi-frontend/src/test/java/au/com/integradev/delphi/antlr/GrammarTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,26 @@ void testEmptyBeginStatement() {
8585
assertParsed("EmptyProcs.pas");
8686
}
8787

88+
@Test
89+
void testAttributesUnit() {
90+
assertParsed("AttributesUnit.pas");
91+
}
92+
93+
@Test
94+
void testAttributesProgram() {
95+
assertParsed("AttributesProgram.dpr");
96+
}
97+
98+
@Test
99+
void testAttributesLibrary() {
100+
assertParsed("AttributesLibrary.dpr");
101+
}
102+
103+
@Test
104+
void testAttributesPackage() {
105+
assertParsed("AttributesPackage.dpk");
106+
}
107+
88108
@Test
89109
void testParseMultipleAttributes() {
90110
assertParsed("MultipleAttributes.pas");
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
library AttributesLibrary;
2+
3+
[xyz]
4+
[assembly: xyz]
5+
6+
type
7+
[xyz]
8+
[assembly: xyz]
9+
[xyz]
10+
TMyType = Integer;
11+
12+
[xyz]
13+
procedure Foo;
14+
[xyz]
15+
var
16+
[xyz]
17+
Bar: Integer;
18+
begin
19+
20+
end;
21+
22+
[xyz]
23+
[assembly: xyz]
24+
25+
begin
26+
27+
end.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package AttributesPackage;
2+
3+
requires
4+
Foo,
5+
Bar;
6+
7+
contains
8+
AmpersandNumericLiterals in 'AmpersandNumericLiterals.pas';
9+
10+
[assembly: xyz]
11+
12+
end.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
program AttributesProgram;
2+
3+
[xyz]
4+
[assembly: xyz]
5+
6+
type
7+
[xyz]
8+
[assembly: xyz]
9+
[xyz]
10+
TMyType = Integer;
11+
12+
[xyz]
13+
procedure Foo;
14+
[xyz]
15+
var
16+
[xyz]
17+
Bar: Integer;
18+
begin
19+
20+
end;
21+
22+
[xyz]
23+
[assembly: xyz]
24+
25+
begin
26+
27+
end.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
unit AttributesUnit;
2+
3+
interface
4+
5+
[xyz]
6+
[assembly: xyz]
7+
8+
type
9+
[xyz]
10+
[assembly: xyz]
11+
[xyz]
12+
TMyType = Integer;
13+
14+
[xyz]
15+
[assembly: xyz]
16+
17+
implementation
18+
19+
[xyz]
20+
procedure Foo;
21+
[xyz]
22+
var
23+
[xyz]
24+
Bar: Integer;
25+
begin
26+
27+
end;
28+
29+
[xyz]
30+
[assembly: xyz]
31+
32+
end.

0 commit comments

Comments
 (0)