Add option to ignore C# attributes (annotations)

This commit is contained in:
Maikel Steneker
2022-05-16 16:42:01 +02:00
parent 9d23d79802
commit 7921e836b1
6 changed files with 441 additions and 16 deletions

View File

@ -147,7 +147,16 @@ public class GUI implements CPDListener {
@Override
public boolean canIgnoreAnnotations() {
return "java".equals(terseName);
if (terseName == null) {
return false;
}
switch (terseName) {
case "cs":
case "java":
return true;
default:
return false;
}
}
@Override

View File

@ -20,6 +20,7 @@ public class CsTokenizer extends AntlrTokenizer {
private boolean ignoreUsings = false;
private boolean ignoreLiteralSequences = false;
private boolean ignoreAttributes = false;
/**
* Sets the possible options for the C# tokenizer.
@ -27,19 +28,16 @@ public class CsTokenizer extends AntlrTokenizer {
* @param properties the properties
* @see #IGNORE_USINGS
* @see #OPTION_IGNORE_LITERAL_SEQUENCES
* @see #IGNORE_ANNOTATIONS
*/
public void setProperties(Properties properties) {
ignoreUsings = Boolean.parseBoolean(properties.getProperty(IGNORE_USINGS, Boolean.FALSE.toString()));
ignoreLiteralSequences = Boolean.parseBoolean(properties.getProperty(OPTION_IGNORE_LITERAL_SEQUENCES,
Boolean.FALSE.toString()));
ignoreUsings = getBooleanProperty(properties, IGNORE_USINGS);
ignoreLiteralSequences = getBooleanProperty(properties, OPTION_IGNORE_LITERAL_SEQUENCES);
ignoreAttributes = getBooleanProperty(properties, IGNORE_ANNOTATIONS);
}
public void setIgnoreUsings(boolean ignoreUsings) {
this.ignoreUsings = ignoreUsings;
}
public void setIgnoreLiteralSequences(boolean ignoreLiteralSequences) {
this.ignoreLiteralSequences = ignoreLiteralSequences;
private boolean getBooleanProperty(final Properties properties, final String property) {
return Boolean.parseBoolean(properties.getProperty(property, Boolean.FALSE.toString()));
}
@Override
@ -50,7 +48,7 @@ public class CsTokenizer extends AntlrTokenizer {
@Override
protected AntlrTokenFilter getTokenFilter(final AntlrTokenManager tokenManager) {
return new CsTokenFilter(tokenManager, ignoreUsings, ignoreLiteralSequences);
return new CsTokenFilter(tokenManager, ignoreUsings, ignoreLiteralSequences, ignoreAttributes);
}
/**
@ -69,15 +67,18 @@ public class CsTokenizer extends AntlrTokenizer {
private final boolean ignoreUsings;
private final boolean ignoreLiteralSequences;
private final boolean ignoreAttributes;
private boolean discardingUsings = false;
private boolean discardingNL = false;
private boolean isDiscardingAttribute = false;
private AntlrToken discardingLiteralsUntil = null;
private boolean discardCurrent = false;
CsTokenFilter(final AntlrTokenManager tokenManager, boolean ignoreUsings, boolean ignoreLiteralSequences) {
CsTokenFilter(final AntlrTokenManager tokenManager, boolean ignoreUsings, boolean ignoreLiteralSequences, boolean ignoreAttributes) {
super(tokenManager);
this.ignoreUsings = ignoreUsings;
this.ignoreLiteralSequences = ignoreLiteralSequences;
this.ignoreAttributes = ignoreAttributes;
}
@Override
@ -90,6 +91,7 @@ public class CsTokenizer extends AntlrTokenizer {
discardCurrent = false;
skipUsingDirectives(currentToken, remainingTokens);
skipLiteralSequences(currentToken, remainingTokens);
skipAttributes(currentToken);
}
private void skipUsingDirectives(final AntlrToken currentToken, final Iterable<AntlrToken> remainingTokens) {
@ -166,6 +168,25 @@ public class CsTokenizer extends AntlrTokenizer {
discardingNL = currentToken.getKind() == CSharpLexer.NL;
}
private void skipAttributes(final AntlrToken currentToken) {
if (ignoreAttributes) {
switch (currentToken.getKind()) {
case CSharpLexer.OPEN_BRACKET:
// Start of an attribute.
isDiscardingAttribute = true;
break;
case CSharpLexer.CLOSE_BRACKET:
// End of an attribute.
isDiscardingAttribute = false;
discardCurrent = true;
break;
default:
// Skip any other token.
break;
}
}
}
private void skipLiteralSequences(final AntlrToken currentToken, final Iterable<AntlrToken> remainingTokens) {
if (ignoreLiteralSequences) {
final int type = currentToken.getKind();
@ -221,7 +242,7 @@ public class CsTokenizer extends AntlrTokenizer {
@Override
protected boolean isLanguageSpecificDiscarding() {
return discardingUsings || discardingNL || isDiscardingLiterals() || discardCurrent;
return discardingUsings || discardingNL || isDiscardingAttribute || isDiscardingLiterals() || discardCurrent;
}
}
}

View File

@ -105,18 +105,33 @@ public class CsTokenizerTest extends CpdTextComparisonTest {
doTest("csharp7And8Additions");
}
@Test
public void testAttributesAreNotIgnored() {
doTest("attributes");
}
@Test
public void testAttributesAreIgnored() {
doTest("attributes", "_ignored", skipAttributes());
}
private Properties ignoreUsings() {
return properties(true, false);
return properties(true, false, false);
}
private Properties skipLiteralSequences() {
return properties(false, true);
return properties(false, true, false);
}
private Properties properties(boolean ignoreUsings, boolean ignoreLiteralSequences) {
private Properties skipAttributes() {
return properties(false, false, true);
}
private Properties properties(boolean ignoreUsings, boolean ignoreLiteralSequences, boolean ignoreAttributes) {
Properties properties = new Properties();
properties.setProperty(Tokenizer.IGNORE_USINGS, Boolean.toString(ignoreUsings));
properties.setProperty(Tokenizer.OPTION_IGNORE_LITERAL_SEQUENCES, Boolean.toString(ignoreLiteralSequences));
properties.setProperty(Tokenizer.IGNORE_ANNOTATIONS, Boolean.toString(ignoreAttributes));
return properties;
}
}

View File

@ -0,0 +1,42 @@
[Serializable]
public class SampleClass
{
// Objects of this type can be serialized.
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();
void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }
[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
// ...
}
[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]
using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]
// default: applies to method
[ValidatedContract]
int Method1() { return 0; }
// applies to method
[method: ValidatedContract]
int Method2() { return 0; }
// applies to parameter
int Method3([ValidatedContract] string contract) { return 0; }
// applies to return value
[return: ValidatedContract]
int Method4() { return 0; }

View File

@ -0,0 +1,229 @@
[Image] or [Truncated image[ Bcol Ecol
L1
[\[] 1 1
[Serializable] 2 13
[\]] 14 14
L2
[public] 1 6
[class] 8 12
[SampleClass] 14 24
L3
[{] 1 1
L5
[}] 1 1
L7
[\[] 1 1
[System] 2 7
[.] 8 8
[Runtime] 9 15
[.] 16 16
[InteropServices] 17 31
[.] 32 32
[DllImport] 33 41
[(] 42 42
["user32.dll"] 43 54
[)] 55 55
[\]] 56 56
L8
[extern] 1 6
[static] 8 13
[void] 15 18
[SampleMethod] 20 31
[(] 32 32
[)] 33 33
[;] 34 34
L10
[void] 1 4
[MethodA] 6 12
[(] 13 13
[\[] 14 14
[In] 15 16
[\]] 17 17
[\[] 18 18
[Out] 19 21
[\]] 22 22
[ref] 24 26
[double] 28 33
[x] 35 35
[)] 36 36
[{] 38 38
[}] 40 40
L11
[void] 1 4
[MethodB] 6 12
[(] 13 13
[\[] 14 14
[Out] 15 17
[\]] 18 18
[\[] 19 19
[In] 20 21
[\]] 22 22
[ref] 24 26
[double] 28 33
[x] 35 35
[)] 36 36
[{] 38 38
[}] 40 40
L12
[void] 1 4
[MethodC] 6 12
[(] 13 13
[\[] 14 14
[In] 15 16
[,] 17 17
[Out] 19 21
[\]] 22 22
[ref] 24 26
[double] 28 33
[x] 35 35
[)] 36 36
[{] 38 38
[}] 40 40
L14
[\[] 1 1
[Conditional] 2 12
[(] 13 13
["DEBUG"] 14 20
[)] 21 21
[,] 22 22
[Conditional] 24 34
[(] 35 35
["TEST1"] 36 42
[)] 43 43
[\]] 44 44
L15
[void] 1 4
[TraceMethod] 6 16
[(] 17 17
[)] 18 18
L16
[{] 1 1
L18
[}] 1 1
L20
[\[] 1 1
[DllImport] 2 10
[(] 11 11
["user32.dll"] 12 23
[)] 24 24
[\]] 25 25
L21
[\[] 1 1
[DllImport] 2 10
[(] 11 11
["user32.dll"] 12 23
[,] 24 24
[SetLastError] 26 37
[=] 38 38
[false] 39 43
[,] 44 44
[ExactSpelling] 46 58
[=] 59 59
[false] 60 64
[)] 65 65
[\]] 66 66
L22
[\[] 1 1
[DllImport] 2 10
[(] 11 11
["user32.dll"] 12 23
[,] 24 24
[ExactSpelling] 26 38
[=] 39 39
[false] 40 44
[,] 45 45
[SetLastError] 47 58
[=] 59 59
[false] 60 64
[)] 65 65
[\]] 66 66
L24
[using] 1 5
[System] 7 12
[;] 13 13
L25
[using] 1 5
[System] 7 12
[.] 13 13
[Reflection] 14 23
[;] 24 24
L26
[\[] 1 1
[assembly] 2 9
[:] 10 10
[AssemblyTitleAttribute] 12 33
[(] 34 34
["Production assembly 4"] 35 57
[)] 58 58
[\]] 59 59
L27
[\[] 1 1
[module] 2 7
[:] 8 8
[CLSCompliant] 10 21
[(] 22 22
[true] 23 26
[)] 27 27
[\]] 28 28
L30
[\[] 1 1
[ValidatedContract] 2 18
[\]] 19 19
L31
[int] 1 3
[Method1] 5 11
[(] 12 12
[)] 13 13
[{] 15 15
[return] 17 22
[0] 24 24
[;] 25 25
[}] 27 27
L34
[\[] 1 1
[method] 2 7
[:] 8 8
[ValidatedContract] 10 26
[\]] 27 27
L35
[int] 1 3
[Method2] 5 11
[(] 12 12
[)] 13 13
[{] 15 15
[return] 17 22
[0] 24 24
[;] 25 25
[}] 27 27
L38
[int] 1 3
[Method3] 5 11
[(] 12 12
[\[] 13 13
[ValidatedContract] 14 30
[\]] 31 31
[string] 33 38
[contract] 40 47
[)] 48 48
[{] 50 50
[return] 52 57
[0] 59 59
[;] 60 60
[}] 62 62
L41
[\[] 1 1
[return] 2 7
[:] 8 8
[ValidatedContract] 10 26
[\]] 27 27
L42
[int] 1 3
[Method4] 5 11
[(] 12 12
[)] 13 13
[{] 15 15
[return] 17 22
[0] 24 24
[;] 25 25
[}] 27 27
EOF

View File

@ -0,0 +1,109 @@
[Image] or [Truncated image[ Bcol Ecol
L2
[public] 1 6
[class] 8 12
[SampleClass] 14 24
L3
[{] 1 1
L5
[}] 1 1
L8
[extern] 1 6
[static] 8 13
[void] 15 18
[SampleMethod] 20 31
[(] 32 32
[)] 33 33
[;] 34 34
L10
[void] 1 4
[MethodA] 6 12
[(] 13 13
[ref] 24 26
[double] 28 33
[x] 35 35
[)] 36 36
[{] 38 38
[}] 40 40
L11
[void] 1 4
[MethodB] 6 12
[(] 13 13
[ref] 24 26
[double] 28 33
[x] 35 35
[)] 36 36
[{] 38 38
[}] 40 40
L12
[void] 1 4
[MethodC] 6 12
[(] 13 13
[ref] 24 26
[double] 28 33
[x] 35 35
[)] 36 36
[{] 38 38
[}] 40 40
L15
[void] 1 4
[TraceMethod] 6 16
[(] 17 17
[)] 18 18
L16
[{] 1 1
L18
[}] 1 1
L24
[using] 1 5
[System] 7 12
[;] 13 13
L25
[using] 1 5
[System] 7 12
[.] 13 13
[Reflection] 14 23
[;] 24 24
L31
[int] 1 3
[Method1] 5 11
[(] 12 12
[)] 13 13
[{] 15 15
[return] 17 22
[0] 24 24
[;] 25 25
[}] 27 27
L35
[int] 1 3
[Method2] 5 11
[(] 12 12
[)] 13 13
[{] 15 15
[return] 17 22
[0] 24 24
[;] 25 25
[}] 27 27
L38
[int] 1 3
[Method3] 5 11
[(] 12 12
[string] 33 38
[contract] 40 47
[)] 48 48
[{] 50 50
[return] 52 57
[0] 59 59
[;] 60 60
[}] 62 62
L42
[int] 1 3
[Method4] 5 11
[(] 12 12
[)] 13 13
[{] 15 15
[return] 17 22
[0] 24 24
[;] 25 25
[}] 27 27
EOF