diff --git a/antlr4-wrapper.xml b/antlr4-wrapper.xml new file mode 100644 index 0000000000..61f9c5fddf --- /dev/null +++ b/antlr4-wrapper.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_config.yml b/docs/_config.yml index 77b485279f..1bfd57e8fd 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,10 +1,10 @@ repository: pmd/pmd pmd: - version: 6.25.0-SNAPSHOT + version: 7.0.0-SNAPSHOT previous_version: 6.24.0 - date: ??-June-2020 - release_type: minor + date: ??-2020 + release_type: major # release types: major, minor, bugfix diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 439fa25e96..2bd5c4f803 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -433,6 +433,9 @@ entries: - title: What does 'PMD' mean? url: /pmd_projectdocs_trivia_meaning.html output: web, pdf + - title: Logo + url: /pmd_projectdocs_logo.html + output: web, pdf - title: FAQ url: /pmd_projectdocs_faq.html output: web, pdf diff --git a/docs/images/logo/PMD.png b/docs/images/logo/PMD.png new file mode 100644 index 0000000000..48d247aea5 Binary files /dev/null and b/docs/images/logo/PMD.png differ diff --git a/docs/images/logo/PMD.svg b/docs/images/logo/PMD.svg new file mode 100644 index 0000000000..fb27428988 --- /dev/null +++ b/docs/images/logo/PMD.svg @@ -0,0 +1,105 @@ + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/images/logo/favicon.ico b/docs/images/logo/favicon.ico new file mode 100644 index 0000000000..bd9e18f2a0 Binary files /dev/null and b/docs/images/logo/favicon.ico differ diff --git a/docs/images/logo/pmd-logo-300px.png b/docs/images/logo/pmd-logo-300px.png new file mode 100644 index 0000000000..e8f2112b3b Binary files /dev/null and b/docs/images/logo/pmd-logo-300px.png differ diff --git a/docs/images/logo/pmd-logo-600px.png b/docs/images/logo/pmd-logo-600px.png new file mode 100644 index 0000000000..387897f800 Binary files /dev/null and b/docs/images/logo/pmd-logo-600px.png differ diff --git a/docs/images/logo/pmd-logo-white-300px.png b/docs/images/logo/pmd-logo-white-300px.png new file mode 100644 index 0000000000..878889121f Binary files /dev/null and b/docs/images/logo/pmd-logo-white-300px.png differ diff --git a/docs/images/logo/pmd-logo-white-600px.png b/docs/images/logo/pmd-logo-white-600px.png new file mode 100644 index 0000000000..933b031e68 Binary files /dev/null and b/docs/images/logo/pmd-logo-white-600px.png differ diff --git a/docs/index.md b/docs/index.md index 55e9c9e5cd..aa76696556 100644 --- a/docs/index.md +++ b/docs/index.md @@ -52,6 +52,7 @@ in a variety of ways, which are [documented here](pmd_userdocs_cpd.html). The latest release of PMD can be downloaded from our [Github releases page](https://github.com/pmd/pmd/releases/latest). +The Logo is available from the [Logo Project Page](pmd_projectdocs_logo.html). ## Documentation diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md index b6d94683e1..4d518453ba 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md @@ -74,3 +74,62 @@ All you need to do is follow this few steps: You should take a look to [Kotlin token filter implementation](https://github.com/pmd/pmd/blob/master/pmd-kotlin/src/main/java/net/sourceforge/pmd/cpd/KotlinTokenizer.java) - For non-Antlr grammars you can use [BaseTokenFilter](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/internal/BaseTokenFilter.java) directly or take a peek to [Java's token filter](https://github.com/pmd/pmd/blob/master/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java) + + +### Testing your implementation + +Add a Maven dependency on `pmd-lang-test` (scope `test`) in your `pom.xml`. +This contains utilities to test your Tokenizer. + +For simple tests, create a test class extending from `CpdTextComparisonTest`. +That class is written in Kotlin, but you can extend it in Java as well. + +To add tests, you need to write regular JUnit `@Test`-annotated methods, and +call the method `doTest` with the name of the test file. + +For example, for the Dart language: + +```java + +public class DartTokenizerTest extends CpdTextComparisonTest { + + /********************************** + Implementation of the superclass + ***********************************/ + + + public DartTokenizerTest() { + super(".dart"); // the file extension for the dart language + } + + @Override + protected String getResourcePrefix() { + // If your class is in src/test/java /some/package + // you need to place the test files in src/test/resources/some/package/cpdData + return "cpdData"; + } + + @Override + public Tokenizer newTokenizer() { + // Override this abstract method to return the correct tokenizer + return new DartTokenizer(); + } + + /************** + Test methods + ***************/ + + + @Test // don't forget the JUnit annotation + public void testLiterals() { + // This will look for a file named literals.dart + // in the directory identified by getResourcePrefix, + // tokenize it, then compare the result against a baseline + // literals.txt file in the same directory + + // If the baseline file does not exist, it is created automatically + doTest("literals"); + } + +} +``` \ No newline at end of file diff --git a/docs/pages/pmd/projectdocs/logo.md b/docs/pages/pmd/projectdocs/logo.md new file mode 100644 index 0000000000..17a94f01e9 --- /dev/null +++ b/docs/pages/pmd/projectdocs/logo.md @@ -0,0 +1,20 @@ +--- +title: Logo +sidebar: pmd_sidebar +permalink: pmd_projectdocs_logo.html +folder: pmd/projectdocs +--- + +![PMD Logo](images/logo/pmd-logo-300px.png) + + +The following PMD Logos and Icons are licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/): + +* [PMD.svg](images/logo/PMD.svg) +* [PMD.png](images/logo/PMD.png) +* [Logo (300px, transparent)](images/logo/pmd-logo-300px.png) +* [Logo (300px, white)](images/logo/pmd-logo-white-300px.png) +* [Logo (600px, transparent)](images/logo/pmd-logo-600px.png) +* [Logo (600px, white)](images/logo/pmd-logo-white-600px.png) + +* [Favicon (16x16)](images/logo/favicon.ico) diff --git a/docs/pages/pmd/userdocs/cli_reference.md b/docs/pages/pmd/userdocs/cli_reference.md index a43c809081..743f5c3a15 100644 --- a/docs/pages/pmd/userdocs/cli_reference.md +++ b/docs/pages/pmd/userdocs/cli_reference.md @@ -40,7 +40,9 @@ The tool comes with a rather extensive help text, simply running with `-help`! {% include custom/cli_option_row.html options="-auxclasspath" option_arg="cp" description="Specifies the classpath for libraries used by the source code. - This is used to resolve types in source files. Alternatively, a `file://` URL + This is used to resolve types in source files. The platform specific path delimiter + (\":\" on Linux, \";\" on Windows) is used to separate the entries. + Alternatively, a single `file:` URL to a text file containing path elements on consecutive lines can be specified." languages="Java" %} diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9eac6d5a65..eee331d256 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -53,30 +53,82 @@ The command line version of PMD continues to use **scala 2.13**. * The new Java Rule {% rule "java/codestyle/UnnecessaryCast" %} (`java-codestyle`) finds casts that are unnecessary while accessing collection elements. +* The new Java Rule {% rule "java/performance/AvoidCalendarDateCreation" %} (`java-performance`) + finds usages of `java.util.Calendar` whose purpose is just to get the current date. This + can be done in a more lightweight way. + +#### Modified rules + +* The Java rule {% rule "java/codestyle/UseDiamondOperator" %} (`java-codestyle`) now by default + finds unnecessary usages of type parameters, which are nested, involve wildcards and are used + within a ternary operator. These usages are usually only unnecessary with Java8 and later, when + the type inference in Java has been improved. + + In order to avoid false positives when checking Java7 only code, the rule has the new property + `java7Compatibility`, which is disabled by default. Settings this to "true" retains + the old rule behaviour. + ### Fixed Issues +* apex-bestpractices + * [#2554](https://github.com/pmd/pmd/issues/2554): \[apex] Exception applying rule UnusedLocalVariable on trigger +* core + * [#2599](https://github.com/pmd/pmd/pull/2599): \[core] Fix XPath 2.0 Rule Chain Analyzer with Unions + * [#2483](https://github.com/pmd/pmd/issues/2483): \[lang-test] Support cpd tests based on text comparison. + For details see + [Testing your implementation](pmd_devdocs_major_adding_new_cpd_language.html#testing-your-implementation) + in the developer documentation. * c# * [#2551](https://github.com/pmd/pmd/issues/2551): \[c#] CPD suppression with comments doesn't work +* cpp + * [#1757](https://github.com/pmd/pmd/issues/1757): \[cpp] Support unicode characters +* java + * [#2549](https://github.com/pmd/pmd/issues/2549): \[java] Auxclasspath in PMD CLI does not support relative file path +* java-codestyle + * [#2545](https://github.com/pmd/pmd/issues/2545): \[java] UseDiamondOperator false negatives + * [#2573](https://github.com/pmd/pmd/pull/2573): \[java] DefaultPackage: Allow package default JUnit 5 Test methods * java-design * [#2563](https://github.com/pmd/pmd/pull/2563): \[java] UselessOverridingMethod false negative with already public methods + * [#2570](https://github.com/pmd/pmd/issues/2570): \[java] NPathComplexity should mention the expected NPath complexity +* java-errorprone + * [#2544](https://github.com/pmd/pmd/issues/2544): \[java] UseProperClassLoader can not detect the case with method call on intermediate variable +* java-performance + * [#2591](https://github.com/pmd/pmd/pull/2591): \[java] InefficientStringBuffering/AppendCharacterWithChar: Fix false negatives with concats in appends + * [#2600](https://github.com/pmd/pmd/pull/2600): \[java] UseStringBufferForStringAppends: fix false negative with fields * scala * [#2547](https://github.com/pmd/pmd/pull/2547): \[scala] Add cross compilation for scala 2.12 and 2.13 + ### API Changes * The maven module `net.sourceforge.pmd:pmd-scala` is deprecated. Use `net.sourceforge.pmd:pmd-scala_2.13` or `net.sourceforge.pmd:pmd-scala_2.12` instead. - + #### Deprecated APIs -* {%jdoc apex::lang.apex.ast.ASTAnnotation#suppresses(core::Rule) %} +* {% jdoc !!apex::lang.apex.ast.ASTAnnotation#suppresses(core::Rule) %} (Apex) +* {% jdoc !!core::cpd.TokenEntry#TokenEntry(java.lang.String, java.lang.String, int) %} +* {% jdoc test::testframework.AbstractTokenizerTest %}. Use CpdTextComparisonTest in module pmd-lang-test instead. + For details see + [Testing your implementation](pmd_devdocs_major_adding_new_cpd_language.html#testing-your-implementation) + in the developer documentation. +* {% jdoc !!java::lang.java.rule.performance.InefficientStringBufferingRule#isInStringBufferOperation(net.sourceforge.pmd.lang.ast.Node, int, java.lang.String) %} + +#### Internal API + +* {% jdoc apex::lang.apex.ApexParser %} +* {% jdoc apex::lang.apex.ApexHandler %} + ### External Contributions +* [#1932](https://github.com/pmd/pmd/pull/1932): \[java] Added 4 performance rules originating from PMD-jPinpoint-rules - [Jeroen Borgers](https://github.com/jborgers) * [#2349](https://github.com/pmd/pmd/pull/2349): \[java] Optimize UnusedPrivateMethodRule - [shilko2013](https://github.com/shilko2013) * [#2547](https://github.com/pmd/pmd/pull/2547): \[scala] Add cross compilation for scala 2.12 and 2.13 - [João Ferreira](https://github.com/jtjeferreira) * [#2567](https://github.com/pmd/pmd/pull/2567): \[c#] Fix CPD suppression with comments doesn't work - [Lixon Lookose](https://github.com/LixonLookose) +* [#2573](https://github.com/pmd/pmd/pull/2573): \[java] DefaultPackage: Allow package default JUnit 5 Test methods - [Craig Andrews](https://github.com/candrews) +* [#2593](https://github.com/pmd/pmd/pull/2593): \[java] NPathComplexity should mention the expected NPath complexity - [Artem Krosheninnikov](https://github.com/KroArtem) {% endtocmaker %} diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/cpd/ApexTokenizer.java b/pmd-apex/src/main/java/net/sourceforge/pmd/cpd/ApexTokenizer.java index 08927b2635..afe8db0b3f 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/cpd/ApexTokenizer.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/cpd/ApexTokenizer.java @@ -55,8 +55,10 @@ public class ApexTokenizer implements Tokenizer { if (!caseSensitive) { tokenText = tokenText.toLowerCase(Locale.ROOT); } - TokenEntry tokenEntry = new TokenEntry(tokenText, sourceCode.getFileName(), token.getLine(), - token.getCharPositionInLine(), token.getCharPositionInLine() + tokenText.length()); + TokenEntry tokenEntry = new TokenEntry(tokenText, sourceCode.getFileName(), + token.getLine(), + token.getCharPositionInLine() + 1, + token.getCharPositionInLine() + tokenText.length() + 1); tokenEntries.add(tokenEntry); } token = lexer.nextToken(); diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java index b82edf8d17..b2d57eb9c9 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java @@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.apex; import java.util.Arrays; import java.util.List; +import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler; import net.sourceforge.pmd.lang.Parser; import net.sourceforge.pmd.lang.ParserOptions; @@ -20,6 +21,7 @@ import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider; import net.sourceforge.pmd.lang.metrics.internal.AbstractLanguageMetricsProvider; import net.sourceforge.pmd.lang.rule.RuleViolationFactory; +@InternalApi public class ApexHandler extends AbstractPmdLanguageVersionHandler { private final ApexMetricsProvider myMetricsProvider = new ApexMetricsProvider(); diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java index d30c027b11..2ab9bd8497 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexParser.java @@ -9,6 +9,7 @@ import java.io.Reader; import org.apache.commons.io.IOUtils; +import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.lang.AbstractParser; import net.sourceforge.pmd.lang.ParserOptions; import net.sourceforge.pmd.lang.apex.ApexJorjeLogging; @@ -19,6 +20,7 @@ import net.sourceforge.pmd.lang.ast.SourceCodePositioner; import apex.jorje.data.Locations; import apex.jorje.semantic.ast.compilation.Compilation; +@InternalApi public final class ApexParser extends AbstractParser { public ApexParser(ParserOptions parserOptions) { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/UnusedLocalVariableRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/UnusedLocalVariableRule.java index 8e1759caf9..e9f2c7b721 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/UnusedLocalVariableRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/UnusedLocalVariableRule.java @@ -24,6 +24,10 @@ public class UnusedLocalVariableRule extends AbstractApexRule { String variableName = node.getImage(); ASTBlockStatement variableContext = node.getFirstParentOfType(ASTBlockStatement.class); + if (variableContext == null) { + // if there is no parent BlockStatement, e.g. in triggers + return data; + } List> potentialUsages = new ArrayList<>(); diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/cpd/ApexTokenizerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/cpd/ApexTokenizerTest.java index d2604656ed..ec002be37c 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/cpd/ApexTokenizerTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/cpd/ApexTokenizerTest.java @@ -4,89 +4,57 @@ package net.sourceforge.pmd.cpd; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; import java.util.Properties; -import org.apache.commons.io.IOUtils; import org.junit.Test; -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.cpd.SourceCode.StringCodeLoader; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; + +public class ApexTokenizerTest extends CpdTextComparisonTest { + + public ApexTokenizerTest() { + super(".cls"); + } + + @Override + protected String getResourcePrefix() { + return "../lang/apex/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + ApexTokenizer tokenizer = new ApexTokenizer(); + tokenizer.setProperties(properties); + return tokenizer; + } -public class ApexTokenizerTest { @Test - public void testTokenize() throws IOException { - Tokens tokens = tokenize(load("Simple.cls")); - if (tokens.size() != 28) { - printTokens(tokens); - } - assertEquals(28, tokens.size()); - assertEquals("someparam", findTokensByLine(8, tokens).get(0).toString()); + public void testTokenize() { + doTest("Simple"); } @Test - public void testTokenizeCaseSensitive() throws IOException { - Tokens tokens = tokenize(load("Simple.cls"), true); - if (tokens.size() != 28) { - printTokens(tokens); - } - assertEquals(28, tokens.size()); - assertEquals("someParam", findTokensByLine(8, tokens).get(0).toString()); + public void testTokenizeCaseSensitive() { + doTest("Simple", "_caseSensitive", caseSensitive()); } /** * Comments are ignored since using ApexLexer. */ @Test - public void testTokenizeWithComments() throws IOException { - Tokens tokens = tokenize(load("issue427/SFDCEncoder.cls")); - assertEquals(17, tokens.size()); - - Tokens tokens2 = tokenize(load("issue427/SFDCEncoderConstants.cls")); - assertEquals(17, tokens2.size()); + public void testTokenizeWithComments() { + doTest("comments"); } - private List findTokensByLine(int line, Tokens tokens) { - List result = new ArrayList<>(); - for (TokenEntry entry : tokens.getTokens()) { - if (entry.getBeginLine() == line) { - result.add(entry); - } - } - if (result.isEmpty()) { - fail("Not tokens found at line " + line); - } - return result; + private Properties caseSensitive() { + return properties(true); } - private Tokens tokenize(String code) { - return tokenize(code, false); - } - - private Tokens tokenize(String code, boolean caseSensitive) { - ApexTokenizer tokenizer = new ApexTokenizer(); + private Properties properties(boolean caseSensitive) { Properties properties = new Properties(); properties.setProperty(ApexTokenizer.CASE_SENSITIVE, Boolean.toString(caseSensitive)); - tokenizer.setProperties(properties); - Tokens tokens = new Tokens(); - tokenizer.tokenize(new SourceCode(new StringCodeLoader(code)), tokens); - return tokens; + return properties; } - private void printTokens(Tokens tokens) { - for (TokenEntry entry : tokens.getTokens()) { - System.out.printf("%02d: %s%s", entry.getBeginLine(), entry.toString(), PMD.EOL); - } - } - - private String load(String name) throws IOException { - return IOUtils.toString(ApexTokenizerTest.class.getResourceAsStream(name), StandardCharsets.UTF_8); - } } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/cpd/Simple.cls b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/Simple.cls similarity index 100% rename from pmd-apex/src/test/resources/net/sourceforge/pmd/cpd/Simple.cls rename to pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/Simple.cls diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/Simple.txt b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/Simple.txt new file mode 100644 index 0000000000..73703e57cc --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/Simple.txt @@ -0,0 +1,35 @@ + [Image] or [Truncated image[ Bcol Ecol +L4 + [public] 1 7 + [with] 8 12 + [sharing] 13 20 + [class] 21 26 + [simple] 27 33 + [{] 34 35 +L5 + [public] 5 11 + [string] 12 18 + [someparam] 19 28 + [{] 29 30 + [get] 31 34 + [;] 34 35 + [set] 36 39 + [;] 39 40 + [}] 41 42 +L7 + [public] 5 11 + [void] 12 16 + [getinit] 17 24 + [(] 24 25 + [)] 25 26 + [{] 27 28 +L8 + [someparam] 9 18 + [=] 19 20 + [test] 22 26 + [;] 27 28 +L9 + [}] 5 6 +L10 + [}] 1 2 +EOF diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/Simple_caseSensitive.txt b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/Simple_caseSensitive.txt new file mode 100644 index 0000000000..72e856ca5e --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/Simple_caseSensitive.txt @@ -0,0 +1,35 @@ + [Image] or [Truncated image[ Bcol Ecol +L4 + [public] 1 7 + [with] 8 12 + [sharing] 13 20 + [class] 21 26 + [Simple] 27 33 + [{] 34 35 +L5 + [public] 5 11 + [String] 12 18 + [someParam] 19 28 + [{] 29 30 + [get] 31 34 + [;] 34 35 + [set] 36 39 + [;] 39 40 + [}] 41 42 +L7 + [public] 5 11 + [void] 12 16 + [getInit] 17 24 + [(] 24 25 + [)] 25 26 + [{] 27 28 +L8 + [someParam] 9 18 + [=] 19 20 + [test] 22 26 + [;] 27 28 +L9 + [}] 5 6 +L10 + [}] 1 2 +EOF diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/comments.cls b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/comments.cls new file mode 100644 index 0000000000..1666787997 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/comments.cls @@ -0,0 +1,14 @@ +/** + * OWO + */ + +/** + * Common character classes used for input validation, output encoding, verifying password strength + */ +public with sharing class SFDCEncoderConstants { + // a single-line comment + + /************ CLASS CODE HERE *************/ + public String someParam { get; set; } +} + diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/comments.txt b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/comments.txt new file mode 100644 index 0000000000..466927ec64 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/comments.txt @@ -0,0 +1,21 @@ + [Image] or [Truncated image[ Bcol Ecol +L8 + [public] 1 7 + [with] 8 12 + [sharing] 13 20 + [class] 21 26 + [sfdcencoderconstants] 27 47 + [{] 48 49 +L12 + [public] 2 8 + [string] 9 15 + [someparam] 16 25 + [{] 26 27 + [get] 28 31 + [;] 31 32 + [set] 33 36 + [;] 36 37 + [}] 38 39 +L13 + [}] 1 2 +EOF diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/UnusedLocalVariable.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/UnusedLocalVariable.xml index 0856903941..1888c60fda 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/UnusedLocalVariable.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/UnusedLocalVariable.xml @@ -83,6 +83,17 @@ public class Foo { public String fieldUsage() { return myfield; } +} + ]]> + + + + NPE with triggers (#2554) + 0 + diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index 2c9a97ffb6..3877315616 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -95,7 +95,11 @@ public class PMDParameters { private String language = null; @Parameter(names = "-auxclasspath", - description = "Specifies the classpath for libraries used by the source code. This is used by the type resolution. Alternatively, a 'file://' URL to a text file containing path elements on consecutive lines can be specified.") + description = "Specifies the classpath for libraries used by the source code. " + + "This is used by the type resolution. The platform specific path delimiter " + + "(\":\" on Linux, \";\" on Windows) is used to separate the entries. " + + "Alternatively, a single 'file:' URL to a text file containing path elements on consecutive lines " + + "can be specified.") private String auxclasspath; @Parameter(names = { "-failOnViolation", "--failOnViolation" }, arity = 1, diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java index a79aee80d4..0de0344457 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractTokenizer.java @@ -34,6 +34,10 @@ public abstract class AbstractTokenizer implements Tokenizer { private int lineNumber = 0; private String currentLine; + // both zero-based + private int tokBeginLine; + private int tokBeginCol; + protected boolean spanMultipleLinesString = true; // Most languages do, so // default is true protected Character spanMultipleLinesLineContinuationCharacter = null; @@ -49,23 +53,35 @@ public abstract class AbstractTokenizer implements Tokenizer { int loc = 0; while (loc < currentLine.length()) { StringBuilder token = new StringBuilder(); - loc = getTokenFromLine(token, loc); + loc = getTokenFromLine(token, loc); // may jump several lines + if (token.length() > 0 && !isIgnorableString(token.toString())) { + final String image; if (downcaseString) { - token = new StringBuilder(token.toString().toLowerCase(Locale.ROOT)); + image = token.toString().toLowerCase(Locale.ROOT); + } else { + image = token.toString(); } - // need to re-think how to link this - // if ( CPD.debugEnable ) { - // System.out.println("Token added:" + token.toString()); - // } - tokenEntries.add(new TokenEntry(token.toString(), tokens.getFileName(), lineNumber + 1, loc - token.length(), loc - 1)); + + tokenEntries.add(new TokenEntry(image, + tokens.getFileName(), + tokBeginLine + 1, + tokBeginCol + 1, + loc + 1)); } } } tokenEntries.add(TokenEntry.getEOF()); } + /** + * Returns (0-based) EXclusive offset of the end of the token, + * may jump several lines (sets {@link #lineNumber} in this case). + */ private int getTokenFromLine(StringBuilder token, int loc) { + tokBeginLine = lineNumber; + tokBeginCol = loc; + for (int j = loc; j < currentLine.length(); j++) { char tok = currentLine.charAt(j); if (!Character.isWhitespace(tok) && !ignoreCharacter(tok)) { @@ -89,6 +105,9 @@ public abstract class AbstractTokenizer implements Tokenizer { } else { if (token.length() > 0) { return j; + } else { + // ignored char + tokBeginCol++; } } loc = j; @@ -125,14 +144,14 @@ public abstract class AbstractTokenizer implements Tokenizer { if (spanMultipleLinesLineContinuationCharacter != null && token.length() > 0 && token.charAt(token.length() - 1) == spanMultipleLinesLineContinuationCharacter) { - token.deleteCharAt(token.length() - 1); + token.setLength(token.length() - 1); } // parsing new line currentLine = code.get(++lineNumber); // Warning : recursive call ! loc = parseString(token, 0, stringDelimiter); } - return loc + 1; + return loc; } private boolean ignoreCharacter(char tok) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyTokenizer.java index 2e9745bb8e..d45a4af7b8 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyTokenizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyTokenizer.java @@ -22,14 +22,17 @@ public class AnyTokenizer implements Tokenizer { StringBuilder sb = sourceCode.getCodeBuffer(); try (BufferedReader reader = new BufferedReader(new CharArrayReader(sb.toString().toCharArray()))) { int lineNumber = 1; + int colNumber = 1; String line = reader.readLine(); while (line != null) { StringTokenizer tokenizer = new StringTokenizer(line, TOKENS, true); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); + int endCol = colNumber + token.length() - 1; // -1 because inclusive if (!" ".equals(token) && !"\t".equals(token)) { - tokenEntries.add(new TokenEntry(token, sourceCode.getFileName(), lineNumber)); + tokenEntries.add(new TokenEntry(token, sourceCode.getFileName(), lineNumber, colNumber, endCol)); } + colNumber = endCol + 1; } // advance iteration variables line = reader.readLine(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java index a1b88be336..c741a337ad 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java @@ -60,6 +60,7 @@ public class Mark implements Comparable { this.endToken = endToken; } + /** Newlines are normalized to \n. */ public String getSourceCodeSlice() { return this.code.getSlice(getBeginLine(), getEndLine()); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java index 19f69b981a..992f551e9c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java @@ -73,6 +73,7 @@ public class Match implements Comparable, Iterable { return this.tokenCount; } + /** Newlines are normalized to \n. */ public String getSourceCodeSlice() { return this.getMark(0).getSourceCodeSlice(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java index 9ccef7f4f1..9d499def1a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java @@ -49,13 +49,13 @@ public class SimpleRenderer implements Renderer, CPDRenderer { String source = match.getSourceCodeSlice(); if (trimLeadingWhitespace) { - String[] lines = source.split('[' + PMD.EOL + ']'); + String[] lines = source.split("\n"); int trimDepth = StringUtil.maxCommonLeadingWhitespaceForAll(lines); if (trimDepth > 0) { lines = StringUtil.trimStartOn(lines, trimDepth); } - for (int i = 0; i < lines.length; i++) { - writer.append(lines[i]).append(PMD.EOL); + for (String line : lines) { + writer.append(line).append(PMD.EOL); } return; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceCode.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceCode.java index cb9468d948..99cf8f8829 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceCode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceCode.java @@ -17,8 +17,6 @@ import java.util.List; import org.apache.commons.io.ByteOrderMark; import org.apache.commons.io.input.BOMInputStream; -import net.sourceforge.pmd.PMD; - public class SourceCode { public abstract static class CodeLoader { @@ -36,6 +34,12 @@ public class SourceCode { return code.get(); } + /** + * Loads a range of lines. + * + * @param startLine Start line (inclusive, 1-based) + * @param endLine End line (inclusive, 1-based) + */ public List getCodeSlice(int startLine, int endLine) { List c = null; if (code != null) { @@ -65,9 +69,15 @@ public class SourceCode { } } + /** + * Loads a range of lines. + * + * @param startLine Start line (inclusive, 1-based) + * @param endLine End line (inclusive, 1-based) + */ protected List load(int startLine, int endLine) { try (BufferedReader reader = new BufferedReader(getReader())) { - int linesToRead = endLine - startLine; + int linesToRead = 1 + endLine - startLine; // +1 because endLine is inclusive List lines = new ArrayList<>(linesToRead); // Skip lines until we reach the start point @@ -185,22 +195,29 @@ public class SourceCode { return cl.getCode(); } + /** Newlines are normalized to \n. */ public StringBuilder getCodeBuffer() { StringBuilder sb = new StringBuilder(); List lines = cl.getCode(); for (String line : lines) { - sb.append(line).append(PMD.EOL); + sb.append(line).append('\n'); } return sb; } + /** + * Loads a range of lines. Newlines are normalized to \n + * + * @param startLine Start line (inclusive, 1-based) + * @param endLine End line (inclusive, 1-based) + */ public String getSlice(int startLine, int endLine) { List lines = cl.getCodeSlice(startLine, endLine); StringBuilder sb = new StringBuilder(); for (String line : lines) { if (sb.length() != 0) { - sb.append(PMD.EOL); + sb.append('\n'); } sb.append(line); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java index 7246dc6acf..85c539965d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java @@ -48,7 +48,10 @@ public class TokenEntry implements Comparable { * @param image * @param tokenSrcID * @param beginLine the linenumber, 1-based. + * + * @deprecated Use {@link #TokenEntry(String, String, int, int, int)}, don't be lazy */ + @Deprecated public TokenEntry(String image, String tokenSrcID, int beginLine) { this(image, tokenSrcID, beginLine, -1, -1); } @@ -62,6 +65,7 @@ public class TokenEntry implements Comparable { * @param endColumn the column number, 1-based */ public TokenEntry(String image, String tokenSrcID, int beginLine, int beginColumn, int endColumn) { + assert isOk(beginLine) && isOk(beginColumn) && isOk(endColumn) : "Coordinates are 1-based"; setImage(image); this.tokenSrcID = tokenSrcID; this.beginLine = beginLine; @@ -70,6 +74,10 @@ public class TokenEntry implements Comparable { this.index = TOKEN_COUNT.get().getAndIncrement(); } + private boolean isOk(int coord) { + return coord >= 1 || coord == -1; + } + public static TokenEntry getEOF() { TOKEN_COUNT.get().getAndIncrement(); return EOF; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java index d7e29d93d7..33230152d9 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java @@ -135,10 +135,12 @@ public final class XMLRenderer implements Renderer, CPDRenderer { } private Element addCodeSnippet(Document doc, Element duplication, Match match) { - String codeSnipet = match.getSourceCodeSlice(); - if (codeSnipet != null) { + String codeSnippet = match.getSourceCodeSlice(); + if (codeSnippet != null) { + // the code snippet has normalized line endings + String platformSpecific = codeSnippet.replace("\n", System.lineSeparator()); Element codefragment = doc.createElement("codefragment"); - codefragment.appendChild(doc.createCDATASection(codeSnipet)); + codefragment.appendChild(doc.createCDATASection(platformSpecific)); duplication.appendChild(codefragment); } return duplication; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java index 7d8462e164..91c4215565 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java @@ -49,7 +49,7 @@ public abstract class AntlrTokenizer implements Tokenizer { } private void processToken(final Tokens tokenEntries, final String fileName, final AntlrToken token) { - final TokenEntry tokenEntry = new TokenEntry(token.getImage(), fileName, token.getBeginLine(), token.getBeginColumn() + 1, token.getEndColumn() + 1); + final TokenEntry tokenEntry = new TokenEntry(token.getImage(), fileName, token.getBeginLine(), token.getBeginColumn(), token.getEndColumn()); tokenEntries.add(tokenEntry); } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java index c3645cfe52..91ab9de067 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/Node.java @@ -244,6 +244,7 @@ public interface Node { } } + /** * Returns a data map used to store additional information on this node. * @@ -251,6 +252,7 @@ public interface Node { */ DataMap> getUserMap(); + /** * Returns the parent of this node, or null if this is the {@linkplain RootNode root} * of the tree. @@ -259,6 +261,7 @@ public interface Node { */ Node getParent(); + /** * Returns the child of this node at the given index. * diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AbstractAntlrVisitor.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AbstractAntlrVisitor.java deleted file mode 100644 index d4acd2a85c..0000000000 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AbstractAntlrVisitor.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.ast.impl.antlr4; - -import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; -import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.ParseTreeVisitor; - -public abstract class AbstractAntlrVisitor extends AbstractParseTreeVisitor implements ParseTreeVisitor { - - @Override - public T visit(ParseTree tree) { - if (tree instanceof AntlrBaseNode) { - return visit((AntlrBaseNode) tree); - } - return tree.accept(this); - } - - public T visit(final AntlrBaseNode node) { - return node.accept(this); - } -} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseNode.java deleted file mode 100644 index 5f6e3f52d7..0000000000 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseNode.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.ast.impl.antlr4; - -import org.antlr.v4.runtime.ParserRuleContext; - -import net.sourceforge.pmd.util.DataMap; -import net.sourceforge.pmd.util.DataMap.DataKey; - -public abstract class AntlrBaseNode extends ParserRuleContext implements AntlrNode { - - private final DataMap> userData = DataMap.newDataMap(); - - /** - * Constructor required by {@link ParserRuleContext} - */ - @SuppressWarnings("unused") - public AntlrBaseNode() { - // Nothing to be done - } - - /** - * Constructor required by {@link ParserRuleContext} - * - * @param parent The parent - * @param invokingStateNumber the invokingState defined by {@link org.antlr.v4.runtime.RuleContext} parent - */ - @SuppressWarnings("unused") - public AntlrBaseNode(final ParserRuleContext parent, final int invokingStateNumber) { - super(parent, invokingStateNumber); - } - - /** - * TODO @NoAttribute (port swift rules) - */ - @Override - @SuppressWarnings("PMD.UselessOverridingMethod") - public String getText() { - return super.getText(); - } - - - // FIXME these coordinates are not accurate - - @Override - public int getBeginLine() { - return start.getLine(); // This goes from 1 to n - } - - @Override - public int getEndLine() { - return stop.getLine(); // This goes from 1 to n - } - - @Override - public int getBeginColumn() { - return start.getCharPositionInLine(); // This goes from 0 to (n - 1) - } - - @Override - public int getEndColumn() { - return stop.getCharPositionInLine(); // This goes from 0 to (n - 1) - } - - @Override - public DataMap> getUserMap() { - return userData; - } - - @Override - public AntlrNode getChild(int i) { - return (AntlrNode) super.getChild(i); - } - - @Override - public AntlrBaseNode getParent() { - return (AntlrBaseNode) super.getParent(); - } - - @Override - public int getNumChildren() { - return getChildCount(); - } - - @Override - public String getXPathNodeName() { - final String simpleName = getClass().getSimpleName(); - return simpleName.substring(0, simpleName.length() - "Context".length()); - } -} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java index 1f92c96862..0e84059e63 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java @@ -7,6 +7,8 @@ package net.sourceforge.pmd.lang.ast.impl.antlr4; import java.io.IOException; import java.io.Reader; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.Lexer; import net.sourceforge.pmd.lang.Parser; @@ -15,9 +17,16 @@ import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.ast.RootNode; /** - * Generic Antlr parser adapter for all Antlr parsers. + * Generic Antlr parser adapter for all Antlr parsers. This wraps a parser + * generated by antlr, soo {@link AntlrGeneratedParserBase}. + * + * @param Supertype of all nodes for the language, eg SwiftNode + * @param Type of the root node */ -public abstract class AntlrBaseParser implements Parser { +public abstract class AntlrBaseParser< + N extends AntlrNode, + R extends BaseAntlrInnerNode & RootNode + > implements Parser { protected final ParserOptions parserOptions; @@ -31,17 +40,17 @@ public abstract class AntlrBaseParser imp } @Override - public RootNode parse(final String fileName, final Reader source) throws ParseException { + public R parse(final String fileName, final Reader source) throws ParseException { + CharStream cs; try { - return getRootNode(getParser(getLexer(source))); + cs = CharStreams.fromReader(source, fileName); } catch (final IOException e) { throw new ParseException(e); } + return parse(getLexer(cs)); } - protected abstract RootNode getRootNode(T parser); + protected abstract R parse(Lexer parser); - protected abstract Lexer getLexer(Reader source) throws IOException; - - protected abstract T getParser(Lexer lexer); + protected abstract Lexer getLexer(CharStream source); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRootNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRootNode.java deleted file mode 100644 index dd482d9bf8..0000000000 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRootNode.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.ast.impl.antlr4; - -import org.antlr.v4.runtime.ParserRuleContext; - -import net.sourceforge.pmd.lang.ast.RootNode; - -public abstract class AntlrBaseRootNode extends AntlrBaseNode implements RootNode { - - /** - * Constructor required by {@link ParserRuleContext} - */ - @SuppressWarnings("unused") - public AntlrBaseRootNode() { - super(); - } - - /** - * Constructor required by {@link ParserRuleContext} - * - * @param parent The parent - * @param invokingStateNumber the invokingState defined by {@link org.antlr.v4.runtime.RuleContext} parent - */ - @SuppressWarnings("unused") - public AntlrBaseRootNode(final ParserRuleContext parent, final int invokingStateNumber) { - super(parent, invokingStateNumber); - } -} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java index 6e822d69ef..db2cd3fa26 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java @@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.ast.impl.antlr4; import java.util.List; import net.sourceforge.pmd.RuleContext; +import net.sourceforge.pmd.lang.ast.AstVisitor; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.rule.AbstractRule; @@ -21,13 +22,11 @@ public abstract class AntlrBaseRule extends AbstractRule { @Override public void apply(List nodes, RuleContext ctx) { - AbstractAntlrVisitor visitor = buildVisitor(ctx); + AstVisitor visitor = buildVisitor(); assert visitor != null : "Rule should provide a non-null visitor"; for (Node node : nodes) { - assert node instanceof AntlrBaseNode : "Incorrect node type " + node + " passed to " + this; - - ((AntlrBaseNode) node).accept(visitor); + node.acceptVisitor(visitor, ctx); } } @@ -36,10 +35,8 @@ public abstract class AntlrBaseRule extends AbstractRule { * This visitor should explore the nodes it's interested in and report * violations on the given rule context. * - * @param ruleCtx Object that accumulates rule violations - * * @return A visitor bound to the given rule context */ - public abstract AbstractAntlrVisitor buildVisitor(RuleContext ruleCtx); + public abstract AstVisitor buildVisitor(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java new file mode 100644 index 0000000000..5571c21e70 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java @@ -0,0 +1,87 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.ast.impl.antlr4; + +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +import net.sourceforge.pmd.lang.ast.Node; + +/** + * This is the base class for antlr generated parsers. The implementation + * of PMD's {@link net.sourceforge.pmd.lang.Parser} interface is {@link AntlrBaseParser}. + * + *

This class must implement the two abstract methods to create terminals + * and error nodes that implement {@code }. The inner nodes implement PMD + * interfaces, and manipulation methods that the {@link Parser} superclass + * uses are redirected to the underlying antlr {@link ParserRuleContext} (the + * protected overloads here). + * + *

This is not enough in general to make the generated parser compilable, + * so an ant script does some cleanup at the end. + * + *

Additionally this must have a {@link AntlrNameDictionary} static final field, + * which stores the XPath names of the generated nodes (and terminals). + * + *

Additional members can be added to a parser with {@code @parser::members { ... }} + * in the g4 file. + */ +public abstract class AntlrGeneratedParserBase> extends Parser { + + public AntlrGeneratedParserBase(TokenStream input) { + super(input); + } + + + @Override + public TerminalNode createTerminalNode(ParserRuleContext parent, Token t) { + return createPmdTerminal(parent, t).asAntlrNode(); + } + + @Override + public ErrorNode createErrorNode(ParserRuleContext parent, Token t) { + return createPmdError(parent, t).asAntlrNode(); + } + + // Those two need to return a node that implements eg SwiftNode + + public abstract BaseAntlrTerminalNode createPmdTerminal(ParserRuleContext parent, Token t); + + public abstract BaseAntlrErrorNode createPmdError(ParserRuleContext parent, Token t); + + + protected Node asPmdNode(RuleContext ctx) { + return ((BaseAntlrNode.AntlrToPmdParseTreeAdapter) ctx).getPmdNode(); + } + + // Necessary API to build the trees + + protected void enterRule(BaseAntlrInnerNode ptree, int state, int alt) { + enterRule(ptree.asAntlrNode(), state, alt); + } + + protected void enterOuterAlt(BaseAntlrInnerNode localctx, int altNum) { + enterOuterAlt(localctx.asAntlrNode(), altNum); + } + + protected void pushNewRecursionContext(BaseAntlrInnerNode localctx, int state, int ruleIndex) { + pushNewRecursionContext(localctx.asAntlrNode(), state, ruleIndex); + } + + protected void enterRecursionRule(BaseAntlrInnerNode localctx, int state, int ruleIndex, int precedence) { + enterRecursionRule(localctx.asAntlrNode(), state, ruleIndex, precedence); + + } + + protected boolean sempred(BaseAntlrInnerNode localctx, int ruleIndex, int predIndex) { + return sempred(localctx.asAntlrNode(), ruleIndex, predIndex); + } + +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNameDictionary.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNameDictionary.java new file mode 100644 index 0000000000..1ca4c4f953 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNameDictionary.java @@ -0,0 +1,219 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.ast.impl.antlr4; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Stream; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.Vocabulary; +import org.apache.commons.lang3.StringUtils; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Stores the XPath name of antlr terminals. I found no simple way to + * give names to punctuation (we could add a lexer rule, but it may + * conflict with other tokens). So their names are hardcoded here. + * + *

Terminal names start with {@code "T-"} in XPath to avoid conflicts + * with other stuff. + */ +public class AntlrNameDictionary { + + private final String[] terminalXPathNames; + private final String[] terminalImages; + private final String[] nonTermXpathNames; + private final Vocabulary vocabulary; + + public AntlrNameDictionary(Vocabulary vocab, String[] ruleNames) { + this.vocabulary = vocab; + + nonTermXpathNames = new String[ruleNames.length]; + for (int i = 0; i < nonTermXpathNames.length; i++) { + nonTermXpathNames[i] = StringUtils.capitalize(ruleNames[i]); + } + Set seen = new HashSet<>(); + Collections.addAll(seen, ruleNames); + + // terminal names + terminalXPathNames = new String[vocab.getMaxTokenType()]; + terminalXPathNames[0] = "Invalid"; // See Token.INVALID_TYPE + + terminalImages = new String[vocab.getMaxTokenType()]; + terminalImages[0] = null; + + for (int i = Token.MIN_USER_TOKEN_TYPE; i < terminalXPathNames.length; i++) { + String name = vocab.getSymbolicName(i); + String literalName = vocab.getLiteralName(i); + + if (literalName != null) { + // cleanup literal name, Antlr surrounds the image with single quotes + literalName = literalName.substring(1, literalName.length() - 1); + terminalImages[i] = literalName; + } + + if (name == null && literalName != null) { + name = literalName; + if (!name.matches("[a-zA-Z][\\w_-]+")) { // not alphanum + name = nonAlphaNumName(name); + } // otherwise something like "final" + } + + + assert name != null : "Token of kind " + i + " has no XPath name (literal " + vocab.getLiteralName(i) + ")"; + + String finalName = "T-" + name; + + assert finalName.matches("[a-zA-Z][\\w_-]+") : "Not a valid XPath name " + finalName; + assert seen.add(finalName) : "Duplicate XPath name " + finalName; + + terminalXPathNames[i] = finalName; + } + + + assert Stream.of(terminalXPathNames).distinct().count() == terminalXPathNames.length + : "Duplicate names in " + Arrays.toString(terminalXPathNames); + } + + public Vocabulary getVocabulary() { + return vocabulary; + } + + /** + * Override this to customize the XPath name of tokes with no symbolic + * name and with an image that is non-alphanumeric. Return null to give + * up. The default just gives some name to common punctuation. Remember + * that the same token may mean several things in different contexts, so + * eg using {@code "not"} as the name of {@code "!"} is too specific. + */ + protected @Nullable String nonAlphaNumName(String name) { + switch (name) { + case "!": return "bang"; + case "!!": return "double-bang"; + + case "?": return "question"; + case "??": return "double-question"; + case "?:": return "elvis"; + case "?.": return "question-dot"; + + case ":": return "colon"; + case ";": return "semi"; + case ",": return "comma"; + + case "(": return "lparen"; + case ")": return "rparen"; + case "[": return "lbracket"; + case "]": return "rbracket"; + case "{": return "lbrace"; + case "}": return "rbrace"; + + case "_": return "underscore"; + + case ".": return "dot"; + case "..": return "double-dot"; + case "...": return "ellipsis"; + + case "@": return "at-symbol"; + case "$": return "dollar"; + + case "\\": return "backslash"; + case "/": return "slash"; + case "//": return "double-slash"; + case "`": return "backtick"; + case "'": return "squote"; + case "\"": return "dquote"; + case "\"\"\"": return "triple-quote"; + + case ">": return "gt"; + case ">=": return "ge"; + case "<": return "lt"; + case "<=": return "le"; + + case ">>": return "double-gt"; + case "<<": return "double-lt"; + case ">>>": return "triple-gt"; + case "<<<": return "triple-lt"; + + case "=": return "eq"; + case "==": return "double-eq"; + case "===": return "triple-eq"; + case "!=": return "not-eq"; + + case "&": return "amp"; + case "&&": return "double-amp"; + case "|": return "pipe"; + case "||": return "double-pipe"; + + case "*": return "star"; + case "**": return "double-star"; + + case "+": return "plus"; + case "++": return "double-plus"; + case "-": return "minus"; + case "--": return "double-minus"; + + case "->": return "rarrow"; + case "<-": return "larrow"; + + default: + return null; + } + } + + /** + * Gets the xpath name of a terminal node with a given {@link Token#getType()}. + * + * @throws IllegalArgumentException If the index is invalid + */ + public @NonNull String getXPathNameOfToken(int tokenType) { + if (tokenType >= 0 && tokenType < terminalXPathNames.length) { + return terminalXPathNames[tokenType]; + } + + if (tokenType == Token.EOF) { + return "EOF"; + } + + throw new IllegalArgumentException("I don't know token type " + tokenType); + } + + /** + * Returns the constant image of the given token (a shared string), + * or null if the token has none. This is a memory optimization to + * avoid creating a new string for tokens with constant images. Antlr + * does not do this by itself sadly. + */ + public @Nullable String getConstantImageOfToken(Token token) { + int tokenType = token.getType(); + if (tokenType >= 0 && tokenType < terminalXPathNames.length) { + return terminalImages[tokenType]; + } else if (token.getStartIndex() == token.getStopIndex()) { + return ""; + } + return null; + } + + /** + * Gets the xpath name of an inner node with a given {@link ParserRuleContext#getRuleIndex()}. + * + * @throws IndexOutOfBoundsException If the index is invalid + */ + public @NonNull String getXPathNameOfRule(int idx) { + return nonTermXpathNames[idx]; + } + + public int getMaxRuleIndex() { + return nonTermXpathNames.length; + } + + public int getMaxTokenType() { + return vocabulary.getMaxTokenType(); + } +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNode.java index 840495b068..e3f81f77a9 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNode.java @@ -4,37 +4,11 @@ package net.sourceforge.pmd.lang.ast.impl.antlr4; -import org.antlr.v4.runtime.tree.ParseTree; - -import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.ast.NodeStream; +import net.sourceforge.pmd.lang.ast.impl.GenericNode; /** - * Base interface for all Antlr-based implementation of Node interface. - *

- * Initially all the methods implemented here will be no-op due to scope limitations + * Base interface for all Antlr-based implementation of the Node interface. */ -public interface AntlrNode extends Node, ParseTree { - - - @Override - AntlrNode getChild(int index); - - - @Override - AntlrNode getParent(); - - - @Override - @SuppressWarnings("unchecked") - default NodeStream children() { - return (NodeStream) Node.super.children(); - } - - @Override - default int getIndexInParent() { - // FIXME, relied on by node streams - throw new UnsupportedOperationException("Out of scope for antlr current implementations"); - } +public interface AntlrNode> extends GenericNode { } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrRuleChainVisitor.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrRuleChainVisitor.java index 720d1db0db..ed5d7fa710 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrRuleChainVisitor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrRuleChainVisitor.java @@ -4,24 +4,19 @@ package net.sourceforge.pmd.lang.ast.impl.antlr4; +import java.util.Collections; import java.util.List; import net.sourceforge.pmd.Rule; import net.sourceforge.pmd.RuleContext; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.rule.AbstractRuleChainVisitor; -import net.sourceforge.pmd.lang.rule.XPathRule; public class AntlrRuleChainVisitor extends AbstractRuleChainVisitor { @Override protected void visit(Rule rule, Node node, RuleContext ctx) { - if (rule instanceof AntlrBaseRule) { - AntlrBaseRule rule1 = (AntlrBaseRule) rule; - ((AntlrBaseNode) node).accept(rule1.buildVisitor(ctx)); - } else { - ((XPathRule) rule).evaluate(node, ctx); - } + rule.apply(Collections.singletonList(node), ctx); } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java index e990fa1ada..cb60813252 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java @@ -4,6 +4,9 @@ package net.sourceforge.pmd.lang.ast.impl.antlr4; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.Token; @@ -14,14 +17,23 @@ import net.sourceforge.pmd.lang.ast.GenericToken; */ public class AntlrToken implements GenericToken { + private static final Pattern NEWLINE_PATTERN = + // \R on java 8+ + Pattern.compile("\\u000D\\u000A|[\\u000A\\u000B\\u000C\\u000D\\u0085\\u2028\\u2029]"); + private final Token token; private final AntlrToken previousComment; AntlrToken next; + private String text; + + private int endline; + private int endcolumn; + /** * Constructor * - * @param token The antlr token implementation + * @param token The antlr token implementation * @param previousComment The previous comment */ public AntlrToken(final Token token, final AntlrToken previousComment) { @@ -41,7 +53,10 @@ public class AntlrToken implements GenericToken { @Override public String getImage() { - return token.getText(); + if (text == null) { + text = token.getText(); + } + return text; } @Override @@ -55,18 +70,71 @@ public class AntlrToken implements GenericToken { } @Override - public int getEndLine() { - return token.getLine(); + public int getBeginColumn() { + int charPos = token.getCharPositionInLine() + 1; + assert charPos > 0; + return charPos; } + @Override - public int getBeginColumn() { - return token.getCharPositionInLine(); + public int getEndLine() { + if (endline == 0) { + computeEndCoords(); + assert endline > 0; + } + return endline; } @Override public int getEndColumn() { - return token.getCharPositionInLine() + token.getStopIndex() - token.getStartIndex(); + if (endcolumn == 0) { + computeEndCoords(); + assert endcolumn > 0; + } + return endcolumn; + } + + private void computeEndCoords() { + String image = getImage(); + if (image.length() == 1) { + // fast path for single char tokens + if (image.charAt(0) != '\n') { + this.endline = getBeginLine(); + this.endcolumn = getBeginColumn() + 1; + return; + } + } + + Matcher matcher = NEWLINE_PATTERN.matcher(image); + int numNls = 0; + int lastOffset = 0; + int lastLineLen = -1; + while (matcher.find()) { + // continue + numNls++; + if (lastLineLen < 0) { + // first iteration, line may not be completely in the image + lastLineLen = token.getCharPositionInLine() + matcher.end(); + } else { + lastLineLen = matcher.end() - lastOffset; + } + lastOffset = matcher.end(); + } + + if (numNls == 0) { + // single line token + this.endline = this.getBeginLine(); + int length = 1 + token.getStopIndex() - token.getStartIndex(); + this.endcolumn = token.getCharPositionInLine() + length + 1; + } else if (lastOffset < image.length()) { + this.endline = this.getBeginLine() + numNls; + this.endcolumn = image.length() - lastOffset + 1; + } else { + // ends with a newline, the newline is considered part of the previous line + this.endline = this.getBeginLine() + numNls - 1; + this.endcolumn = lastLineLen + 1; + } } public int getKind() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrErrorNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrErrorNode.java new file mode 100644 index 0000000000..33babb7eac --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrErrorNode.java @@ -0,0 +1,31 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.ast.impl.antlr4; + +import org.antlr.v4.runtime.Token; +import org.checkerframework.checker.nullness.qual.NonNull; + +public abstract class BaseAntlrErrorNode> extends BaseAntlrTerminalNode { + + protected BaseAntlrErrorNode(Token symbol) { + super(symbol, true); + } + + @Override + protected final AntlrErrorPmdAdapter asAntlrNode() { + return (AntlrErrorPmdAdapter) super.asAntlrNode(); + } + + + @Override + public @NonNull String getText() { + return getFirstAntlrToken().getText(); + } + + @Override + public final String getXPathNodeName() { + return "Error"; + } +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrInnerNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrInnerNode.java new file mode 100644 index 0000000000..4daab3ed6e --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrInnerNode.java @@ -0,0 +1,154 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.ast.impl.antlr4; + +import java.util.List; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; +import org.antlr.v4.runtime.tree.RuleNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +import net.sourceforge.pmd.lang.ast.impl.antlr4.BaseAntlrInnerNode.PmdAsAntlrInnerNode; + +/** + * Base class for the inner nodes (corresponds to {@link ParserRuleContext}). + * Use the {@code contextSuperClass} option to set this in the antlr g4 file, + * eg {@code options { contextSuperClass = SwiftInnerNode; }}. + */ +public abstract class BaseAntlrInnerNode> extends BaseAntlrNode, N> { + + public RecognitionException exception; + + private final PmdAsAntlrInnerNode antlrNode; + + protected BaseAntlrInnerNode() { + antlrNode = new PmdAsAntlrInnerNode<>(this); + } + + protected BaseAntlrInnerNode(ParserRuleContext parent, int invokingStateNumber) { + antlrNode = new PmdAsAntlrInnerNode<>(this, (PmdAsAntlrInnerNode) parent, invokingStateNumber); + } + + @Override + @SuppressWarnings("unchecked") + public N getChild(int index) { + if (0 <= index && index < getNumChildren()) { + N pmdNode = (N) antlrNode.getChild(index).getPmdNode(); + assert pmdNode.getIndexInParent() == index; + return pmdNode; + } + throw new IndexOutOfBoundsException("Index " + index + ", numChildren " + getNumChildren()); + } + + @Override + public int getNumChildren() { + return antlrNode.getChildCount(); + } + + @Override + protected PmdAsAntlrInnerNode asAntlrNode() { + return antlrNode; + } + + protected abstract int getRuleIndex(); + + + @Override + public Token getFirstAntlrToken() { + return asAntlrNode().start; + } + + @Override + public Token getLastAntlrToken() { + return asAntlrNode().stop; + } + + protected > T getRuleContext(Class klass, int idx) { + return children(klass).get(idx); + } + + protected > List getRuleContexts(Class klass) { + return children(klass).toList(); + } + + protected TerminalNode getToken(int kind, int idx) { + @SuppressWarnings("rawtypes") + BaseAntlrTerminalNode pmdWrapper = + children(BaseAntlrTerminalNode.class) + .filter(it -> it.getTokenKind() == kind) + .get(idx); + return pmdWrapper != null ? pmdWrapper.asAntlrNode() : null; + } + + protected void copyFrom(BaseAntlrInnerNode other) { + asAntlrNode().copyFrom(other.asAntlrNode()); + } + + + public void enterRule(ParseTreeListener listener) { + // default does nothing + } + + + public void exitRule(ParseTreeListener listener) { + // default does nothing + } + + protected static class PmdAsAntlrInnerNode> extends ParserRuleContext implements RuleNode, AntlrToPmdParseTreeAdapter { + + private final BaseAntlrInnerNode pmdNode; + + PmdAsAntlrInnerNode(BaseAntlrInnerNode node) { + this.pmdNode = node; + } + + PmdAsAntlrInnerNode(BaseAntlrInnerNode node, PmdAsAntlrInnerNode parent, int invokingStateNumber) { + super(parent, invokingStateNumber); + this.pmdNode = node; + } + + @Override + public BaseAntlrInnerNode getPmdNode() { + return pmdNode; + } + + @Override + @SuppressWarnings("unchecked") + public PmdAsAntlrInnerNode getParent() { + return (PmdAsAntlrInnerNode) super.getParent(); + } + + @Override + @SuppressWarnings("unchecked") + public AntlrToPmdParseTreeAdapter getChild(int i) { + return (AntlrToPmdParseTreeAdapter) super.getChild(i); + } + + @Override + public T addAnyChild(T t) { + assert t instanceof AntlrToPmdParseTreeAdapter; + BaseAntlrNode pmdNode = ((AntlrToPmdParseTreeAdapter) t).getPmdNode(); + pmdNode.setIndexInParent(getChildCount()); + return super.addAnyChild(t); + } + + @Override + public void setParent(RuleContext parent) { + assert parent instanceof PmdAsAntlrInnerNode; + super.setParent(parent); + } + + @Override + public T accept(ParseTreeVisitor visitor) { + throw new UnsupportedOperationException("Cannot visit the underlying antlr nodes"); + } + } +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrNode.java new file mode 100644 index 0000000000..be9147822c --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrNode.java @@ -0,0 +1,123 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.ast.impl.antlr4; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.TerminalNode; + +import net.sourceforge.pmd.lang.ast.impl.GenericNode; +import net.sourceforge.pmd.lang.ast.impl.antlr4.BaseAntlrNode.AntlrToPmdParseTreeAdapter; +import net.sourceforge.pmd.util.DataMap; +import net.sourceforge.pmd.util.DataMap.DataKey; + +/** + * Base class for an antlr node. This implements the PMD interfaces only, + * not the antlr ones. It wraps an antlr node (they are linked both ways). + * Antlr primarily distinguishes {@link ParserRuleContext} for inner nodes, + * {@link TerminalNode} for nodes that wrap tokens (and can have no children), + * and {@link ErrorNode}, a subtype of {@link TerminalNode}. These each have + * a base class here, which refines the type of the underlying antlr node: + * {@link BaseAntlrInnerNode}, {@link BaseAntlrTerminalNode} and {@link BaseAntlrErrorNode}. + * These must be implemented in each language module with a class that also + * implements {@code }. + * + *

During tree construction, the antlr runtime does its thing with the + * underlying antlr nodes. The PMD nodes are just wrappers around those, + * that respect the contract of {@link GenericNode}. + * + * @param Type of the underlying antlr node + * @param Public interface (eg SwiftNode) + */ +public abstract class BaseAntlrNode, N extends AntlrNode> implements AntlrNode { + + private DataMap> userMap; + private int indexInParent = -1; + + protected BaseAntlrNode() { + // protected + } + + /** + * Recurses over the text of all terminal descendants to build the + * text of this node (without spaces). This is extremely inefficient + * and should not be used to write rules. The antlr impl doesn't even + * use a single stringbuilder. + * + * @deprecated Some rules depend on it and have not been rewritten + */ + @Deprecated + public String joinTokenText() { + return asAntlrNode().getText(); + } + + // these are an implementation detail, meant as a crutch while some + // rules depend on it + // Should be made protected + + public abstract Token getFirstAntlrToken(); + + public abstract Token getLastAntlrToken(); + + void setIndexInParent(int indexInParent) { + this.indexInParent = indexInParent; + } + + @Override + public N getParent() { + AntlrToPmdParseTreeAdapter parent = asAntlrNode().getParent(); + return parent == null ? null : (N) parent.getPmdNode(); + } + + @Override + public int getBeginLine() { + return getFirstAntlrToken().getLine(); // This goes from 1 to n + } + + @Override + public int getEndLine() { + // FIXME this is not the end line if the stop token spans several lines + return getLastAntlrToken().getLine(); + } + + @Override + public int getBeginColumn() { + return getFirstAntlrToken().getCharPositionInLine() + 1; + } + + @Override + public int getEndColumn() { + Token tok = getLastAntlrToken(); + return tok.getCharPositionInLine() + tok.getStopIndex() - tok.getStartIndex() + 1; + } + + @Override + public int getIndexInParent() { + assert indexInParent >= 0 : "Index not set"; + return indexInParent; + } + + @Override + public DataMap> getUserMap() { + if (userMap == null) { + userMap = DataMap.newDataMap(); + } + return userMap; + } + + protected abstract A asAntlrNode(); + + + protected interface AntlrToPmdParseTreeAdapter> extends ParseTree { + + BaseAntlrNode getPmdNode(); + + + @Override + AntlrToPmdParseTreeAdapter getParent(); + } +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrTerminalNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrTerminalNode.java new file mode 100644 index 0000000000..8b265ff528 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrTerminalNode.java @@ -0,0 +1,112 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.ast.impl.antlr4; + +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.antlr.v4.runtime.tree.TerminalNodeImpl; +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.ast.impl.antlr4.BaseAntlrTerminalNode.AntlrTerminalPmdAdapter; + +/** + * Base class for terminal nodes (they wrap a {@link TerminalNode}). + */ +public abstract class BaseAntlrTerminalNode> + extends BaseAntlrNode, N> { + + private final AntlrTerminalPmdAdapter antlrNode; + + protected BaseAntlrTerminalNode(Token symbol) { + this(symbol, false); + } + + BaseAntlrTerminalNode(Token symbol, boolean isError) { + if (isError) { + this.antlrNode = new AntlrErrorPmdAdapter<>(this, symbol); + } else { + this.antlrNode = new AntlrTerminalPmdAdapter<>(this, symbol); + } + } + + /** + * Returns the text of the token. + * + * @implNote This should use {@link AntlrNameDictionary#getConstantImageOfToken(Token)}, + * or default to {@link Token#getText()} + */ + public abstract @NonNull String getText(); + + @Override + protected AntlrTerminalPmdAdapter asAntlrNode() { + return antlrNode; + } + + @Override + public Token getFirstAntlrToken() { + return antlrNode.symbol; + } + + @Override + public Token getLastAntlrToken() { + return antlrNode.symbol; + } + + @Override + public int getNumChildren() { + return 0; + } + + protected int getTokenKind() { + return antlrNode.symbol.getTokenIndex(); + } + + @Override + public N getChild(int index) { + throw new IndexOutOfBoundsException("Index " + index + " for terminal node"); + } + + protected static class AntlrTerminalPmdAdapter> extends TerminalNodeImpl implements AntlrToPmdParseTreeAdapter { + + private final BaseAntlrTerminalNode pmdNode; + + public AntlrTerminalPmdAdapter(BaseAntlrTerminalNode pmdNode, Token symbol) { + super(symbol); + this.pmdNode = pmdNode; + } + + @Override + public AntlrToPmdParseTreeAdapter getParent() { + return (AntlrToPmdParseTreeAdapter) super.getParent(); + } + + @Override + public void setParent(RuleContext parent) { + assert parent instanceof BaseAntlrNode.AntlrToPmdParseTreeAdapter; + super.setParent(parent); + } + + @Override + public BaseAntlrNode getPmdNode() { + return pmdNode; + } + } + + protected static class AntlrErrorPmdAdapter> extends AntlrTerminalPmdAdapter implements ErrorNode { + + public AntlrErrorPmdAdapter(BaseAntlrTerminalNode pmdNode, Token symbol) { + super(pmdNode, symbol); + } + + @Override + public T accept(ParseTreeVisitor visitor) { + return visitor.visitErrorNode(this); + } + } + +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrErrorNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrErrorNode.java deleted file mode 100644 index 348927eefb..0000000000 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrErrorNode.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.ast.impl.antlr4; - -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.tree.ErrorNode; -import org.antlr.v4.runtime.tree.ParseTreeVisitor; - -public class PmdAntlrErrorNode extends PmdAntlrTerminalNode implements AntlrNode, ErrorNode { - - public PmdAntlrErrorNode(Token t) { - super(t); - } - - @Override - public String getXPathNodeName() { - return "Error"; - } - - @Override - public T accept(ParseTreeVisitor visitor) { - return visitor.visitErrorNode(this); - } -} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrParserBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrParserBase.java deleted file mode 100644 index 78ced80c9d..0000000000 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrParserBase.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.ast.impl.antlr4; - -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.tree.ErrorNode; -import org.antlr.v4.runtime.tree.TerminalNode; - -public abstract class PmdAntlrParserBase extends Parser { - - public PmdAntlrParserBase(TokenStream input) { - super(input); - } - - @Override - public TerminalNode createTerminalNode(ParserRuleContext parent, Token t) { - return new PmdAntlrTerminalNode(t); - } - - @Override - public ErrorNode createErrorNode(ParserRuleContext parent, Token t) { - return new PmdAntlrErrorNode(t); - } -} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrTerminalNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrTerminalNode.java deleted file mode 100644 index 95122c0665..0000000000 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/PmdAntlrTerminalNode.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.ast.impl.antlr4; - -import org.antlr.v4.runtime.RuleContext; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.tree.TerminalNodeImpl; - -import net.sourceforge.pmd.util.DataMap; -import net.sourceforge.pmd.util.DataMap.DataKey; - -/** - * @author Clément Fournier - */ -public class PmdAntlrTerminalNode extends TerminalNodeImpl implements AntlrNode { - - private final DataMap> userData = DataMap.newDataMap(); - - public PmdAntlrTerminalNode(Token t) { - super(t); - } - - @Override - public AntlrNode getChild(int i) { - return null; - } - - @Override - public int getNumChildren() { - return 0; - } - - @Override - public String getXPathNodeName() { - return "Token" + getSymbol().getType(); // TODO - } - - @Override - public AntlrNode getParent() { - return (AntlrNode) super.getParent(); - } - - - @Override - public void setParent(RuleContext parent) { - assert parent instanceof AntlrNode : "Parent should be a parent"; - super.setParent(parent); - } - - - // FIXME these coordinates are not accurate - - - @Override - public int getBeginLine() { - return getSymbol().getLine(); - } - - @Override - public int getBeginColumn() { - return getSymbol().getCharPositionInLine() + 1; - } - - @Override - public int getEndLine() { - return getBeginLine(); - } - - @Override - public int getEndColumn() { - return getBeginColumn() + getSymbol().getText().length(); - } - - @Override - public DataMap> getUserMap() { - return userData; - } -} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/RuleChainAnalyzer.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/RuleChainAnalyzer.java index 9c9bcdb855..e093c07dd7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/RuleChainAnalyzer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/RuleChainAnalyzer.java @@ -66,17 +66,16 @@ public class RuleChainAnalyzer extends SaxonExprVisitor { if (rootElement != null && !rootElementReplaced) { if (result instanceof PathExpression) { PathExpression newPath = (PathExpression) result; - if (newPath.getStepExpression() instanceof FilterExpression) { + Expression step = newPath.getStepExpression(); + if (step instanceof FilterExpression) { FilterExpression filterExpression = (FilterExpression) newPath.getStepExpression(); result = new FilterExpression(new AxisExpression(Axis.SELF, null), filterExpression.getFilter()); rootElementReplaced = true; - } else if (newPath.getStepExpression() instanceof AxisExpression) { + } else if (step instanceof AxisExpression) { if (newPath.getStartExpression() instanceof RootExpression) { result = new AxisExpression(Axis.SELF, null); - } else { - result = new PathExpression(newPath.getStartExpression(), new AxisExpression(Axis.SELF, null)); + rootElementReplaced = true; } - rootElementReplaced = true; } } else { result = new AxisExpression(Axis.DESCENDANT_OR_SELF, null); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/ClasspathClassLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/ClasspathClassLoader.java index e9b31a13cb..6c8148e274 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/ClasspathClassLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/ClasspathClassLoader.java @@ -62,7 +62,7 @@ public class ClasspathClassLoader extends URLClassLoader { throw new IllegalArgumentException("classpath argument cannot be null"); } final List urls = new ArrayList<>(); - if (classpath.startsWith("file://")) { + if (classpath.startsWith("file:")) { // Treat as file URL addFileURLs(urls, new URL(classpath)); } else { @@ -87,7 +87,7 @@ public class ClasspathClassLoader extends URLClassLoader { while ((line = in.readLine()) != null) { LOG.log(Level.FINE, "Read classpath entry line: <{0}>", line); line = line.trim(); - if (line.length() > 0) { + if (line.length() > 0 && line.charAt(0) != '#') { LOG.log(Level.FINE, "Adding classpath entry: <{0}>", line); urls.add(createURLFromPath(line)); } @@ -97,7 +97,7 @@ public class ClasspathClassLoader extends URLClassLoader { private static URL createURLFromPath(String path) throws MalformedURLException { File file = new File(path); - return file.getAbsoluteFile().toURI().toURL(); + return file.getAbsoluteFile().toURI().normalize().toURL(); } @Override diff --git a/pmd-core/src/main/resources/rulesets/releases/6250.xml b/pmd-core/src/main/resources/rulesets/releases/6250.xml index db652d271d..3dc5b862e2 100644 --- a/pmd-core/src/main/resources/rulesets/releases/6250.xml +++ b/pmd-core/src/main/resources/rulesets/releases/6250.xml @@ -9,5 +9,6 @@ This ruleset contains links to rules that are new in PMD v6.25.0 + diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/ConfigurationTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/ConfigurationTest.java index f1251cd25e..b88e95d8a9 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/ConfigurationTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/ConfigurationTest.java @@ -12,10 +12,13 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Properties; +import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.cache.FileAnalysisCache; @@ -59,6 +62,50 @@ public class ConfigurationTest { configuration.getClassLoader()); } + @Test + public void auxClasspathWithRelativeFileEmpty() throws IOException { + String relativeFilePath = "src/test/resources/net/sourceforge/pmd/cli/auxclasspath-empty.cp"; + PMDConfiguration configuration = new PMDConfiguration(); + configuration.prependClasspath("file:" + relativeFilePath); + URL[] urls = ((ClasspathClassLoader) configuration.getClassLoader()).getURLs(); + Assert.assertEquals(0, urls.length); + } + + @Test + public void auxClasspathWithRelativeFileEmpty2() throws IOException { + String relativeFilePath = "./src/test/resources/net/sourceforge/pmd/cli/auxclasspath-empty.cp"; + PMDConfiguration configuration = new PMDConfiguration(); + configuration.prependClasspath("file:" + relativeFilePath); + URL[] urls = ((ClasspathClassLoader) configuration.getClassLoader()).getURLs(); + Assert.assertEquals(0, urls.length); + } + + @Test + public void auxClasspathWithRelativeFile() throws IOException, URISyntaxException { + final String FILE_SCHEME = "file"; + + String currentWorkingDirectory = new File("").getAbsoluteFile().toURI().getPath(); + String relativeFilePath = "src/test/resources/net/sourceforge/pmd/cli/auxclasspath.cp"; + PMDConfiguration configuration = new PMDConfiguration(); + configuration.prependClasspath("file:" + relativeFilePath); + URL[] urls = ((ClasspathClassLoader) configuration.getClassLoader()).getURLs(); + URI[] uris = new URI[urls.length]; + for (int i = 0; i < urls.length; i++) { + uris[i] = urls[i].toURI(); + } + URI[] expectedUris = new URI[] { + new URI(FILE_SCHEME, null, currentWorkingDirectory + "lib1.jar", null), + new URI(FILE_SCHEME, null, currentWorkingDirectory + "other/directory/lib2.jar", null), + new URI(FILE_SCHEME, null, new File("/home/jondoe/libs/lib3.jar").getAbsoluteFile().toURI().getPath(), null), + new URI(FILE_SCHEME, null, currentWorkingDirectory + "classes", null), + new URI(FILE_SCHEME, null, currentWorkingDirectory + "classes2", null), + new URI(FILE_SCHEME, null, new File("/home/jondoe/classes").getAbsoluteFile().toURI().getPath(), null), + new URI(FILE_SCHEME, null, currentWorkingDirectory, null), + new URI(FILE_SCHEME, null, currentWorkingDirectory + "relative source dir/bar", null), + }; + Assert.assertArrayEquals(expectedUris, uris); + } + @Test public void testRuleSets() { PMDConfiguration configuration = new PMDConfiguration(); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java index 5e0b0ed42c..0afa0144b8 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java @@ -40,8 +40,8 @@ public class MarkTest { final int beginLine = 1; final int beginColumn = 2; final int endColumn = 3; - final TokenEntry token = new TokenEntry("public", "/var/Foo.java", 1, beginColumn, 0); - final TokenEntry endToken = new TokenEntry("}", "/var/Foo.java", 5, 0, endColumn); + final TokenEntry token = new TokenEntry("public", "/var/Foo.java", 1, beginColumn, beginColumn + "public".length()); + final TokenEntry endToken = new TokenEntry("}", "/var/Foo.java", 5, endColumn - 1, endColumn); final Mark mark = new Mark(token); final int lineCount = 10; diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/SourceCodeTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/SourceCodeTest.java index ff3579450e..c672da6ee9 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/SourceCodeTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/SourceCodeTest.java @@ -7,11 +7,9 @@ package net.sourceforge.pmd.cpd; import static org.junit.Assert.assertEquals; import java.io.File; -import java.util.ArrayList; import org.junit.Test; -import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.cpd.SourceCode.FileCodeLoader; public class SourceCodeTest { @@ -20,21 +18,16 @@ public class SourceCodeTest { private static final String SAMPLE_CODE = "Line 1\n" + "Line 2\n" + "Line 3\n" + "Line 4\n"; @Test - public void testSimple() throws Exception { - Tokenizer tokenizer = new AbstractTokenizer() { - { - this.stringToken = new ArrayList<>(); - this.ignorableCharacter = new ArrayList<>(); - this.ignorableStmt = new ArrayList<>(); - } - }; + public void testSlice() { SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader(SAMPLE_CODE, "Foo.java")); assertEquals("Foo.java", sourceCode.getFileName()); - tokenizer.tokenize(sourceCode, new Tokens()); assertEquals("Line 1", sourceCode.getSlice(1, 1)); assertEquals("Line 2", sourceCode.getSlice(2, 2)); - assertEquals("Line 1" + PMD.EOL + "Line 2", sourceCode.getSlice(1, 2)); + assertEquals("Line 1\nLine 2", sourceCode.getSlice(1, 2)); + + sourceCode.getCodeBuffer(); // load into soft reference, must not change behavior + assertEquals("Line 1\nLine 2", sourceCode.getSlice(1, 2)); } @Test diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/SaxonXPathRuleQueryTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/SaxonXPathRuleQueryTest.java index 93b7d4e3a3..4bd83a6fc8 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/SaxonXPathRuleQueryTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/SaxonXPathRuleQueryTest.java @@ -195,4 +195,18 @@ public class SaxonXPathRuleQueryTest { query.setXPath(xpath); return query; } + + @Test + public void ruleChainWithUnions() { + SaxonXPathRuleQuery query = createQuery("(//ForStatement | //WhileStatement | //DoStatement)//AssignmentOperator"); + List ruleChainVisits = query.getRuleChainVisits(); + Assert.assertEquals(0, ruleChainVisits.size()); + } + + @Test + public void ruleChainWithUnionsAndFilter() { + SaxonXPathRuleQuery query = createQuery("(//ForStatement | //WhileStatement | //DoStatement)//AssignmentOperator[@Image='foo']"); + List ruleChainVisits = query.getRuleChainVisits(); + Assert.assertEquals(0, ruleChainVisits.size()); + } } diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/cli/auxclasspath-empty.cp b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/auxclasspath-empty.cp new file mode 100644 index 0000000000..39eeac6911 --- /dev/null +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/auxclasspath-empty.cp @@ -0,0 +1,4 @@ +# this file is deliberately empty +# comments start with # + +# empty lines are ignored diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/cli/auxclasspath.cp b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/auxclasspath.cp new file mode 100644 index 0000000000..852cdf0bce --- /dev/null +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/auxclasspath.cp @@ -0,0 +1,13 @@ +# relative paths here should be resolved relative to the current working directory - not relative to this file +lib1.jar +other/directory/lib2.jar +# absolute paths work as well +/home/jondoe/libs/lib3.jar +# also directories are possible +classes +classes2/ +/home/jondoe/classes +# relative current directory +. +# a test with a space in the uri +relative source dir/bar diff --git a/pmd-cpp/etc/grammar/Cpp.jj b/pmd-cpp/etc/grammar/Cpp.jj index 340b2c315b..450f772c41 100644 --- a/pmd-cpp/etc/grammar/Cpp.jj +++ b/pmd-cpp/etc/grammar/Cpp.jj @@ -191,40 +191,30 @@ TOKEN : | < FINALLY: "finally" > } -TOKEN [IGNORE_CASE] : +TOKEN: { - < OCTALINT : "0" (["'", "0"-"7"])* > -| < OCTALLONG : "l" > -| < UNSIGNED_OCTALINT : "u" > -| < UNSIGNED_OCTALLONG : ("ul" | "lu") > + < #DECIMALDIGIT: ["0"-"9"] > +| < #OCTALDIGIT: ["0"-"7"] > +| < #HEXDIGIT: ["a"-"f", "A"-"F", "0"-"9"] > +| < #INT_SUFFIX: ["u", "U", "l", "L"] | "uL" | "Ul" | "UL" | "ul" | "lu" | "Lu" | "lU" | "LU" > -| < #DECIMALDIGIT : ["'", "0"-"9"] > +| < ZERO: "0" > +| < OCTAL_INT_LITERAL: "0" ("'" | )+ ()? > +| < DECIMAL_INT_LITERAL: ["1"-"9"] ("'" | )* ()? > +| < HEXADECIMAL_INT_LITERAL: "0" ["x", "X"] ("'" | )+ ()? > -| < DECIMALINT : ["1"-"9"] ()* > -| < DECIMALLONG : ["u","l"] > -| < UNSIGNED_DECIMALINT : "u" > -| < UNSIGNED_DECIMALLONG : ("ul" | "lu") > +// like DECIMALINT but may start with 0 +| < #INT_IN_FLOAT: ["0"-"9"] ("'" | )* > +| < #EXP_PART: ["e", "E"] (["-","+"])? > - -| < HEXADECIMALINT : "0x" ( | ["a"-"f"])+ > -| < HEXADECIMALLONG : (["u","l"])? > -| < UNSIGNED_HEXADECIMALINT : "u" > -| < UNSIGNED_HEXADECIMALLONG : ("ul" | "lu") > - - -| < FLOATONE : (["0"-"9"]()* "." - | "." ()+ - | ["0"-"9"]()* "." ()+) - ("e" (["-","+"])? ()+)? (["f","l"])? > - -| < FLOATTWO : ["0"-"9"]()* "e" (["-","+"])? ()+ (["f","l"])? > +| < FLOAT_LITERAL : ("." ( ()?)? | ) (["f", "l", "F", "L"])? > } TOKEN : { < #CHRPREF : > | < CHARACTER : - "'" ( ( ~["'","\\","\r","\n"] ) | ( "\\" ( ~["\n","\r"] ) ) )* "'" > + "'" ( ( ~["'","\\","\r","\n"] ) | ( "\\" ( ~["\n","\r"] ) ) )+ "'" > | < #STRPREF : ("L" | "u" | "U" | "u8")? > | < STRING : @@ -289,7 +279,58 @@ rstringbody: TOKEN : { - < ID : ["$", "a"-"z","A"-"Z", "_"] (["a"-"z","A"-"Z","0"-"9","_","$"])* > +// https://en.cppreference.com/w/cpp/language/identifiers#Unicode_characters_in_identifiers + + < ID : ()* > + +| < #UNICODE_ESCAPE: "\\" ( "u" | "U" ) > +| < #HEXDIGIT_4: > +| < #ID_CHAR: | [ + "a"-"z", "A"-"Z", "0"-"9", "_", "$", + "\u00a8", "\u00aa", "\u00ad", "\u00af", + "\u00b2"-"\u00b5", "\u00b7"-"\u00ba", + "\u00b7"-"\u00ba", "\u00bc"-"\u00be", + "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", + "\u00f8"-"\u167f", "\u1681"-"\u180d", + "\u180f"-"\u1fff", "\u200b"-"\u200d", + "\u202a"-"\u202e", "\u203f"-"\u2040", + "\u2054", "\u2060"-"\u218f", + "\u2460"-"\u24ff", "\u2776"-"\u2793", + "\u2c00"-"\u2dff", "\u2e80"-"\u2fff", + "\u3004"-"\u3007", "\u3021"-"\u302f", + "\u3031"-"\ud7ff", "\uf900"-"\ufd3d", + "\ufd40"-"\ufdcf", "\ufdf0"-"\ufe44", + "\ufe47"-"\ufffd" + // the standard also allows code points in planes 1 through e, + // but javacc doesn't support supplementary characters + ] > +// this production is the same as the above, +// with some ranges subtracted +| < #ID_START_CHAR: | [ + "a"-"z", "A"-"Z", "_", "$", + "\u00a8", "\u00aa", "\u00ad", "\u00af", + "\u00b2"-"\u00b5", "\u00b7"-"\u00ba", + "\u00b7"-"\u00ba", "\u00bc"-"\u00be", + "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", + // subtracted u+0300-u+036f from u+00f8-u+167f + "\u00f8"-"\u02ff", "\u0370"-"\u167f", + "\u1681"-"\u180d", + // subtracted u+1dc0-u+1dff from u+180f-u+1fff + "\u180f"-"\u1dbf", "\u1e00"-"\u1fff", + "\u200b"-"\u200d", + "\u202a"-"\u202e", "\u203f"-"\u2040", + "\u2054", + // subtracted u+20d0-u+20ff from u+2060-u+218f + "\u2060"-"\u20cf", "\u2100"-"\u218f", + "\u2460"-"\u24ff", "\u2776"-"\u2793", + "\u2c00"-"\u2dff", "\u2e80"-"\u2fff", + "\u3004"-"\u3007", "\u3021"-"\u302f", + "\u3031"-"\ud7ff", "\uf900"-"\ufd3d", + "\ufd40"-"\ufdcf", + // subtracted u+fe20-u+fe2f from u+fdf0-u+fe44 + "\ufdf0"-"\ufe1f", "\ufe30"-"\ufe44", + "\ufe47"-"\ufffd" + ] > } @@ -706,8 +747,8 @@ void member_declaration() : void member_declarator_list(boolean isTypedef) : {} { - member_declarator(isTypedef) ("=" )? - ("," member_declarator(isTypedef) ("=" )?)* + member_declarator(isTypedef) ("=" assignment_expression())? + ("," member_declarator(isTypedef) ("=" assignment_expression())?)* } void member_declarator(boolean isTypedef) : @@ -861,7 +902,7 @@ Scope function_direct_declarator(boolean isTypedef) : "(" (parameter_list())? ")" (LOOKAHEAD(2) type_qualifier())? (exception_spec())? - (LOOKAHEAD("=") "=" )? + ("=" )? { if (closeReqd) @@ -1450,23 +1491,14 @@ void expression_list() : void constant() : {} -{ - | - | - | - | - | - - | - | - | - | - | - | +{ + + | + | + | + | | - | - | | "true" | "false" } diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 8102b0ede4..7a2f195f27 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -82,10 +82,21 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + + diff --git a/pmd-cpp/src/test/java/net/sourceforge/pmd/cpd/CPPTokenizerContinuationTest.java b/pmd-cpp/src/test/java/net/sourceforge/pmd/cpd/CPPTokenizerContinuationTest.java deleted file mode 100644 index 9a97edf3b4..0000000000 --- a/pmd-cpp/src/test/java/net/sourceforge/pmd/cpd/CPPTokenizerContinuationTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -import org.apache.commons.io.IOUtils; -import org.junit.Test; - -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.cpd.SourceCode.StringCodeLoader; -import net.sourceforge.pmd.lang.TokenManager; -import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; - -public class CPPTokenizerContinuationTest { - - @Test - public void parseWithContinuation() throws Exception { - String code = load("cpp_with_continuation.cpp"); - Tokens tokens = parse(code); - if (tokens.size() < 52) { - printTokens(tokens); - fail("Not enough tokens - probably parsing error. Tokens: " + tokens.size()); - } - - assertEquals("static", findByLine(8, tokens).get(0).toString()); - assertEquals("int", findByLine(8, tokens).get(1).toString()); - - // special case, if the continuation is *within* a token - // see also test #testContinuationIntraToken - TokenEntry tokenEntry = findByLine(8, tokens).get(2); - assertEquals("ab", tokenEntry.toString()); - - assertEquals("int", findByLine(12, tokens).get(0).toString()); - assertEquals("main", findByLine(12, tokens).get(1).toString()); - assertEquals("(", findByLine(12, tokens).get(2).toString()); - assertEquals(")", findByLine(12, tokens).get(3).toString()); - assertEquals("{", findByLine(13, tokens).get(0).toString()); - assertEquals("\"world!\\n\"", findByLine(16, tokens).get(0).toString()); - assertEquals("\"3 Hello, \\world!\\n\"", findByLine(22, tokens).get(4).toString()); - assertEquals("}", findByLine(29, tokens).get(0).toString()); - } - - /** - * Verifies the begin/end of a token. Uses the underlying JavaCC Token and - * not TokenEntry. - */ - @Test - public void parseWithContinuationCppTokenManager() throws Exception { - String code = load("cpp_with_continuation.cpp"); - TokenManager tokenManager = new CPPTokenizer().getLexerForSource(new SourceCode(new StringCodeLoader(code))); - List tokens = new ArrayList<>(); - - JavaccToken token = tokenManager.getNextToken(); - while (!token.getImage().isEmpty()) { - tokens.add(token); - token = tokenManager.getNextToken(); - } - - assertEquals(51, tokens.size()); - - assertToken(tokens.get(2), "ab", 8, 12, 9, 2); - assertToken(tokens.get(22), "\"2 Hello, world!\\n\"", 18, 16, 19, 10); - } - - - private void assertToken(JavaccToken token, String image, int beginLine, int beginColumn, int endLine, int endColumn) { - assertEquals(image, token.getImage()); - assertEquals(beginLine, token.getBeginLine()); - assertEquals(beginColumn, token.getBeginColumn()); - assertEquals(endLine, token.getEndLine()); - assertEquals(endColumn, token.getEndColumn()); - } - - @Test - public void testContinuationIntraToken() throws Exception { - Tokens tokens = parse(load("cpp_continuation_intra_token.cpp")); - assertEquals(7, tokens.size()); - } - - @Test - public void testContinuationInterToken() throws Exception { - Tokens tokens = parse(load("cpp_continuation_inter_token.cpp")); - assertEquals(17, tokens.size()); - } - - private void printTokens(Tokens tokens) { - for (TokenEntry entry : tokens.getTokens()) { - System.out.printf("%02d: %s%s", entry.getBeginLine(), entry.toString(), PMD.EOL); - } - } - - private List findByLine(int line, Tokens tokens) { - List result = new ArrayList<>(); - for (TokenEntry entry : tokens.getTokens()) { - if (entry.getBeginLine() == line) { - result.add(entry); - } - } - if (result.isEmpty()) { - fail("No tokens at line " + line + " found"); - } - return result; - } - - private String load(String name) throws Exception { - return IOUtils.toString(CPPTokenizerContinuationTest.class - .getResourceAsStream("cpp/" + name), StandardCharsets.UTF_8); - } - - private Tokens parse(String code) throws IOException { - CPPTokenizer tokenizer = new CPPTokenizer(); - tokenizer.setProperties(new Properties()); - Tokens tokens = new Tokens(); - tokenizer.tokenize(new SourceCode(new StringCodeLoader(code)), tokens); - return tokens; - } -} diff --git a/pmd-cpp/src/test/java/net/sourceforge/pmd/cpd/CPPTokenizerTest.java b/pmd-cpp/src/test/java/net/sourceforge/pmd/cpd/CPPTokenizerTest.java index d684d3956a..e055090c13 100644 --- a/pmd-cpp/src/test/java/net/sourceforge/pmd/cpd/CPPTokenizerTest.java +++ b/pmd-cpp/src/test/java/net/sourceforge/pmd/cpd/CPPTokenizerTest.java @@ -5,277 +5,144 @@ package net.sourceforge.pmd.cpd; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertTrue; -import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.Properties; -import org.apache.commons.io.IOUtils; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.lang.ast.TokenMgrError; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -public class CPPTokenizerTest { +public class CPPTokenizerTest extends CpdTextComparisonTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); + public CPPTokenizerTest() { + super(".cpp"); + } + + @Override + protected String getResourcePrefix() { + return "../lang/cpp/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties props) { + CPPTokenizer tok = new CPPTokenizer(); + tok.setProperties(props); + return tok; + } + + @Override + public Properties defaultProperties() { + return dontSkipBlocks(); + } @Test public void testUTFwithBOM() { - Tokens tokens = parse("\ufeffint start()\n{ int ret = 1;\nreturn ret;\n}\n"); - assertNotSame(TokenEntry.getEOF(), tokens.getTokens().get(0)); + Tokenizer tokenizer = newTokenizer(dontSkipBlocks()); + Tokens tokens = tokenize(tokenizer, "\ufeffint start()\n{ int ret = 1;\nreturn ret;\n}\n"); assertEquals(15, tokens.size()); } @Test - public void testUnicodeSupport() { - String code = "\ufeff" + "#include \n" + "#include \n" + "\n" + "// example\n" + "\n" - + "int main()\n" + "{\n" + " std::string text(\"ąęćśźńó\");\n" + " std::cout << text;\n" - + " return 0;\n" + "}\n"; - Tokens tokens = parse(code); - assertNotSame(TokenEntry.getEOF(), tokens.getTokens().get(0)); - assertEquals(24, tokens.size()); + public void testContinuation() { + doTest("continuation"); + } + + @Test + public void testContinuationInIdent() { + doTest("continuation_intra_token"); + } + + @Test + public void testContinuationBetweenTokens() { + doTest("continuation_inter_token"); + } + + @Test + public void testUnicodeStringSupport() { + doTest("unicodeStrings"); } @Test public void testIgnoreBetweenSpecialComments() { - String code = "#include \n" + "#include \n" + "\n" + "// CPD-OFF\n" - + "int main()\n" + "{\n" + " std::string text(\"ąęćśźńó\");\n" + " std::cout << text;\n" - + " return 0;\n" + "// CPD-ON\n" + "}\n"; - Tokens tokens = parse(code); - assertNotSame(TokenEntry.getEOF(), tokens.getTokens().get(0)); - assertEquals(2, tokens.size()); // "}" + EOF + doTest("specialComments"); } @Test public void testMultiLineMacros() { - Tokens tokens = parse(TEST1); - assertEquals(7, tokens.size()); + doTest("multilineMacros"); } @Test - public void testDollarSignInIdentifier() { - parse(TEST2); + public void testIdentifierValidChars() { + doTest("identifierChars"); } @Test - public void testDollarSignStartingIdentifier() { - parse(TEST3); + public void testWrongUnicodeInIdentifier() { + expectTokenMgrError(" void main() { int ⚜ = __; }"); } @Test - public void testWideCharacters() { - parse(TEST4); + public void testTokenizerWithSkipBlocks() { + doTest("simpleSkipBlocks", "_skipDefault", skipBlocks()); } @Test - public void testTokenizerWithSkipBlocks() throws Exception { - String test = IOUtils.toString(CPPTokenizerTest.class.getResourceAsStream("cpp/cpp_with_asm.cpp"), StandardCharsets.UTF_8); - Tokens tokens = parse(test, true, new Tokens()); - assertEquals(19, tokens.size()); + public void testTokenizerWithSkipBlocksPattern() { + doTest("simpleSkipBlocks", "_skipDebug", skipBlocks("#if debug|#endif")); } @Test - public void testTokenizerWithSkipBlocksPattern() throws Exception { - String test = IOUtils.toString(CPPTokenizerTest.class.getResourceAsStream("cpp/cpp_with_asm.cpp"), StandardCharsets.UTF_8); - Tokens tokens = new Tokens(); - try { - parse(test, true, "#if debug|#endif", tokens); - } catch (TokenMgrError ignored) { - // ignored - } - assertEquals(31, tokens.size()); + public void testTokenizerWithoutSkipBlocks() { + doTest("simpleSkipBlocks", "_noSkip", dontSkipBlocks()); } @Test - public void testTokenizerWithoutSkipBlocks() throws Exception { - String test = IOUtils.toString(CPPTokenizerTest.class.getResourceAsStream("cpp/cpp_with_asm.cpp"), StandardCharsets.UTF_8); - Tokens tokens = new Tokens(); - try { - parse(test, false, tokens); - } catch (TokenMgrError ignored) { - // ignored - } - assertEquals(37, tokens.size()); + public void testAsm() { + // ASM code containing the '@' character + doTest("asm", "", dontSkipBlocks()); } @Test - // ASM code containing the '@' character - public void testAsmWithAtSign() { - Tokens tokens = parse(TEST7); - assertEquals(22, tokens.size()); + public void testPreprocessingDirectives() { + doTest("preprocessorDirectives"); } @Test - public void testEOLCommentInPreprocessingDirective() { - parse("#define LSTFVLES_CPP //*" + PMD.EOL); + public void testLiterals() { + doTest("literals"); } @Test - public void testEmptyCharacter() { - Tokens tokens = parse("std::wstring wsMessage( sMessage.length(), L'');" + PMD.EOL); - assertEquals(15, tokens.size()); + public void testLexicalErrorFilename() { + expectTokenMgrError(sourceText("issue-1559"), dontSkipBlocks()); } + @Test - public void testHexCharacter() { - Tokens tokens = parse("if (*pbuf == '\\0x05')" + PMD.EOL); - assertEquals(8, tokens.size()); + public void testRawStringLiterals() { + doTest("issue-1784"); } - @Test - public void testWhiteSpaceEscape() { - Tokens tokens = parse("szPath = m_sdcacheDir + _T(\"\\ oMedia\");" + PMD.EOL); - assertEquals(10, tokens.size()); + + private static Properties skipBlocks(String skipPattern) { + return properties(true, skipPattern); } - @Test - public void testRawStringLiteral() { - String code = "const char* const KDefaultConfig = R\"(\n" + " [Sinks.1]\n" + " Destination=Console\n" - + " AutoFlush=true\n" - + " Format=\"[%TimeStamp%] %ThreadId% %QueryIdHigh% %QueryIdLow% %LoggerFile%:%Line% (%Severity%) - %Message%\"\n" - + " Filter=\"%Severity% >= WRN\"\n" + ")\";\n"; - Tokens tokens = parse(code); - assertTrue(TokenEntry.getEOF() != tokens.getTokens().get(0)); - assertEquals(9, tokens.size()); + private static Properties skipBlocks() { + return skipBlocks(null); } - @Test - public void testLexicalErrorFilename() throws Exception { - Properties properties = new Properties(); - properties.setProperty(Tokenizer.OPTION_SKIP_BLOCKS, Boolean.toString(false)); - String test = IOUtils.toString(CPPTokenizerTest.class.getResourceAsStream("cpp/issue-1559.cpp"), StandardCharsets.UTF_8); - SourceCode code = new SourceCode(new SourceCode.StringCodeLoader(test, "issue-1559.cpp")); - CPPTokenizer tokenizer = new CPPTokenizer(); - tokenizer.setProperties(properties); - - expectedException.expect(TokenMgrError.class); - expectedException.expectMessage("Lexical error in file issue-1559.cpp at"); - tokenizer.tokenize(code, new Tokens()); + private static Properties dontSkipBlocks() { + return properties(false, null); } - public void testStringPrefix(String code, String expToken, int tokenIndex, int expNoTokens) { - final Tokens tokens = parse(code); - final TokenEntry token = tokens.getTokens().get(tokenIndex); - assertEquals(expNoTokens, tokens.size()); - assertEquals(expToken, token.toString()); - } - - public void testCharacterPrefix(String code, String expToken) { - testStringPrefix(code, expToken, 3, 6); - } - - public void testStringPrefix(String code, String expToken) { - testStringPrefix(code, expToken, 5, 8); - } - - @Test - public void testCharacterPrefixNoPrefix() { - testCharacterPrefix("char a = '\\x30';", "'\\x30'"); - } - - @Test - public void testCharacterPrefixWideCharacter() { - testCharacterPrefix("wchar_t b = L'\\xFFEF';", "L'\\xFFEF'"); - } - - @Test - public void testCharacterPrefixChar16() { - testCharacterPrefix("char16_t c = u'\\u00F6';", "u'\\u00F6'"); - } - - @Test - public void testCharacterPrefixChar32() { - testCharacterPrefix("char32_t d = U'\\U0010FFFF';", "U'\\U0010FFFF'"); - } - - @Test - public void testStringPrefixNoPrefix() { - testStringPrefix("char A[] = \"Hello\\x0A\";", "\"Hello\\x0A\""); - } - - @Test - public void testStringPrefixWideString() { - testStringPrefix("wchar_t B[] = L\"Hell\\xF6\\x0A\";", "L\"Hell\\xF6\\x0A\""); - } - - @Test - public void testStringPrefixChar16() { - testStringPrefix("char16_t C[] = u\"Hell\\u00F6\";", "u\"Hell\\u00F6\""); - } - - @Test - public void testStringPrefixChar32() { - testStringPrefix("char32_t D[] = U\"Hell\\U000000F6\\U0010FFFF\";", "U\"Hell\\U000000F6\\U0010FFFF\""); - } - - @Test - public void testStringPrefixUtf8() { - testStringPrefix("auto E[] = u8\"\\u00F6\\U0010FFFF\";", "u8\"\\u00F6\\U0010FFFF\""); - } - - @Test - public void testRawStringLiterals() throws IOException { - final String code = IOUtils.toString(CPPTokenizerTest.class.getResourceAsStream("cpp/issue-1784.cpp"), StandardCharsets.UTF_8); - Tokens tokens = parse(code); - assertTrue(TokenEntry.getEOF() != tokens.getTokens().get(0)); - assertEquals(16, tokens.size()); - } - - @Test - public void testDigitSeparators() { - final String code = "auto integer_literal = 1'000'000;" + PMD.EOL - + "auto floating_point_literal = 0.000'015'3;" + PMD.EOL - + "auto hex_literal = 0x0F00'abcd'6f3d;" + PMD.EOL - + "auto silly_example = 1'0'0'000'00;"; - Tokens tokens = parse(code); - assertTrue(TokenEntry.getEOF() != tokens.getTokens().get(0)); - assertEquals("1'000'000", tokens.getTokens().get(3).toString()); - assertEquals(21, tokens.size()); - } - - private Tokens parse(String snippet) { - try { - return parse(snippet, false, new Tokens()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private Tokens parse(String snippet, boolean skipBlocks, Tokens tokens) throws IOException { - return parse(snippet, skipBlocks, null, tokens); - } - - private Tokens parse(String snippet, boolean skipBlocks, String skipPattern, Tokens tokens) throws IOException { + private static Properties properties(boolean skipBlocks, String skipPattern) { Properties properties = new Properties(); properties.setProperty(Tokenizer.OPTION_SKIP_BLOCKS, Boolean.toString(skipBlocks)); if (skipPattern != null) { properties.setProperty(Tokenizer.OPTION_SKIP_BLOCKS_PATTERN, skipPattern); } - - CPPTokenizer tokenizer = new CPPTokenizer(); - tokenizer.setProperties(properties); - - SourceCode code = new SourceCode(new SourceCode.StringCodeLoader(snippet)); - tokenizer.tokenize(code, tokens); - return tokens; + return properties; } - - private static final String TEST1 = "#define FOO a +\\" + PMD.EOL + " b +\\" + PMD.EOL - + " c +\\" + PMD.EOL + " d +\\" + PMD.EOL + " e +\\" + PMD.EOL - + " f +\\" + PMD.EOL + " g" + PMD.EOL + " void main() {}"; - - private static final String TEST2 = " void main() { int x$y = 42; }"; - - private static final String TEST3 = " void main() { int $x = 42; }"; - - private static final String TEST4 = " void main() { char x = L'a'; }"; - - private static final String TEST7 = "asm void eSPI_boot()" + PMD.EOL + "{" + PMD.EOL + " // setup stack pointer" - + PMD.EOL + " lis r1, _stack_addr@h" + PMD.EOL + " ori r1, r1, _stack_addr@l" + PMD.EOL + "}"; } diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/asm.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/asm.cpp new file mode 100644 index 0000000000..549e7ac740 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/asm.cpp @@ -0,0 +1,36 @@ +asm void eSPI_boot() +{ + // setup stack pointer + + lis r1, _stack_addr@h + ori r1, r1, _stack_addr@l +} + +int main() { +} + +#if DEBUG +int foobar() { +} +#endif + +#if 0 +static void my_memset(void *dest,int fill_value,int count) +{ + __asm __volatile__( + "cld\n" + "mov %ecx, %ebx\n" + "shr 2,%ecx\n" + "rep " + "stosl\n" + "mov %ebx,%ecx\n" + " // line 157 mentioned above" + : + : "c" (count), "a" (fill_value), "D" (dest) + : "cc","%ebx" ); +} +#endif + + +int otherMethod() { +} \ No newline at end of file diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/asm.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/asm.txt new file mode 100644 index 0000000000..6de07f4db0 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/asm.txt @@ -0,0 +1,114 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [asm] 1 4 + [void] 5 9 + [eSPI_boot] 10 19 + [(] 19 20 + [)] 20 21 +L2 + [{] 1 2 +L5 + [lis] 3 6 + [r1] 7 9 + [,] 9 10 + [_stack_addr] 11 22 + [@] 22 23 + [h] 23 24 +L6 + [ori] 3 6 + [r1] 7 9 + [,] 9 10 + [r1] 11 13 + [,] 13 14 + [_stack_addr] 15 26 + [@] 26 27 + [l] 27 28 +L7 + [}] 1 2 +L9 + [int] 1 4 + [main] 5 9 + [(] 9 10 + [)] 10 11 + [{] 12 13 +L10 + [}] 1 2 +L13 + [int] 1 4 + [foobar] 5 11 + [(] 11 12 + [)] 12 13 + [{] 14 15 +L14 + [}] 1 2 +L18 + [static] 1 7 + [void] 8 12 + [my_memset] 13 22 + [(] 22 23 + [void] 23 27 + [*] 28 29 + [dest] 29 33 + [,] 33 34 + [int] 34 37 + [fill_value] 38 48 + [,] 48 49 + [int] 49 52 + [count] 53 58 + [)] 58 59 +L19 + [{] 1 2 +L20 + [__asm] 5 10 + [__volatile__] 11 23 + [(] 23 24 +L21 + ["cld\\n"] 10 17 +L22 + ["mov %ecx, %ebx\\n"] 10 28 +L23 + ["shr 2,%ecx\\n"] 10 24 +L24 + ["rep "] 10 16 +L25 + ["stosl\\n"] 10 19 +L26 + ["mov %ebx,%ecx\\n"] 10 27 +L27 + [" // line 157 mentioned above"] 10 41 +L28 + [:] 10 11 +L29 + [:] 10 11 + ["c"] 12 15 + [(] 16 17 + [count] 17 22 + [)] 22 23 + [,] 23 24 + ["a"] 25 28 + [(] 29 30 + [fill_value] 30 40 + [)] 40 41 + [,] 41 42 + ["D"] 43 46 + [(] 47 48 + [dest] 48 52 + [)] 52 53 +L30 + [:] 10 11 + ["cc"] 12 16 + [,] 16 17 + ["%ebx"] 17 23 + [)] 24 25 + [;] 25 26 +L31 + [}] 1 2 +L35 + [int] 1 4 + [otherMethod] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 +L36 + [}] 1 2 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/cpp_with_continuation.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation.cpp similarity index 100% rename from pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/cpp_with_continuation.cpp rename to pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation.cpp diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation.txt new file mode 100644 index 0000000000..616ca27009 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation.txt @@ -0,0 +1,68 @@ + [Image] or [Truncated image[ Bcol Ecol +L8 + [static] 1 7 + [int] 8 11 + [ab] 12 2 +L9 + [=] 3 4 + [5] 5 6 + [;] 6 7 +L12 + [int] 1 4 + [main] 5 9 + [(] 9 10 + [)] 10 11 +L13 + [{] 1 2 +L15 + [std] 3 6 + [::] 6 8 + [cout] 8 12 + [<<] 13 15 + ["1 Hello, "] 16 27 +L16 + ["world!\\n"] 16 26 + [;] 26 27 +L18 + [std] 3 6 + [::] 6 8 + [cout] 8 12 + [<<] 13 15 + ["2 Hello, world!\\n"] 16 10 +L19 + [;] 10 11 +L22 + [std] 3 6 + [::] 6 8 + [cout] 8 12 + [<<] 13 15 + ["3 Hello, \\world!\\n"] 16 10 +L23 + [;] 10 11 +L25 + [std] 3 6 + [::] 6 8 + [cout] 8 12 + [<<] 13 15 + ["4 Hello, "] 16 27 +L26 + ["world!\\n"] 15 25 + [;] 25 26 +L27 + [std] 3 6 + [::] 6 8 + [cout] 8 12 + [<<] 13 15 + ["ab="] 16 21 + [<<] 22 24 + [ab] 25 27 + [<<] 28 30 + ["\\n"] 31 35 + [;] 35 36 +L28 + [return] 3 9 + [0] 10 11 + [;] 11 12 +L29 + [}] 1 2 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/cpp_continuation_inter_token.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation_inter_token.cpp similarity index 100% rename from pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/cpp_continuation_inter_token.cpp rename to pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation_inter_token.cpp diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation_inter_token.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation_inter_token.txt new file mode 100644 index 0000000000..30c915c3f7 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation_inter_token.txt @@ -0,0 +1,24 @@ + [Image] or [Truncated image[ Bcol Ecol +L3 + [int] 1 4 + [main] 5 9 + [(] 9 10 + [)] 10 11 +L4 + [{] 1 2 +L5 + [std] 4 7 + [::] 7 9 + [cout] 9 13 + [<<] 14 16 + ["Hello, "] 17 26 +L6 + ["world!\\n"] 17 27 + [;] 27 28 +L7 + [return] 4 10 + [0] 11 12 + [;] 12 13 +L8 + [}] 1 2 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/cpp_continuation_intra_token.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation_intra_token.cpp similarity index 100% rename from pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/cpp_continuation_intra_token.cpp rename to pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation_intra_token.cpp diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation_intra_token.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation_intra_token.txt new file mode 100644 index 0000000000..abc147ce72 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/continuation_intra_token.txt @@ -0,0 +1,13 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [void] 1 1 +L5 + [main] 2 1 +L10 + [(] 1 2 + [)] 2 2 +L12 + [{] 2 2 +L14 + [}] 2 2 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/identifierChars.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/identifierChars.cpp new file mode 100644 index 0000000000..696a52e5da --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/identifierChars.cpp @@ -0,0 +1,7 @@ + void main() { + int x$y = 42; + int $yx = 42; + int 県 = µweiß42; + int ❶ = __; + int a\u0048; // unicode escape + } \ No newline at end of file diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/identifierChars.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/identifierChars.txt new file mode 100644 index 0000000000..9916694f63 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/identifierChars.txt @@ -0,0 +1,38 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [void] 2 6 + [main] 7 11 + [(] 11 12 + [)] 12 13 + [{] 14 15 +L2 + [int] 5 8 + [x$y] 9 12 + [=] 13 14 + [42] 15 17 + [;] 17 18 +L3 + [int] 5 8 + [$yx] 9 12 + [=] 13 14 + [42] 15 17 + [;] 17 18 +L4 + [int] 5 8 + [県] 9 10 + [=] 11 12 + [µweiß42] 13 20 + [;] 20 21 +L5 + [int] 5 8 + [❶] 9 10 + [=] 11 12 + [__] 13 15 + [;] 15 16 +L6 + [int] 5 8 + [a\\u0048] 9 16 + [;] 16 17 +L7 + [}] 2 3 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/issue-1559.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/issue-1559.cpp similarity index 100% rename from pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/issue-1559.cpp rename to pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/issue-1559.cpp diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/issue-1784.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/issue-1784.cpp similarity index 100% rename from pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/issue-1784.cpp rename to pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/issue-1784.cpp diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/issue-1784.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/issue-1784.txt new file mode 100644 index 0000000000..be5d5e1ddc --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/issue-1784.txt @@ -0,0 +1,25 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [namespace] 1 10 + [ABC] 11 14 +L2 + [{] 1 2 +L3 + [namespace] 3 12 + [DEF] 13 16 +L4 + [{] 3 4 +L7 + [const] 5 10 + [char] 11 15 + [*] 15 16 + [perPixelQml] 17 28 + [=] 29 30 + [R"QML(\n )NOTTHEND";\n)QML"] 31 6 +L9 + [;] 6 7 +L10 + [}] 3 4 +L11 + [}] 1 2 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/literals.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/literals.cpp new file mode 100644 index 0000000000..9f0d38b06f --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/literals.cpp @@ -0,0 +1,40 @@ + void main() { + char x = L'a'; // wide chars + x = '\0x05'; // hex + // x = L''; // empty character is an error + + print("\ oMedia"); // whitespace escape + + + // char prefixes + char16_t c = u'\u00F6'; + wchar_t b = L'\xFFEF'; + char a = '\x30'; + char32_t d = U'\U0010FFFF'; + + // string prefixes + char A[] = "Hello\x0A"; + wchar_t B[] = L"Hell\xF6\x0A"; + char16_t C[] = u"Hell\u00F6"; + char32_t D[] = U"Hell\U000000F6\U0010FFFF"; + auto E[] = u8"\u00F6\U0010FFFF"; + + + + char* rawString = R"( + [Sinks.1] + Destination=Console + AutoFlush=true + Format="[%TimeStamp%] %ThreadId% %QueryIdHigh% %QueryIdLow% %LoggerFile%:%Line% (%Severity%) - %Message%" + Filter="%Severity% >= WRN" + )"; + + + + // digit separators + auto integer_literal = 1'000''000; + auto floating_point_literal = 0.000'015'3; + auto hex_literal = 0x0F00'abcd'6f3d; + auto silly_example = 1'0'0'000'00; + +} \ No newline at end of file diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/literals.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/literals.txt new file mode 100644 index 0000000000..3a0185425f --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/literals.txt @@ -0,0 +1,123 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [void] 2 6 + [main] 7 11 + [(] 11 12 + [)] 12 13 + [{] 14 15 +L2 + [char] 5 9 + [x] 10 11 + [=] 12 13 + [L'a'] 14 18 + [;] 18 19 +L3 + [x] 5 6 + [=] 7 8 + ['\\0x05'] 9 16 + [;] 16 17 +L6 + [print] 5 10 + [(] 10 11 + ["\\ oMedia"] 11 24 + [)] 24 25 + [;] 25 26 +L10 + [char16_t] 5 13 + [c] 14 15 + [=] 16 17 + [u'\\u00F6'] 18 27 + [;] 27 28 +L11 + [wchar_t] 5 12 + [b] 13 14 + [=] 15 16 + [L'\\xFFEF'] 17 26 + [;] 26 27 +L12 + [char] 5 9 + [a] 10 11 + [=] 12 13 + ['\\x30'] 15 21 + [;] 21 22 +L13 + [char32_t] 5 13 + [d] 14 15 + [=] 16 17 + [U'\\U0010FFFF'] 18 31 + [;] 31 32 +L16 + [char] 5 9 + [A] 10 11 + [\[] 11 12 + [\]] 12 13 + [=] 14 15 + ["Hello\\x0A"] 16 27 + [;] 27 28 +L17 + [wchar_t] 5 12 + [B] 13 14 + [\[] 14 15 + [\]] 15 16 + [=] 17 18 + [L"Hell\\xF6\\x0A"] 19 34 + [;] 34 35 +L18 + [char16_t] 5 13 + [C] 14 15 + [\[] 15 16 + [\]] 16 17 + [=] 18 19 + [u"Hell\\u00F6"] 20 33 + [;] 33 34 +L19 + [char32_t] 5 13 + [D] 14 15 + [\[] 15 16 + [\]] 16 17 + [=] 18 19 + [U"Hell\\U000000F6\\U0010FFFF"] 20 47 + [;] 47 48 +L20 + [auto] 5 9 + [E] 10 11 + [\[] 11 12 + [\]] 12 13 + [=] 14 15 + [u8"\\u00F6\\U0010FFFF"] 16 36 + [;] 36 37 +L24 + [char] 5 9 + [*] 9 10 + [rawString] 11 20 + [=] 21 22 + [R"(\n \[Sinks.1\]\n [ 23 7 +L30 + [;] 7 8 +L35 + [auto] 5 9 + [integer_literal] 10 25 + [=] 26 27 + [1'000''000] 28 38 + [;] 38 39 +L36 + [auto] 5 9 + [floating_point_literal] 10 32 + [=] 33 34 + [0.000'015'3] 35 46 + [;] 46 47 +L37 + [auto] 5 9 + [hex_literal] 10 21 + [=] 22 23 + [0x0F00'abcd'6f3d] 24 40 + [;] 40 41 +L38 + [auto] 5 9 + [silly_example] 10 23 + [=] 24 25 + [1'0'0'000'00] 26 38 + [;] 38 39 +L40 + [}] 1 2 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/multilineMacros.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/multilineMacros.cpp new file mode 100644 index 0000000000..0b6c240d99 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/multilineMacros.cpp @@ -0,0 +1,8 @@ +#define FOO a +\ + b +\ + c +\ + d +\ + e +\ + f +\ + g + void main() {} \ No newline at end of file diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/multilineMacros.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/multilineMacros.txt new file mode 100644 index 0000000000..8fd1dc5134 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/multilineMacros.txt @@ -0,0 +1,9 @@ + [Image] or [Truncated image[ Bcol Ecol +L8 + [void] 2 6 + [main] 7 11 + [(] 11 12 + [)] 12 13 + [{] 14 15 + [}] 15 16 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/preprocessorDirectives.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/preprocessorDirectives.cpp new file mode 100644 index 0000000000..2cebb6493e --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/preprocessorDirectives.cpp @@ -0,0 +1,2 @@ +#define LSTFVLES_CPP //* +// EOL comment in the directive \ No newline at end of file diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/preprocessorDirectives.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/preprocessorDirectives.txt new file mode 100644 index 0000000000..49ab402048 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/preprocessorDirectives.txt @@ -0,0 +1,2 @@ + [Image] or [Truncated image[ Bcol Ecol +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/cpp_with_asm.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks.cpp similarity index 87% rename from pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/cpp_with_asm.cpp rename to pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks.cpp index 93361b4de6..40691867fc 100644 --- a/pmd-cpp/src/test/resources/net/sourceforge/pmd/cpd/cpp/cpp_with_asm.cpp +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks.cpp @@ -16,8 +16,8 @@ static void my_memset(void *dest,int fill_value,int count) "rep " "stosl\n" "mov %ebx,%ecx\n" - " // line 157 mentioned above - : + " // line 157 mentioned above" + : : "c" (count), "a" (fill_value), "D" (dest) : "cc","%ebx" ); } diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks_noSkip.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks_noSkip.txt new file mode 100644 index 0000000000..9105fa25e2 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks_noSkip.txt @@ -0,0 +1,88 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [int] 1 4 + [main] 5 9 + [(] 9 10 + [)] 10 11 + [{] 12 13 +L2 + [}] 1 2 +L5 + [int] 1 4 + [foobar] 5 11 + [(] 11 12 + [)] 12 13 + [{] 14 15 +L6 + [}] 1 2 +L10 + [static] 1 7 + [void] 8 12 + [my_memset] 13 22 + [(] 22 23 + [void] 23 27 + [*] 28 29 + [dest] 29 33 + [,] 33 34 + [int] 34 37 + [fill_value] 38 48 + [,] 48 49 + [int] 49 52 + [count] 53 58 + [)] 58 59 +L11 + [{] 1 2 +L12 + [__asm] 5 10 + [__volatile__] 11 23 + [(] 23 24 +L13 + ["cld\\n"] 10 17 +L14 + ["mov %ecx, %ebx\\n"] 10 28 +L15 + ["shr 2,%ecx\\n"] 10 24 +L16 + ["rep "] 10 16 +L17 + ["stosl\\n"] 10 19 +L18 + ["mov %ebx,%ecx\\n"] 10 27 +L19 + [" // line 157 mentioned above"] 10 41 +L20 + [:] 10 11 +L21 + [:] 10 11 + ["c"] 12 15 + [(] 16 17 + [count] 17 22 + [)] 22 23 + [,] 23 24 + ["a"] 25 28 + [(] 29 30 + [fill_value] 30 40 + [)] 40 41 + [,] 41 42 + ["D"] 43 46 + [(] 47 48 + [dest] 48 52 + [)] 52 53 +L22 + [:] 10 11 + ["cc"] 12 16 + [,] 16 17 + ["%ebx"] 17 23 + [)] 24 25 + [;] 25 26 +L23 + [}] 1 2 +L27 + [int] 1 4 + [otherMethod] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 +L28 + [}] 1 2 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks_skipDebug.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks_skipDebug.txt new file mode 100644 index 0000000000..ccdebae7a0 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks_skipDebug.txt @@ -0,0 +1,80 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [int] 1 4 + [main] 5 9 + [(] 9 10 + [)] 10 11 + [{] 12 13 +L2 + [}] 1 2 +L10 + [static] 1 7 + [void] 8 12 + [my_memset] 13 22 + [(] 22 23 + [void] 23 27 + [*] 28 29 + [dest] 29 33 + [,] 33 34 + [int] 34 37 + [fill_value] 38 48 + [,] 48 49 + [int] 49 52 + [count] 53 58 + [)] 58 59 +L11 + [{] 1 2 +L12 + [__asm] 5 10 + [__volatile__] 11 23 + [(] 23 24 +L13 + ["cld\\n"] 10 17 +L14 + ["mov %ecx, %ebx\\n"] 10 28 +L15 + ["shr 2,%ecx\\n"] 10 24 +L16 + ["rep "] 10 16 +L17 + ["stosl\\n"] 10 19 +L18 + ["mov %ebx,%ecx\\n"] 10 27 +L19 + [" // line 157 mentioned above"] 10 41 +L20 + [:] 10 11 +L21 + [:] 10 11 + ["c"] 12 15 + [(] 16 17 + [count] 17 22 + [)] 22 23 + [,] 23 24 + ["a"] 25 28 + [(] 29 30 + [fill_value] 30 40 + [)] 40 41 + [,] 41 42 + ["D"] 43 46 + [(] 47 48 + [dest] 48 52 + [)] 52 53 +L22 + [:] 10 11 + ["cc"] 12 16 + [,] 16 17 + ["%ebx"] 17 23 + [)] 24 25 + [;] 25 26 +L23 + [}] 1 2 +L27 + [int] 1 4 + [otherMethod] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 +L28 + [}] 1 2 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks_skipDefault.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks_skipDefault.txt new file mode 100644 index 0000000000..d8cd8a6373 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/simpleSkipBlocks_skipDefault.txt @@ -0,0 +1,26 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [int] 1 4 + [main] 5 9 + [(] 9 10 + [)] 10 11 + [{] 12 13 +L2 + [}] 1 2 +L5 + [int] 1 4 + [foobar] 5 11 + [(] 11 12 + [)] 12 13 + [{] 14 15 +L6 + [}] 1 2 +L27 + [int] 1 4 + [otherMethod] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 +L28 + [}] 1 2 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/specialComments.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/specialComments.cpp new file mode 100644 index 0000000000..174385240d --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/specialComments.cpp @@ -0,0 +1,11 @@ +#include +#include + +// CPD-OFF +int main() +{ + std::string text("ąęćśźńó"); + std::cout << text; + return 0; +// CPD-ON +} diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/specialComments.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/specialComments.txt new file mode 100644 index 0000000000..c6fe074514 --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/specialComments.txt @@ -0,0 +1,4 @@ + [Image] or [Truncated image[ Bcol Ecol +L11 + [}] 1 2 +EOF diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/unicodeStrings.cpp b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/unicodeStrings.cpp new file mode 100644 index 0000000000..badbd5465c --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/unicodeStrings.cpp @@ -0,0 +1,11 @@ +#include +#include + +// example + +int main() +{ + std::string text("ąęćśźńó"); + std::cout << text; + return 0; +} diff --git a/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/unicodeStrings.txt b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/unicodeStrings.txt new file mode 100644 index 0000000000..39f38aa76d --- /dev/null +++ b/pmd-cpp/src/test/resources/net/sourceforge/pmd/lang/cpp/cpd/testdata/unicodeStrings.txt @@ -0,0 +1,31 @@ + [Image] or [Truncated image[ Bcol Ecol +L6 + [int] 1 4 + [main] 5 9 + [(] 9 10 + [)] 10 11 +L7 + [{] 1 2 +L8 + [std] 5 8 + [::] 8 10 + [string] 10 16 + [text] 17 21 + [(] 21 22 + ["ąęćśźńó"] 22 31 + [)] 31 32 + [;] 32 33 +L9 + [std] 5 8 + [::] 8 10 + [cout] 10 14 + [<<] 15 17 + [text] 18 22 + [;] 22 23 +L10 + [return] 5 11 + [0] 12 13 + [;] 13 14 +L11 + [}] 1 2 +EOF diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 17f71d4e62..7e11e43d1d 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -45,10 +45,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java b/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java index 7121f2131e..0828c4cc24 100644 --- a/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java +++ b/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java @@ -1,191 +1,97 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.cpd; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; +import java.util.Properties; -import java.util.List; - -import org.junit.Before; import org.junit.Test; +import org.junit.rules.ExpectedException; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; import net.sourceforge.pmd.lang.ast.TokenMgrError; -public class CsTokenizerTest { +public class CsTokenizerTest extends CpdTextComparisonTest { - private CsTokenizer tokenizer; + @org.junit.Rule + public ExpectedException ex = ExpectedException.none(); - private Tokens tokens; + public CsTokenizerTest() { + super(".cs"); + } - @Before - public void init() { - tokenizer = new CsTokenizer(); - tokens = new Tokens(); - TokenEntry.clearImages(); + @Override + protected String getResourcePrefix() { + return "../lang/cs/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + CsTokenizer tok = new CsTokenizer(); + tok.setProperties(properties); + return tok; } @Test public void testSimpleClass() { - tokenizer.tokenize(toSourceCode("class Foo {}"), tokens); - assertEquals(5, tokens.size()); - } - - @Test - public void testSimpleClassDuplicatedTokens() { - tokenizer.tokenize(toSourceCode("class Foo { class Foo { } }"), tokens); - assertEquals(9, tokens.size()); - List tokenList = tokens.getTokens(); - assertEquals(tokenList.get(0).getIdentifier(), tokenList.get(3).getIdentifier()); - assertEquals(tokenList.get(1).getIdentifier(), tokenList.get(4).getIdentifier()); - assertEquals(tokenList.get(2).getIdentifier(), tokenList.get(5).getIdentifier()); - assertEquals(tokenList.get(6).getIdentifier(), tokenList.get(7).getIdentifier()); + doTest("simpleClass"); } @Test public void testSimpleClassMethodMultipleLines() { - tokenizer.tokenize(toSourceCode("class Foo {\n" + " public String foo(int a) {\n" + " int i = a;\n" - + " return \"x\" + a;\n" + " }\n" + "}"), tokens); - assertEquals(24, tokens.size()); - List tokenList = tokens.getTokens(); - assertEquals(1, tokenList.get(0).getBeginLine()); - assertEquals(2, tokenList.get(4).getBeginLine()); - assertEquals(3, tokenList.get(11).getBeginLine()); + doTest("simpleClassMethodMultipleLines"); } @Test public void testStrings() { - tokenizer.tokenize(toSourceCode("String s =\"aaa \\\"b\\n\";"), tokens); - assertEquals(6, tokens.size()); + doTest("strings"); } - @Test(expected = TokenMgrError.class) + @Test public void testOpenString() { - tokenizer.tokenize(toSourceCode("String s =\"aaa \\\"b\\"), tokens); + ex.expect(TokenMgrError.class); + doTest("unlexable_string"); } @Test public void testCommentsIgnored1() { - tokenizer.tokenize(toSourceCode("class Foo { /* class * ** X */ }"), tokens); - assertEquals(5, tokens.size()); - } - - @Test - public void testCommentsIgnored2() { - tokenizer.tokenize(toSourceCode("class Foo { // class X /* aaa */ \n }"), tokens); - assertEquals(5, tokens.size()); + doTest("comments"); } @Test public void testIgnoreBetweenSpecialComments() { - tokenizer - .tokenize( - toSourceCode("// CPD-OFF\n" + "class Foo {\n" + " void bar() {\n" + " int a = 1 >> 2; \n" - + " a += 1; \n" + " a++; \n" + " a /= 3e2; \n" + " float f = -3.1; \n" - + " f *= 2; \n" + " bool b = ! (f == 2.0 || f >= 1.0 && f <= 2.0) \n" - + " }\n" + "// CPD-ON\n" + "}"), - tokens); - assertEquals(2, tokens.size()); // "}" + EOF + doTest("specialComments"); } @Test - public void testCommentsIgnored3() { - tokenizer.tokenize(toSourceCode("class Foo { /// class X /* aaa */ \n }"), tokens); - assertEquals(5, tokens.size()); + public void testOperators() { + doTest("operatorsAndStuff"); } - @Test - public void testMoreTokens() { - tokenizer - .tokenize( - toSourceCode("class Foo {\n" + " void bar() {\n" + " int a = 1 >> 2; \n" + " a += 1; \n" - + " a++; \n" + " a /= 3e2; \n" + " float f = -3.1; \n" + " f *= 2; \n" - + " bool b = ! (f == 2.0 || f >= 1.0 && f <= 2.0) \n" + " }\n" + "}"), - tokens); - assertEquals(57, tokens.size()); - } - - @Test - public void testLineNumberAfterMultilineComment() { - tokenizer - .tokenize( - toSourceCode("/* This is a multiline comment \n" + " * \n" + " * Lorem ipsum dolor sit amet, \n" - + " * consectetur adipiscing elit \n" + " */\n" + "\n" + "class Foo {\n" + "\n" + "}"), - tokens); - assertEquals(5, tokens.size()); - assertEquals(7, tokens.getTokens().get(0).getBeginLine()); - } @Test public void testLineNumberAfterMultilineString() { - tokenizer.tokenize(toSourceCode( - "class Foo {\n" + " void bar() {\n" + " String query = \n" + " @\"SELECT foo, bar\n" - + " FROM table \n" + " WHERE id = 42\"; \n" + " }\n" + "}"), - tokens); - assertEquals(16, tokens.size()); - assertEquals(8, tokens.getTokens().get(14).getBeginLine()); + doTest("strings"); } @Test public void testDoNotIgnoreUsingDirectives() { - tokenizer.setIgnoreUsings(false); - tokenizer.tokenize(toSourceCode("using System.Text;\n"), tokens); - assertEquals(6, tokens.size()); - assertEquals("using", tokens.getTokens().get(0).toString()); + doTest("usingDirectives"); } @Test public void testIgnoreUsingDirectives() { - tokenizer.setIgnoreUsings(true); - tokenizer.tokenize(toSourceCode("using System.Text;\n"), tokens); - assertEquals(1, tokens.size()); - assertNotEquals("using", tokens.getTokens().get(0).toString()); - assertEquals(TokenEntry.EOF, tokens.getTokens().get(0)); + doTest("usingDirectives", "_ignored", ignoreUsings()); } - @Test - public void testStatementsAfterUsingDirectivesAreNotIgnored() { - tokenizer.setIgnoreUsings(true); - tokenizer.tokenize(toSourceCode( - "using System;\n" - + "public class MyClass {\n" - + "}\n"), - tokens); - assertEquals(6, tokens.size()); + private Properties ignoreUsings() { + return properties(true); } - @Test - public void testUsingStatementsAreNotIgnored() { - tokenizer.setIgnoreUsings(true); - tokenizer.tokenize(toSourceCode( - "using (Font font1 = new Font(\"Arial\", 10.0f)) {\n" + " byte charset = font1.GdiCharSet;\n" + "}\n"), - tokens); - assertEquals("using", tokens.getTokens().get(0).toString()); - } - - @Test - public void testUsingVarStatementsAreNotIgnored() { - tokenizer.setIgnoreUsings(true); - tokenizer.tokenize(toSourceCode( - "using var font1 = new Font(\"Arial\", 10.0f);\n" + " byte charset = font1.GdiCharSet;\n"), - tokens); - assertEquals("using", tokens.getTokens().get(0).toString()); - } - - @Test - public void testInterpolatedVerbatimStrings() { - tokenizer.setIgnoreUsings(true); - tokenizer.tokenize(toSourceCode( - "var test = $@\"test\";\n" - + "var test2 = @$\"test\";"), - tokens - ); - assertEquals(15, tokens.size()); - } - - private SourceCode toSourceCode(String source) { - return new SourceCode(new SourceCode.StringCodeLoader(source)); + private Properties properties(boolean ignoreUsings) { + Properties properties = new Properties(); + properties.setProperty(Tokenizer.IGNORE_USINGS, Boolean.toString(ignoreUsings)); + return properties; } } diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/comments.cs b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/comments.cs new file mode 100644 index 0000000000..1757cf2afd --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/comments.cs @@ -0,0 +1,6 @@ +class Foo { /// class X + /* aaa + + dedejde + */ + } \ No newline at end of file diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/comments.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/comments.txt new file mode 100644 index 0000000000..7ab6aaca6b --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/comments.txt @@ -0,0 +1,8 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [class] 1 6 + [Foo] 7 10 + [{] 11 12 +L6 + [}] 2 3 +EOF diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/operatorsAndStuff.cs b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/operatorsAndStuff.cs new file mode 100644 index 0000000000..b94f5972de --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/operatorsAndStuff.cs @@ -0,0 +1,11 @@ +class Foo { + void bar() { + int a = 1 >> 2; + a += 1; + a++; + a /= 3e2; + float f = -3.1; + f *= 2; + bool b = ! (f == 2.0 || f >= 1.0 && f <= 2.0) + } +} \ No newline at end of file diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/operatorsAndStuff.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/operatorsAndStuff.txt new file mode 100644 index 0000000000..30e95711f3 --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/operatorsAndStuff.txt @@ -0,0 +1,69 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [class] 1 6 + [Foo] 7 10 + [{] 11 12 +L2 + [void] 3 7 + [bar] 8 11 + [(] 11 12 + [)] 12 13 + [{] 14 15 +L3 + [int] 5 8 + [a] 9 10 + [=] 11 12 + [1] 13 14 + [>] 15 16 + [>] 16 17 + [2] 18 19 + [;] 19 20 +L4 + [a] 5 6 + [+=] 7 9 + [1] 10 11 + [;] 11 12 +L5 + [a] 5 6 + [++] 6 8 + [;] 8 9 +L6 + [a] 5 6 + [/=] 7 9 + [3e2] 10 13 + [;] 13 14 +L7 + [float] 5 10 + [f] 11 12 + [=] 13 14 + [-] 15 16 + [3.1] 16 19 + [;] 19 20 +L8 + [f] 5 6 + [*=] 7 9 + [2] 10 11 + [;] 11 12 +L9 + [bool] 5 9 + [b] 10 11 + [=] 12 13 + [!] 14 15 + [(] 16 17 + [f] 17 18 + [==] 19 21 + [2.0] 22 25 + [||] 26 28 + [f] 29 30 + [>=] 31 33 + [1.0] 34 37 + [&&] 38 40 + [f] 41 42 + [<=] 43 45 + [2.0] 46 49 + [)] 49 50 +L10 + [}] 3 4 +L11 + [}] 1 2 +EOF diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClass.cs b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClass.cs new file mode 100644 index 0000000000..c3c54739d9 --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClass.cs @@ -0,0 +1 @@ +class Foo { class Foo { } } \ No newline at end of file diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClass.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClass.txt new file mode 100644 index 0000000000..bbe7ed6f13 --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClass.txt @@ -0,0 +1,11 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [class] 1 6 + [Foo] 7 10 + [{] 11 12 + [class] 13 18 + [Foo] 19 22 + [{] 23 24 + [}] 25 26 + [}] 27 28 +EOF diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClassMethodMultipleLines.cs b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClassMethodMultipleLines.cs new file mode 100644 index 0000000000..38b1f8995c --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClassMethodMultipleLines.cs @@ -0,0 +1,6 @@ +class Foo { + public String foo(int a) { + int i = a; + return "x" + a; + } +} \ No newline at end of file diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClassMethodMultipleLines.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClassMethodMultipleLines.txt new file mode 100644 index 0000000000..32b6877fa3 --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/simpleClassMethodMultipleLines.txt @@ -0,0 +1,31 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [class] 1 6 + [Foo] 7 10 + [{] 11 12 +L2 + [public] 3 9 + [String] 10 16 + [foo] 17 20 + [(] 20 21 + [int] 21 24 + [a] 25 26 + [)] 26 27 + [{] 28 29 +L3 + [int] 5 8 + [i] 9 10 + [=] 11 12 + [a] 13 14 + [;] 14 15 +L4 + [return] 5 11 + ["x"] 12 15 + [+] 16 17 + [a] 18 19 + [;] 19 20 +L5 + [}] 3 4 +L6 + [}] 1 2 +EOF diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/specialComments.cs b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/specialComments.cs new file mode 100644 index 0000000000..cde6ce90eb --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/specialComments.cs @@ -0,0 +1,13 @@ +// CPD-OFF +class Foo { + void bar() { + int a = 1 >> 2; + a += 1; + a++; + a /= 3e2; + float f = -3.1; + f *= 2; + bool b = ! (f == 2.0 || f >= 1.0 && f <= 2.0) + } +// CPD-ON +} \ No newline at end of file diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/specialComments.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/specialComments.txt new file mode 100644 index 0000000000..e1b70d0ec0 --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/specialComments.txt @@ -0,0 +1,4 @@ + [Image] or [Truncated image[ Bcol Ecol +L13 + [}] 1 2 +EOF diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/strings.cs b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/strings.cs new file mode 100644 index 0000000000..1d6e607016 --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/strings.cs @@ -0,0 +1,12 @@ +class Foo { + void bar() { + + var test = $@"test"; + var test2 = @$"test"; + + String query = + @"SELECT foo, bar + FROM table + WHERE id = 42"; + } +} \ No newline at end of file diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/strings.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/strings.txt new file mode 100644 index 0000000000..738e3933b7 --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/strings.txt @@ -0,0 +1,40 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [class] 1 6 + [Foo] 7 10 + [{] 11 12 +L2 + [void] 3 7 + [bar] 8 11 + [(] 11 12 + [)] 12 13 + [{] 14 15 +L4 + [var] 5 8 + [test] 9 13 + [=] 14 15 + [$@"] 16 19 + [test] 19 23 + ["] 23 24 + [;] 24 25 +L5 + [var] 5 8 + [test2] 9 14 + [=] 15 16 + [@$"] 17 20 + [test] 20 24 + ["] 24 25 + [;] 25 26 +L7 + [String] 5 11 + [query] 12 17 + [=] 18 19 +L8 + [@"SELECT foo, bar\n FROM t[ 7 24 +L10 + [;] 24 25 +L11 + [}] 3 4 +L12 + [}] 1 2 +EOF diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/unlexable_string.cs b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/unlexable_string.cs new file mode 100644 index 0000000000..ce0b72f2bc --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/unlexable_string.cs @@ -0,0 +1,3 @@ + +// this literal is not closed +String s ="aaa \"b\ \ No newline at end of file diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/usingDirectives.cs b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/usingDirectives.cs new file mode 100644 index 0000000000..c2e193c1d3 --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/usingDirectives.cs @@ -0,0 +1,16 @@ +using System.Text; // ignored +using System; // ignored + +// rest is not ignored +public class MyClass { + + void foo() { + using (Font font1 = new Font("Arial", 10.0f)) { + byte charset = font1.GdiCharSet; + } + + using var font1 = new Font("Arial", 10.0f); + byte charset = font1.GdiCharSet; + } + +} diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/usingDirectives.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/usingDirectives.txt new file mode 100644 index 0000000000..69732da21b --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/usingDirectives.txt @@ -0,0 +1,73 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [using] 1 6 + [System] 7 13 + [.] 13 14 + [Text] 14 18 + [;] 18 19 +L2 + [using] 1 6 + [System] 7 13 + [;] 13 14 +L5 + [public] 1 7 + [class] 8 13 + [MyClass] 14 21 + [{] 22 23 +L7 + [void] 5 9 + [foo] 10 13 + [(] 13 14 + [)] 14 15 + [{] 16 17 +L8 + [using] 9 14 + [(] 15 16 + [Font] 16 20 + [font1] 21 26 + [=] 27 28 + [new] 29 32 + [Font] 33 37 + [(] 37 38 + ["Arial"] 38 45 + [,] 45 46 + [10.0f] 47 52 + [)] 52 53 + [)] 53 54 + [{] 55 56 +L9 + [byte] 11 15 + [charset] 16 23 + [=] 24 25 + [font1] 26 31 + [.] 31 32 + [GdiCharSet] 32 42 + [;] 42 43 +L10 + [}] 9 10 +L12 + [using] 9 14 + [var] 15 18 + [font1] 19 24 + [=] 25 26 + [new] 27 30 + [Font] 31 35 + [(] 35 36 + ["Arial"] 36 43 + [,] 43 44 + [10.0f] 45 50 + [)] 50 51 + [;] 51 52 +L13 + [byte] 9 13 + [charset] 14 21 + [=] 22 23 + [font1] 24 29 + [.] 29 30 + [GdiCharSet] 30 40 + [;] 40 41 +L14 + [}] 5 6 +L16 + [}] 1 2 +EOF diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/usingDirectives_ignored.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/usingDirectives_ignored.txt new file mode 100644 index 0000000000..3f84b0f9f2 --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/usingDirectives_ignored.txt @@ -0,0 +1,63 @@ + [Image] or [Truncated image[ Bcol Ecol +L5 + [public] 1 7 + [class] 8 13 + [MyClass] 14 21 + [{] 22 23 +L7 + [void] 5 9 + [foo] 10 13 + [(] 13 14 + [)] 14 15 + [{] 16 17 +L8 + [using] 9 14 + [(] 15 16 + [Font] 16 20 + [font1] 21 26 + [=] 27 28 + [new] 29 32 + [Font] 33 37 + [(] 37 38 + ["Arial"] 38 45 + [,] 45 46 + [10.0f] 47 52 + [)] 52 53 + [)] 53 54 + [{] 55 56 +L9 + [byte] 11 15 + [charset] 16 23 + [=] 24 25 + [font1] 26 31 + [.] 31 32 + [GdiCharSet] 32 42 + [;] 42 43 +L10 + [}] 9 10 +L12 + [using] 9 14 + [var] 15 18 + [font1] 19 24 + [=] 25 26 + [new] 27 30 + [Font] 31 35 + [(] 35 36 + ["Arial"] 36 43 + [,] 43 44 + [10.0f] 45 50 + [)] 50 51 + [;] 51 52 +L13 + [byte] 9 13 + [charset] 14 21 + [=] 22 23 + [font1] 24 29 + [.] 29 30 + [GdiCharSet] 30 40 + [;] 40 41 +L14 + [}] 5 6 +L16 + [}] 1 2 +EOF diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index ab58a56167..50d4cb3d2f 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -49,10 +49,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-dart/src/test/java/net/sourceforge/pmd/cpd/DartTokenizerTest.java b/pmd-dart/src/test/java/net/sourceforge/pmd/cpd/DartTokenizerTest.java index dc1e125322..26382e6212 100644 --- a/pmd-dart/src/test/java/net/sourceforge/pmd/cpd/DartTokenizerTest.java +++ b/pmd-dart/src/test/java/net/sourceforge/pmd/cpd/DartTokenizerTest.java @@ -1,65 +1,85 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.cpd; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collection; +import java.util.Properties; -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -@RunWith(Parameterized.class) -public class DartTokenizerTest extends AbstractTokenizerTest { +public class DartTokenizerTest extends CpdTextComparisonTest { - private final String filename; - private final int nExpectedTokens; - - public DartTokenizerTest(String filename, int nExpectedTokens) { - this.filename = filename; - this.nExpectedTokens = nExpectedTokens; - } - - @Parameterized.Parameters - public static Collection data() { - return Arrays.asList( - new Object[] { "comment.dart", 5 }, - new Object[] { "escape_sequences.dart", 13 }, - new Object[] { "escaped_backslash.dart", 14 }, - new Object[] { "escaped_string.dart", 17 }, - new Object[] { "increment.dart", 185 }, - new Object[] { "imports.dart", 1 }, - new Object[] { "regex.dart", 13 }, - new Object[] { "regex2.dart", 13 }, - new Object[] { "regex3.dart", 13 }, - new Object[] { "string_with_backslashes.dart", 9 }, - new Object[] { "string_multiline.dart", 13 } - ); - } - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new DartTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), this.filename)); + public DartTokenizerTest() { + super(".dart"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(DartTokenizer.class.getResourceAsStream(this.filename), StandardCharsets.UTF_8); + public Tokenizer newTokenizer(Properties properties) { + return new DartTokenizer(); + } + + + @Test + public void testComment() { + doTest("comment"); } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = nExpectedTokens; - super.tokenizeTest(); + public void testEscapeSequences() { + doTest("escape_sequences"); } + + @Test + public void testEscapedBackslash() { + doTest("escaped_backslash"); + } + + @Test + public void testEscapedString() { + doTest("escaped_string"); + } + + + @Test + public void testIncrement() { + doTest("increment"); + } + + + @Test + public void testImports() { + doTest("imports"); + } + + + + @Test + public void testRegex() { + doTest("regex"); + } + + + @Test + public void testRegex2() { + doTest("regex2"); + } + + @Test + public void testRegex3() { + doTest("regex3"); + } + + @Test + public void testStringWithBackslashes() { + doTest("string_with_backslashes"); + } + + @Test + public void testMultiline() { + doTest("string_multiline"); + } + } diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/comment.dart b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/comment.dart similarity index 100% rename from pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/comment.dart rename to pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/comment.dart diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/comment.txt b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/comment.txt new file mode 100644 index 0000000000..0ffae05d93 --- /dev/null +++ b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/comment.txt @@ -0,0 +1,7 @@ + [Image] or [Truncated image[ Bcol Ecol +L3 + [var] 1 4 + [x] 5 6 + [=] 7 8 + [0] 9 10 +EOF diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/escape_sequences.dart b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escape_sequences.dart similarity index 100% rename from pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/escape_sequences.dart rename to pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escape_sequences.dart diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escape_sequences.txt b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escape_sequences.txt new file mode 100644 index 0000000000..77851f2bc6 --- /dev/null +++ b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escape_sequences.txt @@ -0,0 +1,17 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [var] 1 4 + [newline] 5 12 + [=] 13 14 + ['\\n'] 15 19 +L2 + [var] 1 4 + [dollar] 5 11 + [=] 12 13 + ['$'] 14 17 +L3 + [var] 1 4 + [escaped_dollar] 5 19 + [=] 20 21 + ["\\$"] 22 26 +EOF diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/escaped_backslash.dart b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escaped_backslash.dart similarity index 100% rename from pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/escaped_backslash.dart rename to pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escaped_backslash.dart diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escaped_backslash.txt b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escaped_backslash.txt new file mode 100644 index 0000000000..b5b13f53c3 --- /dev/null +++ b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escaped_backslash.txt @@ -0,0 +1,17 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [var] 1 4 + [separator] 5 14 + [=] 15 16 + ['\\\\'] 17 21 +L2 + [var] 1 4 + [separators] 5 15 + [=] 16 17 + [const] 18 23 + [\[] 24 25 + ['/'] 25 28 + [,] 28 29 + ['\\\\'] 30 34 + [\]] 34 35 +EOF diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/escaped_string.dart b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escaped_string.dart similarity index 100% rename from pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/escaped_string.dart rename to pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escaped_string.dart diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escaped_string.txt b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escaped_string.txt new file mode 100644 index 0000000000..4ed1d06c7f --- /dev/null +++ b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/escaped_string.txt @@ -0,0 +1,22 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [var] 1 4 + [a] 5 6 + [=] 7 8 + ["a"] 9 12 +L2 + [var] 1 4 + [b] 5 6 + [=] 7 8 + ["b"] 9 12 +L3 + [var] 1 4 + [c] 5 6 + [=] 7 8 + ["c"] 9 12 +L4 + [var] 1 4 + [x] 5 6 + [=] 7 8 + ["$a(b: $b, c: \\"$c\\")"] 9 31 +EOF diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/imports.dart b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/imports.dart similarity index 100% rename from pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/imports.dart rename to pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/imports.dart diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/imports.txt b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/imports.txt new file mode 100644 index 0000000000..49ab402048 --- /dev/null +++ b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/imports.txt @@ -0,0 +1,2 @@ + [Image] or [Truncated image[ Bcol Ecol +EOF diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/increment.dart b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/increment.dart similarity index 100% rename from pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/increment.dart rename to pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/increment.dart diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/increment.txt b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/increment.txt new file mode 100644 index 0000000000..3a9c53e1d3 --- /dev/null +++ b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/increment.txt @@ -0,0 +1,207 @@ + [Image] or [Truncated image[ Bcol Ecol +L3 + [var] 1 4 + [x] 5 6 + [=] 7 8 + [0] 9 10 +L5 + [void] 1 5 + [increment1] 6 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 29 30 +L6 + [void] 1 5 + [increment2] 6 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 29 30 +L7 + [void] 1 5 + [increment3] 6 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 29 30 +L8 + [void] 1 5 + [increment4] 6 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 29 30 +L9 + [void] 1 5 + [increment5] 6 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 29 30 +L10 + [void] 1 5 + [increment6] 6 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 29 30 +L11 + [void] 1 5 + [increment7] 6 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 29 30 +L12 + [void] 1 5 + [increment8] 6 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 29 30 +L13 + [void] 1 5 + [increment9] 6 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 29 30 +L14 + [void] 1 5 + [increment10] 6 17 + [(] 17 18 + [)] 18 19 + [{] 20 21 + [x] 22 23 + [+=] 24 26 + [1] 27 28 + [}] 30 31 +L15 + [void] 1 5 + [increment11] 6 17 + [(] 17 18 + [)] 18 19 + [{] 20 21 + [x] 22 23 + [+=] 24 26 + [1] 27 28 + [}] 30 31 +L16 + [void] 1 5 + [increment12] 6 17 + [(] 17 18 + [)] 18 19 + [{] 20 21 + [x] 22 23 + [+=] 24 26 + [1] 27 28 + [}] 30 31 +L17 + [void] 1 5 + [increment13] 6 17 + [(] 17 18 + [)] 18 19 + [{] 20 21 + [x] 22 23 + [+=] 24 26 + [1] 27 28 + [}] 30 31 +L18 + [void] 1 5 + [increment14] 6 17 + [(] 17 18 + [)] 18 19 + [{] 20 21 + [x] 22 23 + [+=] 24 26 + [1] 27 28 + [}] 30 31 +L19 + [void] 1 5 + [increment15] 6 17 + [(] 17 18 + [)] 18 19 + [{] 20 21 + [x] 22 23 + [+=] 24 26 + [1] 27 28 + [}] 30 31 +L20 + [void] 1 5 + [increment16] 6 17 + [(] 17 18 + [)] 18 19 + [{] 20 21 + [x] 22 23 + [+=] 24 26 + [1] 27 28 + [}] 30 31 +L21 + [void] 1 5 + [increment17] 6 17 + [(] 17 18 + [)] 18 19 + [{] 20 21 + [x] 22 23 + [+=] 24 26 + [1] 27 28 + [}] 30 31 +L22 + [void] 1 5 + [increment18] 6 17 + [(] 17 18 + [)] 18 19 + [{] 20 21 + [x] 22 23 + [+=] 24 26 + [1] 27 28 + [}] 30 31 +L23 + [void] 1 5 + [increment19] 6 17 + [(] 17 18 + [)] 18 19 + [{] 20 21 + [x] 22 23 + [+=] 24 26 + [1] 27 28 + [}] 30 31 +L24 + [void] 1 5 + [increment20] 6 17 + [(] 17 18 + [)] 18 19 + [{] 20 21 + [x] 22 23 + [+=] 24 26 + [1] 27 28 + [}] 30 31 +EOF diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/regex.dart b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex.dart similarity index 100% rename from pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/regex.dart rename to pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex.dart diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex.txt b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex.txt new file mode 100644 index 0000000000..282bbb7bdf --- /dev/null +++ b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex.txt @@ -0,0 +1,17 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [class] 1 6 + [MyClass] 7 14 + [{] 15 16 +L2 + [final] 3 8 + [regex] 9 14 + [=] 15 16 + [new] 17 20 + [RegExp] 21 27 + [(] 27 28 + [r'^--(\[a-zA-Z\\-_0-9\]+)(=(.*))?$[ 28 60 + [)] 60 61 +L3 + [}] 1 2 +EOF diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/regex2.dart b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex2.dart similarity index 100% rename from pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/regex2.dart rename to pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex2.dart diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex2.txt b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex2.txt new file mode 100644 index 0000000000..8fe461d9bd --- /dev/null +++ b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex2.txt @@ -0,0 +1,17 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [class] 1 6 + [MyClass] 7 14 + [{] 15 16 +L2 + [final] 3 8 + [regex] 9 14 + [=] 15 16 + [new] 17 20 + [RegExp] 21 27 + [(] 27 28 + [r"(^\[a-zA-Z\]\[-+.a-zA-Z\\d\]*://[ 28 65 + [)] 65 66 +L3 + [}] 1 2 +EOF diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/regex3.dart b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex3.dart similarity index 100% rename from pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/regex3.dart rename to pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex3.dart diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex3.txt b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex3.txt new file mode 100644 index 0000000000..cde3cb0f31 --- /dev/null +++ b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/regex3.txt @@ -0,0 +1,17 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [class] 1 6 + [MyClass] 7 14 + [{] 15 16 +L2 + [final] 3 8 + [regex] 9 14 + [=] 15 16 + [new] 17 20 + [RegExp] 21 27 + [(] 27 28 + [r'''\[ \\t\\r\\n"'\\\\/\]'''] 28 49 + [)] 49 50 +L3 + [}] 1 2 +EOF diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/string_multiline.dart b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/string_multiline.dart similarity index 100% rename from pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/string_multiline.dart rename to pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/string_multiline.dart diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/string_multiline.txt b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/string_multiline.txt new file mode 100644 index 0000000000..ee8d2dcc3e --- /dev/null +++ b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/string_multiline.txt @@ -0,0 +1,18 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [class] 1 6 + [MyClass] 7 14 + [{] 15 16 +L2 + [var] 5 8 + [s1] 9 11 + [=] 12 13 + ['''\nYou can create\nmulti-line st[ 14 4 +L7 + [var] 5 8 + [s2] 9 11 + [=] 12 13 + ["""This is also a\nmulti-line stri[ 14 22 +L9 + [}] 1 2 +EOF diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/string_with_backslashes.dart b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/string_with_backslashes.dart similarity index 100% rename from pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/string_with_backslashes.dart rename to pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/string_with_backslashes.dart diff --git a/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/string_with_backslashes.txt b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/string_with_backslashes.txt new file mode 100644 index 0000000000..3f23356016 --- /dev/null +++ b/pmd-dart/src/test/resources/net/sourceforge/pmd/cpd/testdata/string_with_backslashes.txt @@ -0,0 +1,13 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [class] 1 6 + [MyClass] 7 14 + [{] 15 16 +L2 + [final] 3 8 + [stringWithBackslashes] 9 30 + [=] 31 32 + ["Escaping\\ spaces\\ should work"] 33 64 +L3 + [}] 1 2 +EOF diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 2e65034e59..5af6f49541 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -39,10 +39,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-fortran/src/test/java/net/sourceforge/pmd/cpd/FortranTokenizerTest.java b/pmd-fortran/src/test/java/net/sourceforge/pmd/cpd/FortranTokenizerTest.java index 6058ffe1b0..f143b6339a 100644 --- a/pmd-fortran/src/test/java/net/sourceforge/pmd/cpd/FortranTokenizerTest.java +++ b/pmd-fortran/src/test/java/net/sourceforge/pmd/cpd/FortranTokenizerTest.java @@ -4,36 +4,34 @@ package net.sourceforge.pmd.cpd; -import java.io.IOException; -import java.nio.charset.StandardCharsets; +import java.util.Properties; -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; /** * @author rpelisse * */ -public class FortranTokenizerTest extends AbstractTokenizerTest { +public class FortranTokenizerTest extends CpdTextComparisonTest { - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new FortranTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), "sample.for")); + public FortranTokenizerTest() { + super(".for"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(FortranTokenizerTest.class.getResourceAsStream("sample.for"), StandardCharsets.UTF_8); + protected String getResourcePrefix() { + return "../lang/fortran/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new FortranTokenizer(); } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 434; - super.tokenizeTest(); + public void testSample() { + doTest("sample"); } } diff --git a/pmd-fortran/src/test/resources/net/sourceforge/pmd/cpd/sample.for b/pmd-fortran/src/test/resources/net/sourceforge/pmd/lang/fortran/cpd/testdata/sample.for similarity index 100% rename from pmd-fortran/src/test/resources/net/sourceforge/pmd/cpd/sample.for rename to pmd-fortran/src/test/resources/net/sourceforge/pmd/lang/fortran/cpd/testdata/sample.for diff --git a/pmd-fortran/src/test/resources/net/sourceforge/pmd/lang/fortran/cpd/testdata/sample.txt b/pmd-fortran/src/test/resources/net/sourceforge/pmd/lang/fortran/cpd/testdata/sample.txt new file mode 100644 index 0000000000..8776a93786 --- /dev/null +++ b/pmd-fortran/src/test/resources/net/sourceforge/pmd/lang/fortran/cpd/testdata/sample.txt @@ -0,0 +1,566 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [options/extend_source] 8 29 +L2 + [program] 8 15 + [tp3] 16 19 +L3 + [implicit] 8 16 + [none] 17 21 +L5 + [! ce programme va demander la sais[ 1 88 +L6 + [!parties de la chaine en plusieurs[ 1 93 +L7 + [!sous programme correspondant.] 1 31 +L9 + [character*60] 8 20 + [commande] 21 29 +L10 + [integer*4] 8 17 + [ios] 18 21 +L11 + [1] 8 9 + [compteur] 18 26 +L12 + [1] 8 9 + [sortie] 18 24 +L13 + [1] 8 9 + [errone] 18 24 +L14 + [1] 8 9 + [conf] 18 22 +L15 + [1] 8 9 + [position_espace] 18 33 +L16 + [1] 8 9 + [debut_mot] 18 27 +L17 + [1] 8 9 + [fin_mot] 18 25 +L18 + [1] 8 9 + [nb_mots] 18 25 +L19 + [1] 8 9 + [nb_mots_max] 18 29 +L20 + [1] 8 9 + [fin_chaine] 18 28 +L21 + [1] 8 9 + [trouver_fin] 18 29 +L22 + [1] 8 9 + [num_caractere] 18 31 +L23 + [1] 8 9 + [action] 18 24 +L24 + [1] 8 9 + [premiere_lettre] 18 33 +L25 + [1] 8 9 + [derniere_lettre] 18 33 +L26 + [1] 8 9 + [intervalle_maj_min] 18 36 +L27 + [1] 8 9 + [apres_maj] 18 27 +L28 + [1] 8 9 + [taille_colonne] 18 32 +L29 + [1] 8 9 + [taille_ligne] 18 30 +L30 + [1] 8 9 + [lignes_desc] 18 29 +L32 + [parameter] 8 17 + [nb_mots_max] 18 29 + [=] 30 31 + [9] 32 33 + [ !une saisie correcte ne contient [ 35 90 +L33 + [!elle en contient 9, alors la sais[ 1 60 +L34 + [parameter] 8 17 + [errone] 18 24 + [=] 25 26 + [1] 27 28 +L35 + [parameter] 8 17 + [sortie] 18 24 + [=] 25 26 + [-] 27 28 + [1] 29 30 +L36 + [parameter] 8 17 + [action] 18 24 + [=] 25 26 + [1] 27 28 + [ !il s'agit du 1er mot de la chain[ 31 79 +L37 + [parameter] 8 17 + [premiere_lettre] 18 33 + [=] 34 35 + [1] 36 37 + [ !correspond a la 1ere lettre d'un[ 40 77 +L38 + [parameter] 8 17 + [derniere_lettre] 18 33 + [=] 34 35 + [18] 36 38 + [ !correspond a la derniere lettre [ 41 82 +L39 + [parameter] 8 17 + [intervalle_maj_min] 18 36 + [=] 37 38 + [32] 39 41 + [ !nombre separant un meme caracter[ 44 78 +L40 + [!minuscule de son majuscule] 1 28 +L41 + [parameter] 8 17 + [apres_maj] 18 27 + [=] 28 29 + [96] 30 32 + [ !correspond au dernier caractere [ 35 81 +L42 + [parameter] 8 17 + [taille_colonne] 18 32 + [=] 33 34 + [7] 35 36 +L43 + [parameter] 8 17 + [taille_ligne] 18 30 + [=] 31 32 + [12] 33 35 +L44 + [parameter] 8 17 + [lignes_desc] 18 29 + [=] 30 31 + [11] 32 34 +L46 + [character*19] 9 21 + [n] 22 23 + [taille_colonne] 24 38 + [taille_ligne] 39 51 +L47 + [character*19] 8 20 + [mots_commande] 21 34 + [nb_mots_max] 35 46 +L48 + [character*60] 8 20 + [desc] 21 25 + [lignes_desc] 26 37 +L50 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' '] 19 22 +L51 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' ---------------------------[ 19 80 +L52 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' | bonjour, et bienvenue dan[ 19 80 +L53 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' ---------------------------[ 19 80 +L54 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' '] 19 22 +L55 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' '] 19 22 +L56 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' voici un rappel des fonctions di[ 19 84 +L57 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' '] 19 22 +L58 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' _ task pour creer une tache (e[ 19 84 +L59 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' '] 19 22 +L60 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' _ show pour voir la descriptio[ 19 75 +L61 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' '] 19 22 +L62 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' _ remove pour enlever une tach[ 19 77 +L63 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' '] 19 22 +L64 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' _ clear pour effacer le dashbo[ 19 70 +L65 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' '] 19 22 +L66 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' _ cancel, done, todo pour modi[ 19 100 +L67 + [write] 8 13 + [*] 14 15 + [*] 16 17 + [' '] 19 22 +L69 + [! la boucle de sortie pour quitter[ 1 58 +L70 + [ios] 18 21 + [.ne.] 22 26 + [sortie] 27 33 +L72 + [! initialisons les variables, afin[ 1 96 +L73 + [position_espace] 16 31 + [=] 32 33 + [0] 34 35 +L74 + [debut_mot] 16 25 + [=] 26 27 + [0] 28 29 +L75 + [fin_mot] 16 23 + [=] 24 25 + [0] 26 27 +L76 + [nb_mots] 16 23 + [=] 24 25 + [0] 26 27 +L77 + [fin_chaine] 16 26 + [=] 27 28 + [0] 29 30 +L79 + [! initialisons aussi le tableau de[ 1 50 +L80 + [compteur] 19 27 + [=] 28 29 + [action] 30 36 + [nb_mots_max] 38 49 +L81 + [mots_commande] 24 37 + [compteur] 39 47 + [=] 49 50 + [' '] 51 54 +L84 + [! appelons le sous prgramme qui ge[ 1 86 +L85 + [!l'utilisateur le demande] 1 26 +L86 + [call] 16 20 + [saisie] 21 27 + [commande] 28 36 + [ios] 38 41 +L88 + [ios] 20 23 + [.eq.] 24 28 + [0] 29 30 + [then] 32 36 +L90 + [! trouvons la fin de la chaine] 1 31 +L91 + [fin_chaine] 24 34 + [=] 35 36 + [trouver_fin] 37 48 + [commande] 50 58 +L92 + [compteur] 24 32 + [=] 33 34 + [1] 35 36 +L93 + [position_espace] 34 49 + [.lt.] 50 54 + [fin_chaine] 55 65 + [.and.] 66 71 + [nb_mots] 72 79 + [.lt.] 80 84 + [nb_mots_max] 85 96 +L94 + [debut_mot] 32 41 + [=] 42 43 + [position_espace] 44 59 + [+] 60 61 + [1] 62 63 +L96 + [! decoupons les mots] 1 21 +L97 + [position_espace] 32 47 + [=] 48 49 + [position_espace] 50 65 + [+] 66 67 + [index] 68 73 + [commande] 75 83 + [debut_mot:] 85 95 + [' '] 98 101 +L98 + [fin_mot] 32 39 + [=] 40 41 + [position_espace] 42 57 + [-] 58 59 + [1] 60 61 +L100 + [! ensuite on les enregistre dans m[ 1 47 +L101 + [mots_commande] 32 45 + [compteur] 47 55 + [=] 57 58 + [commande] 59 67 + [debut_mot] 69 78 + [:] 79 80 + [fin_mot] 81 88 +L103 + [! comptons les mots] 1 20 +L104 + [mots_commande] 36 49 + [compteur] 51 59 + [.ne.] 61 65 + [' '] 66 69 + [then] 71 75 +L105 + [nb_mots] 40 47 + [=] 48 49 + [nb_mots] 50 57 + [+] 58 59 + [1] 60 61 +L106 + [compteur] 40 48 + [=] 49 50 + [compteur] 51 59 + [+] 60 61 + [1] 62 63 +L110 + [! le programme ne doit pas tenir c[ 1 82 +L111 + [!dont est ecrit le mot, il sera mi[ 1 49 +L112 + [compteur] 27 35 + [=] 36 37 + [1] 38 39 + [nb_mots] 41 48 +L113 + [num_caractere] 35 48 + [=] 49 50 + [premiere_lettre] 51 66 + [derniere_lettre] 68 83 +L114 + [ichar] 44 49 + [mots_commande] 50 63 + [compteur] 65 73 + [num_caractere:num_caractere] 75 102 +L115 + [1] 8 9 + [.gt.] 10 14 + [apres_maj] 15 24 + [then] 26 30 +L116 + [mots_commande] 48 61 + [compteur] 63 71 + [num_caractere:num_caractere] 73 100 + [=] 102 103 +L117 + [1] 8 9 + [char] 10 14 + [ichar] 15 20 + [mots_commande] 21 34 + [compteur] 36 44 + [num_caractere:num_caractere] 46 73 + [-] 76 77 + [intervalle_maj_min] 78 96 +L122 + [!! affichons les mots (provisoire)] 1 35 +L123 + [!! do compteur[ 1 48 +L124 + [!! wri[ 1 83 +L125 + [!! end do] 1 30 +L126 + [!!] 1 3 +L127 + [!! testons si le mot est bien en m[ 1 62 +L128 + [!! write(*,*) [ 1 80 +L131 + [! si la commande contient plus de [ 1 68 +L133 + [nb_mots] 28 35 + [.eq.] 36 40 + [nb_mots_max] 41 52 + [then] 54 58 +L134 + [write] 32 37 + [*] 38 39 + [*] 40 41 + [' '] 43 46 +L135 + [write] 32 37 + [*] 38 39 + [*] 40 41 + ['err> trop de mot, veuillez ressai[ 43 81 +L136 + [else] 24 28 +L138 + [! maintenant, en fonction du premi[ 1 94 +L139 + [mots_commande] 36 49 + [action] 51 57 + [.eq.] 59 63 + ['task'] 64 70 + [then] 72 76 +L140 + [call] 40 44 + [tache] 45 50 + [mots_commande] 51 64 + [desc] 66 70 + [n] 72 73 +L141 + [else] 32 36 + [mots_commande] 41 54 + [action] 56 62 + [.eq.] 64 68 + ['show'] 69 75 + [then] 77 81 +L142 + [! [ 1 82 +L143 + [call] 40 44 + [show] 45 49 + [mots_commande] 50 63 + [n] 65 66 +L144 + [else] 32 36 + [mots_commande] 41 54 + [action] 56 62 + [.eq.] 64 68 + ['remove'] 69 77 + [then] 79 83 +L145 + [! [ 1 84 +L146 + [call] 40 44 + [remove] 45 51 + [mots_commande] 52 65 + [desc] 67 71 + [n] 73 74 +L147 + [else] 32 36 + [mots_commande] 41 54 + [action] 56 62 + [.eq.] 64 68 + ['clear'] 69 76 + [then] 78 82 +L148 + [! [ 1 83 +L149 + [call] 40 44 + [clear] 45 50 + [mots_commande] 51 64 + [n] 66 67 +L150 + [else] 32 36 + [mots_commande] 41 54 + [action] 56 62 + [.eq.] 64 68 + ['cancel'] 69 77 + [then] 79 83 +L151 + [! [ 1 84 +L152 + [call] 40 44 + [cancel] 45 51 + [mots_commande] 52 65 + [n] 67 68 +L153 + [else] 32 36 + [mots_commande] 41 54 + [action] 56 62 + [.eq.] 64 68 + ['done'] 69 75 + [then] 77 81 +L154 + [! [ 1 82 +L155 + [call] 40 44 + [done] 45 49 + [mots_commande] 50 63 + [n] 65 66 +L156 + [else] 32 36 + [mots_commande] 41 54 + [action] 56 62 + [.eq.] 64 68 + ['todo'] 69 75 + [then] 77 81 +L157 + [! [ 1 82 +L158 + [call] 40 44 + [todo] 45 49 + [mots_commande] 50 63 + [n] 65 66 +L159 + [else] 32 36 +L160 + [write] 40 45 + [*] 46 47 + [*] 48 49 + [' '] 51 54 +L161 + [write] 40 45 + [*] 46 47 + [*] 48 49 + ['l'] 51 54 + ['action suivante n'] 54 73 + ['a pas ete'] 73 84 +L162 + [1] 8 9 + [' comprise: '] 10 23 + [mots_commande] 25 38 + [action] 40 46 +EOF diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index d5fa12f849..3bc42f8f16 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -43,10 +43,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-go/src/test/java/net/sourceforge/pmd/cpd/EdgeCasesTokenizerTest.java b/pmd-go/src/test/java/net/sourceforge/pmd/cpd/EdgeCasesTokenizerTest.java deleted file mode 100644 index 71b085a34e..0000000000 --- a/pmd-go/src/test/java/net/sourceforge/pmd/cpd/EdgeCasesTokenizerTest.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Test; - -public class EdgeCasesTokenizerTest { - - private String getSampleCode(final String filename) throws IOException { - return IOUtils.toString(GoTokenizer.class.getResourceAsStream(filename), StandardCharsets.UTF_8); - } - - @Test - public void testEscapedBackSlash() throws IOException { - // See https://github.com/pmd/pmd/issues/1751 - final String filename = "issue1751.go"; - final GoTokenizer tokenizer = new GoTokenizer(); - final SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader(getSampleCode(filename), filename)); - - final Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); // it should simply not fail - } -} diff --git a/pmd-go/src/test/java/net/sourceforge/pmd/cpd/GoCPDTokenizerTest.java b/pmd-go/src/test/java/net/sourceforge/pmd/cpd/GoCPDTokenizerTest.java deleted file mode 100644 index e46866d012..0000000000 --- a/pmd-go/src/test/java/net/sourceforge/pmd/cpd/GoCPDTokenizerTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -import java.io.IOException; - -import org.apache.commons.io.IOUtils; -import org.junit.Before; -import org.junit.Test; - -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; - -public class GoCPDTokenizerTest extends AbstractTokenizerTest { - - private static final String FILENAME = "hello.go"; - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new GoTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), FILENAME)); - } - - @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(GoTokenizer.class.getResourceAsStream(FILENAME)); - } - - @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 23; - super.tokenizeTest(); - } -} diff --git a/pmd-go/src/test/java/net/sourceforge/pmd/cpd/GoTokenizerTest.java b/pmd-go/src/test/java/net/sourceforge/pmd/cpd/GoTokenizerTest.java index 7e34d93981..309867e995 100644 --- a/pmd-go/src/test/java/net/sourceforge/pmd/cpd/GoTokenizerTest.java +++ b/pmd-go/src/test/java/net/sourceforge/pmd/cpd/GoTokenizerTest.java @@ -4,33 +4,40 @@ package net.sourceforge.pmd.cpd; -import java.io.IOException; +import java.util.Properties; -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -public class GoTokenizerTest extends AbstractTokenizerTest { +public class GoTokenizerTest extends CpdTextComparisonTest { - private static final String FILENAME = "btrfs.go"; - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new GoTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), FILENAME)); + public GoTokenizerTest() { + super(".go"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(GoTokenizer.class.getResourceAsStream(FILENAME)); + public Tokenizer newTokenizer(Properties properties) { + return new GoTokenizer(); + } + + @Override + protected String getResourcePrefix() { + return "../lang/go/cpd/testdata"; } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 3517; - super.tokenizeTest(); + public void simpleTest() { + doTest("hello"); + } + + @Test + public void bigFileTest() { + doTest("btrfs"); + } + + @Test + public void testIssue1751() { + doTest("issue-1751"); } } diff --git a/pmd-go/src/test/resources/net/sourceforge/pmd/cpd/btrfs.go b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/btrfs.go similarity index 100% rename from pmd-go/src/test/resources/net/sourceforge/pmd/cpd/btrfs.go rename to pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/btrfs.go diff --git a/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/btrfs.txt b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/btrfs.txt new file mode 100644 index 0000000000..2eca870e38 --- /dev/null +++ b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/btrfs.txt @@ -0,0 +1,4047 @@ + [Image] or [Truncated image[ Bcol Ecol +L9 + [package] 1 8 + [btrfs] 9 14 +L21 + [import] 1 7 + ["C"] 8 11 +L23 + [import] 1 7 + [(] 8 9 +L24 + ["fmt"] 2 7 +L25 + ["io/ioutil"] 2 13 +L26 + ["math"] 2 8 +L27 + ["os"] 2 6 +L28 + ["path"] 2 8 +L29 + ["path/filepath"] 2 17 +L30 + ["strconv"] 2 11 +L31 + ["strings"] 2 11 +L32 + ["sync"] 2 8 +L33 + ["unsafe"] 2 10 +L35 + ["github.com/docker/docker/daemon/g[ 2 47 +L36 + ["github.com/docker/docker/pkg/cont[ 2 44 +L37 + ["github.com/docker/docker/pkg/idto[ 2 40 +L38 + ["github.com/docker/docker/pkg/moun[ 2 38 +L39 + ["github.com/docker/docker/pkg/pars[ 2 40 +L40 + ["github.com/docker/docker/pkg/syst[ 2 39 +L41 + ["github.com/docker/go-units"] 2 30 +L42 + ["github.com/opencontainers/selinux[ 2 54 +L43 + ["github.com/pkg/errors"] 2 25 +L44 + ["github.com/sirupsen/logrus"] 2 30 +L45 + ["golang.org/x/sys/unix"] 2 25 +L46 + [)] 1 2 +L48 + [func] 1 5 + [init] 6 10 + [(] 10 11 + [)] 11 12 + [{] 13 14 +L49 + [graphdriver] 2 13 + [.] 13 14 + [Register] 14 22 + [(] 22 23 + ["btrfs"] 23 30 + [,] 30 31 + [Init] 32 36 + [)] 36 37 +L50 + [}] 1 2 +L52 + [type] 1 5 + [btrfsOptions] 6 18 + [struct] 19 25 + [{] 26 27 +L53 + [minSpace] 2 10 + [uint64] 11 17 +L54 + [size] 2 6 + [uint64] 11 17 +L55 + [}] 1 2 +L59 + [func] 1 5 + [Init] 6 10 + [(] 10 11 + [home] 11 15 + [string] 16 22 + [,] 22 23 + [options] 24 31 + [\[] 32 33 + [\]] 33 34 + [string] 34 40 + [,] 40 41 + [uidMaps] 42 49 + [,] 49 50 + [gidMaps] 51 58 + [\[] 59 60 + [\]] 60 61 + [idtools] 61 68 + [.] 68 69 + [IDMap] 69 74 + [)] 74 75 + [(] 76 77 + [graphdriver] 77 88 + [.] 88 89 + [Driver] 89 95 + [,] 95 96 + [error] 97 102 + [)] 102 103 + [{] 104 105 +L65 + [testdir] 2 9 + [:=] 10 12 + [home] 13 17 +L66 + [if] 2 4 + [_] 5 6 + [,] 6 7 + [err] 8 11 + [:=] 12 14 + [os] 15 17 + [.] 17 18 + [Stat] 18 22 + [(] 22 23 + [testdir] 23 30 + [)] 30 31 + [;] 31 32 + [os] 33 35 + [.] 35 36 + [IsNotExist] 36 46 + [(] 46 47 + [err] 47 50 + [)] 50 51 + [{] 52 53 +L67 + [testdir] 3 10 + [=] 11 12 + [filepath] 13 21 + [.] 21 22 + [Dir] 22 25 + [(] 25 26 + [testdir] 26 33 + [)] 33 34 +L68 + [}] 2 3 +L70 + [fsMagic] 2 9 + [,] 9 10 + [err] 11 14 + [:=] 15 17 + [graphdriver] 18 29 + [.] 29 30 + [GetFSMagic] 30 40 + [(] 40 41 + [testdir] 41 48 + [)] 48 49 +L71 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L72 + [return] 3 9 + [nil] 10 13 + [,] 13 14 + [err] 15 18 +L73 + [}] 2 3 +L75 + [if] 2 4 + [fsMagic] 5 12 + [!=] 13 15 + [graphdriver] 16 27 + [.] 27 28 + [FsMagicBtrfs] 28 40 + [{] 41 42 +L76 + [return] 3 9 + [nil] 10 13 + [,] 13 14 + [graphdriver] 15 26 + [.] 26 27 + [ErrPrerequisites] 27 43 +L77 + [}] 2 3 +L79 + [rootUID] 2 9 + [,] 9 10 + [rootGID] 11 18 + [,] 18 19 + [err] 20 23 + [:=] 24 26 + [idtools] 27 34 + [.] 34 35 + [GetRootUIDGID] 35 48 + [(] 48 49 + [uidMaps] 49 56 + [,] 56 57 + [gidMaps] 58 65 + [)] 65 66 +L80 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L81 + [return] 3 9 + [nil] 10 13 + [,] 13 14 + [err] 15 18 +L82 + [}] 2 3 +L83 + [if] 2 4 + [err] 5 8 + [:=] 9 11 + [idtools] 12 19 + [.] 19 20 + [MkdirAllAndChown] 20 36 + [(] 36 37 + [home] 37 41 + [,] 41 42 + [0700] 43 47 + [,] 47 48 + [idtools] 49 56 + [.] 56 57 + [Identity] 57 65 + [{] 65 66 + [UID] 66 69 + [:] 69 70 + [rootUID] 71 78 + [,] 78 79 + [GID] 80 83 + [:] 83 84 + [rootGID] 85 92 + [}] 92 93 + [)] 93 94 + [;] 94 95 + [err] 96 99 + [!=] 100 102 + [nil] 103 106 + [{] 107 108 +L84 + [return] 3 9 + [nil] 10 13 + [,] 13 14 + [err] 15 18 +L85 + [}] 2 3 +L87 + [opt] 2 5 + [,] 5 6 + [userDiskQuota] 7 20 + [,] 20 21 + [err] 22 25 + [:=] 26 28 + [parseOptions] 29 41 + [(] 41 42 + [options] 42 49 + [)] 49 50 +L88 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L89 + [return] 3 9 + [nil] 10 13 + [,] 13 14 + [err] 15 18 +L90 + [}] 2 3 +L96 + [err] 2 5 + [=] 6 7 + [mount] 8 13 + [.] 13 14 + [MakeMount] 14 23 + [(] 23 24 + [home] 24 28 + [)] 28 29 +L97 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L98 + [return] 3 9 + [nil] 10 13 + [,] 13 14 + [errors] 15 21 + [.] 21 22 + [Wrapf] 22 27 + [(] 27 28 + [err] 28 31 + [,] 31 32 + ["failed to make %s a mount"] 33 60 + [,] 60 61 + [home] 62 66 + [)] 66 67 +L99 + [}] 2 3 +L101 + [driver] 2 8 + [:=] 9 11 + [&] 12 13 + [Driver] 13 19 + [{] 19 20 +L102 + [home] 3 7 + [:] 7 8 + [home] 12 16 + [,] 16 17 +L103 + [uidMaps] 3 10 + [:] 10 11 + [uidMaps] 12 19 + [,] 19 20 +L104 + [gidMaps] 3 10 + [:] 10 11 + [gidMaps] 12 19 + [,] 19 20 +L105 + [options] 3 10 + [:] 10 11 + [opt] 12 15 + [,] 15 16 +L106 + [}] 2 3 +L108 + [if] 2 4 + [userDiskQuota] 5 18 + [{] 19 20 +L109 + [if] 3 5 + [err] 6 9 + [:=] 10 12 + [driver] 13 19 + [.] 19 20 + [subvolEnableQuota] 20 37 + [(] 37 38 + [)] 38 39 + [;] 39 40 + [err] 41 44 + [!=] 45 47 + [nil] 48 51 + [{] 52 53 +L110 + [return] 4 10 + [nil] 11 14 + [,] 14 15 + [err] 16 19 +L111 + [}] 3 4 +L112 + [}] 2 3 +L114 + [return] 2 8 + [graphdriver] 9 20 + [.] 20 21 + [NewNaiveDiffDriver] 21 39 + [(] 39 40 + [driver] 40 46 + [,] 46 47 + [uidMaps] 48 55 + [,] 55 56 + [gidMaps] 57 64 + [)] 64 65 + [,] 65 66 + [nil] 67 70 +L115 + [}] 1 2 +L117 + [func] 1 5 + [parseOptions] 6 18 + [(] 18 19 + [opt] 19 22 + [\[] 23 24 + [\]] 24 25 + [string] 25 31 + [)] 31 32 + [(] 33 34 + [btrfsOptions] 34 46 + [,] 46 47 + [bool] 48 52 + [,] 52 53 + [error] 54 59 + [)] 59 60 + [{] 61 62 +L118 + [var] 2 5 + [options] 6 13 + [btrfsOptions] 14 26 +L119 + [userDiskQuota] 2 15 + [:=] 16 18 + [false] 19 24 +L120 + [for] 2 5 + [_] 6 7 + [,] 7 8 + [option] 9 15 + [:=] 16 18 + [range] 19 24 + [opt] 25 28 + [{] 29 30 +L121 + [key] 3 6 + [,] 6 7 + [val] 8 11 + [,] 11 12 + [err] 13 16 + [:=] 17 19 + [parsers] 20 27 + [.] 27 28 + [ParseKeyValueOpt] 28 44 + [(] 44 45 + [option] 45 51 + [)] 51 52 +L122 + [if] 3 5 + [err] 6 9 + [!=] 10 12 + [nil] 13 16 + [{] 17 18 +L123 + [return] 4 10 + [options] 11 18 + [,] 18 19 + [userDiskQuota] 20 33 + [,] 33 34 + [err] 35 38 +L124 + [}] 3 4 +L125 + [key] 3 6 + [=] 7 8 + [strings] 9 16 + [.] 16 17 + [ToLower] 17 24 + [(] 24 25 + [key] 25 28 + [)] 28 29 +L126 + [switch] 3 9 + [key] 10 13 + [{] 14 15 +L127 + [case] 3 7 + ["btrfs.min_space"] 8 25 + [:] 25 26 +L128 + [minSpace] 4 12 + [,] 12 13 + [err] 14 17 + [:=] 18 20 + [units] 21 26 + [.] 26 27 + [RAMInBytes] 27 37 + [(] 37 38 + [val] 38 41 + [)] 41 42 +L129 + [if] 4 6 + [err] 7 10 + [!=] 11 13 + [nil] 14 17 + [{] 18 19 +L130 + [return] 5 11 + [options] 12 19 + [,] 19 20 + [userDiskQuota] 21 34 + [,] 34 35 + [err] 36 39 +L131 + [}] 4 5 +L132 + [userDiskQuota] 4 17 + [=] 18 19 + [true] 20 24 +L133 + [options] 4 11 + [.] 11 12 + [minSpace] 12 20 + [=] 21 22 + [uint64] 23 29 + [(] 29 30 + [minSpace] 30 38 + [)] 38 39 +L134 + [default] 3 10 + [:] 10 11 +L135 + [return] 4 10 + [options] 11 18 + [,] 18 19 + [userDiskQuota] 20 33 + [,] 33 34 + [fmt] 35 38 + [.] 38 39 + [Errorf] 39 45 + [(] 45 46 + ["Unknown option %s"] 46 65 + [,] 65 66 + [key] 67 70 + [)] 70 71 +L136 + [}] 3 4 +L137 + [}] 2 3 +L138 + [return] 2 8 + [options] 9 16 + [,] 16 17 + [userDiskQuota] 18 31 + [,] 31 32 + [nil] 33 36 +L139 + [}] 1 2 +L142 + [type] 1 5 + [Driver] 6 12 + [struct] 13 19 + [{] 20 21 +L144 + [home] 2 6 + [string] 15 21 +L145 + [uidMaps] 2 9 + [\[] 15 16 + [\]] 16 17 + [idtools] 17 24 + [.] 24 25 + [IDMap] 25 30 +L146 + [gidMaps] 2 9 + [\[] 15 16 + [\]] 16 17 + [idtools] 17 24 + [.] 24 25 + [IDMap] 25 30 +L147 + [options] 2 9 + [btrfsOptions] 15 27 +L148 + [quotaEnabled] 2 14 + [bool] 15 19 +L149 + [once] 2 6 + [sync] 15 19 + [.] 19 20 + [Once] 20 24 +L150 + [}] 1 2 +L153 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [String] 18 24 + [(] 24 25 + [)] 25 26 + [string] 27 33 + [{] 34 35 +L154 + [return] 2 8 + ["btrfs"] 9 16 +L155 + [}] 1 2 +L160 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [Status] 18 24 + [(] 24 25 + [)] 25 26 + [\[] 27 28 + [\]] 28 29 + [\[] 29 30 + [2] 30 31 + [\]] 31 32 + [string] 32 38 + [{] 39 40 +L161 + [status] 2 8 + [:=] 9 11 + [\[] 12 13 + [\]] 13 14 + [\[] 14 15 + [2] 15 16 + [\]] 16 17 + [string] 17 23 + [{] 23 24 + [}] 24 25 +L162 + [if] 2 4 + [bv] 5 7 + [:=] 8 10 + [btrfsBuildVersion] 11 28 + [(] 28 29 + [)] 29 30 + [;] 30 31 + [bv] 32 34 + [!=] 35 37 + ["-"] 38 41 + [{] 42 43 +L163 + [status] 3 9 + [=] 10 11 + [append] 12 18 + [(] 18 19 + [status] 19 25 + [,] 25 26 + [\[] 27 28 + [2] 28 29 + [\]] 29 30 + [string] 30 36 + [{] 36 37 + ["Build Version"] 37 52 + [,] 52 53 + [bv] 54 56 + [}] 56 57 + [)] 57 58 +L164 + [}] 2 3 +L165 + [if] 2 4 + [lv] 5 7 + [:=] 8 10 + [btrfsLibVersion] 11 26 + [(] 26 27 + [)] 27 28 + [;] 28 29 + [lv] 30 32 + [!=] 33 35 + [-] 36 37 + [1] 37 38 + [{] 39 40 +L166 + [status] 3 9 + [=] 10 11 + [append] 12 18 + [(] 18 19 + [status] 19 25 + [,] 25 26 + [\[] 27 28 + [2] 28 29 + [\]] 29 30 + [string] 30 36 + [{] 36 37 + ["Library Version"] 37 54 + [,] 54 55 + [fmt] 56 59 + [.] 59 60 + [Sprintf] 60 67 + [(] 67 68 + ["%d"] 68 72 + [,] 72 73 + [lv] 74 76 + [)] 76 77 + [}] 77 78 + [)] 78 79 +L167 + [}] 2 3 +L168 + [return] 2 8 + [status] 9 15 +L169 + [}] 1 2 +L172 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [GetMetadata] 18 29 + [(] 29 30 + [id] 30 32 + [string] 33 39 + [)] 39 40 + [(] 41 42 + [map] 42 45 + [\[] 45 46 + [string] 46 52 + [\]] 52 53 + [string] 53 59 + [,] 59 60 + [error] 61 66 + [)] 66 67 + [{] 68 69 +L173 + [return] 2 8 + [nil] 9 12 + [,] 12 13 + [nil] 14 17 +L174 + [}] 1 2 +L177 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [Cleanup] 18 25 + [(] 25 26 + [)] 26 27 + [error] 28 33 + [{] 34 35 +L178 + [err] 2 5 + [:=] 6 8 + [d] 9 10 + [.] 10 11 + [subvolDisableQuota] 11 29 + [(] 29 30 + [)] 30 31 +L179 + [umountErr] 2 11 + [:=] 12 14 + [mount] 15 20 + [.] 20 21 + [Unmount] 21 28 + [(] 28 29 + [d] 29 30 + [.] 30 31 + [home] 31 35 + [)] 35 36 +L182 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L183 + [return] 3 9 + [err] 10 13 +L184 + [}] 2 3 +L186 + [if] 2 4 + [umountErr] 5 14 + [!=] 15 17 + [nil] 18 21 + [{] 22 23 +L187 + [return] 3 9 + [errors] 10 16 + [.] 16 17 + [Wrapf] 17 22 + [(] 22 23 + [umountErr] 23 32 + [,] 32 33 + ["error unmounting %s"] 34 55 + [,] 55 56 + [d] 57 58 + [.] 58 59 + [home] 59 63 + [)] 63 64 +L188 + [}] 2 3 +L190 + [return] 2 8 + [nil] 9 12 +L191 + [}] 1 2 +L193 + [func] 1 5 + [free] 6 10 + [(] 10 11 + [p] 11 12 + [*] 13 14 + [C] 14 15 + [.] 15 16 + [char] 16 20 + [)] 20 21 + [{] 22 23 +L194 + [C] 2 3 + [.] 3 4 + [free] 4 8 + [(] 8 9 + [unsafe] 9 15 + [.] 15 16 + [Pointer] 16 23 + [(] 23 24 + [p] 24 25 + [)] 25 26 + [)] 26 27 +L195 + [}] 1 2 +L197 + [func] 1 5 + [openDir] 6 13 + [(] 13 14 + [path] 14 18 + [string] 19 25 + [)] 25 26 + [(] 27 28 + [*] 28 29 + [C] 29 30 + [.] 30 31 + [DIR] 31 34 + [,] 34 35 + [error] 36 41 + [)] 41 42 + [{] 43 44 +L198 + [Cpath] 2 7 + [:=] 8 10 + [C] 11 12 + [.] 12 13 + [CString] 13 20 + [(] 20 21 + [path] 21 25 + [)] 25 26 +L199 + [defer] 2 7 + [free] 8 12 + [(] 12 13 + [Cpath] 13 18 + [)] 18 19 +L201 + [dir] 2 5 + [:=] 6 8 + [C] 9 10 + [.] 10 11 + [opendir] 11 18 + [(] 18 19 + [Cpath] 19 24 + [)] 24 25 +L202 + [if] 2 4 + [dir] 5 8 + [==] 9 11 + [nil] 12 15 + [{] 16 17 +L203 + [return] 3 9 + [nil] 10 13 + [,] 13 14 + [fmt] 15 18 + [.] 18 19 + [Errorf] 19 25 + [(] 25 26 + ["Can't open dir"] 26 42 + [)] 42 43 +L204 + [}] 2 3 +L205 + [return] 2 8 + [dir] 9 12 + [,] 12 13 + [nil] 14 17 +L206 + [}] 1 2 +L208 + [func] 1 5 + [closeDir] 6 14 + [(] 14 15 + [dir] 15 18 + [*] 19 20 + [C] 20 21 + [.] 21 22 + [DIR] 22 25 + [)] 25 26 + [{] 27 28 +L209 + [if] 2 4 + [dir] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L210 + [C] 3 4 + [.] 4 5 + [closedir] 5 13 + [(] 13 14 + [dir] 14 17 + [)] 17 18 +L211 + [}] 2 3 +L212 + [}] 1 2 +L214 + [func] 1 5 + [getDirFd] 6 14 + [(] 14 15 + [dir] 15 18 + [*] 19 20 + [C] 20 21 + [.] 21 22 + [DIR] 22 25 + [)] 25 26 + [uintptr] 27 34 + [{] 35 36 +L215 + [return] 2 8 + [uintptr] 9 16 + [(] 16 17 + [C] 17 18 + [.] 18 19 + [dirfd] 19 24 + [(] 24 25 + [dir] 25 28 + [)] 28 29 + [)] 29 30 +L216 + [}] 1 2 +L218 + [func] 1 5 + [subvolCreate] 6 18 + [(] 18 19 + [path] 19 23 + [,] 23 24 + [name] 25 29 + [string] 30 36 + [)] 36 37 + [error] 38 43 + [{] 44 45 +L219 + [dir] 2 5 + [,] 5 6 + [err] 7 10 + [:=] 11 13 + [openDir] 14 21 + [(] 21 22 + [path] 22 26 + [)] 26 27 +L220 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L221 + [return] 3 9 + [err] 10 13 +L222 + [}] 2 3 +L223 + [defer] 2 7 + [closeDir] 8 16 + [(] 16 17 + [dir] 17 20 + [)] 20 21 +L225 + [var] 2 5 + [args] 6 10 + [C] 11 12 + [.] 12 13 + [struct_btrfs_ioctl_vol_args] 13 40 +L226 + [for] 2 5 + [i] 6 7 + [,] 7 8 + [c] 9 10 + [:=] 11 13 + [range] 14 19 + [\[] 20 21 + [\]] 21 22 + [byte] 22 26 + [(] 26 27 + [name] 27 31 + [)] 31 32 + [{] 33 34 +L227 + [args] 3 7 + [.] 7 8 + [name] 8 12 + [\[] 12 13 + [i] 13 14 + [\]] 14 15 + [=] 16 17 + [C] 18 19 + [.] 19 20 + [char] 20 24 + [(] 24 25 + [c] 25 26 + [)] 26 27 +L228 + [}] 2 3 +L230 + [_] 2 3 + [,] 3 4 + [_] 5 6 + [,] 6 7 + [errno] 8 13 + [:=] 14 16 + [unix] 17 21 + [.] 21 22 + [Syscall] 22 29 + [(] 29 30 + [unix] 30 34 + [.] 34 35 + [SYS_IOCTL] 35 44 + [,] 44 45 + [getDirFd] 46 54 + [(] 54 55 + [dir] 55 58 + [)] 58 59 + [,] 59 60 + [C] 61 62 + [.] 62 63 + [BTRFS_IOC_SUBVOL_CREATE] 63 86 + [,] 86 87 +L231 + [uintptr] 3 10 + [(] 10 11 + [unsafe] 11 17 + [.] 17 18 + [Pointer] 18 25 + [(] 25 26 + [&] 26 27 + [args] 27 31 + [)] 31 32 + [)] 32 33 + [)] 33 34 +L232 + [if] 2 4 + [errno] 5 10 + [!=] 11 13 + [0] 14 15 + [{] 16 17 +L233 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["Failed to create btrfs subvolume:[ 21 59 + [,] 59 60 + [errno] 61 66 + [.] 66 67 + [Error] 67 72 + [(] 72 73 + [)] 73 74 + [)] 74 75 +L234 + [}] 2 3 +L235 + [return] 2 8 + [nil] 9 12 +L236 + [}] 1 2 +L238 + [func] 1 5 + [subvolSnapshot] 6 20 + [(] 20 21 + [src] 21 24 + [,] 24 25 + [dest] 26 30 + [,] 30 31 + [name] 32 36 + [string] 37 43 + [)] 43 44 + [error] 45 50 + [{] 51 52 +L239 + [srcDir] 2 8 + [,] 8 9 + [err] 10 13 + [:=] 14 16 + [openDir] 17 24 + [(] 24 25 + [src] 25 28 + [)] 28 29 +L240 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L241 + [return] 3 9 + [err] 10 13 +L242 + [}] 2 3 +L243 + [defer] 2 7 + [closeDir] 8 16 + [(] 16 17 + [srcDir] 17 23 + [)] 23 24 +L245 + [destDir] 2 9 + [,] 9 10 + [err] 11 14 + [:=] 15 17 + [openDir] 18 25 + [(] 25 26 + [dest] 26 30 + [)] 30 31 +L246 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L247 + [return] 3 9 + [err] 10 13 +L248 + [}] 2 3 +L249 + [defer] 2 7 + [closeDir] 8 16 + [(] 16 17 + [destDir] 17 24 + [)] 24 25 +L251 + [var] 2 5 + [args] 6 10 + [C] 11 12 + [.] 12 13 + [struct_btrfs_ioctl_vol_args_v2] 13 43 +L252 + [args] 2 6 + [.] 6 7 + [fd] 7 9 + [=] 10 11 + [C] 12 13 + [.] 13 14 + [__s64] 14 19 + [(] 19 20 + [getDirFd] 20 28 + [(] 28 29 + [srcDir] 29 35 + [)] 35 36 + [)] 36 37 +L254 + [var] 2 5 + [cs] 6 8 + [=] 9 10 + [C] 11 12 + [.] 12 13 + [CString] 13 20 + [(] 20 21 + [name] 21 25 + [)] 25 26 +L255 + [C] 2 3 + [.] 3 4 + [set_name_btrfs_ioctl_vol_args_v2] 4 36 + [(] 36 37 + [&] 37 38 + [args] 38 42 + [,] 42 43 + [cs] 44 46 + [)] 46 47 +L256 + [C] 2 3 + [.] 3 4 + [free] 4 8 + [(] 8 9 + [unsafe] 9 15 + [.] 15 16 + [Pointer] 16 23 + [(] 23 24 + [cs] 24 26 + [)] 26 27 + [)] 27 28 +L258 + [_] 2 3 + [,] 3 4 + [_] 5 6 + [,] 6 7 + [errno] 8 13 + [:=] 14 16 + [unix] 17 21 + [.] 21 22 + [Syscall] 22 29 + [(] 29 30 + [unix] 30 34 + [.] 34 35 + [SYS_IOCTL] 35 44 + [,] 44 45 + [getDirFd] 46 54 + [(] 54 55 + [destDir] 55 62 + [)] 62 63 + [,] 63 64 + [C] 65 66 + [.] 66 67 + [BTRFS_IOC_SNAP_CREATE_V2] 67 91 + [,] 91 92 +L259 + [uintptr] 3 10 + [(] 10 11 + [unsafe] 11 17 + [.] 17 18 + [Pointer] 18 25 + [(] 25 26 + [&] 26 27 + [args] 27 31 + [)] 31 32 + [)] 32 33 + [)] 33 34 +L260 + [if] 2 4 + [errno] 5 10 + [!=] 11 13 + [0] 14 15 + [{] 16 17 +L261 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["Failed to create btrfs snapshot: [ 21 58 + [,] 58 59 + [errno] 60 65 + [.] 65 66 + [Error] 66 71 + [(] 71 72 + [)] 72 73 + [)] 73 74 +L262 + [}] 2 3 +L263 + [return] 2 8 + [nil] 9 12 +L264 + [}] 1 2 +L266 + [func] 1 5 + [isSubvolume] 6 17 + [(] 17 18 + [p] 18 19 + [string] 20 26 + [)] 26 27 + [(] 28 29 + [bool] 29 33 + [,] 33 34 + [error] 35 40 + [)] 40 41 + [{] 42 43 +L267 + [var] 2 5 + [bufStat] 6 13 + [unix] 14 18 + [.] 18 19 + [Stat_t] 19 25 +L268 + [if] 2 4 + [err] 5 8 + [:=] 9 11 + [unix] 12 16 + [.] 16 17 + [Lstat] 17 22 + [(] 22 23 + [p] 23 24 + [,] 24 25 + [&] 26 27 + [bufStat] 27 34 + [)] 34 35 + [;] 35 36 + [err] 37 40 + [!=] 41 43 + [nil] 44 47 + [{] 48 49 +L269 + [return] 3 9 + [false] 10 15 + [,] 15 16 + [err] 17 20 +L270 + [}] 2 3 +L273 + [return] 2 8 + [bufStat] 9 16 + [.] 16 17 + [Ino] 17 20 + [==] 21 23 + [C] 24 25 + [.] 25 26 + [BTRFS_FIRST_FREE_OBJECTID] 26 51 + [,] 51 52 + [nil] 53 56 +L274 + [}] 1 2 +L276 + [func] 1 5 + [subvolDelete] 6 18 + [(] 18 19 + [dirpath] 19 26 + [,] 26 27 + [name] 28 32 + [string] 33 39 + [,] 39 40 + [quotaEnabled] 41 53 + [bool] 54 58 + [)] 58 59 + [error] 60 65 + [{] 66 67 +L277 + [dir] 2 5 + [,] 5 6 + [err] 7 10 + [:=] 11 13 + [openDir] 14 21 + [(] 21 22 + [dirpath] 22 29 + [)] 29 30 +L278 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L279 + [return] 3 9 + [err] 10 13 +L280 + [}] 2 3 +L281 + [defer] 2 7 + [closeDir] 8 16 + [(] 16 17 + [dir] 17 20 + [)] 20 21 +L282 + [fullPath] 2 10 + [:=] 11 13 + [path] 14 18 + [.] 18 19 + [Join] 19 23 + [(] 23 24 + [dirpath] 24 31 + [,] 31 32 + [name] 33 37 + [)] 37 38 +L284 + [var] 2 5 + [args] 6 10 + [C] 11 12 + [.] 12 13 + [struct_btrfs_ioctl_vol_args] 13 40 +L287 + [walkSubvolumes] 2 16 + [:=] 17 19 + [func] 20 24 + [(] 24 25 + [p] 25 26 + [string] 27 33 + [,] 33 34 + [f] 35 36 + [os] 37 39 + [.] 39 40 + [FileInfo] 40 48 + [,] 48 49 + [err] 50 53 + [error] 54 59 + [)] 59 60 + [error] 61 66 + [{] 67 68 +L288 + [if] 3 5 + [err] 6 9 + [!=] 10 12 + [nil] 13 16 + [{] 17 18 +L289 + [if] 4 6 + [os] 7 9 + [.] 9 10 + [IsNotExist] 10 20 + [(] 20 21 + [err] 21 24 + [)] 24 25 + [&&] 26 28 + [p] 29 30 + [!=] 31 33 + [fullPath] 34 42 + [{] 43 44 +L292 + [return] 5 11 + [nil] 12 15 +L293 + [}] 4 5 +L294 + [return] 4 10 + [fmt] 11 14 + [.] 14 15 + [Errorf] 15 21 + [(] 21 22 + ["error walking subvolumes: %v"] 22 52 + [,] 52 53 + [err] 54 57 + [)] 57 58 +L295 + [}] 3 4 +L298 + [if] 3 5 + [f] 6 7 + [.] 7 8 + [IsDir] 8 13 + [(] 13 14 + [)] 14 15 + [&&] 16 18 + [p] 19 20 + [!=] 21 23 + [fullPath] 24 32 + [{] 33 34 +L299 + [sv] 4 6 + [,] 6 7 + [err] 8 11 + [:=] 12 14 + [isSubvolume] 15 26 + [(] 26 27 + [p] 27 28 + [)] 28 29 +L300 + [if] 4 6 + [err] 7 10 + [!=] 11 13 + [nil] 14 17 + [{] 18 19 +L301 + [return] 5 11 + [fmt] 12 15 + [.] 15 16 + [Errorf] 16 22 + [(] 22 23 + ["Failed to test if %s is a btrfs s[ 23 70 + [,] 70 71 + [p] 72 73 + [,] 73 74 + [err] 75 78 + [)] 78 79 +L302 + [}] 4 5 +L303 + [if] 4 6 + [sv] 7 9 + [{] 10 11 +L304 + [if] 5 7 + [err] 8 11 + [:=] 12 14 + [subvolDelete] 15 27 + [(] 27 28 + [path] 28 32 + [.] 32 33 + [Dir] 33 36 + [(] 36 37 + [p] 37 38 + [)] 38 39 + [,] 39 40 + [f] 41 42 + [.] 42 43 + [Name] 43 47 + [(] 47 48 + [)] 48 49 + [,] 49 50 + [quotaEnabled] 51 63 + [)] 63 64 + [;] 64 65 + [err] 66 69 + [!=] 70 72 + [nil] 73 76 + [{] 77 78 +L305 + [return] 6 12 + [fmt] 13 16 + [.] 16 17 + [Errorf] 17 23 + [(] 23 24 + ["Failed to destroy btrfs child sub[ 24 89 + [,] 89 90 + [p] 91 92 + [,] 92 93 + [dirpath] 94 101 + [,] 101 102 + [err] 103 106 + [)] 106 107 +L306 + [}] 5 6 +L307 + [}] 4 5 +L308 + [}] 3 4 +L309 + [return] 3 9 + [nil] 10 13 +L310 + [}] 2 3 +L311 + [if] 2 4 + [err] 5 8 + [:=] 9 11 + [filepath] 12 20 + [.] 20 21 + [Walk] 21 25 + [(] 25 26 + [path] 26 30 + [.] 30 31 + [Join] 31 35 + [(] 35 36 + [dirpath] 36 43 + [,] 43 44 + [name] 45 49 + [)] 49 50 + [,] 50 51 + [walkSubvolumes] 52 66 + [)] 66 67 + [;] 67 68 + [err] 69 72 + [!=] 73 75 + [nil] 76 79 + [{] 80 81 +L312 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["Recursively walking subvolumes fo[ 21 71 + [,] 71 72 + [dirpath] 73 80 + [,] 80 81 + [err] 82 85 + [)] 85 86 +L313 + [}] 2 3 +L315 + [if] 2 4 + [quotaEnabled] 5 17 + [{] 18 19 +L316 + [if] 3 5 + [qgroupid] 6 14 + [,] 14 15 + [err] 16 19 + [:=] 20 22 + [subvolLookupQgroup] 23 41 + [(] 41 42 + [fullPath] 42 50 + [)] 50 51 + [;] 51 52 + [err] 53 56 + [==] 57 59 + [nil] 60 63 + [{] 64 65 +L317 + [var] 4 7 + [args] 8 12 + [C] 13 14 + [.] 14 15 + [struct_btrfs_ioctl_qgroup_create_a[ 15 52 +L318 + [args] 4 8 + [.] 8 9 + [qgroupid] 9 17 + [=] 18 19 + [C] 20 21 + [.] 21 22 + [__u64] 22 27 + [(] 27 28 + [qgroupid] 28 36 + [)] 36 37 +L320 + [_] 4 5 + [,] 5 6 + [_] 7 8 + [,] 8 9 + [errno] 10 15 + [:=] 16 18 + [unix] 19 23 + [.] 23 24 + [Syscall] 24 31 + [(] 31 32 + [unix] 32 36 + [.] 36 37 + [SYS_IOCTL] 37 46 + [,] 46 47 + [getDirFd] 48 56 + [(] 56 57 + [dir] 57 60 + [)] 60 61 + [,] 61 62 + [C] 63 64 + [.] 64 65 + [BTRFS_IOC_QGROUP_CREATE] 65 88 + [,] 88 89 +L321 + [uintptr] 5 12 + [(] 12 13 + [unsafe] 13 19 + [.] 19 20 + [Pointer] 20 27 + [(] 27 28 + [&] 28 29 + [args] 29 33 + [)] 33 34 + [)] 34 35 + [)] 35 36 +L322 + [if] 4 6 + [errno] 7 12 + [!=] 13 15 + [0] 16 17 + [{] 18 19 +L323 + [logrus] 5 11 + [.] 11 12 + [WithField] 12 21 + [(] 21 22 + ["storage-driver"] 22 38 + [,] 38 39 + ["btrfs"] 40 47 + [)] 47 48 + [.] 48 49 + [Errorf] 49 55 + [(] 55 56 + ["Failed to delete btrfs qgroup %v [ 56 101 + [,] 101 102 + [qgroupid] 103 111 + [,] 111 112 + [fullPath] 113 121 + [,] 121 122 + [errno] 123 128 + [.] 128 129 + [Error] 129 134 + [(] 134 135 + [)] 135 136 + [)] 136 137 +L324 + [}] 4 5 +L325 + [}] 3 4 + [else] 5 9 + [{] 10 11 +L326 + [logrus] 4 10 + [.] 10 11 + [WithField] 11 20 + [(] 20 21 + ["storage-driver"] 21 37 + [,] 37 38 + ["btrfs"] 39 46 + [)] 46 47 + [.] 47 48 + [Errorf] 48 54 + [(] 54 55 + ["Failed to lookup btrfs qgroup for[ 55 97 + [,] 97 98 + [fullPath] 99 107 + [,] 107 108 + [err] 109 112 + [.] 112 113 + [Error] 113 118 + [(] 118 119 + [)] 119 120 + [)] 120 121 +L327 + [}] 3 4 +L328 + [}] 2 3 +L332 + [for] 2 5 + [i] 6 7 + [,] 7 8 + [c] 9 10 + [:=] 11 13 + [range] 14 19 + [\[] 20 21 + [\]] 21 22 + [byte] 22 26 + [(] 26 27 + [name] 27 31 + [)] 31 32 + [{] 33 34 +L333 + [args] 3 7 + [.] 7 8 + [name] 8 12 + [\[] 12 13 + [i] 13 14 + [\]] 14 15 + [=] 16 17 + [C] 18 19 + [.] 19 20 + [char] 20 24 + [(] 24 25 + [c] 25 26 + [)] 26 27 +L334 + [}] 2 3 +L335 + [_] 2 3 + [,] 3 4 + [_] 5 6 + [,] 6 7 + [errno] 8 13 + [:=] 14 16 + [unix] 17 21 + [.] 21 22 + [Syscall] 22 29 + [(] 29 30 + [unix] 30 34 + [.] 34 35 + [SYS_IOCTL] 35 44 + [,] 44 45 + [getDirFd] 46 54 + [(] 54 55 + [dir] 55 58 + [)] 58 59 + [,] 59 60 + [C] 61 62 + [.] 62 63 + [BTRFS_IOC_SNAP_DESTROY] 63 85 + [,] 85 86 +L336 + [uintptr] 3 10 + [(] 10 11 + [unsafe] 11 17 + [.] 17 18 + [Pointer] 18 25 + [(] 25 26 + [&] 26 27 + [args] 27 31 + [)] 31 32 + [)] 32 33 + [)] 33 34 +L337 + [if] 2 4 + [errno] 5 10 + [!=] 11 13 + [0] 14 15 + [{] 16 17 +L338 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["Failed to destroy btrfs snapshot [ 21 69 + [,] 69 70 + [dirpath] 71 78 + [,] 78 79 + [name] 80 84 + [,] 84 85 + [errno] 86 91 + [.] 91 92 + [Error] 92 97 + [(] 97 98 + [)] 98 99 + [)] 99 100 +L339 + [}] 2 3 +L340 + [return] 2 8 + [nil] 9 12 +L341 + [}] 1 2 +L343 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [updateQuotaStatus] 18 35 + [(] 35 36 + [)] 36 37 + [{] 38 39 +L344 + [d] 2 3 + [.] 3 4 + [once] 4 8 + [.] 8 9 + [Do] 9 11 + [(] 11 12 + [func] 12 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 +L345 + [if] 3 5 + [!] 6 7 + [d] 7 8 + [.] 8 9 + [quotaEnabled] 9 21 + [{] 22 23 +L347 + [if] 4 6 + [err] 7 10 + [:=] 11 13 + [subvolQgroupStatus] 14 32 + [(] 32 33 + [d] 33 34 + [.] 34 35 + [home] 35 39 + [)] 39 40 + [;] 40 41 + [err] 42 45 + [!=] 46 48 + [nil] 49 52 + [{] 53 54 +L349 + [return] 5 11 +L350 + [}] 4 5 +L351 + [d] 4 5 + [.] 5 6 + [quotaEnabled] 6 18 + [=] 19 20 + [true] 21 25 +L352 + [}] 3 4 +L353 + [}] 2 3 + [)] 3 4 +L354 + [}] 1 2 +L356 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [subvolEnableQuota] 18 35 + [(] 35 36 + [)] 36 37 + [error] 38 43 + [{] 44 45 +L357 + [d] 2 3 + [.] 3 4 + [updateQuotaStatus] 4 21 + [(] 21 22 + [)] 22 23 +L359 + [if] 2 4 + [d] 5 6 + [.] 6 7 + [quotaEnabled] 7 19 + [{] 20 21 +L360 + [return] 3 9 + [nil] 10 13 +L361 + [}] 2 3 +L363 + [dir] 2 5 + [,] 5 6 + [err] 7 10 + [:=] 11 13 + [openDir] 14 21 + [(] 21 22 + [d] 22 23 + [.] 23 24 + [home] 24 28 + [)] 28 29 +L364 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L365 + [return] 3 9 + [err] 10 13 +L366 + [}] 2 3 +L367 + [defer] 2 7 + [closeDir] 8 16 + [(] 16 17 + [dir] 17 20 + [)] 20 21 +L369 + [var] 2 5 + [args] 6 10 + [C] 11 12 + [.] 12 13 + [struct_btrfs_ioctl_quota_ctl_args] 13 46 +L370 + [args] 2 6 + [.] 6 7 + [cmd] 7 10 + [=] 11 12 + [C] 13 14 + [.] 14 15 + [BTRFS_QUOTA_CTL_ENABLE] 15 37 +L371 + [_] 2 3 + [,] 3 4 + [_] 5 6 + [,] 6 7 + [errno] 8 13 + [:=] 14 16 + [unix] 17 21 + [.] 21 22 + [Syscall] 22 29 + [(] 29 30 + [unix] 30 34 + [.] 34 35 + [SYS_IOCTL] 35 44 + [,] 44 45 + [getDirFd] 46 54 + [(] 54 55 + [dir] 55 58 + [)] 58 59 + [,] 59 60 + [C] 61 62 + [.] 62 63 + [BTRFS_IOC_QUOTA_CTL] 63 82 + [,] 82 83 +L372 + [uintptr] 3 10 + [(] 10 11 + [unsafe] 11 17 + [.] 17 18 + [Pointer] 18 25 + [(] 25 26 + [&] 26 27 + [args] 27 31 + [)] 31 32 + [)] 32 33 + [)] 33 34 +L373 + [if] 2 4 + [errno] 5 10 + [!=] 11 13 + [0] 14 15 + [{] 16 17 +L374 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["Failed to enable btrfs quota for [ 21 62 + [,] 62 63 + [dir] 64 67 + [,] 67 68 + [errno] 69 74 + [.] 74 75 + [Error] 75 80 + [(] 80 81 + [)] 81 82 + [)] 82 83 +L375 + [}] 2 3 +L377 + [d] 2 3 + [.] 3 4 + [quotaEnabled] 4 16 + [=] 17 18 + [true] 19 23 +L379 + [return] 2 8 + [nil] 9 12 +L380 + [}] 1 2 +L382 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [subvolDisableQuota] 18 36 + [(] 36 37 + [)] 37 38 + [error] 39 44 + [{] 45 46 +L383 + [d] 2 3 + [.] 3 4 + [updateQuotaStatus] 4 21 + [(] 21 22 + [)] 22 23 +L385 + [if] 2 4 + [!] 5 6 + [d] 6 7 + [.] 7 8 + [quotaEnabled] 8 20 + [{] 21 22 +L386 + [return] 3 9 + [nil] 10 13 +L387 + [}] 2 3 +L389 + [dir] 2 5 + [,] 5 6 + [err] 7 10 + [:=] 11 13 + [openDir] 14 21 + [(] 21 22 + [d] 22 23 + [.] 23 24 + [home] 24 28 + [)] 28 29 +L390 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L391 + [return] 3 9 + [err] 10 13 +L392 + [}] 2 3 +L393 + [defer] 2 7 + [closeDir] 8 16 + [(] 16 17 + [dir] 17 20 + [)] 20 21 +L395 + [var] 2 5 + [args] 6 10 + [C] 11 12 + [.] 12 13 + [struct_btrfs_ioctl_quota_ctl_args] 13 46 +L396 + [args] 2 6 + [.] 6 7 + [cmd] 7 10 + [=] 11 12 + [C] 13 14 + [.] 14 15 + [BTRFS_QUOTA_CTL_DISABLE] 15 38 +L397 + [_] 2 3 + [,] 3 4 + [_] 5 6 + [,] 6 7 + [errno] 8 13 + [:=] 14 16 + [unix] 17 21 + [.] 21 22 + [Syscall] 22 29 + [(] 29 30 + [unix] 30 34 + [.] 34 35 + [SYS_IOCTL] 35 44 + [,] 44 45 + [getDirFd] 46 54 + [(] 54 55 + [dir] 55 58 + [)] 58 59 + [,] 59 60 + [C] 61 62 + [.] 62 63 + [BTRFS_IOC_QUOTA_CTL] 63 82 + [,] 82 83 +L398 + [uintptr] 3 10 + [(] 10 11 + [unsafe] 11 17 + [.] 17 18 + [Pointer] 18 25 + [(] 25 26 + [&] 26 27 + [args] 27 31 + [)] 31 32 + [)] 32 33 + [)] 33 34 +L399 + [if] 2 4 + [errno] 5 10 + [!=] 11 13 + [0] 14 15 + [{] 16 17 +L400 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["Failed to disable btrfs quota for[ 21 63 + [,] 63 64 + [dir] 65 68 + [,] 68 69 + [errno] 70 75 + [.] 75 76 + [Error] 76 81 + [(] 81 82 + [)] 82 83 + [)] 83 84 +L401 + [}] 2 3 +L403 + [d] 2 3 + [.] 3 4 + [quotaEnabled] 4 16 + [=] 17 18 + [false] 19 24 +L405 + [return] 2 8 + [nil] 9 12 +L406 + [}] 1 2 +L408 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [subvolRescanQuota] 18 35 + [(] 35 36 + [)] 36 37 + [error] 38 43 + [{] 44 45 +L409 + [d] 2 3 + [.] 3 4 + [updateQuotaStatus] 4 21 + [(] 21 22 + [)] 22 23 +L411 + [if] 2 4 + [!] 5 6 + [d] 6 7 + [.] 7 8 + [quotaEnabled] 8 20 + [{] 21 22 +L412 + [return] 3 9 + [nil] 10 13 +L413 + [}] 2 3 +L415 + [dir] 2 5 + [,] 5 6 + [err] 7 10 + [:=] 11 13 + [openDir] 14 21 + [(] 21 22 + [d] 22 23 + [.] 23 24 + [home] 24 28 + [)] 28 29 +L416 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L417 + [return] 3 9 + [err] 10 13 +L418 + [}] 2 3 +L419 + [defer] 2 7 + [closeDir] 8 16 + [(] 16 17 + [dir] 17 20 + [)] 20 21 +L421 + [var] 2 5 + [args] 6 10 + [C] 11 12 + [.] 12 13 + [struct_btrfs_ioctl_quota_rescan_ar[ 13 49 +L422 + [_] 2 3 + [,] 3 4 + [_] 5 6 + [,] 6 7 + [errno] 8 13 + [:=] 14 16 + [unix] 17 21 + [.] 21 22 + [Syscall] 22 29 + [(] 29 30 + [unix] 30 34 + [.] 34 35 + [SYS_IOCTL] 35 44 + [,] 44 45 + [getDirFd] 46 54 + [(] 54 55 + [dir] 55 58 + [)] 58 59 + [,] 59 60 + [C] 61 62 + [.] 62 63 + [BTRFS_IOC_QUOTA_RESCAN_WAIT] 63 90 + [,] 90 91 +L423 + [uintptr] 3 10 + [(] 10 11 + [unsafe] 11 17 + [.] 17 18 + [Pointer] 18 25 + [(] 25 26 + [&] 26 27 + [args] 27 31 + [)] 31 32 + [)] 32 33 + [)] 33 34 +L424 + [if] 2 4 + [errno] 5 10 + [!=] 11 13 + [0] 14 15 + [{] 16 17 +L425 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["Failed to rescan btrfs quota for [ 21 62 + [,] 62 63 + [dir] 64 67 + [,] 67 68 + [errno] 69 74 + [.] 74 75 + [Error] 75 80 + [(] 80 81 + [)] 81 82 + [)] 82 83 +L426 + [}] 2 3 +L428 + [return] 2 8 + [nil] 9 12 +L429 + [}] 1 2 +L431 + [func] 1 5 + [subvolLimitQgroup] 6 23 + [(] 23 24 + [path] 24 28 + [string] 29 35 + [,] 35 36 + [size] 37 41 + [uint64] 42 48 + [)] 48 49 + [error] 50 55 + [{] 56 57 +L432 + [dir] 2 5 + [,] 5 6 + [err] 7 10 + [:=] 11 13 + [openDir] 14 21 + [(] 21 22 + [path] 22 26 + [)] 26 27 +L433 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L434 + [return] 3 9 + [err] 10 13 +L435 + [}] 2 3 +L436 + [defer] 2 7 + [closeDir] 8 16 + [(] 16 17 + [dir] 17 20 + [)] 20 21 +L438 + [var] 2 5 + [args] 6 10 + [C] 11 12 + [.] 12 13 + [struct_btrfs_ioctl_qgroup_limit_ar[ 13 49 +L439 + [args] 2 6 + [.] 6 7 + [lim] 7 10 + [.] 10 11 + [max_referenced] 11 25 + [=] 26 27 + [C] 28 29 + [.] 29 30 + [__u64] 30 35 + [(] 35 36 + [size] 36 40 + [)] 40 41 +L440 + [args] 2 6 + [.] 6 7 + [lim] 7 10 + [.] 10 11 + [flags] 11 16 + [=] 17 18 + [C] 19 20 + [.] 20 21 + [BTRFS_QGROUP_LIMIT_MAX_RFER] 21 48 +L441 + [_] 2 3 + [,] 3 4 + [_] 5 6 + [,] 6 7 + [errno] 8 13 + [:=] 14 16 + [unix] 17 21 + [.] 21 22 + [Syscall] 22 29 + [(] 29 30 + [unix] 30 34 + [.] 34 35 + [SYS_IOCTL] 35 44 + [,] 44 45 + [getDirFd] 46 54 + [(] 54 55 + [dir] 55 58 + [)] 58 59 + [,] 59 60 + [C] 61 62 + [.] 62 63 + [BTRFS_IOC_QGROUP_LIMIT] 63 85 + [,] 85 86 +L442 + [uintptr] 3 10 + [(] 10 11 + [unsafe] 11 17 + [.] 17 18 + [Pointer] 18 25 + [(] 25 26 + [&] 26 27 + [args] 27 31 + [)] 31 32 + [)] 32 33 + [)] 33 34 +L443 + [if] 2 4 + [errno] 5 10 + [!=] 11 13 + [0] 14 15 + [{] 16 17 +L444 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["Failed to limit qgroup for %s: %v[ 21 56 + [,] 56 57 + [dir] 58 61 + [,] 61 62 + [errno] 63 68 + [.] 68 69 + [Error] 69 74 + [(] 74 75 + [)] 75 76 + [)] 76 77 +L445 + [}] 2 3 +L447 + [return] 2 8 + [nil] 9 12 +L448 + [}] 1 2 +L454 + [func] 1 5 + [subvolQgroupStatus] 6 24 + [(] 24 25 + [path] 25 29 + [string] 30 36 + [)] 36 37 + [error] 38 43 + [{] 44 45 +L455 + [dir] 2 5 + [,] 5 6 + [err] 7 10 + [:=] 11 13 + [openDir] 14 21 + [(] 21 22 + [path] 22 26 + [)] 26 27 +L456 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L457 + [return] 3 9 + [err] 10 13 +L458 + [}] 2 3 +L459 + [defer] 2 7 + [closeDir] 8 16 + [(] 16 17 + [dir] 17 20 + [)] 20 21 +L461 + [var] 2 5 + [args] 6 10 + [C] 11 12 + [.] 12 13 + [struct_btrfs_ioctl_search_args] 13 43 +L462 + [args] 2 6 + [.] 6 7 + [key] 7 10 + [.] 10 11 + [tree_id] 11 18 + [=] 19 20 + [C] 21 22 + [.] 22 23 + [BTRFS_QUOTA_TREE_OBJECTID] 23 48 +L463 + [args] 2 6 + [.] 6 7 + [key] 7 10 + [.] 10 11 + [min_type] 11 19 + [=] 20 21 + [C] 22 23 + [.] 23 24 + [BTRFS_QGROUP_STATUS_KEY] 24 47 +L464 + [args] 2 6 + [.] 6 7 + [key] 7 10 + [.] 10 11 + [max_type] 11 19 + [=] 20 21 + [C] 22 23 + [.] 23 24 + [BTRFS_QGROUP_STATUS_KEY] 24 47 +L465 + [args] 2 6 + [.] 6 7 + [key] 7 10 + [.] 10 11 + [max_objectid] 11 23 + [=] 24 25 + [C] 26 27 + [.] 27 28 + [__u64] 28 33 + [(] 33 34 + [math] 34 38 + [.] 38 39 + [MaxUint64] 39 48 + [)] 48 49 +L466 + [args] 2 6 + [.] 6 7 + [key] 7 10 + [.] 10 11 + [max_offset] 11 21 + [=] 22 23 + [C] 24 25 + [.] 25 26 + [__u64] 26 31 + [(] 31 32 + [math] 32 36 + [.] 36 37 + [MaxUint64] 37 46 + [)] 46 47 +L467 + [args] 2 6 + [.] 6 7 + [key] 7 10 + [.] 10 11 + [max_transid] 11 22 + [=] 23 24 + [C] 25 26 + [.] 26 27 + [__u64] 27 32 + [(] 32 33 + [math] 33 37 + [.] 37 38 + [MaxUint64] 38 47 + [)] 47 48 +L468 + [args] 2 6 + [.] 6 7 + [key] 7 10 + [.] 10 11 + [nr_items] 11 19 + [=] 20 21 + [4096] 22 26 +L470 + [_] 2 3 + [,] 3 4 + [_] 5 6 + [,] 6 7 + [errno] 8 13 + [:=] 14 16 + [unix] 17 21 + [.] 21 22 + [Syscall] 22 29 + [(] 29 30 + [unix] 30 34 + [.] 34 35 + [SYS_IOCTL] 35 44 + [,] 44 45 + [getDirFd] 46 54 + [(] 54 55 + [dir] 55 58 + [)] 58 59 + [,] 59 60 + [C] 61 62 + [.] 62 63 + [BTRFS_IOC_TREE_SEARCH] 63 84 + [,] 84 85 +L471 + [uintptr] 3 10 + [(] 10 11 + [unsafe] 11 17 + [.] 17 18 + [Pointer] 18 25 + [(] 25 26 + [&] 26 27 + [args] 27 31 + [)] 31 32 + [)] 32 33 + [)] 33 34 +L472 + [if] 2 4 + [errno] 5 10 + [!=] 11 13 + [0] 14 15 + [{] 16 17 +L473 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["Failed to search qgroup for %s: %[ 21 57 + [,] 57 58 + [path] 59 63 + [,] 63 64 + [errno] 65 70 + [.] 70 71 + [Error] 71 76 + [(] 76 77 + [)] 77 78 + [)] 78 79 +L474 + [}] 2 3 +L475 + [sh] 2 4 + [:=] 5 7 + [(] 8 9 + [*] 9 10 + [C] 10 11 + [.] 11 12 + [struct_btrfs_ioctl_search_header] 12 44 + [)] 44 45 + [(] 45 46 + [unsafe] 46 52 + [.] 52 53 + [Pointer] 53 60 + [(] 60 61 + [&] 61 62 + [args] 62 66 + [.] 66 67 + [buf] 67 70 + [)] 70 71 + [)] 71 72 +L476 + [if] 2 4 + [sh] 5 7 + [.] 7 8 + [_type] 8 13 + [!=] 14 16 + [C] 17 18 + [.] 18 19 + [BTRFS_QGROUP_STATUS_KEY] 19 42 + [{] 43 44 +L477 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["Invalid qgroup search header type[ 21 67 + [,] 67 68 + [path] 69 73 + [,] 73 74 + [sh] 75 77 + [.] 77 78 + [_type] 78 83 + [)] 83 84 +L478 + [}] 2 3 +L479 + [return] 2 8 + [nil] 9 12 +L480 + [}] 1 2 +L482 + [func] 1 5 + [subvolLookupQgroup] 6 24 + [(] 24 25 + [path] 25 29 + [string] 30 36 + [)] 36 37 + [(] 38 39 + [uint64] 39 45 + [,] 45 46 + [error] 47 52 + [)] 52 53 + [{] 54 55 +L483 + [dir] 2 5 + [,] 5 6 + [err] 7 10 + [:=] 11 13 + [openDir] 14 21 + [(] 21 22 + [path] 22 26 + [)] 26 27 +L484 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L485 + [return] 3 9 + [0] 10 11 + [,] 11 12 + [err] 13 16 +L486 + [}] 2 3 +L487 + [defer] 2 7 + [closeDir] 8 16 + [(] 16 17 + [dir] 17 20 + [)] 20 21 +L489 + [var] 2 5 + [args] 6 10 + [C] 11 12 + [.] 12 13 + [struct_btrfs_ioctl_ino_lookup_args] 13 47 +L490 + [args] 2 6 + [.] 6 7 + [objectid] 7 15 + [=] 16 17 + [C] 18 19 + [.] 19 20 + [BTRFS_FIRST_FREE_OBJECTID] 20 45 +L492 + [_] 2 3 + [,] 3 4 + [_] 5 6 + [,] 6 7 + [errno] 8 13 + [:=] 14 16 + [unix] 17 21 + [.] 21 22 + [Syscall] 22 29 + [(] 29 30 + [unix] 30 34 + [.] 34 35 + [SYS_IOCTL] 35 44 + [,] 44 45 + [getDirFd] 46 54 + [(] 54 55 + [dir] 55 58 + [)] 58 59 + [,] 59 60 + [C] 61 62 + [.] 62 63 + [BTRFS_IOC_INO_LOOKUP] 63 83 + [,] 83 84 +L493 + [uintptr] 3 10 + [(] 10 11 + [unsafe] 11 17 + [.] 17 18 + [Pointer] 18 25 + [(] 25 26 + [&] 26 27 + [args] 27 31 + [)] 31 32 + [)] 32 33 + [)] 33 34 +L494 + [if] 2 4 + [errno] 5 10 + [!=] 11 13 + [0] 14 15 + [{] 16 17 +L495 + [return] 3 9 + [0] 10 11 + [,] 11 12 + [fmt] 13 16 + [.] 16 17 + [Errorf] 17 23 + [(] 23 24 + ["Failed to lookup qgroup for %s: %[ 24 60 + [,] 60 61 + [dir] 62 65 + [,] 65 66 + [errno] 67 72 + [.] 72 73 + [Error] 73 78 + [(] 78 79 + [)] 79 80 + [)] 80 81 +L496 + [}] 2 3 +L497 + [if] 2 4 + [args] 5 9 + [.] 9 10 + [treeid] 10 16 + [==] 17 19 + [0] 20 21 + [{] 22 23 +L498 + [return] 3 9 + [0] 10 11 + [,] 11 12 + [fmt] 13 16 + [.] 16 17 + [Errorf] 17 23 + [(] 23 24 + ["Invalid qgroup id for %s: 0"] 24 53 + [,] 53 54 + [dir] 55 58 + [)] 58 59 +L499 + [}] 2 3 +L501 + [return] 2 8 + [uint64] 9 15 + [(] 15 16 + [args] 16 20 + [.] 20 21 + [treeid] 21 27 + [)] 27 28 + [,] 28 29 + [nil] 30 33 +L502 + [}] 1 2 +L504 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [subvolumesDir] 18 31 + [(] 31 32 + [)] 32 33 + [string] 34 40 + [{] 41 42 +L505 + [return] 2 8 + [path] 9 13 + [.] 13 14 + [Join] 14 18 + [(] 18 19 + [d] 19 20 + [.] 20 21 + [home] 21 25 + [,] 25 26 + ["subvolumes"] 27 39 + [)] 39 40 +L506 + [}] 1 2 +L508 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [subvolumesDirID] 18 33 + [(] 33 34 + [id] 34 36 + [string] 37 43 + [)] 43 44 + [string] 45 51 + [{] 52 53 +L509 + [return] 2 8 + [path] 9 13 + [.] 13 14 + [Join] 14 18 + [(] 18 19 + [d] 19 20 + [.] 20 21 + [subvolumesDir] 21 34 + [(] 34 35 + [)] 35 36 + [,] 36 37 + [id] 38 40 + [)] 40 41 +L510 + [}] 1 2 +L512 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [quotasDir] 18 27 + [(] 27 28 + [)] 28 29 + [string] 30 36 + [{] 37 38 +L513 + [return] 2 8 + [path] 9 13 + [.] 13 14 + [Join] 14 18 + [(] 18 19 + [d] 19 20 + [.] 20 21 + [home] 21 25 + [,] 25 26 + ["quotas"] 27 35 + [)] 35 36 +L514 + [}] 1 2 +L516 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [quotasDirID] 18 29 + [(] 29 30 + [id] 30 32 + [string] 33 39 + [)] 39 40 + [string] 41 47 + [{] 48 49 +L517 + [return] 2 8 + [path] 9 13 + [.] 13 14 + [Join] 14 18 + [(] 18 19 + [d] 19 20 + [.] 20 21 + [quotasDir] 21 30 + [(] 30 31 + [)] 31 32 + [,] 32 33 + [id] 34 36 + [)] 36 37 +L518 + [}] 1 2 +L522 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [CreateReadWrite] 18 33 + [(] 33 34 + [id] 34 36 + [,] 36 37 + [parent] 38 44 + [string] 45 51 + [,] 51 52 + [opts] 53 57 + [*] 58 59 + [graphdriver] 59 70 + [.] 70 71 + [CreateOpts] 71 81 + [)] 81 82 + [error] 83 88 + [{] 89 90 +L523 + [return] 2 8 + [d] 9 10 + [.] 10 11 + [Create] 11 17 + [(] 17 18 + [id] 18 20 + [,] 20 21 + [parent] 22 28 + [,] 28 29 + [opts] 30 34 + [)] 34 35 +L524 + [}] 1 2 +L527 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [Create] 18 24 + [(] 24 25 + [id] 25 27 + [,] 27 28 + [parent] 29 35 + [string] 36 42 + [,] 42 43 + [opts] 44 48 + [*] 49 50 + [graphdriver] 50 61 + [.] 61 62 + [CreateOpts] 62 72 + [)] 72 73 + [error] 74 79 + [{] 80 81 +L528 + [quotas] 2 8 + [:=] 9 11 + [path] 12 16 + [.] 16 17 + [Join] 17 21 + [(] 21 22 + [d] 22 23 + [.] 23 24 + [home] 24 28 + [,] 28 29 + ["quotas"] 30 38 + [)] 38 39 +L529 + [subvolumes] 2 12 + [:=] 13 15 + [path] 16 20 + [.] 20 21 + [Join] 21 25 + [(] 25 26 + [d] 26 27 + [.] 27 28 + [home] 28 32 + [,] 32 33 + ["subvolumes"] 34 46 + [)] 46 47 +L530 + [rootUID] 2 9 + [,] 9 10 + [rootGID] 11 18 + [,] 18 19 + [err] 20 23 + [:=] 24 26 + [idtools] 27 34 + [.] 34 35 + [GetRootUIDGID] 35 48 + [(] 48 49 + [d] 49 50 + [.] 50 51 + [uidMaps] 51 58 + [,] 58 59 + [d] 60 61 + [.] 61 62 + [gidMaps] 62 69 + [)] 69 70 +L531 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L532 + [return] 3 9 + [err] 10 13 +L533 + [}] 2 3 +L534 + [if] 2 4 + [err] 5 8 + [:=] 9 11 + [idtools] 12 19 + [.] 19 20 + [MkdirAllAndChown] 20 36 + [(] 36 37 + [subvolumes] 37 47 + [,] 47 48 + [0700] 49 53 + [,] 53 54 + [idtools] 55 62 + [.] 62 63 + [Identity] 63 71 + [{] 71 72 + [UID] 72 75 + [:] 75 76 + [rootUID] 77 84 + [,] 84 85 + [GID] 86 89 + [:] 89 90 + [rootGID] 91 98 + [}] 98 99 + [)] 99 100 + [;] 100 101 + [err] 102 105 + [!=] 106 108 + [nil] 109 112 + [{] 113 114 +L535 + [return] 3 9 + [err] 10 13 +L536 + [}] 2 3 +L537 + [if] 2 4 + [parent] 5 11 + [==] 12 14 + [""] 15 17 + [{] 18 19 +L538 + [if] 3 5 + [err] 6 9 + [:=] 10 12 + [subvolCreate] 13 25 + [(] 25 26 + [subvolumes] 26 36 + [,] 36 37 + [id] 38 40 + [)] 40 41 + [;] 41 42 + [err] 43 46 + [!=] 47 49 + [nil] 50 53 + [{] 54 55 +L539 + [return] 4 10 + [err] 11 14 +L540 + [}] 3 4 +L541 + [}] 2 3 + [else] 4 8 + [{] 9 10 +L542 + [parentDir] 3 12 + [:=] 13 15 + [d] 16 17 + [.] 17 18 + [subvolumesDirID] 18 33 + [(] 33 34 + [parent] 34 40 + [)] 40 41 +L543 + [st] 3 5 + [,] 5 6 + [err] 7 10 + [:=] 11 13 + [os] 14 16 + [.] 16 17 + [Stat] 17 21 + [(] 21 22 + [parentDir] 22 31 + [)] 31 32 +L544 + [if] 3 5 + [err] 6 9 + [!=] 10 12 + [nil] 13 16 + [{] 17 18 +L545 + [return] 4 10 + [err] 11 14 +L546 + [}] 3 4 +L547 + [if] 3 5 + [!] 6 7 + [st] 7 9 + [.] 9 10 + [IsDir] 10 15 + [(] 15 16 + [)] 16 17 + [{] 18 19 +L548 + [return] 4 10 + [fmt] 11 14 + [.] 14 15 + [Errorf] 15 21 + [(] 21 22 + ["%s: not a directory"] 22 43 + [,] 43 44 + [parentDir] 45 54 + [)] 54 55 +L549 + [}] 3 4 +L550 + [if] 3 5 + [err] 6 9 + [:=] 10 12 + [subvolSnapshot] 13 27 + [(] 27 28 + [parentDir] 28 37 + [,] 37 38 + [subvolumes] 39 49 + [,] 49 50 + [id] 51 53 + [)] 53 54 + [;] 54 55 + [err] 56 59 + [!=] 60 62 + [nil] 63 66 + [{] 67 68 +L551 + [return] 4 10 + [err] 11 14 +L552 + [}] 3 4 +L553 + [}] 2 3 +L555 + [var] 2 5 + [storageOpt] 6 16 + [map] 17 20 + [\[] 20 21 + [string] 21 27 + [\]] 27 28 + [string] 28 34 +L556 + [if] 2 4 + [opts] 5 9 + [!=] 10 12 + [nil] 13 16 + [{] 17 18 +L557 + [storageOpt] 3 13 + [=] 14 15 + [opts] 16 20 + [.] 20 21 + [StorageOpt] 21 31 +L558 + [}] 2 3 +L560 + [if] 2 4 + [_] 5 6 + [,] 6 7 + [ok] 8 10 + [:=] 11 13 + [storageOpt] 14 24 + [\[] 24 25 + ["size"] 25 31 + [\]] 31 32 + [;] 32 33 + [ok] 34 36 + [{] 37 38 +L561 + [driver] 3 9 + [:=] 10 12 + [&] 13 14 + [Driver] 14 20 + [{] 20 21 + [}] 21 22 +L562 + [if] 3 5 + [err] 6 9 + [:=] 10 12 + [d] 13 14 + [.] 14 15 + [parseStorageOpt] 15 30 + [(] 30 31 + [storageOpt] 31 41 + [,] 41 42 + [driver] 43 49 + [)] 49 50 + [;] 50 51 + [err] 52 55 + [!=] 56 58 + [nil] 59 62 + [{] 63 64 +L563 + [return] 4 10 + [err] 11 14 +L564 + [}] 3 4 +L566 + [if] 3 5 + [err] 6 9 + [:=] 10 12 + [d] 13 14 + [.] 14 15 + [setStorageSize] 15 29 + [(] 29 30 + [path] 30 34 + [.] 34 35 + [Join] 35 39 + [(] 39 40 + [subvolumes] 40 50 + [,] 50 51 + [id] 52 54 + [)] 54 55 + [,] 55 56 + [driver] 57 63 + [)] 63 64 + [;] 64 65 + [err] 66 69 + [!=] 70 72 + [nil] 73 76 + [{] 77 78 +L567 + [return] 4 10 + [err] 11 14 +L568 + [}] 3 4 +L569 + [if] 3 5 + [err] 6 9 + [:=] 10 12 + [idtools] 13 20 + [.] 20 21 + [MkdirAllAndChown] 21 37 + [(] 37 38 + [quotas] 38 44 + [,] 44 45 + [0700] 46 50 + [,] 50 51 + [idtools] 52 59 + [.] 59 60 + [Identity] 60 68 + [{] 68 69 + [UID] 69 72 + [:] 72 73 + [rootUID] 74 81 + [,] 81 82 + [GID] 83 86 + [:] 86 87 + [rootGID] 88 95 + [}] 95 96 + [)] 96 97 + [;] 97 98 + [err] 99 102 + [!=] 103 105 + [nil] 106 109 + [{] 110 111 +L570 + [return] 4 10 + [err] 11 14 +L571 + [}] 3 4 +L572 + [if] 3 5 + [err] 6 9 + [:=] 10 12 + [ioutil] 13 19 + [.] 19 20 + [WriteFile] 20 29 + [(] 29 30 + [path] 30 34 + [.] 34 35 + [Join] 35 39 + [(] 39 40 + [quotas] 40 46 + [,] 46 47 + [id] 48 50 + [)] 50 51 + [,] 51 52 + [\[] 53 54 + [\]] 54 55 + [byte] 55 59 + [(] 59 60 + [fmt] 60 63 + [.] 63 64 + [Sprint] 64 70 + [(] 70 71 + [driver] 71 77 + [.] 77 78 + [options] 78 85 + [.] 85 86 + [size] 86 90 + [)] 90 91 + [)] 91 92 + [,] 92 93 + [0644] 94 98 + [)] 98 99 + [;] 99 100 + [err] 101 104 + [!=] 105 107 + [nil] 108 111 + [{] 112 113 +L573 + [return] 4 10 + [err] 11 14 +L574 + [}] 3 4 +L575 + [}] 2 3 +L579 + [if] 2 4 + [rootUID] 5 12 + [!=] 13 15 + [0] 16 17 + [||] 18 20 + [rootGID] 21 28 + [!=] 29 31 + [0] 32 33 + [{] 34 35 +L580 + [if] 3 5 + [err] 6 9 + [:=] 10 12 + [os] 13 15 + [.] 15 16 + [Chown] 16 21 + [(] 21 22 + [path] 22 26 + [.] 26 27 + [Join] 27 31 + [(] 31 32 + [subvolumes] 32 42 + [,] 42 43 + [id] 44 46 + [)] 46 47 + [,] 47 48 + [rootUID] 49 56 + [,] 56 57 + [rootGID] 58 65 + [)] 65 66 + [;] 66 67 + [err] 68 71 + [!=] 72 74 + [nil] 75 78 + [{] 79 80 +L581 + [return] 4 10 + [err] 11 14 +L582 + [}] 3 4 +L583 + [}] 2 3 +L585 + [mountLabel] 2 12 + [:=] 13 15 + [""] 16 18 +L586 + [if] 2 4 + [opts] 5 9 + [!=] 10 12 + [nil] 13 16 + [{] 17 18 +L587 + [mountLabel] 3 13 + [=] 14 15 + [opts] 16 20 + [.] 20 21 + [MountLabel] 21 31 +L588 + [}] 2 3 +L590 + [return] 2 8 + [label] 9 14 + [.] 14 15 + [Relabel] 15 22 + [(] 22 23 + [path] 23 27 + [.] 27 28 + [Join] 28 32 + [(] 32 33 + [subvolumes] 33 43 + [,] 43 44 + [id] 45 47 + [)] 47 48 + [,] 48 49 + [mountLabel] 50 60 + [,] 60 61 + [false] 62 67 + [)] 67 68 +L591 + [}] 1 2 +L594 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [parseStorageOpt] 18 33 + [(] 33 34 + [storageOpt] 34 44 + [map] 45 48 + [\[] 48 49 + [string] 49 55 + [\]] 55 56 + [string] 56 62 + [,] 62 63 + [driver] 64 70 + [*] 71 72 + [Driver] 72 78 + [)] 78 79 + [error] 80 85 + [{] 86 87 +L596 + [for] 2 5 + [key] 6 9 + [,] 9 10 + [val] 11 14 + [:=] 15 17 + [range] 18 23 + [storageOpt] 24 34 + [{] 35 36 +L597 + [key] 3 6 + [:=] 7 9 + [strings] 10 17 + [.] 17 18 + [ToLower] 18 25 + [(] 25 26 + [key] 26 29 + [)] 29 30 +L598 + [switch] 3 9 + [key] 10 13 + [{] 14 15 +L599 + [case] 3 7 + ["size"] 8 14 + [:] 14 15 +L600 + [size] 4 8 + [,] 8 9 + [err] 10 13 + [:=] 14 16 + [units] 17 22 + [.] 22 23 + [RAMInBytes] 23 33 + [(] 33 34 + [val] 34 37 + [)] 37 38 +L601 + [if] 4 6 + [err] 7 10 + [!=] 11 13 + [nil] 14 17 + [{] 18 19 +L602 + [return] 5 11 + [err] 12 15 +L603 + [}] 4 5 +L604 + [driver] 4 10 + [.] 10 11 + [options] 11 18 + [.] 18 19 + [size] 19 23 + [=] 24 25 + [uint64] 26 32 + [(] 32 33 + [size] 33 37 + [)] 37 38 +L605 + [default] 3 10 + [:] 10 11 +L606 + [return] 4 10 + [fmt] 11 14 + [.] 14 15 + [Errorf] 15 21 + [(] 21 22 + ["Unknown option %s"] 22 41 + [,] 41 42 + [key] 43 46 + [)] 46 47 +L607 + [}] 3 4 +L608 + [}] 2 3 +L610 + [return] 2 8 + [nil] 9 12 +L611 + [}] 1 2 +L614 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [setStorageSize] 18 32 + [(] 32 33 + [dir] 33 36 + [string] 37 43 + [,] 43 44 + [driver] 45 51 + [*] 52 53 + [Driver] 53 59 + [)] 59 60 + [error] 61 66 + [{] 67 68 +L615 + [if] 2 4 + [driver] 5 11 + [.] 11 12 + [options] 12 19 + [.] 19 20 + [size] 20 24 + [<=] 25 27 + [0] 28 29 + [{] 30 31 +L616 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["btrfs: invalid storage size: %s"] 21 54 + [,] 54 55 + [units] 56 61 + [.] 61 62 + [HumanSize] 62 71 + [(] 71 72 + [float64] 72 79 + [(] 79 80 + [driver] 80 86 + [.] 86 87 + [options] 87 94 + [.] 94 95 + [size] 95 99 + [)] 99 100 + [)] 100 101 + [)] 101 102 +L617 + [}] 2 3 +L618 + [if] 2 4 + [d] 5 6 + [.] 6 7 + [options] 7 14 + [.] 14 15 + [minSpace] 15 23 + [>] 24 25 + [0] 26 27 + [&&] 28 30 + [driver] 31 37 + [.] 37 38 + [options] 38 45 + [.] 45 46 + [size] 46 50 + [<] 51 52 + [d] 53 54 + [.] 54 55 + [options] 55 62 + [.] 62 63 + [minSpace] 63 71 + [{] 72 73 +L619 + [return] 3 9 + [fmt] 10 13 + [.] 13 14 + [Errorf] 14 20 + [(] 20 21 + ["btrfs: storage size cannot be les[ 21 65 + [,] 65 66 + [units] 67 72 + [.] 72 73 + [HumanSize] 73 82 + [(] 82 83 + [float64] 83 90 + [(] 90 91 + [d] 91 92 + [.] 92 93 + [options] 93 100 + [.] 100 101 + [minSpace] 101 109 + [)] 109 110 + [)] 110 111 + [)] 111 112 +L620 + [}] 2 3 +L621 + [if] 2 4 + [err] 5 8 + [:=] 9 11 + [d] 12 13 + [.] 13 14 + [subvolEnableQuota] 14 31 + [(] 31 32 + [)] 32 33 + [;] 33 34 + [err] 35 38 + [!=] 39 41 + [nil] 42 45 + [{] 46 47 +L622 + [return] 3 9 + [err] 10 13 +L623 + [}] 2 3 +L624 + [return] 2 8 + [subvolLimitQgroup] 9 26 + [(] 26 27 + [dir] 27 30 + [,] 30 31 + [driver] 32 38 + [.] 38 39 + [options] 39 46 + [.] 46 47 + [size] 47 51 + [)] 51 52 +L625 + [}] 1 2 +L628 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [Remove] 18 24 + [(] 24 25 + [id] 25 27 + [string] 28 34 + [)] 34 35 + [error] 36 41 + [{] 42 43 +L629 + [dir] 2 5 + [:=] 6 8 + [d] 9 10 + [.] 10 11 + [subvolumesDirID] 11 26 + [(] 26 27 + [id] 27 29 + [)] 29 30 +L630 + [if] 2 4 + [_] 5 6 + [,] 6 7 + [err] 8 11 + [:=] 12 14 + [os] 15 17 + [.] 17 18 + [Stat] 18 22 + [(] 22 23 + [dir] 23 26 + [)] 26 27 + [;] 27 28 + [err] 29 32 + [!=] 33 35 + [nil] 36 39 + [{] 40 41 +L631 + [return] 3 9 + [err] 10 13 +L632 + [}] 2 3 +L633 + [quotasDir] 2 11 + [:=] 12 14 + [d] 15 16 + [.] 16 17 + [quotasDirID] 17 28 + [(] 28 29 + [id] 29 31 + [)] 31 32 +L634 + [if] 2 4 + [_] 5 6 + [,] 6 7 + [err] 8 11 + [:=] 12 14 + [os] 15 17 + [.] 17 18 + [Stat] 18 22 + [(] 22 23 + [quotasDir] 23 32 + [)] 32 33 + [;] 33 34 + [err] 35 38 + [==] 39 41 + [nil] 42 45 + [{] 46 47 +L635 + [if] 3 5 + [err] 6 9 + [:=] 10 12 + [os] 13 15 + [.] 15 16 + [Remove] 16 22 + [(] 22 23 + [quotasDir] 23 32 + [)] 32 33 + [;] 33 34 + [err] 35 38 + [!=] 39 41 + [nil] 42 45 + [{] 46 47 +L636 + [return] 4 10 + [err] 11 14 +L637 + [}] 3 4 +L638 + [}] 2 3 + [else] 4 8 + [if] 9 11 + [!] 12 13 + [os] 13 15 + [.] 15 16 + [IsNotExist] 16 26 + [(] 26 27 + [err] 27 30 + [)] 30 31 + [{] 32 33 +L639 + [return] 3 9 + [err] 10 13 +L640 + [}] 2 3 +L643 + [d] 2 3 + [.] 3 4 + [updateQuotaStatus] 4 21 + [(] 21 22 + [)] 22 23 +L645 + [if] 2 4 + [err] 5 8 + [:=] 9 11 + [subvolDelete] 12 24 + [(] 24 25 + [d] 25 26 + [.] 26 27 + [subvolumesDir] 27 40 + [(] 40 41 + [)] 41 42 + [,] 42 43 + [id] 44 46 + [,] 46 47 + [d] 48 49 + [.] 49 50 + [quotaEnabled] 50 62 + [)] 62 63 + [;] 63 64 + [err] 65 68 + [!=] 69 71 + [nil] 72 75 + [{] 76 77 +L646 + [return] 3 9 + [err] 10 13 +L647 + [}] 2 3 +L648 + [if] 2 4 + [err] 5 8 + [:=] 9 11 + [system] 12 18 + [.] 18 19 + [EnsureRemoveAll] 19 34 + [(] 34 35 + [dir] 35 38 + [)] 38 39 + [;] 39 40 + [err] 41 44 + [!=] 45 47 + [nil] 48 51 + [{] 52 53 +L649 + [return] 3 9 + [err] 10 13 +L650 + [}] 2 3 +L651 + [return] 2 8 + [d] 9 10 + [.] 10 11 + [subvolRescanQuota] 11 28 + [(] 28 29 + [)] 29 30 +L652 + [}] 1 2 +L655 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [Get] 18 21 + [(] 21 22 + [id] 22 24 + [,] 24 25 + [mountLabel] 26 36 + [string] 37 43 + [)] 43 44 + [(] 45 46 + [containerfs] 46 57 + [.] 57 58 + [ContainerFS] 58 69 + [,] 69 70 + [error] 71 76 + [)] 76 77 + [{] 78 79 +L656 + [dir] 2 5 + [:=] 6 8 + [d] 9 10 + [.] 10 11 + [subvolumesDirID] 11 26 + [(] 26 27 + [id] 27 29 + [)] 29 30 +L657 + [st] 2 4 + [,] 4 5 + [err] 6 9 + [:=] 10 12 + [os] 13 15 + [.] 15 16 + [Stat] 16 20 + [(] 20 21 + [dir] 21 24 + [)] 24 25 +L658 + [if] 2 4 + [err] 5 8 + [!=] 9 11 + [nil] 12 15 + [{] 16 17 +L659 + [return] 3 9 + [nil] 10 13 + [,] 13 14 + [err] 15 18 +L660 + [}] 2 3 +L662 + [if] 2 4 + [!] 5 6 + [st] 6 8 + [.] 8 9 + [IsDir] 9 14 + [(] 14 15 + [)] 15 16 + [{] 17 18 +L663 + [return] 3 9 + [nil] 10 13 + [,] 13 14 + [fmt] 15 18 + [.] 18 19 + [Errorf] 19 25 + [(] 25 26 + ["%s: not a directory"] 26 47 + [,] 47 48 + [dir] 49 52 + [)] 52 53 +L664 + [}] 2 3 +L666 + [if] 2 4 + [quota] 5 10 + [,] 10 11 + [err] 12 15 + [:=] 16 18 + [ioutil] 19 25 + [.] 25 26 + [ReadFile] 26 34 + [(] 34 35 + [d] 35 36 + [.] 36 37 + [quotasDirID] 37 48 + [(] 48 49 + [id] 49 51 + [)] 51 52 + [)] 52 53 + [;] 53 54 + [err] 55 58 + [==] 59 61 + [nil] 62 65 + [{] 66 67 +L667 + [if] 3 5 + [size] 6 10 + [,] 10 11 + [err] 12 15 + [:=] 16 18 + [strconv] 19 26 + [.] 26 27 + [ParseUint] 27 36 + [(] 36 37 + [string] 37 43 + [(] 43 44 + [quota] 44 49 + [)] 49 50 + [,] 50 51 + [10] 52 54 + [,] 54 55 + [64] 56 58 + [)] 58 59 + [;] 59 60 + [err] 61 64 + [==] 65 67 + [nil] 68 71 + [&&] 72 74 + [size] 75 79 + [>=] 80 82 + [d] 83 84 + [.] 84 85 + [options] 85 92 + [.] 92 93 + [minSpace] 93 101 + [{] 102 103 +L668 + [if] 4 6 + [err] 7 10 + [:=] 11 13 + [d] 14 15 + [.] 15 16 + [subvolEnableQuota] 16 33 + [(] 33 34 + [)] 34 35 + [;] 35 36 + [err] 37 40 + [!=] 41 43 + [nil] 44 47 + [{] 48 49 +L669 + [return] 5 11 + [nil] 12 15 + [,] 15 16 + [err] 17 20 +L670 + [}] 4 5 +L671 + [if] 4 6 + [err] 7 10 + [:=] 11 13 + [subvolLimitQgroup] 14 31 + [(] 31 32 + [dir] 32 35 + [,] 35 36 + [size] 37 41 + [)] 41 42 + [;] 42 43 + [err] 44 47 + [!=] 48 50 + [nil] 51 54 + [{] 55 56 +L672 + [return] 5 11 + [nil] 12 15 + [,] 15 16 + [err] 17 20 +L673 + [}] 4 5 +L674 + [}] 3 4 +L675 + [}] 2 3 +L677 + [return] 2 8 + [containerfs] 9 20 + [.] 20 21 + [NewLocalContainerFS] 21 40 + [(] 40 41 + [dir] 41 44 + [)] 44 45 + [,] 45 46 + [nil] 47 50 +L678 + [}] 1 2 +L681 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [Put] 18 21 + [(] 21 22 + [id] 22 24 + [string] 25 31 + [)] 31 32 + [error] 33 38 + [{] 39 40 +L684 + [return] 2 8 + [nil] 9 12 +L685 + [}] 1 2 +L688 + [func] 1 5 + [(] 6 7 + [d] 7 8 + [*] 9 10 + [Driver] 10 16 + [)] 16 17 + [Exists] 18 24 + [(] 24 25 + [id] 25 27 + [string] 28 34 + [)] 34 35 + [bool] 36 40 + [{] 41 42 +L689 + [dir] 2 5 + [:=] 6 8 + [d] 9 10 + [.] 10 11 + [subvolumesDirID] 11 26 + [(] 26 27 + [id] 27 29 + [)] 29 30 +L690 + [_] 2 3 + [,] 3 4 + [err] 5 8 + [:=] 9 11 + [os] 12 14 + [.] 14 15 + [Stat] 15 19 + [(] 19 20 + [dir] 20 23 + [)] 23 24 +L691 + [return] 2 8 + [err] 9 12 + [==] 13 15 + [nil] 16 19 +L692 + [}] 1 2 +EOF diff --git a/pmd-go/src/test/resources/net/sourceforge/pmd/cpd/hello.go b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/hello.go similarity index 100% rename from pmd-go/src/test/resources/net/sourceforge/pmd/cpd/hello.go rename to pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/hello.go diff --git a/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/hello.txt b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/hello.txt new file mode 100644 index 0000000000..f5c908b261 --- /dev/null +++ b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/hello.txt @@ -0,0 +1,31 @@ + [Image] or [Truncated image[ Bcol Ecol +L21 + [import] 1 7 + [(] 8 9 +L22 + ["fmt"] 2 7 +L24 + ["github.com/golang/example/stringu[ 2 40 +L25 + [)] 1 2 +L27 + [func] 1 5 + [main] 6 10 + [(] 10 11 + [)] 11 12 + [{] 13 14 +L28 + [fmt] 2 5 + [.] 5 6 + [Println] 6 13 + [(] 13 14 + [stringutil] 14 24 + [.] 24 25 + [Reverse] 25 32 + [(] 32 33 + ["!selpmaxe oG ,olleH"] 33 54 + [)] 54 55 + [)] 55 56 +L29 + [}] 1 2 +EOF diff --git a/pmd-go/src/test/resources/net/sourceforge/pmd/cpd/issue1751.go b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/issue-1751.go similarity index 100% rename from pmd-go/src/test/resources/net/sourceforge/pmd/cpd/issue1751.go rename to pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/issue-1751.go diff --git a/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/issue-1751.txt b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/issue-1751.txt new file mode 100644 index 0000000000..53237260ef --- /dev/null +++ b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/issue-1751.txt @@ -0,0 +1,84 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [func] 1 5 + [test] 6 10 + [(] 10 11 + [in] 11 13 + [*] 14 15 + [Value] 15 20 + [,] 20 21 + [param] 22 27 + [*] 28 29 + [Value] 29 34 + [)] 34 35 + [(] 36 37 + [*] 37 38 + [Value] 38 43 + [,] 43 44 + [*] 45 46 + [Error] 46 51 + [)] 51 52 + [{] 53 54 +L2 + [output] 2 8 + [:=] 9 11 + [strings] 12 19 + [.] 19 20 + [Replace] 20 27 + [(] 27 28 + [in] 28 30 + [.] 30 31 + [String] 31 37 + [(] 37 38 + [)] 38 39 + [,] 39 40 + ["\\\\"] 41 45 + [,] 45 46 + ["\\\\\\\\"] 47 53 + [,] 53 54 + [-] 55 56 + [1] 56 57 + [)] 57 58 +L3 + [output] 2 8 + [=] 9 10 + [strings] 11 18 + [.] 18 19 + [Replace] 19 26 + [(] 26 27 + [output] 27 33 + [,] 33 34 + ["\\""] 35 39 + [,] 39 40 + ["\\\\\\""] 41 47 + [,] 47 48 + [-] 49 50 + [1] 50 51 + [)] 51 52 +L4 + [output] 2 8 + [=] 9 10 + [strings] 11 18 + [.] 18 19 + [Replace] 19 26 + [(] 26 27 + [output] 27 33 + [,] 33 34 + ["'"] 35 38 + [,] 38 39 + ["\\\\'"] 40 45 + [,] 45 46 + [-] 47 48 + [1] 48 49 + [)] 49 50 +L5 + [return] 2 8 + [AsValue] 9 16 + [(] 16 17 + [output] 17 23 + [)] 23 24 + [,] 24 25 + [nil] 26 29 +L6 + [}] 1 2 +EOF diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 3feb7a47e7..f38fadd1cf 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -45,10 +45,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-groovy/src/main/java/net/sourceforge/pmd/cpd/GroovyTokenizer.java b/pmd-groovy/src/main/java/net/sourceforge/pmd/cpd/GroovyTokenizer.java index 4e387cc07f..18a2e94779 100644 --- a/pmd-groovy/src/main/java/net/sourceforge/pmd/cpd/GroovyTokenizer.java +++ b/pmd-groovy/src/main/java/net/sourceforge/pmd/cpd/GroovyTokenizer.java @@ -6,6 +6,7 @@ package net.sourceforge.pmd.cpd; import java.io.StringReader; +import org.codehaus.groovy.antlr.SourceInfo; import org.codehaus.groovy.antlr.parser.GroovyLexer; import net.sourceforge.pmd.lang.ast.TokenMgrError; @@ -31,8 +32,16 @@ public class GroovyTokenizer implements Tokenizer { while (token.getType() != Token.EOF_TYPE) { String tokenText = token.getText(); - TokenEntry tokenEntry = new TokenEntry(tokenText, sourceCode.getFileName(), token.getLine(), - token.getColumn(), tokenText.length()); + + + int lastCol; + if (token instanceof SourceInfo) { + lastCol = ((SourceInfo) token).getColumnLast(); + } else { + // fallback + lastCol = token.getColumn() + tokenText.length(); + } + TokenEntry tokenEntry = new TokenEntry(tokenText, sourceCode.getFileName(), token.getLine(), token.getColumn(), lastCol); tokenEntries.add(tokenEntry); token = tokenStream.nextToken(); diff --git a/pmd-groovy/src/test/java/net/sourceforge/pmd/cpd/GroovyTokenizerTest.java b/pmd-groovy/src/test/java/net/sourceforge/pmd/cpd/GroovyTokenizerTest.java index 200fecfb80..ba6e2d1d65 100644 --- a/pmd-groovy/src/test/java/net/sourceforge/pmd/cpd/GroovyTokenizerTest.java +++ b/pmd-groovy/src/test/java/net/sourceforge/pmd/cpd/GroovyTokenizerTest.java @@ -4,34 +4,30 @@ package net.sourceforge.pmd.cpd; -import java.io.IOException; -import java.nio.charset.StandardCharsets; +import java.util.Properties; -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -public class GroovyTokenizerTest extends AbstractTokenizerTest { +public class GroovyTokenizerTest extends CpdTextComparisonTest { - private static final String FILENAME = "BTree.groovy"; - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new GroovyTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), FILENAME)); + public GroovyTokenizerTest() { + super(".groovy"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(GroovyTokenizer.class.getResourceAsStream(FILENAME), StandardCharsets.UTF_8); + protected String getResourcePrefix() { + return "../lang/groovy/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new GroovyTokenizer(); } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 369; - super.tokenizeTest(); + public void testSample() { + doTest("sample"); } } diff --git a/pmd-groovy/src/test/resources/net/sourceforge/pmd/cpd/BTree.groovy b/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/sample.groovy similarity index 100% rename from pmd-groovy/src/test/resources/net/sourceforge/pmd/cpd/BTree.groovy rename to pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/sample.groovy diff --git a/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/sample.txt b/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/sample.txt new file mode 100644 index 0000000000..997a1005bd --- /dev/null +++ b/pmd-groovy/src/test/resources/net/sourceforge/pmd/lang/groovy/cpd/testdata/sample.txt @@ -0,0 +1,421 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [] 49 1 +L2 + [package] 1 8 + [net] 9 12 + [.] 12 13 + [sourceforge] 13 24 + [.] 24 25 + [pmd] 25 28 + [.] 28 29 + [cpd] 29 32 + [] 32 1 +L7 + [class] 1 6 + [BTree] 7 12 + [<] 12 13 + [K] 13 14 + [,] 14 15 + [V] 16 17 + [>] 17 18 + [extends] 19 26 + [BTreeNode] 27 36 + [<] 36 37 + [K] 37 38 + [>] 38 39 + [{] 40 41 + [] 41 2 +L9 + [static] 2 8 + [def] 9 12 + [instance] 13 21 + [] 21 2 +L11 + [BlockManager] 2 14 + [<] 14 15 + [V] 15 16 + [>] 16 17 + [manager] 18 25 + [] 25 2 +L13 + [BTree] 2 7 + [(] 7 8 + [)] 8 9 + [{] 10 11 + [] 11 3 +L14 + [instance] 3 11 + [=] 12 13 + [this] 14 18 + [] 18 3 +L15 + [getLeaf] 3 10 + [(] 10 11 + [this] 11 15 + [)] 15 16 + [] 16 3 +L16 + [manager] 3 10 + [=] 11 12 + [new] 13 16 + [BlockManager] 17 29 + [<] 29 30 + [>] 30 31 + [(] 31 32 + [)] 32 33 + [] 33 2 +L17 + [}] 2 3 + [] 3 2 +L19 + [def] 2 5 + [split] 6 11 + [(] 11 12 + [)] 12 13 + [{] 14 15 + [] 15 3 +L22 + [BTreeNode] 3 12 + [<] 12 13 + [K] 13 14 + [>] 14 15 + [left] 16 20 + [=] 21 22 + [clone] 23 28 + [(] 28 29 + [)] 29 30 + [] 30 3 +L23 + [BTreeNode] 3 12 + [<] 12 13 + [K] 13 14 + [>] 14 15 + [right] 16 21 + [=] 22 23 + [clone] 24 29 + [(] 29 30 + [)] 30 31 + [] 31 3 +L26 + [\[] 3 4 + [left] 4 8 + [,] 8 9 + [right] 10 15 + [\]] 15 16 + [*.] 16 18 + [parent] 18 24 + [=] 25 26 + [this] 27 31 + [] 31 3 +L29 + [left] 3 7 + [.] 7 8 + [pointers] 8 16 + [=] 17 18 + [pointers] 19 27 + [.] 27 28 + [subList] 28 35 + [(] 35 36 + [0] 36 37 + [,] 37 38 + [count] 39 44 + [/] 45 46 + [2] 47 48 + [as] 49 51 + [int] 52 55 + [)] 55 56 + [as] 57 59 + [LinkedList] 60 70 + [] 70 3 +L30 + [right] 3 8 + [.] 8 9 + [pointers] 9 17 + [=] 18 19 + [pointers] 20 28 + [.] 28 29 + [subList] 29 36 + [(] 36 37 + [count] 37 42 + [/] 43 44 + [2] 45 46 + [as] 47 49 + [int] 50 53 + [,] 53 54 + [count] 55 60 + [)] 60 61 + [as] 62 64 + [LinkedList] 65 75 + [] 75 3 +L33 + [if] 3 5 + [(] 6 7 + [left] 7 11 + [.] 11 12 + [internalNode] 12 24 + [)] 24 25 + [{] 26 27 + [] 27 4 +L34 + [left] 4 8 + [.] 8 9 + [pointers] 9 17 + [\[] 17 18 + [-] 18 19 + [1] 19 20 + [\]] 20 21 + [.] 21 22 + [key] 22 25 + [=] 26 27 + [null] 28 32 + [] 32 3 +L35 + [}] 3 4 + [] 4 3 +L36 + [else] 3 7 + [{] 8 9 + [] 9 4 +L37 + [left] 4 8 + [.] 8 9 + [rightSibling] 9 21 + [=] 22 23 + [right] 24 29 + [] 29 4 +L38 + [right] 4 9 + [.] 9 10 + [leftSibling] 10 21 + [=] 22 23 + [left] 24 28 + [] 28 3 +L39 + [}] 3 4 + [] 4 3 +L42 + [if] 3 5 + [(] 6 7 + [!] 7 8 + [bucketNode] 8 18 + [)] 18 19 + [{] 20 21 + [] 21 4 +L43 + [\[] 4 5 + [left] 5 9 + [,] 9 10 + [right] 11 16 + [\]] 16 17 + [.] 17 18 + [each] 18 22 + [{] 23 24 + [node] 25 29 + [->] 30 32 + [node] 33 37 + [.] 37 38 + [pointers] 38 46 + [*.] 46 48 + [value] 48 53 + [*.] 53 55 + [parent] 55 61 + [=] 62 63 + [node] 64 68 + [}] 69 70 + [] 70 3 +L44 + [}] 3 4 + [] 4 3 +L47 + [pointers] 3 11 + [.] 11 12 + [clear] 12 17 + [(] 17 18 + [)] 18 19 + [] 19 3 +L48 + [addDirect] 3 12 + [(] 12 13 + [new] 13 16 + [BTreeEntry] 17 27 + [(] 27 28 + [right] 28 33 + [.] 33 34 + [smallestKey] 34 45 + [,] 45 46 + [left] 47 51 + [)] 51 52 + [)] 52 53 + [] 53 3 +L49 + [addDirect] 3 12 + [(] 12 13 + [new] 13 16 + [BTreeEntry] 17 27 + [(] 27 28 + [null] 28 32 + [,] 32 33 + [right] 34 39 + [)] 39 40 + [)] 40 41 + [] 41 3 +L52 + [if] 3 5 + [(] 6 7 + [leafNode] 7 15 + [)] 15 16 + [{] 17 18 + [] 18 4 +L53 + [getPointer] 4 14 + [(] 14 15 + [this] 15 19 + [)] 19 20 + [] 20 3 +L54 + [}] 3 4 + [] 4 2 +L55 + [}] 2 3 + [] 3 2 +L57 + [def] 2 5 + [add] 6 9 + [(] 9 10 + [K] 10 11 + [key] 12 15 + [,] 15 16 + [V] 17 18 + [value] 19 24 + [)] 24 25 + [{] 26 27 + [] 27 3 +L59 + [if] 3 5 + [(] 6 7 + [count] 7 12 + [>] 13 14 + [0] 15 16 + [&&] 17 19 + [search] 20 26 + [(] 26 27 + [key] 27 30 + [)] 30 31 + [)] 31 32 + [{] 33 34 + [] 34 4 +L60 + [throw] 4 9 + [new] 10 13 + [IllegalArgumentException] 14 38 + [(] 38 39 + [] 39 41 + [key] 41 44 + [ is already in the tree] 44 68 + [)] 68 69 + [] 69 3 +L61 + [}] 3 4 + [] 4 3 +L63 + [BlockManager] 3 15 + [.] 15 16 + [Block] 16 21 + [.] 21 22 + [BlockElement] 22 34 + [<] 34 35 + [V] 35 36 + [>] 36 37 + [element] 38 45 + [=] 46 47 + [manager] 48 55 + [.] 55 56 + [element] 56 63 + [] 63 3 +L64 + [element] 3 10 + [.] 10 11 + [value] 11 16 + [=] 17 18 + [value] 19 24 + [] 24 3 +L66 + [super] 3 8 + [.] 8 9 + [add] 9 12 + [key] 13 16 + [,] 16 17 + [element] 18 25 + [] 25 2 +L67 + [}] 2 3 + [] 3 2 +L69 + [def] 2 5 + [delete] 6 12 + [(] 12 13 + [K] 13 14 + [key] 15 18 + [)] 18 19 + [{] 20 21 + [] 21 3 +L71 + [if] 3 5 + [(] 6 7 + [count] 7 12 + [>] 13 14 + [0] 15 16 + [&&] 17 19 + [!] 20 21 + [search] 21 27 + [(] 27 28 + [key] 28 31 + [)] 31 32 + [)] 32 33 + [{] 34 35 + [] 35 4 +L72 + [throw] 4 9 + [new] 10 13 + [IllegalArgumentException] 14 38 + [(] 38 39 + [] 39 41 + [key] 41 44 + [ is not in the tree] 44 64 + [)] 64 65 + [] 65 3 +L73 + [}] 3 4 + [] 4 3 +L75 + [super] 3 8 + [.] 8 9 + [delete] 9 15 + [key] 16 19 + [] 19 3 +L77 + [if] 3 5 + [(] 6 7 + [count] 7 12 + [==] 13 15 + [0] 16 17 + [)] 17 18 + [{] 19 20 + [] 20 4 +L78 + [getLeaf] 4 11 + [(] 11 12 + [this] 12 16 + [)] 16 17 + [] 17 3 +L79 + [}] 3 4 + [] 4 2 +L80 + [}] 2 3 + [] 3 1 +L81 + [}] 1 2 + [] 2 1 +EOF diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NPathComplexityRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NPathComplexityRule.java index 9260ae6b4f..656cce0fee 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NPathComplexityRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NPathComplexityRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ @@ -78,7 +78,9 @@ public class NPathComplexityRule extends AbstractJavaMetricsRule { int npath = (int) MetricsUtil.computeMetric(JavaOperationMetricKey.NPATH, node); if (npath >= reportLevel) { addViolation(data, node, new String[] {node instanceof ASTMethodDeclaration ? "method" : "constructor", - PrettyPrintingUtil.displaySignature(node), "" + npath, }); + PrettyPrintingUtil.displaySignature(node), + String.valueOf(npath), + String.valueOf(reportLevel)}); } return data; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharRule.java index 6f725ef954..9969cabe42 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharRule.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.lang.java.rule.performance; +import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression; +import net.sourceforge.pmd.lang.java.ast.ASTArgumentList; import net.sourceforge.pmd.lang.java.ast.ASTBlockStatement; import net.sourceforge.pmd.lang.java.ast.ASTLiteral; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; @@ -25,6 +27,10 @@ import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; */ public class AppendCharacterWithCharRule extends AbstractJavaRule { + public AppendCharacterWithCharRule() { + addRuleChainVisit(ASTLiteral.class); + } + @Override public Object visit(ASTLiteral node, Object data) { ASTBlockStatement bs = node.getFirstParentOfType(ASTBlockStatement.class); @@ -33,7 +39,7 @@ public class AppendCharacterWithCharRule extends AbstractJavaRule { } if (node.isSingleCharacterStringLiteral()) { - if (!InefficientStringBufferingRule.isInStringBufferOperation(node, 8, "append")) { + if (!InefficientStringBufferingRule.isInStringBufferOperationChain(node, "append")) { return data; } @@ -42,6 +48,14 @@ public class AppendCharacterWithCharRule extends AbstractJavaRule { if (primaryExpression != null && primaryExpression.getFirstChildOfType(ASTPrimarySuffix.class) != null) { return data; } + // ignore, if this literal is part of a different expression, e.g. "X" + something else + if (primaryExpression != null && !(primaryExpression.getNthParent(2) instanceof ASTArgumentList)) { + return data; + } + // ignore if this string literal is used as a constructor argument + if (primaryExpression != null && primaryExpression.getNthParent(4) instanceof ASTAllocationExpression) { + return data; + } addViolation(data, node); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java index 065df94419..bad078608e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java @@ -21,6 +21,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTDoStatement; import net.sourceforge.pmd.lang.java.ast.ASTFinallyStatement; import net.sourceforge.pmd.lang.java.ast.ASTForStatement; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; +import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTLiteral; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTName; @@ -78,6 +79,7 @@ public class ConsecutiveLiteralAppendsRule extends AbstractJavaRule { BLOCK_PARENTS.add(ASTMethodDeclaration.class); BLOCK_PARENTS.add(ASTCatchStatement.class); BLOCK_PARENTS.add(ASTFinallyStatement.class); + BLOCK_PARENTS.add(ASTLambdaExpression.class); } private static final PropertyDescriptor THRESHOLD_DESCRIPTOR @@ -119,7 +121,7 @@ public class ConsecutiveLiteralAppendsRule extends AbstractJavaRule { currentBlock = getFirstParentBlock(n); - if (InefficientStringBufferingRule.isInStringBufferOperation(n, 3, "append")) { + if (InefficientStringBufferingRule.isInStringBufferOperationChain(n, "append")) { // append method call detected ASTPrimaryExpression s = n.getFirstParentOfType(ASTPrimaryExpression.class); int numChildren = s.getNumChildren(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingRule.java index b6151fd576..3850e21101 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingRule.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.lang.java.rule.performance; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -13,10 +14,14 @@ import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression; import net.sourceforge.pmd.lang.java.ast.ASTArgumentList; import net.sourceforge.pmd.lang.java.ast.ASTBlockStatement; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType; +import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter; import net.sourceforge.pmd.lang.java.ast.ASTLiteral; import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTName; +import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; +import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix; +import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix; import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType; import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression; import net.sourceforge.pmd.lang.java.ast.ASTType; @@ -35,8 +40,17 @@ import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper; */ public class InefficientStringBufferingRule extends AbstractJavaRule { + public InefficientStringBufferingRule() { + addRuleChainVisit(ASTAdditiveExpression.class); + } + @Override public Object visit(ASTAdditiveExpression node, Object data) { + if (node.getParent() instanceof ASTConditionalExpression || node.getNthParent(2) instanceof ASTConditionalExpression) { + // ignore concats in ternary expressions + return data; + } + ASTBlockStatement bs = node.getFirstParentOfType(ASTBlockStatement.class); if (bs == null) { return data; @@ -58,17 +72,19 @@ public class InefficientStringBufferingRule extends AbstractJavaRule { } } - if (immediateLiterals > 1) { + boolean onlyStringLiterals = immediateLiterals == immediateStringLiterals + && immediateLiterals == node.getNumChildren(); + if (onlyStringLiterals) { return data; } - // if literal + public static final, return + // if literal + final, return List nameNodes = node.findDescendantsOfType(ASTName.class); for (ASTName name : nameNodes) { if (name.getNameDeclaration() != null && name.getNameDeclaration() instanceof VariableNameDeclaration) { VariableNameDeclaration vnd = (VariableNameDeclaration) name.getNameDeclaration(); AccessNode accessNodeParent = vnd.getAccessNodeParent(); - if (accessNodeParent.isFinal() && accessNodeParent.isStatic()) { + if (accessNodeParent.isFinal()) { return data; } } @@ -98,8 +114,10 @@ public class InefficientStringBufferingRule extends AbstractJavaRule { if (isAllocatedStringBuffer(node)) { addViolation(data, node); + } else if (isInStringBufferOperationChain(node, "append")) { + addViolation(data, node); } - } else if (isInStringBufferOperation(node, 6, "append")) { + } else if (isInStringBufferOperationChain(node, "append")) { addViolation(data, node); } return data; @@ -111,7 +129,7 @@ public class InefficientStringBufferingRule extends AbstractJavaRule { List types = type.findDescendantsOfType(ASTClassOrInterfaceType.class); if (!types.isEmpty()) { ASTClassOrInterfaceType typeDeclaration = types.get(0); - if (String.class == typeDeclaration.getType() || "String".equals(typeDeclaration.getImage())) { + if (TypeHelper.isA(typeDeclaration, String.class)) { return true; } } @@ -125,19 +143,39 @@ public class InefficientStringBufferingRule extends AbstractJavaRule { } private ASTType getTypeNode(ASTName name) { + ASTType result = null; if (name.getNameDeclaration() instanceof VariableNameDeclaration) { VariableNameDeclaration vnd = (VariableNameDeclaration) name.getNameDeclaration(); if (vnd.getAccessNodeParent() instanceof ASTLocalVariableDeclaration) { ASTLocalVariableDeclaration l = (ASTLocalVariableDeclaration) vnd.getAccessNodeParent(); - return l.getTypeNode(); + result = l.getTypeNode(); } else if (vnd.getAccessNodeParent() instanceof ASTFormalParameter) { ASTFormalParameter p = (ASTFormalParameter) vnd.getAccessNodeParent(); - return p.getTypeNode(); + result = p.getTypeNode(); } } - return null; + return result; } + static boolean isInStringBufferOperationChain(Node node, String methodName) { + ASTPrimaryExpression expr = node.getFirstParentOfType(ASTPrimaryExpression.class); + MethodCallChain methodCalls = MethodCallChain.wrap(expr); + while (expr != null && methodCalls == null) { + expr = expr.getFirstParentOfType(ASTPrimaryExpression.class); + methodCalls = MethodCallChain.wrap(expr); + } + + if (methodCalls != null && !methodCalls.isExactlyOfAnyType(StringBuffer.class, StringBuilder.class)) { + methodCalls = null; + } + + return methodCalls != null && methodCalls.getMethodNames().contains(methodName); + } + + /** + * @deprecated will be removed with PMD 7 + */ + @Deprecated protected static boolean isInStringBufferOperation(Node node, int length, String methodName) { if (!(node.getNthParent(length) instanceof ASTStatementExpression)) { return false; @@ -174,4 +212,70 @@ public class InefficientStringBufferingRule extends AbstractJavaRule { ASTClassOrInterfaceType an = ao.getFirstChildOfType(ASTClassOrInterfaceType.class); return an != null && TypeHelper.isEither(an, StringBuffer.class, StringBuilder.class); } + + private static class MethodCallChain { + private final ASTPrimaryExpression primary; + + private MethodCallChain(ASTPrimaryExpression primary) { + this.primary = primary; + } + + // Note: The impl here is technically not correct: The type of a method call + // chain is the result of the last method called, not the type of the + // first receiver object (== PrimaryPrefix). + boolean isExactlyOfAnyType(Class clazz, Class ... clazzes) { + ASTPrimaryPrefix typeNode = getTypeNode(); + + if (TypeHelper.isExactlyA(typeNode, clazz.getName())) { + return true; + } + if (clazzes != null) { + for (Class c : clazzes) { + if (TypeHelper.isExactlyA(typeNode, c.getName())) { + return true; + } + } + } + return false; + } + + ASTPrimaryPrefix getTypeNode() { + return primary.getFirstChildOfType(ASTPrimaryPrefix.class); + } + + List getMethodNames() { + List methodNames = new ArrayList<>(); + + ASTPrimaryPrefix prefix = getTypeNode(); + ASTName name = prefix.getFirstChildOfType(ASTName.class); + if (name != null) { + String firstMethod = name.getImage(); + int dot = firstMethod.lastIndexOf('.'); + if (dot != -1) { + firstMethod = firstMethod.substring(dot + 1); + } + methodNames.add(firstMethod); + } + + for (ASTPrimarySuffix suffix : primary.findChildrenOfType(ASTPrimarySuffix.class)) { + if (suffix.getImage() != null) { + methodNames.add(suffix.getImage()); + } + } + return methodNames; + } + + static MethodCallChain wrap(ASTPrimaryExpression primary) { + if (primary != null && isMethodCall(primary)) { + return new MethodCallChain(primary); + } + return null; + } + + private static boolean isMethodCall(ASTPrimaryExpression primary) { + return primary.getNumChildren() >= 2 + && primary.getChild(0) instanceof ASTPrimaryPrefix + && primary.getChild(1) instanceof ASTPrimarySuffix; + } + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index 53c1bc4098..e384b66d42 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -73,10 +73,10 @@ public class InsufficientStringBufferDeclarationRule extends AbstractJavaRule { for (NameOccurrence no : usage) { JavaNameOccurrence jno = (JavaNameOccurrence) no; Node n = jno.getLocation(); - if (!InefficientStringBufferingRule.isInStringBufferOperation(n, 3, "append")) { + if (!InefficientStringBufferingRule.isInStringBufferOperationChain(n, "append")) { if (!jno.isOnLeftHandSide() - && !InefficientStringBufferingRule.isInStringBufferOperation(n, 3, "setLength")) { + && !InefficientStringBufferingRule.isInStringBufferOperationChain(n, "setLength")) { continue; } if (constructorLength != -1 && anticipatedLength > constructorLength) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferForStringAppendsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferForStringAppendsRule.java index 88b5cf3b75..283a38d3b0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferForStringAppendsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferForStringAppendsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ @@ -10,27 +10,33 @@ import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTArgumentList; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentOperator; import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; +import net.sourceforge.pmd.lang.java.ast.ASTDoStatement; import net.sourceforge.pmd.lang.java.ast.ASTEqualityExpression; -import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTForStatement; +import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter; import net.sourceforge.pmd.lang.java.ast.ASTName; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; +import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper; import net.sourceforge.pmd.lang.symboltable.NameOccurrence; public class UseStringBufferForStringAppendsRule extends AbstractJavaRule { + public UseStringBufferForStringAppendsRule() { + addRuleChainVisit(ASTVariableDeclaratorId.class); + } + @Override public Object visit(ASTVariableDeclaratorId node, Object data) { - if (!TypeHelper.isA(node, String.class) || node.isArray()) { - return data; - } - Node parent = node.getParent().getParent(); - if (!(parent instanceof ASTLocalVariableDeclaration)) { + if (!TypeHelper.isA(node, String.class) || node.isArray() + || node.getNthParent(3) instanceof ASTForStatement) { return data; } + for (NameOccurrence no : node.getUsages()) { Node name = no.getLocation(); ASTStatementExpression statement = name.getFirstParentOfType(ASTStatementExpression.class); @@ -47,6 +53,12 @@ public class UseStringBufferForStringAppendsRule extends AbstractJavaRule { // used in condition continue; } + if ((node.getNthParent(2) instanceof ASTFieldDeclaration + || node.getParent() instanceof ASTFormalParameter) + && isNotWithinLoop(name)) { + // ignore if the field or formal parameter is *not* used within loops + continue; + } ASTConditionalExpression conditional = name.getFirstParentOfType(ASTConditionalExpression.class); if (conditional != null) { @@ -80,4 +92,10 @@ public class UseStringBufferForStringAppendsRule extends AbstractJavaRule { } return data; } + + private boolean isNotWithinLoop(Node name) { + return name.getFirstParentOfType(ASTForStatement.class) == null + && name.getFirstParentOfType(ASTWhileStatement.class) == null + && name.getFirstParentOfType(ASTDoStatement.class) == null; + } } diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 62a8c4c589..861b470741 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -402,7 +402,7 @@ while (true) { // preferred approach externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#defaultpackage"> Use explicit scoping instead of accidental usage of default package private level. -The rule allows methods and fields annotated with Guava's @VisibleForTesting. +The rule allows methods and fields annotated with Guava's @VisibleForTesting and JUnit 5's annotations. 3 @@ -413,7 +413,17 @@ The rule allows methods and fields annotated with Guava's @VisibleForTesting. //ClassOrInterfaceDeclaration[@Interface= false()] /ClassOrInterfaceBody /ClassOrInterfaceBodyDeclaration -[not(Annotation//Name[ends-with(@Image, 'VisibleForTesting')])] +[not(Annotation//Name[ + pmd-java:typeIs('org.junit.jupiter.api.Test') + or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest') + or pmd-java:typeIs('org.junit.jupiter.api.ParameterizedTest') + or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') + or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate') + or pmd-java:typeIs('org.junit.jupiter.api.BeforeAll') + or pmd-java:typeIs('org.junit.jupiter.api.AfterAll') + or pmd-java:typeIs('org.junit.jupiter.api.BeforeEach') + or pmd-java:typeIs('org.junit.jupiter.api.AfterEach') + or ends-with(@Image, 'VisibleForTesting')])] [ FieldDeclaration[@PackagePrivate= true()] or MethodDeclaration[@PackagePrivate= true()] @@ -1673,6 +1683,11 @@ Use the diamond operator to let the type be inferred automatically. With the Dia to avoid duplication of the type parameters. Instead, the compiler is now able to infer the parameter types for constructor calls, which makes the code also more readable. + +The diamond operator has been introduced with java 7. However, type inference has been improved further +with java8, rendering more type parameters unnecessary. This is only possible with java8 and the resulting +code won't compile with java7. If you use java7, make sure to enable `java7Compatibility` for this rule to avoid +false positives. 3 @@ -1685,15 +1700,17 @@ which makes the code also more readable. | //StatementExpression[AssignmentOperator and PrimaryExpression/PrimaryPrefix[not(Expression)]] ) -/Expression/PrimaryExpression[not(PrimarySuffix) and not(ancestor::ArgumentList)] +/(Expression | Expression[$java7Compatibility = false()]/ConditionalExpression | Expression[$java7Compatibility = false()]/ConditionalExpression/Expression) +/PrimaryExpression[not(PrimarySuffix) and not(ancestor::ArgumentList)] /PrimaryPrefix /AllocationExpression [@AnonymousClass=false()] - [ClassOrInterfaceType/TypeArguments[@Diamond=false() and not(TypeArgument//TypeArguments)]] + [ClassOrInterfaceType/TypeArguments[@Diamond=false() and not($java7Compatibility = true() and .//TypeArgument[@Wildcard=true()])]] [not(ArrayDimsAndInits)] ]]> + diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index fb581bb756..803156fdf4 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -3486,7 +3486,7 @@ Thread.currentThread().getContextClassLoader() instead. - //PrimarySuffix[@Image='getClassLoader'] + //PrimarySuffix[@Image='getClassLoader'] | //PrimaryPrefix[ends-with(Name/@Image, '.getClassLoader')] diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index d0285f9d90..370d3ab34f 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -114,6 +114,73 @@ public class Test { + + +Problem: A Calendar is a heavyweight object and expensive to create. + +Solution: Use `new Date()`, Java 8+ `java.time.LocalDateTime.now()` or `ZonedDateTime.now()`. + + 2 + + + + 2 and ../PrimarySuffix[last()-1][@Image = 'getTime' or @Image='getTimeInMillis']] +| +//MethodDeclaration[not(MethodDeclarator/FormalParameters//ClassOrInterfaceType[pmd-java:typeIs('java.util.Calendar')])] + /Block/BlockStatement//PrimaryExpression + /PrimaryPrefix/Name + [pmd-java:typeIs('java.util.Calendar')] + [every $var in @Image satisfies ( + (ends-with($var, '.getTime') or ends-with($var, '.getTimeInMillis')) + and + (: ignore if .set* or .add* or .clear is called on the variable :) + not(ancestor::Block/BlockStatement//Name[ + starts-with(@Image, concat((tokenize($var, '\.'), $var)[1], '.set')) + or + starts-with(@Image, concat((tokenize($var, '\.'), $var)[1], '.add')) + or + starts-with(@Image, concat((tokenize($var, '\.'), $var)[1], '.clear')) + ]) + )] +| +//ClassOrInterfaceType[pmd-java:typeIs('org.joda.time.DateTime') or pmd-java:typeIs('org.joda.time.LocalDateTime')][../Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Name[ends-with(@Image, 'Calendar.getInstance')]] + ]]> + + + + + + + --> + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/cpd/JavaTokenizerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/cpd/JavaTokenizerTest.java new file mode 100644 index 0000000000..60fed368f8 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/cpd/JavaTokenizerTest.java @@ -0,0 +1,116 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.cpd; + +import java.util.Properties; + +import org.junit.Test; + +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; + +public class JavaTokenizerTest extends CpdTextComparisonTest { + + public JavaTokenizerTest() { + super(".java"); + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + JavaTokenizer javaTokenizer = new JavaTokenizer(); + javaTokenizer.setProperties(properties); + return javaTokenizer; + } + + @Override + protected String getResourcePrefix() { + return "../lang/java/cpd/testdata"; + } + + @Test + public void testCommentsIgnored() { + doTest("simpleClassWithComments"); + } + + @Test + public void testDiscardedElements() { + doTest("discardedElements", "_ignore_annots", ignoreAnnotations()); + } + + @Test + public void testDiscardedElementsExceptAnnots() { + doTest("discardedElements", "_no_ignore_annots"); + } + + @Test + public void testIgnoreBetweenSpecialComments() { + doTest("specialComments"); + } + + @Test + public void testIgnoreBetweenSpecialAnnotation() { + doTest("ignoreSpecialAnnotations"); + } + + @Test + public void testIgnoreBetweenSpecialAnnotationAndIgnoreAnnotations() { + doTest("ignoreSpecialAnnotations", "_ignore_annots", ignoreAnnotations()); + } + + @Test + public void testIgnoreIdentifiersDontAffectConstructors() { + doTest("ignoreIdentsPreservesCtor", "", ignoreIdents()); + } + + @Test + public void testIgnoreIdentifiersHandlesEnums() { + doTest("ignoreIdentsPreservesEnum", "", ignoreIdents()); + } + + @Test + public void testIgnoreIdentifiersWithClassKeyword() { + doTest("ignoreIdentsPreservesClassLiteral", "", ignoreIdents()); + } + + @Test + public void testIgnoreLiterals() { + doTest("ignoreLiterals", "", ignoreLiterals()); + } + + @Test + public void testNoIgnoreLiterals() { + doTest("ignoreLiterals", "_noignore"); + } + + + private static Properties ignoreAnnotations() { + return properties(true, false, false); + } + + private static Properties ignoreIdents() { + return properties(false, false, true); + } + + private static Properties ignoreLiterals() { + return properties(false, true, false); + } + + + @Override + public Properties defaultProperties() { + return properties(false, false, false); + } + + private static Properties properties(boolean ignoreAnnotations, + boolean ignoreLiterals, + boolean ignoreIdents) { + Properties properties = new Properties(); + properties.setProperty(Tokenizer.IGNORE_ANNOTATIONS, Boolean.toString(ignoreAnnotations)); + properties.setProperty(Tokenizer.IGNORE_IDENTIFIERS, Boolean.toString(ignoreIdents)); + properties.setProperty(Tokenizer.IGNORE_LITERALS, Boolean.toString(ignoreLiterals)); + return properties; + } + + +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/cpd/JavaTokensTokenizerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/cpd/JavaTokensTokenizerTest.java deleted file mode 100644 index 255535afe2..0000000000 --- a/pmd-java/src/test/java/net/sourceforge/pmd/cpd/JavaTokensTokenizerTest.java +++ /dev/null @@ -1,270 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.util.List; - -import org.junit.Test; - -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.lang.java.ast.JavaTokenKinds; - -public class JavaTokensTokenizerTest { - - @Test - public void test1() throws IOException { - Tokenizer tokenizer = new JavaTokenizer(); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("public class Foo {}")); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); - assertEquals(6, tokens.size()); - assertEquals("public class Foo {}", sourceCode.getSlice(1, 1)); - } - - @Test - public void testCommentsIgnored() throws IOException { - Tokenizer tokenizer = new JavaTokenizer(); - SourceCode sourceCode = new SourceCode( - new SourceCode.StringCodeLoader("public class Foo { // class Bar */ \n }")); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); - assertEquals(6, tokens.size()); - } - - @Test - public void test2() throws IOException { - Tokenizer t = new JavaTokenizer(); - String data = "public class Foo {" + PMD.EOL + "public void bar() {}" + PMD.EOL + "public void buz() {}" - + PMD.EOL + "}"; - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader(data)); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - assertEquals("public class Foo {" + PMD.EOL + "public void bar() {}", sourceCode.getSlice(1, 2)); - } - - @Test - public void testDiscardSemicolons() throws IOException { - Tokenizer t = new JavaTokenizer(); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("public class Foo {private int x;}")); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - assertEquals(9, tokens.size()); - } - - @Test - public void testDiscardImports() throws IOException { - Tokenizer t = new JavaTokenizer(); - SourceCode sourceCode = new SourceCode( - new SourceCode.StringCodeLoader("import java.io.File;" + PMD.EOL + "public class Foo {}")); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - assertEquals(6, tokens.size()); - } - - @Test - public void testDiscardPkgStmts() throws IOException { - Tokenizer t = new JavaTokenizer(); - SourceCode sourceCode = new SourceCode( - new SourceCode.StringCodeLoader("package foo.bar.baz;" + PMD.EOL + "public class Foo {}")); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - assertEquals(6, tokens.size()); - } - - @Test - public void testDiscardSimpleOneLineAnnotation() throws IOException { - JavaTokenizer t = new JavaTokenizer(); - t.setIgnoreAnnotations(true); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader( - "package foo.bar.baz;" + PMD.EOL + "@MyAnnotation" + PMD.EOL + "public class Foo {}")); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - assertEquals(6, tokens.size()); - } - - @Test - public void testIgnoreComments() throws IOException { - JavaTokenizer t = new JavaTokenizer(); - t.setIgnoreAnnotations(false); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("package foo.bar.baz;" + PMD.EOL - + "/*****" + PMD.EOL + " * ugh" + PMD.EOL + " *****/" + PMD.EOL + "public class Foo {}")); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - assertEquals(6, tokens.size()); - } - - @Test - public void testDiscardOneLineAnnotationWithParams() throws IOException { - JavaTokenizer t = new JavaTokenizer(); - t.setIgnoreAnnotations(true); - - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader( - "package foo.bar.baz;" + PMD.EOL + "@ MyAnnotation (\"ugh\")" + PMD.EOL + "@NamedQueries({" + PMD.EOL - + "@NamedQuery(" + PMD.EOL + ")})" + PMD.EOL + "public class Foo {" + PMD.EOL + "}")); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - assertEquals(6, tokens.size()); - } - - @Test - public void testIgnoreBetweenSpecialComments() throws IOException { - JavaTokenizer t = new JavaTokenizer(); - t.setIgnoreAnnotations(false); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("package foo.bar.baz;" + PMD.EOL - + "// CPD-OFF" + PMD.EOL + "// CPD-OFF" + PMD.EOL - + "@ MyAnnotation (\"ugh\")" + PMD.EOL + "@NamedQueries({" + PMD.EOL + "@NamedQuery(" + PMD.EOL + ")})" - + PMD.EOL + "public class Foo {" + "// CPD-ON" + PMD.EOL - + "}" - )); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - assertEquals(2, tokens.size()); // 2 tokens: "}" + EOF - } - - @Test - public void testIgnoreBetweenSpecialCommentsMultiple() throws IOException { - JavaTokenizer t = new JavaTokenizer(); - t.setIgnoreAnnotations(false); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("package foo.bar.baz;" + PMD.EOL - + "// CPD-OFF" + PMD.EOL + "// another irrelevant comment" + PMD.EOL - + "@ MyAnnotation (\"ugh\")" + PMD.EOL + "@NamedQueries({" + PMD.EOL + "@NamedQuery(" + PMD.EOL + ")})" - + PMD.EOL + "public class Foo {" + "// CPD-ON" + PMD.EOL - + "}" - )); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - assertEquals(2, tokens.size()); // 2 tokens: "}" + EOF - } - - @Test - public void testIgnoreBetweenSpecialCommentsMultiline() throws IOException { - JavaTokenizer t = new JavaTokenizer(); - t.setIgnoreAnnotations(false); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("package foo.bar.baz;" + PMD.EOL - + "/* " + PMD.EOL + " * CPD-OFF" + PMD.EOL + "*/" + PMD.EOL - + "@ MyAnnotation (\"ugh\")" + PMD.EOL + "@NamedQueries({" + PMD.EOL + "@NamedQuery(" + PMD.EOL + ")})" - + PMD.EOL + "public class Foo {" + PMD.EOL - + "/* " + PMD.EOL + " * CPD-ON" + PMD.EOL + "*/" + PMD.EOL - + "}" - )); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - assertEquals(2, tokens.size()); // 2 tokens: "}" + EOF - } - - @Test - public void testIgnoreBetweenSpecialAnnotation() throws IOException { - JavaTokenizer t = new JavaTokenizer(); - t.setIgnoreAnnotations(false); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("package foo.bar.baz;" + PMD.EOL - + "@SuppressWarnings({\"woof\",\"CPD-START\"})" + PMD.EOL + "@SuppressWarnings(\"CPD-START\")" + PMD.EOL - + "@ MyAnnotation (\"ugh\")" + PMD.EOL + "@NamedQueries({" + PMD.EOL + "@NamedQuery(" + PMD.EOL + ")})" - + PMD.EOL + "public class Foo {}" + "@SuppressWarnings({\"ugh\",\"CPD-END\"})" + PMD.EOL - - )); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - assertEquals(10, tokens.size()); - } - - @Test - public void testIgnoreBetweenSpecialAnnotationAndIgnoreAnnotations() throws IOException { - JavaTokenizer t = new JavaTokenizer(); - t.setIgnoreAnnotations(true); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("package foo.bar.baz;" + PMD.EOL - + "@SuppressWarnings({\"woof\",\"CPD-START\"})" + PMD.EOL + "@SuppressWarnings(\"CPD-START\")" + PMD.EOL - + "@ MyAnnotation (\"ugh\")" + PMD.EOL + "@NamedQueries({" + PMD.EOL + "@NamedQuery(" + PMD.EOL + ")})" - + PMD.EOL + "public class Foo {}" + PMD.EOL + "@SuppressWarnings({\"ugh\",\"CPD-END\"})" + PMD.EOL - - )); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - assertEquals(1, tokens.size()); - } - - @Test - public void testIgnoreIdentifiersDontAffectConstructors() throws IOException { - JavaTokenizer t = new JavaTokenizer(); - t.setIgnoreAnnotations(false); - t.setIgnoreIdentifiers(true); - - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("package foo.bar.baz;" + PMD.EOL - + "public class Foo extends Bar {" + PMD.EOL + "private Foo notAConstructor;" + PMD.EOL - + "public Foo(int i) { super(i); }" + PMD.EOL + "private Foo(int i, String s) { super(i, s); }" - + PMD.EOL + "/* default */ Foo(int i, String s, Object o) { super(i, s, o); }" + PMD.EOL - + "private static class Inner {" + PMD.EOL + "Inner() { System.out.println(\"Guess who?\"); }" + PMD.EOL - + "}" + PMD.EOL + "}" + PMD.EOL - - )); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - List tokenList = tokens.getTokens(); - - // Member variable of type Foo - assertEquals(String.valueOf(JavaTokenKinds.IDENTIFIER), tokenList.get(7).toString()); - // Public constructor - assertEquals("Foo", tokenList.get(10).toString()); - // Private constructor - assertEquals("Foo", tokenList.get(22).toString()); - // Package-private constructor - assertEquals("Foo", tokenList.get(38).toString()); - // Inner class constructor - assertEquals("Inner", tokenList.get(64).toString()); - } - - @Test - public void testIgnoreIdentifiersHandlesEnums() throws IOException { - JavaTokenizer t = new JavaTokenizer(); - t.setIgnoreAnnotations(false); - t.setIgnoreIdentifiers(true); - - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader( - "package foo.bar.baz;" + PMD.EOL + "public enum Foo {" + PMD.EOL + "BAR(1)," + PMD.EOL + "BAZ(2);" - + PMD.EOL + "Foo(int val) {" + PMD.EOL + "}" + PMD.EOL + "}" + PMD.EOL - - )); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - List tokenList = tokens.getTokens(); - - // Enum member - assertEquals(String.valueOf(JavaTokenKinds.IDENTIFIER), tokenList.get(4).toString()); - assertEquals(String.valueOf(JavaTokenKinds.IDENTIFIER), tokenList.get(9).toString()); - // Enum constructor - assertEquals("Foo", tokenList.get(13).toString()); - } - - @Test - public void testIgnoreIdentifiersWithClassKeyword() throws IOException { - JavaTokenizer t = new JavaTokenizer(); - t.setIgnoreAnnotations(false); - t.setIgnoreIdentifiers(true); - - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader( - "package foo.bar.baz;" + PMD.EOL + "public class Foo {" + PMD.EOL + "Foo() {" + PMD.EOL - + "}" + PMD.EOL + "public void bar() {" + PMD.EOL + "Bar.baz(Foo.class, () -> {});" - + PMD.EOL + "}" + PMD.EOL + "}" + PMD.EOL - )); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - List tokenList = tokens.getTokens(); - - // Class constructor - assertEquals("Foo", tokenList.get(4).toString()); - assertEquals(String.valueOf(JavaTokenKinds.IDENTIFIER), tokenList.get(11).toString()); - } -} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/cpd/MatchAlgorithmTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/cpd/MatchAlgorithmTest.java index 6c2e4937bb..a4f74ba363 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/cpd/MatchAlgorithmTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/cpd/MatchAlgorithmTest.java @@ -14,8 +14,6 @@ import java.util.Map; import org.junit.Test; -import net.sourceforge.pmd.PMD; - public class MatchAlgorithmTest { private static final String LINE_1 = "public class Foo { "; @@ -28,8 +26,8 @@ public class MatchAlgorithmTest { private static final String LINE_8 = "}"; private static String getSampleCode() { - return LINE_1 + PMD.EOL + LINE_2 + PMD.EOL + LINE_3 + PMD.EOL + LINE_4 + PMD.EOL + LINE_5 + PMD.EOL + LINE_6 - + PMD.EOL + LINE_7 + PMD.EOL + LINE_8; + return LINE_1 + "\n" + LINE_2 + "\n" + LINE_3 + "\n" + LINE_4 + "\n" + LINE_5 + "\n" + LINE_6 + + "\n" + LINE_7 + "\n" + LINE_8; } @Test diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidCalendarDateCreationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidCalendarDateCreationTest.java new file mode 100644 index 0000000000..5acaecbf0d --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidCalendarDateCreationTest.java @@ -0,0 +1,10 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.performance; + +import net.sourceforge.pmd.testframework.PmdRuleTst; + +public class AvoidCalendarDateCreationTest extends PmdRuleTst { +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferForStringAppendsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferForStringAppendsTest.java index a77785ec25..b1ae669420 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferForStringAppendsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferForStringAppendsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/discardedElements.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/discardedElements.java new file mode 100644 index 0000000000..54858f8423 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/discardedElements.java @@ -0,0 +1,36 @@ +/* + * This comment is ignored + */ +package a.b.c; // ignored + +// imports are ignored +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.List; +import java.util.Properties; + + + +@Foo // ignored +public class Foo { // class Bar + // comments are ignored + + + // semicolons are ignored + int x; + { + x++; + foo(); + } + + // annotations are ignored + @AnnotationWithParams("ugh") + @AnnotationWithParams({@Nested(1) , + @Nested(2) , + @Nested + }) + public void foo() { + + } +} \ No newline at end of file diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/discardedElements_ignore_annots.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/discardedElements_ignore_annots.txt new file mode 100644 index 0000000000..d0f28d1977 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/discardedElements_ignore_annots.txt @@ -0,0 +1,32 @@ + [Image] or [Truncated image[ Bcol Ecol +L16 + [public] 1 7 + [class] 8 13 + [Foo] 14 17 + [{] 18 19 +L21 + [int] 5 8 + [x] 9 10 +L22 + [{] 5 6 +L23 + [x] 9 10 + [++] 10 12 +L24 + [foo] 9 12 + [(] 12 13 + [)] 13 14 +L25 + [}] 5 6 +L33 + [public] 5 11 + [void] 12 16 + [foo] 17 20 + [(] 20 21 + [)] 21 22 + [{] 23 24 +L35 + [}] 5 6 +L36 + [}] 1 2 +EOF diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/discardedElements_no_ignore_annots.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/discardedElements_no_ignore_annots.txt new file mode 100644 index 0000000000..17a1259e12 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/discardedElements_no_ignore_annots.txt @@ -0,0 +1,65 @@ + [Image] or [Truncated image[ Bcol Ecol +L15 + [@] 1 2 + [Foo] 2 5 +L16 + [public] 1 7 + [class] 8 13 + [Foo] 14 17 + [{] 18 19 +L21 + [int] 5 8 + [x] 9 10 +L22 + [{] 5 6 +L23 + [x] 9 10 + [++] 10 12 +L24 + [foo] 9 12 + [(] 12 13 + [)] 13 14 +L25 + [}] 5 6 +L28 + [@] 5 6 + [AnnotationWithParams] 6 26 + [(] 26 27 + ["ugh"] 27 32 + [)] 32 33 +L29 + [@] 5 6 + [AnnotationWithParams] 6 26 + [(] 26 27 + [{] 27 28 + [@] 28 29 + [Nested] 29 35 + [(] 35 36 + [1] 36 37 + [)] 37 38 + [,] 39 40 +L30 + [@] 28 29 + [Nested] 29 35 + [(] 35 36 + [2] 36 37 + [)] 37 38 + [,] 39 40 +L31 + [@] 28 29 + [Nested] 29 35 +L32 + [}] 14 15 + [)] 15 16 +L33 + [public] 5 11 + [void] 12 16 + [foo] 17 20 + [(] 20 21 + [)] 21 22 + [{] 23 24 +L35 + [}] 5 6 +L36 + [}] 1 2 +EOF diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesClassLiteral.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesClassLiteral.java new file mode 100644 index 0000000000..7e2864cc4c --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesClassLiteral.java @@ -0,0 +1,9 @@ +package foo.bar.baz; +public class Foo { + Foo() { + } + public void bar() { + Bar.baz(Foo.class, () -> {}); + + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesClassLiteral.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesClassLiteral.txt new file mode 100644 index 0000000000..98813a84f4 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesClassLiteral.txt @@ -0,0 +1,40 @@ + [Image] or [Truncated image[ Bcol Ecol +L2 + [public] 1 7 + [class] 8 13 + [73] 14 17 + [{] 18 19 +L3 + [Foo] 5 8 + [(] 8 9 + [)] 9 10 + [{] 11 12 +L4 + [}] 5 6 +L5 + [public] 5 11 + [void] 12 16 + [73] 17 20 + [(] 20 21 + [)] 21 22 + [{] 23 24 +L6 + [73] 9 12 + [.] 12 13 + [73] 13 16 + [(] 16 17 + [73] 17 20 + [.] 20 21 + [class] 21 26 + [Foo] 26 27 + [(] 28 29 + [)] 29 30 + [->] 31 33 + [{] 34 35 + [}] 35 36 + [)] 36 37 +L8 + [}] 5 6 +L9 + [}] 1 2 +EOF diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesCtor.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesCtor.java new file mode 100644 index 0000000000..c722bf236a --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesCtor.java @@ -0,0 +1,17 @@ +package foo.bar.baz; +public class Foo extends Bar { + + private Foo notAConstructor; + + public Foo(int i) { super(i); } + + private Foo(int i, String s) { super(i, s); } + + /* default */ Foo(int i, String s, Object o) { super(i, s, o); } + + private static class Inner { + + Inner() { System.out.println("Guess who?"); } + + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesCtor.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesCtor.txt new file mode 100644 index 0000000000..87d6f860b7 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesCtor.txt @@ -0,0 +1,90 @@ + [Image] or [Truncated image[ Bcol Ecol +L2 + [public] 1 7 + [class] 8 13 + [73] 14 17 + [extends] 18 25 + [73] 26 29 + [{] 30 31 +L4 + [private] 5 12 + [73] 13 16 + [73] 17 32 +L6 + [public] 5 11 + [Foo] 12 15 + [(] 15 16 + [int] 16 19 + [73] 20 21 + [)] 21 22 + [{] 23 24 + [super] 25 30 + [(] 30 31 + [73] 31 32 + [)] 32 33 + [}] 35 36 +L8 + [private] 5 12 + [Foo] 13 16 + [(] 16 17 + [int] 17 20 + [73] 21 22 + [,] 22 23 + [73] 24 30 + [73] 31 32 + [)] 32 33 + [{] 34 35 + [super] 36 41 + [(] 41 42 + [73] 42 43 + [,] 43 44 + [73] 45 46 + [)] 46 47 + [}] 49 50 +L10 + [Foo] 19 22 + [(] 22 23 + [int] 23 26 + [73] 27 28 + [,] 28 29 + [73] 30 36 + [73] 37 38 + [,] 38 39 + [73] 40 46 + [73] 47 48 + [)] 48 49 + [{] 50 51 + [super] 52 57 + [(] 57 58 + [73] 58 59 + [,] 59 60 + [73] 61 62 + [,] 62 63 + [73] 64 65 + [)] 65 66 + [}] 68 69 +L12 + [private] 5 12 + [static] 13 19 + [class] 20 25 + [73] 26 31 + [{] 32 33 +L14 + [Inner] 9 14 + [(] 14 15 + [)] 15 16 + [{] 17 18 + [73] 19 25 + [.] 25 26 + [73] 26 29 + [.] 29 30 + [73] 30 37 + [(] 37 38 + ["Guess who?"] 38 50 + [)] 50 51 + [}] 53 54 +L16 + [}] 5 6 +L17 + [}] 1 2 +EOF diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesEnum.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesEnum.java new file mode 100644 index 0000000000..0d5e9fa32a --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesEnum.java @@ -0,0 +1,8 @@ +package foo.bar.baz; +public enum Foo { + BAR(1), + BAZ(2); + + Foo(int val) { + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesEnum.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesEnum.txt new file mode 100644 index 0000000000..de757f9e7e --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreIdentsPreservesEnum.txt @@ -0,0 +1,29 @@ + [Image] or [Truncated image[ Bcol Ecol +L2 + [public] 1 7 + [73] 8 12 + [73] 13 16 + [{] 17 18 +L3 + [73] 5 8 + [(] 8 9 + [1] 9 10 + [)] 10 11 + [,] 11 12 +L4 + [73] 5 8 + [(] 8 9 + [2] 9 10 + [)] 10 11 +L6 + [Foo] 5 8 + [(] 8 9 + [int] 9 12 + [73] 13 16 + [)] 16 17 + [{] 18 19 +L7 + [}] 5 6 +L8 + [}] 1 2 +EOF diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreLiterals.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreLiterals.java new file mode 100644 index 0000000000..497591db2c --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreLiterals.java @@ -0,0 +1,9 @@ +public class Foo { + public void bar() { + System.out.println("hello"); + System.out.println("hello"); + int i = 5 + System.out.print("hello"); + + } +} \ No newline at end of file diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreLiterals.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreLiterals.txt new file mode 100644 index 0000000000..578cb5162e --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreLiterals.txt @@ -0,0 +1,50 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [public] 1 7 + [class] 8 13 + [Foo] 14 17 + [{] 18 19 +L2 + [public] 5 11 + [void] 12 16 + [bar] 17 20 + [(] 20 21 + [)] 21 22 + [{] 23 24 +L3 + [System] 9 15 + [.] 15 16 + [out] 16 19 + [.] 19 20 + [println] 20 27 + [(] 27 28 + [71] 28 35 + [)] 35 36 +L4 + [System] 9 15 + [.] 15 16 + [out] 16 19 + [.] 19 20 + [println] 20 27 + [(] 27 28 + [71] 28 35 + [)] 35 36 +L5 + [int] 9 12 + [i] 13 14 + [=] 15 16 + [5] 17 18 +L6 + [System] 9 15 + [.] 15 16 + [out] 16 19 + [.] 19 20 + [print] 20 25 + [(] 25 26 + [71] 26 33 + [)] 33 34 +L8 + [}] 5 6 +L9 + [}] 1 2 +EOF diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreLiterals_noignore.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreLiterals_noignore.txt new file mode 100644 index 0000000000..db7ba4182b --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreLiterals_noignore.txt @@ -0,0 +1,50 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [public] 1 7 + [class] 8 13 + [Foo] 14 17 + [{] 18 19 +L2 + [public] 5 11 + [void] 12 16 + [bar] 17 20 + [(] 20 21 + [)] 21 22 + [{] 23 24 +L3 + [System] 9 15 + [.] 15 16 + [out] 16 19 + [.] 19 20 + [println] 20 27 + [(] 27 28 + ["hello"] 28 35 + [)] 35 36 +L4 + [System] 9 15 + [.] 15 16 + [out] 16 19 + [.] 19 20 + [println] 20 27 + [(] 27 28 + ["hello"] 28 35 + [)] 35 36 +L5 + [int] 9 12 + [i] 13 14 + [=] 15 16 + [5] 17 18 +L6 + [System] 9 15 + [.] 15 16 + [out] 16 19 + [.] 19 20 + [print] 20 25 + [(] 25 26 + ["hello"] 26 33 + [)] 33 34 +L8 + [}] 5 6 +L9 + [}] 1 2 +EOF diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreSpecialAnnotations.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreSpecialAnnotations.java new file mode 100644 index 0000000000..b581a387f0 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreSpecialAnnotations.java @@ -0,0 +1,13 @@ +package foo.bar.baz; +@SuppressWarnings({"woof","CPD-START"}) + +@SuppressWarnings("CPD-START") + +@ MyAnnotation ("ugh") +@NamedQueries({ + @NamedQuery( + )}) + +public class Foo {} +@SuppressWarnings({"ugh","CPD-END"}) + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreSpecialAnnotations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreSpecialAnnotations.txt new file mode 100644 index 0000000000..938bf8fb9a --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreSpecialAnnotations.txt @@ -0,0 +1,13 @@ + [Image] or [Truncated image[ Bcol Ecol +L2 + [@] 1 2 + [SuppressWarnings] 2 18 + [(] 18 19 + [{] 19 20 + ["woof"] 20 26 + [,] 26 27 +L12 + ["CPD-END"] 26 35 + [}] 35 36 + [)] 36 37 +EOF diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreSpecialAnnotations_ignore_annots.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreSpecialAnnotations_ignore_annots.txt new file mode 100644 index 0000000000..49ab402048 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/ignoreSpecialAnnotations_ignore_annots.txt @@ -0,0 +1,2 @@ + [Image] or [Truncated image[ Bcol Ecol +EOF diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/simpleClassWithComments.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/simpleClassWithComments.java new file mode 100644 index 0000000000..cc888f8b17 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/simpleClassWithComments.java @@ -0,0 +1,7 @@ +/* + * This comment is ignored too + */ + +public class Foo { // class Bar + // comments are ignored +} \ No newline at end of file diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/simpleClassWithComments.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/simpleClassWithComments.txt new file mode 100644 index 0000000000..552c9950a0 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/simpleClassWithComments.txt @@ -0,0 +1,9 @@ + [Image] or [Truncated image[ Bcol Ecol +L5 + [public] 1 7 + [class] 8 13 + [Foo] 14 17 + [{] 18 19 +L7 + [}] 1 2 +EOF diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/specialComments.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/specialComments.java new file mode 100644 index 0000000000..7b985c8bde --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/specialComments.java @@ -0,0 +1,25 @@ +package foo.bar.baz; +// CPD-OFF +// CPD-OFF +// another irrelevant comment +@ MyAnnotation ("ugh") +@NamedQueries({ + @NamedQuery( + )}) + +public class Foo {// CPD-ON + + // special multiline comments + class Foo /* CPD-OFF */{ } /* CPD-ON */ + class Foo /* CPD-OFF */{ + + {something();} + + } /* CPD-ON */ +} + + + + + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/specialComments.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/specialComments.txt new file mode 100644 index 0000000000..0acb7d24b2 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/specialComments.txt @@ -0,0 +1,10 @@ + [Image] or [Truncated image[ Bcol Ecol +L13 + [class] 5 10 + [Foo] 11 14 +L14 + [class] 5 10 + [Foo] 11 14 +L19 + [}] 1 2 +EOF diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/DefaultPackage.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/DefaultPackage.xml index b4ba144101..7a9b4a83f9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/DefaultPackage.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/DefaultPackage.xml @@ -61,6 +61,114 @@ public class Foo { + + + + #2573 DefaultPackage triggers on field annotated with JUnit 5 @Test + 0 + + + + + #2573 DefaultPackage triggers on field annotated with JUnit 5 @RepeatedTest + 0 + + + + + #2573 DefaultPackage triggers on field annotated with JUnit 5 @ParameterizedTest + 0 + + + + + #2573 DefaultPackage triggers on field annotated with JUnit 5 @TestFactory + 0 + + + + + #2573 DefaultPackage triggers on field annotated with JUnit 5 @TestTemplate + 0 + + + + + #2573 DefaultPackage triggers on field annotated with JUnit 5 @BeforeAll + 0 + + + + + #2573 DefaultPackage triggers on field annotated with JUnit 5 @AfterAll + 0 + + + + + #2573 DefaultPackage triggers on field annotated with JUnit 5 @BeforeEach + 0 + + + + + #2573 DefaultPackage triggers on field annotated with JUnit 5 @AfterEach + 0 + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml index 5c1b3c67d9..000a53c4b8 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml @@ -6,8 +6,8 @@ Use Diamond - 2 - 6,11 + 3 + 6,9,10 strings = new ArrayList(); List strings2 = new ArrayList<>(); List> strings3 = new ArrayList<>(); - // this is a known false negative, see at the bottom List> strings4 = new ArrayList>>(); this.field = new ArrayList(); } @@ -139,35 +138,43 @@ class Foo { - - - (J7) Version sensitive tests - 1 - 6 + + (J7) Version sensitive tests - avoid possible false positives on Java7 + true + 0 > typeReference; public void foo() { // this should be positive in Java 8, negative in Java 7 + // in java 7: no violation, in java 8 violation + typeReference = new WeakReference>(String.class); // this is because in java 7, new WeakReference<>(String.class) types as WeakReference> // which is incompatible with WeakReference>, whereas Java 8's type inference is better. - typeReference = new WeakReference>(String.class); + + // the following is the same: + // in java 7: no violation, in java 8 violation Class type = null; - typeReference = new WeakReference>(type); // this should be positive on all versions + typeReference = new WeakReference>(type); } } ]]> - - (J8) Version sensitive tests + + (J8) Version sensitive tests - known false negatives on Java8+ 2 - 4,6 + 6,8 > typeReference; public void foo() { @@ -175,6 +182,51 @@ public class Foo { Class type = null; typeReference = new WeakReference>(type); // pos } +} + ]]> + + + + False negative for nested type parameters (#2545) + true + 3 + 7,8,17 + > l = new ArrayList>(); // FN + WeakReference> typeReference = new WeakReference>(String.class); // FN + WeakReference> typeReference2 = new WeakReference>(String.class); // FP + + public void test() { + final List l2; + l2 = true ? new ArrayList() : new ArrayList(); // FN twice for java8+, but for java7, this is ok! + } + + static { + l = new ArrayList>(); // FN + } +} + ]]> + + + + (J8+) False negative for Java8+ and ternary operator (#2545) + 2 + 7,7 + l2; + l2 = true ? new ArrayList() : new ArrayList(); // FN twice for java8+, but for java7, this is ok! + } } ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/NPathComplexity.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/NPathComplexity.xml index d49adcc291..60dd6d958f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/NPathComplexity.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/NPathComplexity.xml @@ -55,7 +55,7 @@ public class Foo { Full example 1 - The method 'bar()' has an NPath complexity of 2016 + The method 'bar()' has an NPath complexity of 2016, current threshold is 200 @@ -65,7 +65,7 @@ public class Foo { 0 1 - The method 'bar()' has an NPath complexity of 200 + The method 'bar()' has an NPath complexity of 200, current threshold is 0 2 1 - The method 'bar()' has an NPath complexity of 4 + The method 'bar()' has an NPath complexity of 4, current threshold is 2 4 2 - The method 'x(boolean, boolean)' has an NPath complexity of 4 - The method 'y(boolean, boolean)' has an NPath complexity of 4 + The method 'x(boolean, boolean)' has an NPath complexity of 4, current threshold is 4 + The method 'y(boolean, boolean)' has an NPath complexity of 4, current threshold is 4 @@ -174,7 +174,7 @@ class Bar { 6 1 - The constructor 'Foo()' has an NPath complexity of 7 + The constructor 'Foo()' has an NPath complexity of 7, current threshold is 6 + + + + False negatives (#2544) + 2 + 4,7 + c = o.getClass(); + ClassLoader cl2 = c.getClassLoader(); + } } ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AppendCharacterWithChar.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AppendCharacterWithChar.xml index 869fde46d4..a6c3759c71 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AppendCharacterWithChar.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AppendCharacterWithChar.xml @@ -190,6 +190,34 @@ public class Foo { public void bar(StringBuffer sb, int length) { sb.append("a".repeat(length)); } +} + ]]> + + + + append single character string in constructor chain + 2 + 3,4 + + + + + false positive with string as constructor arg in StringBuilder method chain + 0 + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AvoidCalendarDateCreation.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AvoidCalendarDateCreation.xml new file mode 100644 index 0000000000..ce34feba1f --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AvoidCalendarDateCreation.xml @@ -0,0 +1,164 @@ + + + + + violation: [Gregorian]Calendar.getInstance().getTime() + 4 + 7,8,9,12 + + + + + violation: joda-time: new DateTime([Gregorian]Calendar.getInstance()) + 2 + 7,8 + + + + + violation: Calendar.getInstance().getTimeInMillis() + 2 + 5,6 + + + + + violation: cal.getTimeInMillis() + 2 + 7,8 + + + + + no violation + 0 + + + + + false positive when Calendar is not created here + 0 + + + + + false positive if Calendar is modified via set + 0 + + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveLiteralAppends.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveLiteralAppends.xml index 6a7e4ceb80..abe85b048e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveLiteralAppends.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveLiteralAppends.xml @@ -1446,6 +1446,24 @@ public final class Test { r2.run(); return sb.toString(); } +} + ]]> + + + + StringBuilder chains + 2 + 3,6 + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientStringBuffering.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientStringBuffering.xml index 625f0f9712..0c31fbb10a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientStringBuffering.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientStringBuffering.xml @@ -340,6 +340,117 @@ public class Foo { String str2 = "b"; StringBuffer sb = new StringBuffer(str1.length() + str2.length()); } +} + ]]> + + + + Violation: Avoid concat in append method invocations + 5 + 9,13,18,27,33 + + + + + No violation: Avoid concat in append method invocations + 0 + + + + + false positive with ternary + 0 + = 0 ? this.someInt + "ms" : "n/a"); + sb.append('}'); + return sb.toString(); + } } ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferForStringAppends.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferForStringAppends.xml index b6244aee41..e430e4a433 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferForStringAppends.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferForStringAppends.xml @@ -7,6 +7,7 @@ failure case 1 + 6 compound append, should only report 1 failure 1 + 5 failure case 1 + 5 static failure case 1 + 5 reference self 1 + 5 + + + + violation: concat to String in for/while loop + 5 + 9,13,20,22,29 + values = Arrays.asList("tic", "tac", "toe"); + for (String val : values) { + logStatement = logStatement + val + ", "; // bad + } + Iterator iter = values.iterator(); + while (iter.hasNext()) { + logStatement = logStatement + iter.next() + ", "; // bad + } + } + public void bad2() { + String log = ""; + List values = Arrays.asList("tic", "tac", "toe"); + for (String val1 : values) { + log += val1; // bad + } + for (String val2 : values) log += val2; // bad + } + + public void bad3() { + String logStatement = ""; + List values = Arrays.asList("tic", "tac", "toe"); + for (String val : values) { + logStatement += val + ", "; // bad + } + } +} + ]]> + + + + no violation: add numbers in loop + 0 + values = Arrays.asList(new Integer[]{1, 2, 3}); + for (int val : values) { + log = log + val; + } + Iterator iter = values.iterator(); + while (iter.hasNext()) { + log = log + iter.next(); + } + } + + public void good2() { + int log = 0; + List values = Arrays.asList(new Integer[]{1, 2, 3}); + for (int val : values) { + log += val; + } + } + + public void good3() { + double totalParticipationPercentage = 0; + for (Object portfolioByCategory : new ArrayList()) { + for (Object portfolioInstrumentDetails : new ArrayList()) { + totalParticipationPercentage = totalParticipationPercentage + + (double) portfolioInstrumentDetails.hashCode(); + } + } + } + + public int good4(String keyName) { + int index = 0; + HashMap columnsTypes = new HashMap(); + for (String variableName : columnsTypes.keySet()) { + if (keyName.equals(variableName)) { + return index; + } + index += 1; + } + } + + public long good5(String keyName) { + long index = 0; + HashMap columnsTypes = new HashMap(); + for (String variableName : columnsTypes.keySet()) { + if (keyName.equals(variableName)) { + return index; + } + index += 1; + } + } +} + ]]> + + + + no violation: concat in append in loops is caught by other rule InefficientStringBuffering + 0 + values = Arrays.asList("tic", "tac", "toe"); + for (String val : values) { + logStatement.append(val + ", "); // bad, but that's InefficientStringBuffering + } + } +} + ]]> + + + + no violation: proper append in loop + 0 + values = Arrays.asList("tic", "tac", "toe"); + for (String val1 : values) { + logStatement.append(val1); + } + for (String val2 : values) logStatement.append(val2); + } +} + ]]> + + + + violation: various concats in loop + 5 + 9,11,13,14,15 + persons = new ArrayList(); + for (final String person : persons) { + if (person != null) { + description += "0" + ":"; //bad + } else { + description += ":"; //bad + } + description += person.toString() + ":"; // bad + description += ";"; // bad + description += person.toString(); // bad + } + return description; + } +} + ]]> + + + + no violation: various concats in loop which do not aggregate + 0 + functionNames = Arrays.asList(new String[]{"a", "b"}); + for (final String functionName : functionNames) { + if (true) { + functionNames.add(ROLE_PREFIX + functionName); + } + } + } + + public static void good2(String propertyFile) { + String[] properyFilenames = propertyFile.split(","); + for (String propertyFilename : properyFilenames) { + if (propertyFilename != null) { + try { + //getResourceAsStream(propertyFilename); + } catch (Exception e) { + logError("Failed to load propertyFile with name " + propertyFilename + ": ", e); + } + } + } + } + + public static void good3() { + List linkNames = new ArrayList(); + Map messages = new HashMap(); + for (String linkName : linkNames) { + messages.put(linkName + ".url", "url"); + messages.put(linkName + ".description", "desc"); + } + } + + public static void good4() { + List linkNames = new ArrayList(); + Map messages = new HashMap(); + String URL = "", DESCRIPTION = ""; + for (String linkName : linkNames) { + if (!messages.containsKey(linkName + URL)) { + messages.put(linkName + URL, "some"); + } + if (!messages.containsKey(linkName + DESCRIPTION)) { + messages.put(linkName + DESCRIPTION, "some"); + } + } + } + + private static void logError(String text, Exception e) { + } +} + ]]> + + + + violation: concat to String in do-loop + 1 + 10 + values = Arrays.asList("tic", "tac", "toe"); + int i = 0; + do { + logStatement = logStatement + values.get(i++) + ", "; // bad + } while (i < values.length()); + } +} + ]]> + + + + violation: concat to String field in loop + 1 + 10 + values = Arrays.asList("tic", "tac", "toe"); + for (String val : values) { + logStatement = logStatement + val + ", "; // bad + } + } + + public void good() { + List values = Arrays.asList("tic", "tac", "toe"); + StringBuilder sb = new StringBuilder(logStatement); + for (String val : values) { + sb.append(val).append(", "); + } + logStatement = sb.toString(); + } +} + ]]> + + + + false positive with not accumulating String + 0 + fileExtensions = new ArrayList(); + public void good(List fileExtensions) { + for (String fileExtension : fileExtensions) { + if (fileExtension.charAt(0) != '.') { + fileExtension = "." + fileExtension; + } + this.fileExtensions.add(fileExtension); + } + } +} + ]]> + + + + false positives with field assignment and shadowing parameters + 0 + diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/cpd/EcmascriptTokenizerTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/cpd/EcmascriptTokenizerTest.java index d23253be15..50df3786b4 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/cpd/EcmascriptTokenizerTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/cpd/EcmascriptTokenizerTest.java @@ -4,158 +4,63 @@ package net.sourceforge.pmd.cpd; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import java.io.IOException; -import java.util.List; +import java.util.Properties; import org.junit.Test; -import net.sourceforge.pmd.PMD; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -public class EcmascriptTokenizerTest { +public class EcmascriptTokenizerTest extends CpdTextComparisonTest { - @Test - public void test1() throws IOException { - Tokenizer tokenizer = new EcmascriptTokenizer(); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader(getCode1())); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); - assertEquals(40, tokens.size()); + public EcmascriptTokenizerTest() { + super(".js"); + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new EcmascriptTokenizer(); + } + + @Override + protected String getResourcePrefix() { + return "../lang/ecmascript/cpd/testdata"; } @Test - public void test2() throws IOException { - Tokenizer t = new EcmascriptTokenizer(); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader(getCode2())); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - assertEquals(45, tokens.size()); + public void testSimple() { + doTest("simple"); } @Test - public void testIgnoreBetweenSpecialComments() throws IOException { - final String code = "// CPD-OFF" + PMD.EOL - + "function switchToRealPassword() {" + PMD.EOL - + "var real = $('realPass');" + PMD.EOL - + " var prompt = $('promptPass');" + PMD.EOL - + "// CPD-ON" + PMD.EOL - + "}" + PMD.EOL; + public void testSimplewithSemis() { + doTest("simpleWithSemis"); + } - Tokenizer t = new EcmascriptTokenizer(); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader(code)); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - assertEquals(2, tokens.size()); // Only "}" and EOL + @Test + public void testIgnoreBetweenSpecialComments() { + doTest("specialComments"); } /** * See: https://sourceforge.net/p/pmd/bugs/1239/ - * - * @throws IOException - * IO Exception */ @Test - public void parseStringNotAsMultiline() throws IOException { - Tokenizer t = new EcmascriptTokenizer(); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader( - "var s = \"a string \\\n" + "continues\";\n" + "var s = \"a string \\\n" + "continues2\";\n")); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - assertEquals(11, tokens.size()); - List list = tokens.getTokens(); - assertEquals("var", list.get(0).getIdentifier(), list.get(5).getIdentifier()); - assertEquals("s", list.get(1).getIdentifier(), list.get(6).getIdentifier()); - assertEquals("=", list.get(2).getIdentifier(), list.get(7).getIdentifier()); - assertEquals("\"a string continues\"", list.get(3).toString()); - assertEquals("\"a string continues2\"", list.get(8).toString()); - assertFalse(list.get(3).getIdentifier() == list.get(8).getIdentifier()); + public void parseStringNotAsMultiline() { + doTest("lineContinuations"); } @Test - public void testIgnoreSingleLineComments() throws IOException { - Tokenizer t = new EcmascriptTokenizer(); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader( - "//This is a single line comment\n" + "var i = 0;\n\n" + "//This is another comment\n" + "i++;")); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - assertEquals(9, tokens.size()); - List list = tokens.getTokens(); - assertEquals("var", list.get(0).toString()); - assertEquals("++", list.get(6).toString()); + public void testIgnoreSingleLineComments() { + doTest("singleLineCommentIgnore"); } @Test - public void testIgnoreMultiLineComments() throws IOException { - Tokenizer t = new EcmascriptTokenizer(); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("/* This is a multi line comment\n" - + " * \n" + " */ \n" + "var i = 0;\n\n" - + "/* This is another multi line comment\n" + " * second line \n" - + " * third line */\n" + "i++;")); - Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - assertEquals(9, tokens.size()); - List list = tokens.getTokens(); - assertEquals("var", list.get(0).toString()); - assertEquals("++", list.get(6).toString()); - } - - // no semi-colons - private String getCode1() { - StringBuilder sb = new StringBuilder(); - sb.append("function switchToRealPassword() {").append(PMD.EOL); - sb.append(" var real = $('realPass')").append(PMD.EOL); - sb.append(" var prompt = $('promptPass')").append(PMD.EOL); - sb.append(" real.style.display = 'inline'").append(PMD.EOL); - sb.append(" prompt.style.display = 'none'").append(PMD.EOL); - sb.append(" real.focus()").append(PMD.EOL); - sb.append("}").append(PMD.EOL); - return sb.toString(); - } - - // same as getCode1, but lines are ended with semi-colons - private String getCode2() { - StringBuilder sb = new StringBuilder(); - sb.append("function switchToRealPassword() {").append(PMD.EOL); - sb.append(" var real = $('realPass');").append(PMD.EOL); - sb.append(" var prompt = $('promptPass');").append(PMD.EOL); - sb.append(" real.style.display = 'inline';").append(PMD.EOL); - sb.append(" prompt.style.display = 'none';").append(PMD.EOL); - sb.append(" real.focus();").append(PMD.EOL); - sb.append("}").append(PMD.EOL); - return sb.toString(); + public void testIgnoreMultiLineComments() { + doTest("multilineCommentIgnore"); } @Test - public void testTemplateStrings() throws IOException { - Tokenizer t = new EcmascriptTokenizer(); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader( - "export default class DrawLocation extends joint.shapes.basic.Generic {" + PMD.EOL - + " constructor(location: ILocation) {" + PMD.EOL - + " this.markup = `" + PMD.EOL - + " " + PMD.EOL - + " " + PMD.EOL - + PMD.EOL - + " " + PMD.EOL - + " " + PMD.EOL - + " ${drawIndicators.Check.markup}" + PMD.EOL - + PMD.EOL - + " `;" + PMD.EOL - + " }" + PMD.EOL - + "" + PMD.EOL - + "}")); - final Tokens tokens = new Tokens(); - t.tokenize(sourceCode, tokens); - final String templateString = "`" + PMD.EOL - + " " + PMD.EOL - + " " + PMD.EOL - + PMD.EOL - + " " + PMD.EOL - + " " + PMD.EOL - + " ${drawIndicators.Check.markup}" + PMD.EOL - + PMD.EOL - + " `"; - assertEquals(templateString, tokens.getTokens().get(24).toString()); + public void testTemplateStrings() { + doTest("templateStrings"); } } diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/lineContinuations.js b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/lineContinuations.js new file mode 100644 index 0000000000..d35601feaa --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/lineContinuations.js @@ -0,0 +1,4 @@ +var s = "a string \ +continues"; +var s = "a string \ +continues2"; diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/lineContinuations.txt b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/lineContinuations.txt new file mode 100644 index 0000000000..0b944898ad --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/lineContinuations.txt @@ -0,0 +1,16 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [var] 1 4 + [s] 5 6 + [=] 7 8 + ["a string continues"] 9 11 +L2 + [;] 11 12 +L3 + [var] 1 4 + [s] 5 6 + [=] 7 8 + ["a string continues2"] 9 12 +L4 + [;] 12 13 +EOF diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/multilineCommentIgnore.js b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/multilineCommentIgnore.js new file mode 100644 index 0000000000..ed40ce6d70 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/multilineCommentIgnore.js @@ -0,0 +1,10 @@ + +/* This is a multi line comment + * + */ +var i = 0; + +/* This is another multi line comment + * second line + * third line */ +i++; \ No newline at end of file diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/multilineCommentIgnore.txt b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/multilineCommentIgnore.txt new file mode 100644 index 0000000000..3ebbcb14f2 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/multilineCommentIgnore.txt @@ -0,0 +1,12 @@ + [Image] or [Truncated image[ Bcol Ecol +L5 + [var] 1 4 + [i] 5 6 + [=] 7 8 + [0] 9 10 + [;] 10 11 +L10 + [i] 1 2 + [++] 2 4 + [;] 4 5 +EOF diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simple.js b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simple.js new file mode 100644 index 0000000000..b9c17dc4b3 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simple.js @@ -0,0 +1,7 @@ +function switchToRealPassword() { + var real = $('realPass') + var prompt = $('promptPass') + real.style.display = 'inline' + prompt.style.display = 'none' + real.focus() +} diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simple.txt b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simple.txt new file mode 100644 index 0000000000..60447768a1 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simple.txt @@ -0,0 +1,48 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [function] 1 9 + [switchToRealPassword] 10 30 + [(] 30 31 + [)] 31 32 + [{] 33 34 +L2 + [var] 5 8 + [real] 9 13 + [=] 14 15 + [$] 16 17 + [(] 17 18 + ['realPass'] 18 28 + [)] 28 29 +L3 + [var] 5 8 + [prompt] 9 15 + [=] 16 17 + [$] 18 19 + [(] 19 20 + ['promptPass'] 20 32 + [)] 32 33 +L4 + [real] 5 9 + [.] 9 10 + [style] 10 15 + [.] 15 16 + [display] 16 23 + [=] 24 25 + ['inline'] 26 34 +L5 + [prompt] 5 11 + [.] 11 12 + [style] 12 17 + [.] 17 18 + [display] 18 25 + [=] 26 27 + ['none'] 28 34 +L6 + [real] 5 9 + [.] 9 10 + [focus] 10 15 + [(] 15 16 + [)] 16 17 +L7 + [}] 1 2 +EOF diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simpleWithSemis.js b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simpleWithSemis.js new file mode 100644 index 0000000000..86c9a74bbb --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simpleWithSemis.js @@ -0,0 +1,7 @@ +function switchToRealPassword() { + var real = $('realPass'); + var prompt = $('promptPass'); + real.style.display = 'inline'; + prompt.style.display = 'none'; + real.focus(); +} diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simpleWithSemis.txt b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simpleWithSemis.txt new file mode 100644 index 0000000000..4d9788509f --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/simpleWithSemis.txt @@ -0,0 +1,53 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [function] 1 9 + [switchToRealPassword] 10 30 + [(] 30 31 + [)] 31 32 + [{] 33 34 +L2 + [var] 5 8 + [real] 9 13 + [=] 14 15 + [$] 16 17 + [(] 17 18 + ['realPass'] 18 28 + [)] 28 29 + [;] 29 30 +L3 + [var] 5 8 + [prompt] 9 15 + [=] 16 17 + [$] 18 19 + [(] 19 20 + ['promptPass'] 20 32 + [)] 32 33 + [;] 33 34 +L4 + [real] 5 9 + [.] 9 10 + [style] 10 15 + [.] 15 16 + [display] 16 23 + [=] 24 25 + ['inline'] 26 34 + [;] 34 35 +L5 + [prompt] 5 11 + [.] 11 12 + [style] 12 17 + [.] 17 18 + [display] 18 25 + [=] 26 27 + ['none'] 28 34 + [;] 34 35 +L6 + [real] 5 9 + [.] 9 10 + [focus] 10 15 + [(] 15 16 + [)] 16 17 + [;] 17 18 +L7 + [}] 1 2 +EOF diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/singleLineCommentIgnore.js b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/singleLineCommentIgnore.js new file mode 100644 index 0000000000..84ebb94742 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/singleLineCommentIgnore.js @@ -0,0 +1,6 @@ + +//This is a single line comment +var i = 0; + +//This is another comment +i++; \ No newline at end of file diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/singleLineCommentIgnore.txt b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/singleLineCommentIgnore.txt new file mode 100644 index 0000000000..a847f7d298 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/singleLineCommentIgnore.txt @@ -0,0 +1,12 @@ + [Image] or [Truncated image[ Bcol Ecol +L3 + [var] 1 4 + [i] 5 6 + [=] 7 8 + [0] 9 10 + [;] 10 11 +L6 + [i] 1 2 + [++] 2 4 + [;] 4 5 +EOF diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/specialComments.js b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/specialComments.js new file mode 100644 index 0000000000..668fb642f0 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/specialComments.js @@ -0,0 +1,6 @@ +// CPD-OFF +function switchToRealPassword() { + var real = $('realPass'); + var prompt = $('promptPass'); +// CPD-ON +} diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/specialComments.txt b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/specialComments.txt new file mode 100644 index 0000000000..a5c023d777 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/specialComments.txt @@ -0,0 +1,4 @@ + [Image] or [Truncated image[ Bcol Ecol +L6 + [}] 1 2 +EOF diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/templateStrings.js b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/templateStrings.js new file mode 100644 index 0000000000..a8c25859f8 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/templateStrings.js @@ -0,0 +1,14 @@ +export default class DrawLocation extends joint.shapes.basic.Generic { + constructor(location: ILocation) { + this.markup = ` + + + + + + ${drawIndicators.Check.markup} + + `; + } + +} \ No newline at end of file diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/templateStrings.txt b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/templateStrings.txt new file mode 100644 index 0000000000..59cf1adcf6 --- /dev/null +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/cpd/testdata/templateStrings.txt @@ -0,0 +1,36 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [export] 1 7 + [default] 8 15 + [class] 16 21 + [DrawLocation] 22 34 + [extends] 35 42 + [joint] 43 48 + [.] 48 49 + [shapes] 49 55 + [.] 55 56 + [basic] 56 61 + [.] 61 62 + [Generic] 62 69 + [{] 70 71 +L2 + [constructor] 5 16 + [(] 16 17 + [location] 17 25 + [:] 25 26 + [ILocation] 27 36 + [)] 36 37 + [{] 38 39 +L3 + [this] 9 13 + [.] 13 14 + [markup] 14 20 + [=] 21 22 + [`\n ", - "<%", - PMD.EOL + "String nodeContent = \"<% %>\";" + PMD.EOL, - "%>", - "<%", - PMD.EOL + "\";" + PMD.EOL - + "]]>" + PMD.EOL, - "%>", - "", - }; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; +public class JSPTokenizerTest extends CpdTextComparisonTest { - Assert.assertEquals(expectedTokens.length, tokenEntries.getTokens().size()); - for (int i = 0; i < expectedTokens.length - 1; i++) { - TokenEntry tokenEntry = tokenEntries.getTokens().get(i); - Assert.assertEquals(expectedTokens[i], tokenEntry.toString()); - } + public JSPTokenizerTest() { + super(".jsp"); } + @Override + protected String getResourcePrefix() { + return "../lang/jsp/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new JSPTokenizer(); + } + + @Test + public void scriptletWithString() { + doTest("scriptletWithString"); + } } diff --git a/pmd-jsp/src/test/resources/net/sourceforge/pmd/cpd/scriptletWithString.jsp b/pmd-jsp/src/test/resources/net/sourceforge/pmd/lang/jsp/cpd/testdata/scriptletWithString.jsp similarity index 100% rename from pmd-jsp/src/test/resources/net/sourceforge/pmd/cpd/scriptletWithString.jsp rename to pmd-jsp/src/test/resources/net/sourceforge/pmd/lang/jsp/cpd/testdata/scriptletWithString.jsp diff --git a/pmd-jsp/src/test/resources/net/sourceforge/pmd/lang/jsp/cpd/testdata/scriptletWithString.txt b/pmd-jsp/src/test/resources/net/sourceforge/pmd/lang/jsp/cpd/testdata/scriptletWithString.txt new file mode 100644 index 0000000000..a27643e225 --- /dev/null +++ b/pmd-jsp/src/test/resources/net/sourceforge/pmd/lang/jsp/cpd/testdata/scriptletWithString.txt @@ -0,0 +1,17 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [<%--] 1 5 + [\nBSD-style license; for more info[ 5 1 +L3 + [--%>] 1 5 +L5 + [<%] 1 3 + [\nString nodeContent = "<% %>";\n] 3 1 +L7 + [%>] 1 3 +L8 + [<%] 1 3 + [\n] 1 3 +EOF diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 95a258d794..85d61faee3 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -49,10 +49,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-kotlin/src/test/java/net/sourceforge/pmd/cpd/KotlinTokenizerTest.java b/pmd-kotlin/src/test/java/net/sourceforge/pmd/cpd/KotlinTokenizerTest.java index 6d45a5bc8b..539b527858 100644 --- a/pmd-kotlin/src/test/java/net/sourceforge/pmd/cpd/KotlinTokenizerTest.java +++ b/pmd-kotlin/src/test/java/net/sourceforge/pmd/cpd/KotlinTokenizerTest.java @@ -4,53 +4,40 @@ package net.sourceforge.pmd.cpd; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; +import java.util.Properties; -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -@RunWith(Parameterized.class) -public class KotlinTokenizerTest extends AbstractTokenizerTest { +public class KotlinTokenizerTest extends CpdTextComparisonTest { - private final String filename; - private final int nExpectedTokens; - - public KotlinTokenizerTest(String filename, int nExpectedTokens) { - this.filename = filename; - this.nExpectedTokens = nExpectedTokens; - } - - @Parameterized.Parameters - public static Collection data() { - return Arrays.asList( - new Object[] { "comment.kt", 5 }, - new Object[] { "increment.kt", 185 }, - new Object[] { "imports.kt", 1 } - ); - } - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new KotlinTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), this.filename)); + public KotlinTokenizerTest() { + super(".kt"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(KotlinTokenizer.class.getResourceAsStream(this.filename)); + protected String getResourcePrefix() { + return "../lang/kotlin/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new KotlinTokenizer(); } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = nExpectedTokens; - super.tokenizeTest(); + public void testComments() { + doTest("comment"); + } + + @Test + public void testIncrement() { + doTest("increment"); + } + + @Test + public void testImportsIgnored() { + doTest("imports"); } } diff --git a/pmd-kotlin/src/test/resources/net/sourceforge/pmd/cpd/comment.kt b/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/comment.kt similarity index 100% rename from pmd-kotlin/src/test/resources/net/sourceforge/pmd/cpd/comment.kt rename to pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/comment.kt diff --git a/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/comment.txt b/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/comment.txt new file mode 100644 index 0000000000..0ffae05d93 --- /dev/null +++ b/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/comment.txt @@ -0,0 +1,7 @@ + [Image] or [Truncated image[ Bcol Ecol +L3 + [var] 1 4 + [x] 5 6 + [=] 7 8 + [0] 9 10 +EOF diff --git a/pmd-kotlin/src/test/resources/net/sourceforge/pmd/cpd/imports.kt b/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/imports.kt similarity index 100% rename from pmd-kotlin/src/test/resources/net/sourceforge/pmd/cpd/imports.kt rename to pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/imports.kt diff --git a/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/imports.txt b/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/imports.txt new file mode 100644 index 0000000000..49ab402048 --- /dev/null +++ b/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/imports.txt @@ -0,0 +1,2 @@ + [Image] or [Truncated image[ Bcol Ecol +EOF diff --git a/pmd-kotlin/src/test/resources/net/sourceforge/pmd/cpd/increment.kt b/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/increment.kt similarity index 100% rename from pmd-kotlin/src/test/resources/net/sourceforge/pmd/cpd/increment.kt rename to pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/increment.kt diff --git a/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/increment.txt b/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/increment.txt new file mode 100644 index 0000000000..a2f684d832 --- /dev/null +++ b/pmd-kotlin/src/test/resources/net/sourceforge/pmd/lang/kotlin/cpd/testdata/increment.txt @@ -0,0 +1,207 @@ + [Image] or [Truncated image[ Bcol Ecol +L3 + [var] 1 4 + [x] 5 6 + [=] 7 8 + [0] 9 10 +L5 + [fun] 1 4 + [increment1] 5 15 + [(] 15 16 + [)] 16 17 + [{] 18 19 + [x] 20 21 + [+=] 22 24 + [1] 25 26 + [}] 27 28 +L6 + [fun] 1 4 + [increment2] 5 15 + [(] 15 16 + [)] 16 17 + [{] 18 19 + [x] 20 21 + [+=] 22 24 + [1] 25 26 + [}] 27 28 +L7 + [fun] 1 4 + [increment3] 5 15 + [(] 15 16 + [)] 16 17 + [{] 18 19 + [x] 20 21 + [+=] 22 24 + [1] 25 26 + [}] 27 28 +L8 + [fun] 1 4 + [increment4] 5 15 + [(] 15 16 + [)] 16 17 + [{] 18 19 + [x] 20 21 + [+=] 22 24 + [1] 25 26 + [}] 27 28 +L9 + [fun] 1 4 + [increment5] 5 15 + [(] 15 16 + [)] 16 17 + [{] 18 19 + [x] 20 21 + [+=] 22 24 + [1] 25 26 + [}] 27 28 +L10 + [fun] 1 4 + [increment6] 5 15 + [(] 15 16 + [)] 16 17 + [{] 18 19 + [x] 20 21 + [+=] 22 24 + [1] 25 26 + [}] 27 28 +L11 + [fun] 1 4 + [increment7] 5 15 + [(] 15 16 + [)] 16 17 + [{] 18 19 + [x] 20 21 + [+=] 22 24 + [1] 25 26 + [}] 27 28 +L12 + [fun] 1 4 + [increment8] 5 15 + [(] 15 16 + [)] 16 17 + [{] 18 19 + [x] 20 21 + [+=] 22 24 + [1] 25 26 + [}] 27 28 +L13 + [fun] 1 4 + [increment9] 5 15 + [(] 15 16 + [)] 16 17 + [{] 18 19 + [x] 20 21 + [+=] 22 24 + [1] 25 26 + [}] 27 28 +L14 + [fun] 1 4 + [increment10] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 28 29 +L15 + [fun] 1 4 + [increment11] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 28 29 +L16 + [fun] 1 4 + [increment12] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 28 29 +L17 + [fun] 1 4 + [increment13] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 28 29 +L18 + [fun] 1 4 + [increment14] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 28 29 +L19 + [fun] 1 4 + [increment15] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 28 29 +L20 + [fun] 1 4 + [increment16] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 28 29 +L21 + [fun] 1 4 + [increment17] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 28 29 +L22 + [fun] 1 4 + [increment18] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 28 29 +L23 + [fun] 1 4 + [increment19] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 28 29 +L24 + [fun] 1 4 + [increment20] 5 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [x] 21 22 + [+=] 23 25 + [1] 26 27 + [}] 28 29 +EOF diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/cpd/test/CpdTextComparisonTest.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/cpd/test/CpdTextComparisonTest.kt new file mode 100644 index 0000000000..2b198984cd --- /dev/null +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/cpd/test/CpdTextComparisonTest.kt @@ -0,0 +1,154 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.cpd.test + +import io.kotlintest.shouldThrow +import net.sourceforge.pmd.cpd.SourceCode +import net.sourceforge.pmd.cpd.TokenEntry +import net.sourceforge.pmd.cpd.Tokenizer +import net.sourceforge.pmd.cpd.Tokens +import net.sourceforge.pmd.lang.ast.TokenMgrError +import net.sourceforge.pmd.test.BaseTextComparisonTest +import org.apache.commons.lang3.StringUtils +import java.util.* + +/** + * CPD test comparing a dump of a file against a saved baseline. + * Each token is printed on a separate line. + * + * @param extensionIncludingDot File extension for the language. + * Baseline files are saved in txt files. + */ +abstract class CpdTextComparisonTest( + override val extensionIncludingDot: String +) : BaseTextComparisonTest() { + + abstract fun newTokenizer(properties: Properties): Tokenizer + + override val resourceLoader: Class<*> + get() = javaClass + + override val resourcePrefix: String + get() = "testdata" + + + open fun defaultProperties() = Properties() + + /** + * A test comparing the output of the tokenizer. + * + * @param fileBaseName Name of the source file (without extension or resource prefix) + * @param expectedSuffix Suffix to append to the expected file. This allows reusing the same source file + * with different configurations, provided the suffix is different + * @param properties Properties to configure [newTokenizer] + */ + @JvmOverloads + fun doTest(fileBaseName: String, expectedSuffix: String = "", properties: Properties = defaultProperties()) { + super.doTest(fileBaseName, expectedSuffix) { sourceText -> + val sourceCode = SourceCode(SourceCode.StringCodeLoader(sourceText, "$fileBaseName$extensionIncludingDot")) + val tokens = Tokens().also { + val tokenizer = newTokenizer(properties) + tokenizer.tokenize(sourceCode, it) + } + + buildString { format(tokens) } + } + } + + @JvmOverloads + fun expectTokenMgrError(source: String, properties: Properties = defaultProperties()): TokenMgrError = + shouldThrow { + newTokenizer(properties).tokenize(sourceCodeOf(source), Tokens()) + } + + + private fun StringBuilder.format(tokens: Tokens) { + appendHeader().appendln() + + var curLine = -1 + + for (token in tokens.iterator()) { + + if (token === TokenEntry.EOF) { + append("EOF").appendln() + continue + } + + if (curLine != token.beginLine) { + curLine = token.beginLine + append('L').append(curLine).appendln() + } + + formatLine(token).appendln() + } + } + + + private fun StringBuilder.appendHeader() = + formatLine( + escapedImage = "[Image] or [Truncated image[", + bcol = "Bcol", + ecol = "Ecol" + ) + + + private fun StringBuilder.formatLine(token: TokenEntry) = + formatLine( + escapedImage = escapeImage(token.toString()), + bcol = token.beginColumn, + ecol = token.endColumn + ) + + + private fun StringBuilder.formatLine(escapedImage: String, bcol: Any, ecol: Any): StringBuilder { + var colStart = length + colStart = append(Indent).append(escapedImage).padCol(colStart, Col0Width) + colStart = append(Indent).append(bcol).padCol(colStart, Col1Width) + return append(ecol) + } + + private fun StringBuilder.padCol(colStart: Int, colWidth: Int): Int { + for (i in 1..(colStart + colWidth - this.length)) + append(' ') + + return length + } + + + private fun escapeImage(str: String): String { + val escaped = str + .replace("\\", "\\\\") // escape backslashes + .replace("\r\n", "\\r\\n") // CRLF (treated specially because it has a different length) + .replace("\t", "\\t") // TAB + .replace(Regex("\\u000D\\u000A|[\\u000A\\u000B\\u000C\\u000D\\u0085\\u2028\\u2029]"), "\\\\n") // escape other newlines (normalizing), use \\R with java8+ + .replace(Regex("[]\\[]"), "\\\\$0") // escape [] + + var truncated = StringUtils.truncate(escaped, ImageSize) + + if (truncated.endsWith('\\') && !truncated.endsWith("\\\\")) + truncated = truncated.substring(0, truncated.length - 1) // cut inside an escape + + return if (truncated.length < escaped.length) + "[$truncated[" + else + "[$truncated]" + + } + + + fun sourceCodeOf(str: String): SourceCode = SourceCode(SourceCode.StringCodeLoader(str)) + + fun tokenize(tokenizer: Tokenizer, str: String): Tokens = + Tokens().also { + tokenizer.tokenize(sourceCodeOf(str), it) + } + + private companion object { + const val Indent = " " + const val Col0Width = 40 + const val Col1Width = 10 + Indent.length + val ImageSize = Col0Width - Indent.length - 2 // -2 is for the "[]" + } +} diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseTreeDumpTest.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseTreeDumpTest.kt index 4fab7ba383..2a1614151c 100644 --- a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseTreeDumpTest.kt +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseTreeDumpTest.kt @@ -4,71 +4,37 @@ package net.sourceforge.pmd.lang.ast.test +import net.sourceforge.pmd.test.BaseTextComparisonTest import net.sourceforge.pmd.util.treeexport.TreeRenderer -import java.nio.file.Path -import java.nio.file.Paths -import kotlin.test.assertEquals /** - * Compare a dump of a file against a saved baseline. + * Compare a dump of an AST against a saved baseline. * * @param printer The node printer used to dump the trees - * @param extension Extension that the unparsed source file is supposed to have + * @param extensionIncludingDot Extension that the unparsed source file is supposed to have */ abstract class BaseTreeDumpTest( - val printer: TreeRenderer, - val extension: String -) { + private val printer: TreeRenderer, + override val extensionIncludingDot: String +) : BaseTextComparisonTest() { abstract val parser: BaseParsingHelper<*, *> + override val resourceLoader: Class<*> + get() = parser.resourceLoader + + override val resourcePrefix: String + get() = parser.resourcePrefix + /** - * Executes the test. The test files are looked up using the [parser]. - * The reference test file must be named [fileBaseName] + [ExpectedExt]. - * The source file to parse must be named [fileBaseName] + [extension]. + * @see BaseTextComparisonTest.doTest */ fun doTest(fileBaseName: String) { - val expectedFile = findTestFile(parser.resourceLoader, "${parser.resourcePrefix}/$fileBaseName$ExpectedExt").toFile() - val sourceFile = findTestFile(parser.resourceLoader, "${parser.resourcePrefix}/$fileBaseName$extension").toFile() - - assert(sourceFile.isFile) { - "Source file $sourceFile is missing" + super.doTest(fileBaseName, "") { sourceText -> + buildString { + printer.renderSubtree(parser.parse(sourceText), this) + } } - - val parsed = parser.parse(sourceFile.readText()) // UTF-8 - val actual = StringBuilder().also { printer.renderSubtree(parsed, it) }.toString() - - if (!expectedFile.exists()) { - expectedFile.writeText(actual) - throw AssertionError("Reference file doesn't exist, created it at $expectedFile") - } - - val expected = expectedFile.readText() - - assertEquals(expected.normalize(), actual.normalize(), "Tree dump comparison failed, see the reference: $expectedFile") } - - // Outputting a path makes for better error messages - private val srcTestResources = let { - // this is set from maven surefire - see parent pom.xml configuration for surefire (systemPropertyVariables) - System.getProperty("mvn.project.src.test.resources") - ?.let { Paths.get(it).toAbsolutePath() } - // that's for when the tests are run inside the IDE - ?: Paths.get(javaClass.protectionDomain.codeSource.location.file) - // go up from target/test-classes into the project root - .resolve("../../src/test/resources").normalize() - } - - private fun findTestFile(contextClass: Class<*>, resourcePath: String): Path { - val path = contextClass.`package`.name.replace('.', '/') - return srcTestResources.resolve("$path/$resourcePath") - } - - companion object { - const val ExpectedExt = ".txt" - - fun String.normalize() = replace(Regex("\\R"), "\n") - } - } diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/test/BaseTextComparisonTest.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/test/BaseTextComparisonTest.kt new file mode 100644 index 0000000000..bacae235ab --- /dev/null +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/test/BaseTextComparisonTest.kt @@ -0,0 +1,100 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.test + +import java.nio.file.Path +import java.nio.file.Paths +import kotlin.test.assertEquals + + +/** + * Compare a dump of a file against a saved baseline. + * See subclasses CpdTextComparisonTest, BaseTreeDumpTest. + */ +abstract class BaseTextComparisonTest { + + protected abstract val resourceLoader: Class<*> + + /** + * Resource prefix to look for test files. This is + * resolved from the [resourceLoader] class. Separate + * directories with '/', not '.'. + */ + protected abstract val resourcePrefix: String + + /** Extension that the unparsed source file is supposed to have. */ + protected abstract val extensionIncludingDot: String + + /** + * Executes the test. The test files are looked up using the [parser]. + * The reference test file must be named [fileBaseName] + [ExpectedExt]. + * The source file to parse must be named [fileBaseName] + [extensionIncludingDot]. + * + * @param transformTextContent Function that maps the contents of the source file to the + * "expected" format. + */ + internal fun doTest(fileBaseName: String, + expectedSuffix: String = "", + transformTextContent: (String) -> String) { + val expectedFile = findTestFile(resourceLoader, "${resourcePrefix}/$fileBaseName$expectedSuffix$ExpectedExt").toFile() + + val actual = transformTextContent(sourceText(fileBaseName)) + + if (!expectedFile.exists()) { + expectedFile.writeText(actual) + throw AssertionError( + """ + Reference file doesn't exist, created it at $expectedFile + Don't forget to `git add` it! + """.trimIndent()) + } + + val expected = expectedFile.readText() + + assertEquals(expected.normalize(), actual.normalize(), "File comparison failed, see the reference: $expectedFile") + } + + protected fun sourceText(fileBaseName: String): String { + val sourceFile = findTestFile(resourceLoader, "${resourcePrefix}/$fileBaseName$extensionIncludingDot").toFile() + + assert(sourceFile.isFile) { + "Source file $sourceFile is missing" + } + + val sourceText = sourceFile.readText(Charsets.UTF_8).normalize() + return sourceText + } + + // Outputting a path makes for better error messages + private val srcTestResources = let { + // this is set from maven surefire + System.getProperty("mvn.project.src.test.resources") + ?.let { Paths.get(it).toAbsolutePath() } + // that's for when the tests are run inside the IDE + ?: Paths.get(javaClass.protectionDomain.codeSource.location.file) + // go up from target/test-classes into the project root + .resolve("../../src/test/resources").normalize() + } + + private fun findTestFile(contextClass: Class<*>, resourcePath: String): Path { + val path = contextClass.`package`.name.replace('.', '/') + // normalize the path, because if eg we have src/test/resources/some/pack/../other, + // where the directory 'some/pack' does not exist, the file will not be found, even if + // some/other exists. Normalization turns the above path into src/test/resources/some/other + val norm = Paths.get("$path/$resourcePath").normalize() + return srcTestResources.resolve(norm) + } + + companion object { + const val ExpectedExt = ".txt" + + fun String.normalize() = replace( + // \R on java 8+ + regex = Regex("\\u000D\\u000A|[\\u000A\\u000B\\u000C\\u000D\\u0085\\u2028\\u2029]"), + replacement = "\n" + ) + } + +} diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 149fc00145..f9c2334c65 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -49,10 +49,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-lua/src/test/java/net/sourceforge/pmd/cpd/LuaTokenizerTest.java b/pmd-lua/src/test/java/net/sourceforge/pmd/cpd/LuaTokenizerTest.java index 5328e71823..6c2dafa050 100644 --- a/pmd-lua/src/test/java/net/sourceforge/pmd/cpd/LuaTokenizerTest.java +++ b/pmd-lua/src/test/java/net/sourceforge/pmd/cpd/LuaTokenizerTest.java @@ -4,53 +4,34 @@ package net.sourceforge.pmd.cpd; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collection; +import java.util.Properties; -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -@RunWith(Parameterized.class) -public class LuaTokenizerTest extends AbstractTokenizerTest { - - private final String filename; - private final int nExpectedTokens; - - public LuaTokenizerTest(String filename, int nExpectedTokens) { - this.filename = filename; - this.nExpectedTokens = nExpectedTokens; - } - - @Parameterized.Parameters - public static Collection data() { - return Arrays.asList( - new Object[] { "factorial.lua", 44 }, - new Object[] { "helloworld.lua", 5 } - ); - } - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new LuaTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), this.filename)); +public class LuaTokenizerTest extends CpdTextComparisonTest { + public LuaTokenizerTest() { + super(".lua"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(LuaTokenizer.class.getResourceAsStream(this.filename), StandardCharsets.UTF_8); + protected String getResourcePrefix() { + return "../lang/lua/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new LuaTokenizer(); } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = nExpectedTokens; - super.tokenizeTest(); + public void testSimple() { + doTest("helloworld"); + } + + @Test + public void testFactorial() { + doTest("factorial"); } } diff --git a/pmd-lua/src/test/resources/net/sourceforge/pmd/cpd/factorial.lua b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/factorial.lua similarity index 100% rename from pmd-lua/src/test/resources/net/sourceforge/pmd/cpd/factorial.lua rename to pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/factorial.lua diff --git a/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/factorial.txt b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/factorial.txt new file mode 100644 index 0000000000..b037f76728 --- /dev/null +++ b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/factorial.txt @@ -0,0 +1,55 @@ + [Image] or [Truncated image[ Bcol Ecol +L2 + [function] 5 13 + [fact] 14 18 + [(] 19 20 + [n] 20 21 + [)] 21 22 +L3 + [if] 7 9 + [n] 10 11 + [==] 12 14 + [0] 15 16 + [then] 17 21 +L4 + [return] 9 15 + [1] 16 17 +L5 + [else] 7 11 +L6 + [return] 9 15 + [n] 16 17 + [*] 18 19 + [fact] 20 24 + [(] 24 25 + [n] 25 26 + [-] 26 27 + [1] 27 28 + [)] 28 29 +L7 + [end] 7 10 +L8 + [end] 5 8 +L10 + [print] 5 10 + [(] 10 11 + ["enter a number:"] 11 28 + [)] 28 29 +L11 + [a] 5 6 + [=] 7 8 + [io] 9 11 + [.] 11 12 + [read] 12 16 + [(] 16 17 + ["*number"] 17 26 + [)] 26 27 +L12 + [print] 5 10 + [(] 10 11 + [fact] 11 15 + [(] 15 16 + [a] 16 17 + [)] 17 18 + [)] 18 19 +EOF diff --git a/pmd-lua/src/test/resources/net/sourceforge/pmd/cpd/helloworld.lua b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/helloworld.lua similarity index 100% rename from pmd-lua/src/test/resources/net/sourceforge/pmd/cpd/helloworld.lua rename to pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/helloworld.lua diff --git a/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/helloworld.txt b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/helloworld.txt new file mode 100644 index 0000000000..22b01d214e --- /dev/null +++ b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/helloworld.txt @@ -0,0 +1,7 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [print] 2 7 + [(] 7 8 + ["Hello World"] 8 21 + [)] 21 22 +EOF diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index e4ea7dcbe8..00df34912c 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -82,10 +82,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-matlab/src/test/java/net/sourceforge/pmd/cpd/MatlabTokenizerTest.java b/pmd-matlab/src/test/java/net/sourceforge/pmd/cpd/MatlabTokenizerTest.java index 7275d917bb..ae216ed7a4 100644 --- a/pmd-matlab/src/test/java/net/sourceforge/pmd/cpd/MatlabTokenizerTest.java +++ b/pmd-matlab/src/test/java/net/sourceforge/pmd/cpd/MatlabTokenizerTest.java @@ -4,102 +4,56 @@ package net.sourceforge.pmd.cpd; -import static org.junit.Assert.assertEquals; +import java.util.Properties; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -public class MatlabTokenizerTest extends AbstractTokenizerTest { +public class MatlabTokenizerTest extends CpdTextComparisonTest { - private static final String FILENAME = "sample-matlab.m"; - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new MatlabTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), FILENAME)); + public MatlabTokenizerTest() { + super(".m"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(MatlabTokenizer.class.getResourceAsStream(FILENAME), StandardCharsets.UTF_8); + protected String getResourcePrefix() { + return "../lang/matlab/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new MatlabTokenizer(); + } + + @Test + public void testLongSample() { + doTest("sample-matlab"); } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 3925; - super.tokenizeTest(); + public void testIgnoreBetweenSpecialComments() { + doTest("specialComments"); + } @Test - public void testIgnoreBetweenSpecialComments() throws IOException { - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("% CPD-OFF" + PMD.EOL - + "function g = vec(op, y)" + PMD.EOL - + " opy = op(y);" + PMD.EOL - + " if ( any(size(opy) > 1) )" + PMD.EOL - + " g = @loopWrapperArray;" + PMD.EOL - + " end" + PMD.EOL - + " % CPD-ON" + PMD.EOL - + "end" - )); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); - assertEquals(2, tokens.size()); // 2 tokens: "end" + EOF + public void testComments() { + doTest("comments"); } @Test - public void testComments() throws IOException { - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("classdef LC" + PMD.EOL - + " methods" + PMD.EOL - + " function [obj, c,t, s ] = Classification( obj,m,t, cm )%#codegen" + PMD.EOL - + " end" + PMD.EOL - + " end" + PMD.EOL - + "end")); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); // should not result in parse error - assertEquals(28, tokens.size()); + public void testBlockComments() { + doTest("multilineComments"); } @Test - public void testBlockComments() throws IOException { - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("%{" + PMD.EOL - + " Name: helloworld.m\n" + PMD.EOL - + " Purpose: Say \"Hello World!\" in two different ways" + PMD.EOL - + "%}" + PMD.EOL - + PMD.EOL - + "% Do it the good ol' fashioned way...command window" + PMD.EOL - + "disp('Hello World!');\n" + PMD.EOL - + "%" + PMD.EOL - + "% Do it the new hip GUI way...with a message box" + PMD.EOL - + "msgbox('Hello World!','Hello World!');")); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); // should not result in parse error - assertEquals(13, tokens.size()); + public void testQuestionMark() { + doTest("questionMark"); } @Test - public void testQuestionMark() throws IOException { - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("classdef Class1" + PMD.EOL - + "properties (SetAccess = ?Class2)")); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); - assertEquals(10, tokens.size()); - } - - @Test - public void testDoubleQuotedStrings() throws IOException { - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader( - "error(\"This is a double-quoted string\");")); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); - assertEquals("\"This is a double-quoted string\"", tokens.getTokens().get(2).toString()); - assertEquals(6, tokens.size()); + public void testDoubleQuotedStrings() { + doTest("doubleQuotedStrings"); } } diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/comments.m b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/comments.m new file mode 100644 index 0000000000..f9340a056d --- /dev/null +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/comments.m @@ -0,0 +1,6 @@ +classdef LC + methods + function [obj, c,t, s ] = Classification( obj,m,t, cm )%#codegen + end + end +end \ No newline at end of file diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/comments.txt b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/comments.txt new file mode 100644 index 0000000000..5e48259a90 --- /dev/null +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/comments.txt @@ -0,0 +1,35 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [classdef] 1 9 + [LC] 10 12 +L2 + [methods] 5 12 +L3 + [function] 9 17 + [\[] 18 19 + [obj] 19 22 + [,] 22 23 + [c] 24 25 + [,] 25 26 + [t] 26 27 + [,] 27 28 + [s] 29 30 + [\]] 31 32 + [=] 33 34 + [Classification] 35 49 + [(] 49 50 + [obj] 51 54 + [,] 54 55 + [m] 55 56 + [,] 56 57 + [t] 57 58 + [,] 58 59 + [cm] 60 62 + [)] 63 64 +L4 + [end] 9 12 +L5 + [end] 5 8 +L6 + [end] 1 4 +EOF diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/doubleQuotedStrings.m b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/doubleQuotedStrings.m new file mode 100644 index 0000000000..309b0f091e --- /dev/null +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/doubleQuotedStrings.m @@ -0,0 +1 @@ +error("This is a double-quoted string"); \ No newline at end of file diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/doubleQuotedStrings.txt b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/doubleQuotedStrings.txt new file mode 100644 index 0000000000..2d6e7e1bd1 --- /dev/null +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/doubleQuotedStrings.txt @@ -0,0 +1,8 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [error] 1 6 + [(] 6 7 + ["This is a double-quoted string"] 7 39 + [)] 39 40 + [;] 40 41 +EOF diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/multilineComments.m b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/multilineComments.m new file mode 100644 index 0000000000..c5e958c291 --- /dev/null +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/multilineComments.m @@ -0,0 +1,12 @@ +%{ + Name: helloworld.m + + Purpose: Say "Hello World!" in two different ways +%} + +% Do it the good ol' fashioned way...command window +disp('Hello World!'); + +% +% Do it the new hip GUI way...with a message box +msgbox('Hello World!','Hello World!'); \ No newline at end of file diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/multilineComments.txt b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/multilineComments.txt new file mode 100644 index 0000000000..3513e6dc37 --- /dev/null +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/multilineComments.txt @@ -0,0 +1,16 @@ + [Image] or [Truncated image[ Bcol Ecol +L8 + [disp] 1 5 + [(] 5 6 + ['Hello World!'] 6 20 + [)] 20 21 + [;] 21 22 +L12 + [msgbox] 1 7 + [(] 7 8 + ['Hello World!'] 8 22 + [,] 22 23 + ['Hello World!'] 23 37 + [)] 37 38 + [;] 38 39 +EOF diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/questionMark.m b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/questionMark.m new file mode 100644 index 0000000000..5a9fdc4665 --- /dev/null +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/questionMark.m @@ -0,0 +1,2 @@ +classdef Class1 +properties (SetAccess = ?Class2) \ No newline at end of file diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/questionMark.txt b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/questionMark.txt new file mode 100644 index 0000000000..73262e0dc9 --- /dev/null +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/questionMark.txt @@ -0,0 +1,13 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [classdef] 1 9 + [Class1] 10 16 +L2 + [properties] 1 11 + [(] 12 13 + [SetAccess] 13 22 + [=] 23 24 + [?] 25 26 + [Class2] 26 32 + [)] 32 33 +EOF diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/cpd/sample-matlab.m b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.m similarity index 100% rename from pmd-matlab/src/test/resources/net/sourceforge/pmd/cpd/sample-matlab.m rename to pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.m diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.txt b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.txt new file mode 100644 index 0000000000..0c9d927a13 --- /dev/null +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.txt @@ -0,0 +1,4434 @@ + [Image] or [Truncated image[ Bcol Ecol +L4 + [classdef] 1 9 + [chebfun] 10 17 +L134 + [properties] 5 15 + [(] 16 17 + [Access] 17 23 + [=] 24 25 + [public] 26 32 + [)] 32 33 +L142 + [domain] 9 15 +L149 + [funs] 9 13 +L152 + [pointValues] 9 20 + [=] 21 22 + [\[] 23 24 + [\]] 24 25 + [;] 25 26 +L161 + [isTransposed] 9 21 + [=] 22 23 + [0] 24 25 + [;] 25 26 +L162 + [end] 5 8 +L167 + [methods] 5 12 + [(] 13 14 + [Access] 15 21 + [=] 22 23 + [public] 24 30 + [,] 30 31 + [Static] 32 38 + [=] 39 40 + [false] 41 46 + [)] 47 48 +L169 + [function] 9 17 + [f] 18 19 + [=] 20 21 + [chebfun] 22 29 + [(] 29 30 + [varargin] 30 38 + [)] 38 39 +L173 + [if] 13 15 + [(] 16 17 + [(] 18 19 + [nargin] 19 25 + [==] 26 28 + [0] 29 30 + [)] 30 31 + [||] 32 34 + [isempty] 35 42 + [(] 42 43 + [varargin] 43 51 + [{] 51 52 + [1] 52 53 + [}] 53 54 + [)] 54 55 + [)] 56 57 +L174 + [return] 17 23 +L175 + [end] 13 16 +L177 + [if] 13 15 + [(] 16 17 + [iscell] 18 24 + [(] 24 25 + [varargin] 25 33 + [{] 33 34 + [1] 34 35 + [}] 35 36 + [)] 36 37 + [&&] 38 40 + [.] 41 42 + [.] 42 43 + [.] 43 44 +L178 + [all] 21 24 + [(] 24 25 + [cellfun] 25 32 + [(] 32 33 + [@] 33 34 + [(] 34 35 + [x] 35 36 + [)] 36 37 + [isa] 38 41 + [(] 41 42 + [x] 42 43 + [,] 43 44 + ['fun'] 45 50 + [)] 50 51 + [,] 51 52 + [varargin] 54 62 + [{] 62 63 + [1] 63 64 + [}] 64 65 + [)] 65 66 + [)] 66 67 + [)] 68 69 +L182 + [if] 17 19 + [(] 20 21 + [nargin] 22 28 + [>] 29 30 + [1] 31 32 + [)] 33 34 +L183 + [error] 21 26 + [(] 26 27 + ['CHEBFUN:CHEBFUN:chebfun:nargin'] 27 59 + [,] 59 60 + [.] 61 62 + [.] 62 63 + [.] 63 64 +L184 + ['Only one input is allowed when pa[ 22 80 + [)] 80 81 +L185 + [end] 17 20 +L187 + [f] 17 18 + [.] 18 19 + [funs] 19 23 + [=] 24 25 + [varargin] 26 34 + [{] 34 35 + [1] 35 36 + [}] 36 37 + [;] 37 38 +L189 + [dom] 17 20 + [=] 21 22 + [cellfun] 23 30 + [(] 30 31 + [@] 31 32 + [(] 32 33 + [fun] 33 36 + [)] 36 37 + [get] 38 41 + [(] 41 42 + [fun] 42 45 + [,] 45 46 + ['domain'] 47 55 + [)] 55 56 + [,] 56 57 + [f] 58 59 + [.] 59 60 + [funs] 60 64 + [,] 64 65 + [.] 66 67 + [.] 67 68 + [.] 68 69 +L190 + ['uniformOutput'] 21 36 + [,] 36 37 + [false] 38 43 + [)] 43 44 + [;] 44 45 +L191 + [f] 17 18 + [.] 18 19 + [domain] 19 25 + [=] 26 27 + [unique] 28 34 + [(] 34 35 + [\[] 35 36 + [dom] 36 39 + [{] 39 40 + [:] 40 41 + [}] 41 42 + [\]] 42 43 + [)] 43 44 + [;] 44 45 +L193 + [f] 17 18 + [.] 18 19 + [pointValues] 19 30 + [=] 31 32 + [chebfun] 33 40 + [.] 40 41 + [getValuesAtBreakpoints] 41 63 + [(] 63 64 + [f] 64 65 + [.] 65 66 + [funs] 66 70 + [,] 70 71 + [f] 72 73 + [.] 73 74 + [domain] 74 80 + [)] 80 81 + [;] 81 82 +L194 + [return] 17 23 +L195 + [end] 13 16 +L198 + [\[] 13 14 + [op] 14 16 + [,] 16 17 + [dom] 18 21 + [,] 21 22 + [data] 23 27 + [,] 27 28 + [pref] 29 33 + [\]] 33 34 + [=] 35 36 + [parseInputs] 37 48 + [(] 48 49 + [varargin] 49 57 + [{] 57 58 + [:] 58 59 + [}] 59 60 + [)] 60 61 + [;] 61 62 +L200 + [if] 13 15 + [(] 16 17 + [strcmp] 18 24 + [(] 24 25 + [op] 25 27 + [,] 27 28 + ['done'] 29 35 + [)] 35 36 + [)] 37 38 +L202 + [throwAsCaller] 17 30 + [(] 30 31 + [MException] 31 41 + [(] 41 42 + [''] 42 44 + [,] 44 45 + [''] 46 48 + [)] 48 49 + [)] 49 50 +L203 + [end] 13 16 +L206 + [doTrunc] 13 20 + [=] 21 22 + [false] 23 28 + [;] 28 29 +L207 + [truncLength] 13 24 + [=] 25 26 + [NaN] 27 30 + [;] 30 31 +L208 + [for] 13 16 + [k] 17 18 + [=] 19 20 + [1] 21 22 + [:] 22 23 + [length] 23 29 + [(] 29 30 + [varargin] 30 38 + [)] 38 39 +L209 + [if] 17 19 + [(] 20 21 + [strcmpi] 22 29 + [(] 29 30 + [varargin] 30 38 + [{] 38 39 + [k] 39 40 + [}] 40 41 + [,] 41 42 + ['trunc'] 43 50 + [)] 50 51 + [)] 52 53 +L210 + [doTrunc] 21 28 + [=] 29 30 + [true] 31 35 + [;] 35 36 +L211 + [truncLength] 21 32 + [=] 33 34 + [varargin] 35 43 + [{] 43 44 + [k] 44 45 + [+] 45 46 + [1] 46 47 + [}] 47 48 + [;] 48 49 +L212 + [break] 21 26 +L213 + [end] 17 20 +L214 + [end] 13 16 +L216 + [if] 13 15 + [(] 16 17 + [isa] 18 21 + [(] 21 22 + [op] 22 24 + [,] 24 25 + ['chebfun'] 26 35 + [)] 35 36 + [&&] 37 39 + [doTrunc] 40 47 + [)] 48 49 +L219 + [f] 17 18 + [=] 19 20 + [op] 21 23 + [;] 23 24 +L221 + [else] 13 17 +L225 + [\[] 17 18 + [f] 18 19 + [.] 19 20 + [funs] 20 24 + [,] 24 25 + [f] 26 27 + [.] 27 28 + [domain] 28 34 + [\]] 34 35 + [=] 36 37 + [chebfun] 38 45 + [.] 45 46 + [constructor] 46 57 + [(] 57 58 + [op] 58 60 + [,] 60 61 + [dom] 62 65 + [,] 65 66 + [data] 67 71 + [,] 71 72 + [pref] 73 77 + [)] 77 78 + [;] 78 79 +L228 + [f] 17 18 + [.] 18 19 + [pointValues] 19 30 + [=] 31 32 + [chebfun] 33 40 + [.] 40 41 + [getValuesAtBreakpoints] 41 63 + [(] 63 64 + [f] 64 65 + [.] 65 66 + [funs] 66 70 + [,] 70 71 + [.] 72 73 + [.] 73 74 + [.] 74 75 +L229 + [f] 21 22 + [.] 22 23 + [domain] 23 29 + [,] 29 30 + [op] 31 33 + [)] 33 34 + [;] 34 35 +L232 + [\[] 17 18 + [ignored] 18 25 + [,] 25 26 + [index] 27 32 + [\]] 32 33 + [=] 34 35 + [setdiff] 36 43 + [(] 43 44 + [f] 44 45 + [.] 45 46 + [domain] 46 52 + [,] 52 53 + [dom] 54 57 + [)] 57 58 + [;] 58 59 +L233 + [f] 17 18 + [=] 19 20 + [merge] 21 26 + [(] 26 27 + [f] 27 28 + [,] 28 29 + [index] 30 35 + [(] 35 36 + [:] 36 37 + [)] 37 38 + [.'] 38 40 + [,] 40 41 + [pref] 42 46 + [)] 46 47 + [;] 47 48 +L235 + [end] 13 16 +L237 + [if] 13 15 + [(] 16 17 + [doTrunc] 18 25 + [)] 26 27 +L239 + [if] 17 19 + [(] 20 21 + [isa] 22 25 + [(] 25 26 + [pref] 27 31 + [.] 31 32 + [tech] 32 36 + [(] 36 37 + [)] 37 38 + [,] 38 39 + ['chebtech'] 39 49 + [)] 50 51 + [)] 52 53 +L240 + [c] 21 22 + [=] 23 24 + [chebcoeffs] 25 35 + [(] 35 36 + [f] 36 37 + [,] 37 38 + [truncLength] 39 50 + [)] 50 51 + [;] 51 52 +L241 + [else] 17 21 +L242 + [c] 21 22 + [=] 23 24 + [trigcoeffs] 25 35 + [(] 35 36 + [f] 36 37 + [,] 37 38 + [truncLength] 39 50 + [)] 50 51 + [;] 51 52 +L243 + [end] 17 20 +L244 + [f] 17 18 + [=] 19 20 + [chebfun] 21 28 + [(] 28 29 + [c] 29 30 + [,] 30 31 + [f] 32 33 + [.] 33 34 + [domain] 34 40 + [(] 40 41 + [\[] 41 42 + [1] 42 43 + [,] 43 44 + [end] 44 47 + [\]] 47 48 + [)] 48 49 + [,] 49 50 + ['coeffs'] 51 59 + [,] 59 60 + [pref] 61 65 + [)] 65 66 + [;] 66 67 +L245 + [end] 13 16 +L247 + [end] 9 12 +L249 + [end] 5 8 +L254 + [methods] 5 12 + [(] 13 14 + [Access] 15 21 + [=] 22 23 + [public] 24 30 + [,] 30 31 + [Static] 32 38 + [=] 39 40 + [false] 41 46 + [)] 47 48 +L257 + [f] 9 10 + [=] 11 12 + [abs] 13 16 + [(] 16 17 + [f] 17 18 + [,] 18 19 + [pref] 20 24 + [)] 24 25 +L260 + [a] 9 10 + [=] 11 12 + [any] 13 16 + [(] 16 17 + [f] 17 18 + [,] 18 19 + [dim] 20 23 + [)] 23 24 +L263 + [out] 9 12 + [=] 13 14 + [arcLength] 15 24 + [(] 24 25 + [f] 25 26 + [,] 26 27 + [a] 28 29 + [,] 29 30 + [b] 31 32 + [)] 32 33 +L266 + [\[] 9 10 + [y] 10 11 + [,] 11 12 + [t] 13 14 + [\]] 14 15 + [=] 16 17 + [bvp4c] 18 23 + [(] 23 24 + [fun1] 24 28 + [,] 28 29 + [fun2] 30 34 + [,] 34 35 + [y0] 36 38 + [,] 38 39 + [varargin] 40 48 + [)] 48 49 + [;] 49 50 +L269 + [\[] 9 10 + [y] 10 11 + [,] 11 12 + [t] 13 14 + [\]] 14 15 + [=] 16 17 + [bvp5c] 18 23 + [(] 23 24 + [fun1] 24 28 + [,] 28 29 + [fun2] 30 34 + [,] 34 35 + [y0] 36 38 + [,] 38 39 + [varargin] 40 48 + [)] 48 49 + [;] 49 50 +L272 + [g] 9 10 + [=] 11 12 + [ceil] 13 17 + [(] 17 18 + [f] 18 19 + [)] 19 20 +L275 + [h] 9 10 + [=] 11 12 + [plotcoeffs] 13 23 + [(] 23 24 + [f] 24 25 + [,] 25 26 + [varargin] 27 35 + [)] 35 36 + [;] 36 37 +L278 + [C] 9 10 + [=] 11 12 + [complex] 13 20 + [(] 20 21 + [A] 21 22 + [,] 22 23 + [B] 24 25 + [)] 25 26 +L281 + [h] 9 10 + [=] 11 12 + [compose] 13 20 + [(] 20 21 + [f] 21 22 + [,] 22 23 + [op] 24 26 + [,] 26 27 + [g] 28 29 + [,] 29 30 + [pref] 31 35 + [)] 35 36 +L284 + [f] 9 10 + [=] 11 12 + [conj] 13 17 + [(] 17 18 + [f] 18 19 + [)] 19 20 +L287 + [f] 9 10 + [=] 11 12 + [ctranspose] 13 23 + [(] 23 24 + [f] 24 25 + [)] 25 26 +L290 + [display] 9 16 + [(] 16 17 + [f] 17 18 + [)] 18 19 + [;] 19 20 +L293 + [out] 9 12 + [=] 13 14 + [epslevel] 15 23 + [(] 23 24 + [f] 24 25 + [,] 25 26 + [flag] 27 31 + [)] 31 32 + [;] 32 33 +L296 + [y] 9 10 + [=] 11 12 + [feval] 13 18 + [(] 18 19 + [f] 19 20 + [,] 20 21 + [x] 22 23 + [,] 23 24 + [varargin] 25 33 + [)] 33 34 +L299 + [g] 9 10 + [=] 11 12 + [fix] 13 16 + [(] 16 17 + [f] 17 18 + [)] 18 19 + [;] 19 20 +L302 + [g] 9 10 + [=] 11 12 + [floor] 13 18 + [(] 18 19 + [f] 19 20 + [)] 20 21 + [;] 21 22 +L305 + [out] 9 12 + [=] 13 14 + [get] 15 18 + [(] 18 19 + [f] 19 20 + [,] 20 21 + [prop] 22 26 + [,] 26 27 + [simpLevel] 28 37 + [)] 37 38 + [;] 38 39 +L308 + [out] 9 12 + [=] 13 14 + [hscale] 15 21 + [(] 21 22 + [f] 22 23 + [)] 23 24 + [;] 24 25 +L311 + [f] 9 10 + [=] 11 12 + [imag] 13 17 + [(] 17 18 + [f] 18 19 + [)] 19 20 +L314 + [out] 9 12 + [=] 13 14 + [isempty] 15 22 + [(] 22 23 + [f] 23 24 + [)] 24 25 +L317 + [out] 9 12 + [=] 13 14 + [isequal] 15 22 + [(] 22 23 + [f] 23 24 + [,] 24 25 + [g] 26 27 + [)] 27 28 +L320 + [out] 9 12 + [=] 13 14 + [isfinite] 15 23 + [(] 23 24 + [f] 24 25 + [)] 25 26 +L323 + [out] 9 12 + [=] 13 14 + [isinf] 15 20 + [(] 20 21 + [f] 21 22 + [)] 22 23 +L326 + [out] 9 12 + [=] 13 14 + [isnan] 15 20 + [(] 20 21 + [f] 21 22 + [)] 22 23 +L329 + [out] 9 12 + [=] 13 14 + [isreal] 15 21 + [(] 21 22 + [f] 22 23 + [)] 23 24 + [;] 24 25 +L332 + [out] 9 12 + [=] 13 14 + [isdelta] 15 22 + [(] 22 23 + [f] 23 24 + [)] 24 25 + [;] 25 26 +L335 + [out] 9 12 + [=] 13 14 + [issing] 15 21 + [(] 21 22 + [f] 22 23 + [)] 23 24 +L339 + [out] 9 12 + [=] 13 14 + [isPeriodicTech] 15 29 + [(] 29 30 + [f] 30 31 + [)] 31 32 +L342 + [out] 9 12 + [=] 13 14 + [iszero] 15 21 + [(] 21 22 + [f] 22 23 + [)] 23 24 +L345 + [out] 9 12 + [=] 13 14 + [kron] 15 19 + [(] 19 20 + [f] 20 21 + [,] 21 22 + [g] 23 24 + [)] 24 25 +L348 + [\[] 9 10 + [out] 10 13 + [,] 13 14 + [out2] 15 19 + [\]] 19 20 + [=] 21 22 + [length] 23 29 + [(] 29 30 + [f] 30 31 + [)] 31 32 + [;] 32 33 +L351 + [c_leg] 9 14 + [=] 15 16 + [legpoly] 17 24 + [(] 24 25 + [f] 25 26 + [,] 26 27 + [n] 28 29 + [)] 29 30 +L354 + [h] 9 10 + [=] 11 12 + [loglog] 13 19 + [(] 19 20 + [f] 20 21 + [,] 21 22 + [varargin] 23 31 + [)] 31 32 + [;] 32 33 +L357 + [f] 9 10 + [=] 11 12 + [minus] 13 18 + [(] 18 19 + [f] 19 20 + [,] 20 21 + [g] 22 23 + [)] 23 24 +L360 + [f] 9 10 + [=] 11 12 + [mtimes] 13 19 + [(] 19 20 + [f] 20 21 + [,] 21 22 + [c] 23 24 + [)] 24 25 +L363 + [\[] 9 10 + [f] 10 11 + [,] 11 12 + [mergedPts] 13 22 + [\]] 22 23 + [=] 24 25 + [merge] 26 31 + [(] 31 32 + [f] 32 33 + [,] 33 34 + [index] 35 40 + [,] 40 41 + [pref] 42 46 + [)] 46 47 +L366 + [\[] 9 10 + [f] 10 11 + [,] 11 12 + [g] 13 14 + [\]] 14 15 + [=] 16 17 + [overlap] 18 25 + [(] 25 26 + [f] 26 27 + [,] 27 28 + [g] 29 30 + [)] 30 31 +L369 + [varargout] 9 18 + [=] 19 20 + [plot] 21 25 + [(] 25 26 + [f] 26 27 + [,] 27 28 + [varargin] 29 37 + [)] 37 38 + [;] 38 39 +L372 + [varargout] 9 18 + [=] 19 20 + [plot3] 21 26 + [(] 26 27 + [f] 27 28 + [,] 28 29 + [g] 30 31 + [,] 31 32 + [h] 33 34 + [,] 34 35 + [varargin] 36 44 + [)] 44 45 +L375 + [f] 9 10 + [=] 11 12 + [power] 13 18 + [(] 18 19 + [f] 19 20 + [,] 20 21 + [b] 22 23 + [,] 23 24 + [pref] 25 29 + [)] 29 30 + [;] 30 31 +L378 + [f] 9 10 + [=] 11 12 + [real] 13 17 + [(] 17 18 + [f] 18 19 + [)] 19 20 +L381 + [f] 9 10 + [=] 11 12 + [restrict] 13 21 + [(] 21 22 + [f] 22 23 + [,] 23 24 + [newDomain] 25 34 + [)] 34 35 + [;] 35 36 +L384 + [r] 9 10 + [=] 11 12 + [roots] 13 18 + [(] 18 19 + [f] 19 20 + [,] 20 21 + [varargin] 22 30 + [)] 30 31 + [;] 31 32 +L387 + [g] 9 10 + [=] 11 12 + [round] 13 18 + [(] 18 19 + [f] 19 20 + [)] 20 21 +L390 + [h] 9 10 + [=] 11 12 + [semilogx] 13 21 + [(] 21 22 + [f] 22 23 + [,] 23 24 + [varargin] 25 33 + [)] 33 34 + [;] 34 35 +L393 + [h] 9 10 + [=] 11 12 + [semilogy] 13 21 + [(] 21 22 + [f] 22 23 + [,] 23 24 + [varargin] 25 33 + [)] 33 34 + [;] 34 35 +L396 + [f] 9 10 + [=] 11 12 + [sign] 13 17 + [(] 17 18 + [f] 18 19 + [,] 19 20 + [pref] 21 25 + [)] 25 26 +L399 + [f] 9 10 + [=] 11 12 + [simplify] 13 21 + [(] 21 22 + [f] 22 23 + [,] 23 24 + [tol] 25 28 + [)] 28 29 + [;] 29 30 +L402 + [\[] 9 10 + [s1] 10 12 + [,] 12 13 + [s2] 14 16 + [\]] 16 17 + [=] 18 19 + [size] 20 24 + [(] 24 25 + [f] 25 26 + [,] 26 27 + [dim] 28 31 + [)] 31 32 + [;] 32 33 +L405 + [f] 9 10 + [=] 11 12 + [sqrt] 13 17 + [(] 17 18 + [f] 18 19 + [,] 19 20 + [pref] 21 25 + [)] 25 26 +L408 + [varargout] 9 18 + [=] 19 20 + [subsref] 21 28 + [(] 28 29 + [f] 29 30 + [,] 30 31 + [index] 32 37 + [)] 37 38 + [;] 38 39 +L411 + [varargout] 9 18 + [=] 19 20 + [subsasgn] 21 29 + [(] 29 30 + [f] 30 31 + [,] 31 32 + [varargin] 33 41 + [)] 41 42 + [;] 42 43 +L414 + [f] 9 10 + [=] 11 12 + [times] 13 18 + [(] 18 19 + [f] 19 20 + [,] 20 21 + [g] 22 23 + [,] 23 24 + [varargin] 25 33 + [)] 33 34 +L417 + [f] 9 10 + [=] 11 12 + [transpose] 13 22 + [(] 22 23 + [f] 23 24 + [)] 24 25 +L420 + [f] 9 10 + [=] 11 12 + [uminus] 13 19 + [(] 19 20 + [f] 20 21 + [)] 21 22 +L423 + [f] 9 10 + [=] 11 12 + [uplus] 13 18 + [(] 18 19 + [f] 19 20 + [)] 20 21 +L426 + [out] 9 12 + [=] 13 14 + [vscale] 15 21 + [(] 21 22 + [f] 22 23 + [,] 23 24 + [s] 25 26 + [)] 26 27 + [;] 27 28 +L427 + [end] 5 8 +L432 + [methods] 5 12 + [(] 13 14 + [Hidden] 15 21 + [=] 22 23 + [true] 24 28 + [,] 28 29 + [Static] 30 36 + [=] 37 38 + [false] 39 44 + [)] 45 46 +L435 + [f] 9 10 + [=] 11 12 + [addBreaks] 13 22 + [(] 22 23 + [f] 23 24 + [,] 24 25 + [breaks] 26 32 + [,] 32 33 + [tol] 34 37 + [)] 37 38 +L438 + [f] 9 10 + [=] 11 12 + [addBreaksAtRoots] 13 29 + [(] 29 30 + [f] 30 31 + [,] 31 32 + [tol] 33 36 + [)] 36 37 +L441 + [f] 9 10 + [=] 11 12 + [assignColumns] 13 26 + [(] 26 27 + [f] 27 28 + [,] 28 29 + [colIdx] 30 36 + [,] 36 37 + [g] 38 39 + [)] 39 40 +L444 + [f] 9 10 + [=] 11 12 + [changeTech] 13 23 + [(] 23 24 + [f] 24 25 + [,] 25 26 + [newtech] 27 34 + [)] 34 35 + [;] 35 36 +L447 + [f] 9 10 + [=] 11 12 + [define] 13 19 + [(] 19 20 + [f] 20 21 + [,] 21 22 + [s] 22 23 + [,] 23 24 + [v] 24 25 + [)] 25 26 + [;] 26 27 +L450 + [f] 9 10 + [=] 11 12 + [defineInterval] 13 27 + [(] 27 28 + [f] 28 29 + [,] 29 30 + [subInt] 31 37 + [,] 37 38 + [g] 39 40 + [)] 40 41 +L453 + [f] 9 10 + [=] 11 12 + [definePoint] 13 24 + [(] 24 25 + [f] 25 26 + [,] 26 27 + [s] 28 29 + [,] 29 30 + [v] 31 32 + [)] 32 33 +L456 + [M] 9 10 + [=] 11 12 + [diag] 13 17 + [(] 17 18 + [f] 18 19 + [)] 19 20 +L459 + [\[] 9 10 + [name] 10 14 + [,] 14 15 + [data] 16 20 + [\]] 20 21 + [=] 22 23 + [dispData] 24 32 + [(] 32 33 + [f] 33 34 + [)] 34 35 +L462 + [pass] 9 13 + [=] 14 15 + [domainCheck] 16 27 + [(] 27 28 + [f] 28 29 + [,] 29 30 + [g] 31 32 + [)] 32 33 + [;] 33 34 +L465 + [f] 9 10 + [=] 11 12 + [extractColumns] 13 27 + [(] 27 28 + [f] 28 29 + [,] 29 30 + [columnIndex] 31 42 + [)] 42 43 + [;] 43 44 +L468 + [varargin] 9 17 + [=] 18 19 + [fzero] 20 25 + [(] 25 26 + [varargout] 26 35 + [)] 35 36 + [;] 36 37 +L471 + [\[] 9 10 + [deltaMag] 10 18 + [,] 18 19 + [deltLoc] 20 27 + [\]] 27 28 + [=] 29 30 + [getDeltaFunctions] 31 48 + [(] 48 49 + [f] 49 50 + [)] 50 51 + [;] 51 52 +L474 + [\[] 9 10 + [rBreaks] 10 17 + [,] 17 18 + [rAll] 19 23 + [\]] 23 24 + [=] 25 26 + [getRootsForBreaks] 27 44 + [(] 44 45 + [f] 45 46 + [,] 46 47 + [tol] 48 51 + [)] 51 52 +L477 + [out] 9 12 + [=] 13 14 + [isQuasi] 15 22 + [(] 22 23 + [f] 23 24 + [)] 24 25 +L480 + [out] 9 12 + [=] 13 14 + [numColumns] 15 25 + [(] 25 26 + [f] 26 27 + [)] 27 28 +L483 + [data] 9 13 + [=] 14 15 + [plotData] 16 24 + [(] 24 25 + [f] 25 26 + [,] 26 27 + [g] 28 29 + [,] 29 30 + [h] 31 32 + [)] 32 33 +L486 + [varargin] 9 17 + [=] 18 19 + [quad] 20 24 + [(] 24 25 + [varargout] 25 34 + [)] 34 35 + [;] 35 36 +L489 + [f] 9 10 + [=] 11 12 + [setPointValues] 13 27 + [(] 27 28 + [f] 28 29 + [,] 29 30 + [j] 31 32 + [,] 32 33 + [k] 34 35 + [,] 35 36 + [vals] 37 41 + [)] 41 42 +L492 + [f] 9 10 + [=] 11 12 + [tidyImpulses] 13 25 + [(] 25 26 + [f] 26 27 + [)] 27 28 +L495 + [\[] 9 10 + [f] 10 11 + [,] 11 12 + [g] 13 14 + [,] 14 15 + [newBreaksLocF] 16 29 + [,] 29 30 + [newBreaksLocG] 31 44 + [\]] 44 45 + [=] 46 47 + [tweakDomain] 48 59 + [(] 59 60 + [f] 60 61 + [,] 61 62 + [g] 63 64 + [,] 64 65 + [tol] 66 69 + [,] 69 70 + [pos] 71 74 + [)] 74 75 +L497 + [end] 5 8 +L502 + [methods] 5 12 + [(] 13 14 + [Access] 15 21 + [=] 22 23 + [private] 24 31 + [,] 31 32 + [Static] 33 39 + [=] 40 41 + [false] 42 47 + [)] 48 49 +L504 + [f] 9 10 + [=] 11 12 + [thresholdBreakpointValues] 13 38 + [(] 38 39 + [f] 39 40 + [)] 40 41 + [;] 41 42 +L505 + [end] 5 8 +L511 + [methods] 5 12 + [(] 13 14 + [Access] 15 21 + [=] 22 23 + [public] 24 30 + [,] 30 31 + [Static] 32 38 + [=] 39 40 + [true] 41 45 + [)] 46 47 +L514 + [y] 9 10 + [=] 11 12 + [dct] 13 16 + [(] 16 17 + [u] 17 18 + [,] 18 19 + [kind] 20 24 + [)] 24 25 + [;] 25 26 +L517 + [u] 9 10 + [=] 11 12 + [idct] 13 17 + [(] 17 18 + [y] 18 19 + [,] 19 20 + [kind] 21 25 + [)] 25 26 + [;] 26 27 +L520 + [y] 9 10 + [=] 11 12 + [dst] 13 16 + [(] 16 17 + [u] 17 18 + [,] 18 19 + [kind] 20 24 + [)] 24 25 + [;] 25 26 +L523 + [u] 9 10 + [=] 11 12 + [idst] 13 17 + [(] 17 18 + [y] 18 19 + [,] 19 20 + [kind] 21 25 + [)] 25 26 + [;] 26 27 +L526 + [f] 9 10 + [=] 11 12 + [interp1] 13 20 + [(] 20 21 + [x] 21 22 + [,] 22 23 + [y] 24 25 + [,] 25 26 + [method] 27 33 + [,] 33 34 + [dom] 35 38 + [)] 38 39 + [;] 39 40 +L529 + [f] 9 10 + [=] 11 12 + [lagrange] 13 21 + [(] 21 22 + [x] 22 23 + [,] 23 24 + [varargin] 25 33 + [)] 33 34 + [;] 34 35 +L532 + [\[] 9 10 + [t] 10 11 + [,] 11 12 + [y] 13 14 + [\]] 14 15 + [=] 16 17 + [ode113] 18 24 + [(] 24 25 + [varargin] 25 33 + [)] 33 34 + [;] 34 35 +L535 + [\[] 9 10 + [t] 10 11 + [,] 11 12 + [y] 13 14 + [\]] 14 15 + [=] 16 17 + [ode15s] 18 24 + [(] 24 25 + [varargin] 25 33 + [)] 33 34 + [;] 34 35 +L538 + [\[] 9 10 + [t] 10 11 + [,] 11 12 + [y] 13 14 + [\]] 14 15 + [=] 16 17 + [ode45] 18 23 + [(] 23 24 + [varargin] 24 32 + [)] 32 33 + [;] 33 34 +L541 + [f] 9 10 + [=] 11 12 + [pchip] 13 18 + [(] 18 19 + [x] 19 20 + [,] 20 21 + [y] 22 23 + [,] 23 24 + [method] 25 31 + [)] 31 32 + [;] 32 33 +L544 + [f] 9 10 + [=] 11 12 + [spline] 13 19 + [(] 19 20 + [x] 20 21 + [,] 21 22 + [y] 23 24 + [,] 24 25 + [d] 26 27 + [)] 27 28 + [;] 28 29 +L547 + [update] 9 15 + [(] 15 16 + [varargin] 16 24 + [)] 24 25 +L549 + [end] 5 8 +L554 + [methods] 5 12 + [(] 13 14 + [Hidden] 15 21 + [=] 22 23 + [true] 24 28 + [,] 28 29 + [Static] 30 36 + [=] 37 38 + [true] 39 43 + [)] 44 45 +L557 + [G] 9 10 + [=] 11 12 + [cell2quasi] 13 23 + [(] 23 24 + [F] 24 25 + [)] 25 26 +L560 + [vals] 9 13 + [=] 14 15 + [getValuesAtBreakpoints] 16 38 + [(] 38 39 + [funs] 39 43 + [,] 43 44 + [ends] 45 49 + [,] 49 50 + [op] 51 53 + [)] 53 54 + [;] 54 55 +L563 + [out] 9 12 + [=] 13 14 + [whichInterval] 15 28 + [(] 28 29 + [dom] 29 32 + [,] 32 33 + [x] 34 35 + [,] 35 36 + [direction] 37 46 + [)] 46 47 + [;] 47 48 +L565 + [end] 5 8 +L570 + [methods] 5 12 + [(] 13 14 + [Access] 15 21 + [=] 22 23 + [private] 24 31 + [,] 31 32 + [Static] 33 39 + [=] 40 41 + [true] 42 46 + [)] 47 48 +L573 + [\[] 9 10 + [funs] 10 14 + [,] 14 15 + [ends] 16 20 + [\]] 20 21 + [=] 22 23 + [constructor] 24 35 + [(] 35 36 + [op] 36 38 + [,] 38 39 + [domain] 40 46 + [,] 46 47 + [data] 48 52 + [,] 52 53 + [pref] 54 58 + [)] 58 59 + [;] 59 60 +L576 + [\[] 9 10 + [y] 10 11 + [,] 11 12 + [t] 13 14 + [\]] 14 15 + [=] 16 17 + [odesol] 18 24 + [(] 24 25 + [sol] 25 28 + [,] 28 29 + [dom] 30 33 + [,] 33 34 + [opt] 35 38 + [)] 38 39 + [;] 39 40 +L579 + [\[] 9 10 + [lineStyle] 10 19 + [,] 19 20 + [pointStyle] 21 31 + [,] 31 32 + [jumpStyle] 33 42 + [,] 42 43 + [deltaStyle] 44 54 + [,] 54 55 + [out] 56 59 + [\]] 59 60 + [=] 61 62 + [.] 63 64 + [.] 64 65 + [.] 65 66 +L580 + [parsePlotStyle] 13 27 + [(] 27 28 + [varargin] 28 36 + [)] 36 37 +L582 + [end] 5 8 +L584 + [end] 1 4 +L590 + [function] 1 9 + [op] 10 12 + [=] 13 14 + [str2op] 15 21 + [(] 21 22 + [op] 22 24 + [)] 24 25 +L592 + [sop] 5 8 + [=] 9 10 + [str2num] 11 18 + [(] 18 19 + [op] 19 21 + [)] 21 22 + [;] 22 23 +L593 + [if] 5 7 + [(] 8 9 + [~] 10 11 + [isempty] 11 18 + [(] 18 19 + [sop] 19 22 + [)] 22 23 + [)] 24 25 +L594 + [op] 9 11 + [=] 12 13 + [sop] 14 17 + [;] 17 18 +L595 + [else] 5 9 +L596 + [depVar] 9 15 + [=] 16 17 + [symvar] 18 24 + [(] 24 25 + [op] 25 27 + [)] 27 28 + [;] 28 29 +L597 + [if] 9 11 + [(] 12 13 + [numel] 14 19 + [(] 19 20 + [depVar] 20 26 + [)] 26 27 + [~=] 28 30 + [1] 31 32 + [)] 33 34 +L598 + [error] 13 18 + [(] 18 19 + ['CHEBFUN:CHEBFUN:str2op:indepvars'] 19 53 + [,] 53 54 + [.] 55 56 + [.] 56 57 + [.] 57 58 +L599 + ['Incorrect number of independent v[ 17 77 + [)] 77 78 + [;] 78 79 +L600 + [end] 9 12 +L601 + [op] 9 11 + [=] 12 13 + [eval] 14 18 + [(] 18 19 + [\[] 19 20 + ['@('] 20 24 + [depVar] 25 31 + [{] 31 32 + [:] 32 33 + [}] 33 34 + [')'] 35 38 + [,] 38 39 + [op] 40 42 + [\]] 42 43 + [)] 43 44 + [;] 44 45 +L602 + [end] 5 8 +L603 + [end] 1 4 +L605 + [function] 1 9 + [\[] 10 11 + [op] 11 13 + [,] 13 14 + [dom] 15 18 + [,] 18 19 + [data] 20 24 + [,] 24 25 + [pref] 26 30 + [\]] 30 31 + [=] 32 33 + [parseInputs] 34 45 + [(] 45 46 + [op] 46 48 + [,] 48 49 + [varargin] 50 58 + [)] 58 59 +L612 + [if] 5 7 + [(] 8 9 + [strncmp] 10 17 + [(] 17 18 + [op] 18 20 + [,] 20 21 + ['--'] 22 26 + [,] 26 27 + [2] 28 29 + [)] 29 30 + [)] 31 32 +L614 + [if] 9 11 + [(] 12 13 + [strcmpi] 14 21 + [(] 21 22 + [op] 22 24 + [,] 24 25 + ['--update'] 26 36 + [)] 36 37 + [)] 38 39 +L615 + [chebfun] 13 20 + [.] 20 21 + [update] 21 27 + [(] 27 28 + [)] 28 29 + [;] 29 30 +L616 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [op] 26 28 + [,] 28 29 + ['--update-devel'] 30 46 + [)] 46 47 + [)] 48 49 +L617 + [chebfun] 13 20 + [.] 20 21 + [update] 21 27 + [(] 27 28 + ['development'] 28 41 + [)] 41 42 + [;] 42 43 +L618 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [op] 26 28 + [,] 28 29 + ['--version'] 30 41 + [)] 41 42 + [)] 43 44 +L619 + [installDir] 13 23 + [=] 24 25 + [chebfunroot] 26 37 + [(] 37 38 + [)] 38 39 + [;] 39 40 +L620 + [fid] 13 16 + [=] 17 18 + [fopen] 19 24 + [(] 24 25 + [fullfile] 25 33 + [(] 33 34 + [installDir] 34 44 + [,] 44 45 + ['Contents.m'] 46 58 + [)] 58 59 + [,] 59 60 + ['r'] 61 64 + [)] 64 65 + [;] 65 66 +L621 + [fgetl] 13 18 + [(] 18 19 + [fid] 19 22 + [)] 22 23 + [;] 23 24 +L622 + [str] 13 16 + [=] 17 18 + [fgetl] 19 24 + [(] 24 25 + [fid] 25 28 + [)] 28 29 + [;] 29 30 +L623 + [disp] 13 17 + [(] 17 18 + [\[] 18 19 + ['Chebfun '] 19 29 + [,] 29 30 + [str] 31 34 + [(] 34 35 + [3] 35 36 + [:] 36 37 + [end] 37 40 + [)] 40 41 + [\]] 41 42 + [)] 42 43 + [;] 43 44 +L624 + [fclose] 13 19 + [(] 19 20 + [fid] 20 23 + [)] 23 24 + [;] 24 25 +L625 + [else] 9 13 +L626 + [error] 13 18 + [(] 18 19 + ['CHEBFUN:parseInputs:unknown'] 19 48 + [,] 48 49 + [.] 50 51 + [.] 51 52 + [.] 52 53 +L627 + ['Unknow command %s.'] 17 37 + [,] 37 38 + [op] 39 41 + [)] 41 42 + [;] 42 43 +L628 + [end] 9 12 +L629 + [op] 9 11 + [=] 12 13 + ['done'] 14 20 + [;] 20 21 +L630 + [dom] 9 12 + [=] 13 14 + [\[] 15 16 + [\]] 16 17 + [;] 17 18 +L631 + [data] 9 13 + [=] 14 15 + [struct] 16 22 + [(] 22 23 + [)] 23 24 + [;] 24 25 +L632 + [pref] 9 13 + [=] 14 15 + [\[] 16 17 + [\]] 17 18 + [;] 18 19 +L633 + [return] 9 15 +L634 + [end] 5 8 +L637 + [data] 5 9 + [.] 9 10 + [hscale] 10 16 + [=] 17 18 + [\[] 19 20 + [\]] 20 21 + [;] 21 22 +L638 + [data] 5 9 + [.] 9 10 + [vscale] 10 16 + [=] 17 18 + [\[] 19 20 + [\]] 20 21 + [;] 21 22 +L639 + [data] 5 9 + [.] 9 10 + [exponents] 10 19 + [=] 20 21 + [\[] 22 23 + [\]] 23 24 + [;] 24 25 +L640 + [data] 5 9 + [.] 9 10 + [singType] 10 18 + [=] 19 20 + [\[] 21 22 + [\]] 22 23 + [;] 23 24 +L642 + [args] 5 9 + [=] 10 11 + [varargin] 12 20 + [;] 20 21 +L645 + [if] 5 7 + [(] 8 9 + [nargin] 10 16 + [==] 17 19 + [1] 20 21 + [)] 22 23 +L646 + [pref] 9 13 + [=] 14 15 + [chebfunpref] 16 27 + [(] 27 28 + [)] 28 29 + [;] 29 30 +L647 + [end] 5 8 +L650 + [domainWasPassed] 5 20 + [=] 21 22 + [false] 23 28 + [;] 28 29 +L651 + [if] 5 7 + [(] 8 9 + [~] 10 11 + [isempty] 11 18 + [(] 18 19 + [args] 19 23 + [)] 23 24 + [)] 25 26 +L652 + [if] 9 11 + [(] 12 13 + [isnumeric] 14 23 + [(] 23 24 + [args] 24 28 + [{] 28 29 + [1] 29 30 + [}] 30 31 + [)] 31 32 + [&&] 33 35 + [.] 36 37 + [.] 37 38 + [.] 38 39 +L653 + [(] 17 18 + [(] 18 19 + [length] 19 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [)] 33 34 + [>=] 35 37 + [2] 38 39 + [)] 39 40 + [||] 41 43 + [isempty] 44 51 + [(] 51 52 + [args] 52 56 + [{] 56 57 + [1] 57 58 + [}] 58 59 + [)] 59 60 + [)] 60 61 + [)] 62 63 +L654 + [dom] 13 16 + [=] 17 18 + [args] 19 23 + [{] 23 24 + [1] 24 25 + [}] 25 26 + [;] 26 27 +L655 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [)] 19 20 + [=] 21 22 + [\[] 23 24 + [\]] 24 25 + [;] 25 26 +L656 + [domainWasPassed] 13 28 + [=] 29 30 + [true] 31 35 + [;] 35 36 +L657 + [elseif] 9 15 + [(] 16 17 + [isa] 18 21 + [(] 21 22 + [args] 22 26 + [{] 26 27 + [1] 27 28 + [}] 28 29 + [,] 29 30 + ['domain'] 31 39 + [)] 39 40 + [)] 41 42 +L658 + [dom] 13 16 + [=] 17 18 + [double] 19 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [)] 33 34 + [;] 34 35 +L659 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [)] 19 20 + [=] 21 22 + [\[] 23 24 + [\]] 24 25 + [;] 25 26 +L660 + [domainWasPassed] 13 28 + [=] 29 30 + [true] 31 35 + [;] 35 36 +L661 + [end] 9 12 +L662 + [end] 5 8 +L665 + [keywordPrefs] 5 17 + [=] 18 19 + [struct] 20 26 + [(] 26 27 + [)] 27 28 + [;] 28 29 +L668 + [prefWasPassed] 5 18 + [=] 19 20 + [false] 21 26 + [;] 26 27 +L669 + [isPeriodic] 5 15 + [=] 16 17 + [false] 18 23 + [;] 23 24 +L670 + [vectorize] 5 14 + [=] 15 16 + [false] 17 22 + [;] 22 23 +L671 + [doVectorCheck] 5 18 + [=] 19 20 + [true] 21 25 + [;] 25 26 +L672 + [while] 5 10 + [(] 11 12 + [~] 13 14 + [isempty] 14 21 + [(] 21 22 + [args] 22 26 + [)] 26 27 + [)] 28 29 +L673 + [if] 9 11 + [(] 12 13 + [isstruct] 14 22 + [(] 22 23 + [args] 23 27 + [{] 27 28 + [1] 28 29 + [}] 29 30 + [)] 30 31 + [||] 32 34 + [isa] 35 38 + [(] 38 39 + [args] 39 43 + [{] 43 44 + [1] 44 45 + [}] 45 46 + [,] 46 47 + ['chebfunpref'] 48 61 + [)] 61 62 + [)] 63 64 +L676 + [if] 13 15 + [(] 16 17 + [~] 18 19 + [prefWasPassed] 19 32 + [)] 33 34 +L677 + [pref] 17 21 + [=] 22 23 + [chebfunpref] 24 35 + [(] 35 36 + [args] 36 40 + [{] 40 41 + [1] 41 42 + [}] 42 43 + [)] 43 44 + [;] 44 45 +L678 + [prefWasPassed] 17 30 + [=] 31 32 + [true] 33 37 + [;] 37 38 +L679 + [args] 17 21 + [(] 21 22 + [1] 22 23 + [)] 23 24 + [=] 25 26 + [\[] 27 28 + [\]] 28 29 + [;] 29 30 +L680 + [else] 13 17 +L681 + [error] 17 22 + [(] 22 23 + ['CHEBFUN:CHEBFUN:parseInputs:twoPr[ 23 61 + [,] 61 62 + [.] 63 64 + [.] 64 65 + [.] 65 66 +L682 + ['Multiple preference inputs are no[ 21 66 + [)] 66 67 + [;] 67 68 +L683 + [end] 13 16 +L684 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['equi'] 35 41 + [)] 41 42 + [)] 43 44 +L686 + [keywordPrefs] 13 25 + [.] 25 26 + [tech] 26 30 + [=] 31 32 + ['funqui'] 33 41 + [;] 41 42 +L687 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [)] 19 20 + [=] 21 22 + [\[] 23 24 + [\]] 24 25 + [;] 25 26 +L688 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['vectorize'] 35 46 + [)] 46 47 + [||] 48 50 + [.] 51 52 + [.] 52 53 + [.] 53 54 +L689 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['vectorise'] 35 46 + [)] 46 47 + [)] 48 49 +L691 + [vectorize] 13 22 + [=] 23 24 + [true] 25 29 + [;] 29 30 +L692 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [)] 19 20 + [=] 21 22 + [\[] 23 24 + [\]] 24 25 + [;] 25 26 +L693 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['novectorcheck'] 35 50 + [)] 50 51 + [)] 52 53 +L695 + [doVectorCheck] 13 26 + [=] 27 28 + [false] 29 34 + [;] 34 35 +L696 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [)] 19 20 + [=] 21 22 + [\[] 23 24 + [\]] 24 25 + [;] 25 26 +L697 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['coeffs'] 35 43 + [)] 43 44 + [&&] 45 47 + [isnumeric] 48 57 + [(] 57 58 + [op] 58 60 + [)] 60 61 + [)] 62 63 +L699 + [op] 13 15 + [=] 16 17 + [{] 18 19 + [{] 19 20 + [\[] 20 21 + [\]] 21 22 + [,] 22 23 + [op] 24 26 + [}] 26 27 + [}] 27 28 + [;] 28 29 +L700 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [)] 19 20 + [=] 21 22 + [\[] 23 24 + [\]] 24 25 + [;] 25 26 +L701 + [elseif] 9 15 + [(] 16 17 + [any] 18 21 + [(] 21 22 + [strcmpi] 22 29 + [(] 29 30 + [args] 30 34 + [{] 34 35 + [1] 35 36 + [}] 36 37 + [,] 37 38 + [{] 39 40 + ['periodic'] 40 50 + [,] 50 51 + ['trig'] 52 58 + [}] 58 59 + [)] 59 60 + [)] 60 61 + [)] 62 63 +L702 + [isPeriodic] 13 23 + [=] 24 25 + [true] 26 30 + [;] 30 31 +L703 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [)] 19 20 + [=] 21 22 + [\[] 23 24 + [\]] 24 25 + [;] 25 26 +L704 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['coeffs'] 35 43 + [)] 43 44 + [&&] 45 47 + [iscell] 48 54 + [(] 54 55 + [op] 55 57 + [)] 57 58 + [)] 59 60 +L705 + [error] 13 18 + [(] 18 19 + ['CHEBFUN:CHEBFUN:parseInputs:coeff[ 19 58 + [,] 58 59 + [.] 60 61 + [.] 61 62 + [.] 62 63 +L706 + ['Cannot construct CHEBFUN from a c[ 17 78 + [)] 78 79 + [;] 79 80 +L707 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['trunc'] 35 42 + [)] 42 43 + [)] 44 45 +L709 + [keywordPrefs] 13 25 + [.] 25 26 + [splitting] 26 35 + [=] 36 37 + [true] 38 42 + [;] 42 43 +L710 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L711 + [elseif] 9 15 + [(] 16 17 + [isnumeric] 18 27 + [(] 27 28 + [args] 28 32 + [{] 32 33 + [1] 33 34 + [}] 34 35 + [)] 35 36 + [&&] 37 39 + [isscalar] 40 48 + [(] 48 49 + [args] 49 53 + [{] 53 54 + [1] 54 55 + [}] 55 56 + [)] 56 57 + [)] 58 59 +L713 + [keywordPrefs] 13 25 + [.] 25 26 + [techPrefs] 26 35 + [.] 35 36 + [fixedLength] 36 47 + [=] 48 49 + [args] 50 54 + [{] 54 55 + [1] 55 56 + [}] 56 57 + [;] 57 58 +L714 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [)] 19 20 + [=] 21 22 + [\[] 23 24 + [\]] 24 25 + [;] 25 26 +L715 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['splitting'] 35 46 + [)] 46 47 + [)] 48 49 +L716 + [keywordPrefs] 13 25 + [.] 25 26 + [splitting] 26 35 + [=] 36 37 + [strcmpi] 38 45 + [(] 45 46 + [args] 46 50 + [{] 50 51 + [2] 51 52 + [}] 52 53 + [,] 53 54 + ['on'] 55 59 + [)] 59 60 + [;] 60 61 +L717 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L718 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['minsamples'] 35 47 + [)] 47 48 + [)] 49 50 +L720 + [keywordPrefs] 13 25 + [.] 25 26 + [techPrefs] 26 35 + [.] 35 36 + [minSamples] 36 46 + [=] 47 48 + [args] 49 53 + [{] 53 54 + [2] 54 55 + [}] 55 56 + [;] 56 57 +L721 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L722 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['blowup'] 35 43 + [)] 43 44 + [)] 45 46 +L723 + [if] 13 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [2] 31 32 + [}] 32 33 + [,] 33 34 + ['off'] 35 40 + [)] 40 41 + [)] 42 43 +L725 + [keywordPrefs] 17 29 + [.] 29 30 + [blowup] 30 36 + [=] 37 38 + [0] 39 40 + [;] 40 41 +L726 + [else] 13 17 +L732 + [if] 17 19 + [(] 20 21 + [(] 22 23 + [isnumeric] 23 32 + [(] 32 33 + [args] 33 37 + [{] 37 38 + [2] 38 39 + [}] 39 40 + [)] 40 41 + [&&] 42 44 + [args] 45 49 + [{] 49 50 + [2] 50 51 + [}] 51 52 + [==] 53 55 + [1] 56 57 + [)] 58 59 + [||] 60 62 + [.] 63 64 + [.] 64 65 + [.] 65 66 +L733 + [strcmpi] 25 32 + [(] 32 33 + [args] 33 37 + [{] 37 38 + [2] 38 39 + [}] 39 40 + [,] 40 41 + ['on'] 42 46 + [)] 46 47 + [)] 48 49 +L736 + [keywordPrefs] 21 33 + [.] 33 34 + [blowup] 34 40 + [=] 41 42 + [1] 43 44 + [;] 44 45 +L737 + [data] 21 25 + [.] 25 26 + [singType] 26 34 + [=] 35 36 + [{] 37 38 + ['pole'] 38 44 + [}] 44 45 + [;] 45 46 +L738 + [elseif] 17 23 + [(] 24 25 + [args] 26 30 + [{] 30 31 + [2] 31 32 + [}] 32 33 + [==] 34 36 + [2] 37 38 + [)] 39 40 +L741 + [keywordPrefs] 21 33 + [.] 33 34 + [blowup] 34 40 + [=] 41 42 + [1] 43 44 + [;] 44 45 +L742 + [data] 21 25 + [.] 25 26 + [singType] 26 34 + [=] 35 36 + [{] 37 38 + ['sing'] 38 44 + [}] 44 45 + [;] 45 46 +L743 + [else] 17 21 +L744 + [error] 21 26 + [(] 26 27 + ['CHEBFUN:CHEBFUN:parseInputs:badBl[ 27 72 + [,] 72 73 + [.] 74 75 + [.] 75 76 + [.] 76 77 +L745 + ['Invalid value for ''blowup'' opti[ 25 63 + [)] 63 64 + [;] 64 65 +L746 + [end] 17 20 +L747 + [end] 13 16 +L748 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L749 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['vscale'] 35 43 + [)] 43 44 + [)] 45 46 +L751 + [data] 13 17 + [.] 17 18 + [vscale] 18 24 + [=] 25 26 + [args] 27 31 + [{] 31 32 + [2] 32 33 + [}] 33 34 + [;] 34 35 +L752 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L753 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['hscale'] 35 43 + [)] 43 44 + [)] 45 46 +L755 + [data] 13 17 + [.] 17 18 + [vscale] 18 24 + [=] 25 26 + [args] 27 31 + [{] 31 32 + [2] 32 33 + [}] 33 34 + [;] 34 35 +L756 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L757 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['singType'] 35 45 + [)] 45 46 + [)] 47 48 +L759 + [data] 13 17 + [.] 17 18 + [singType] 18 26 + [=] 27 28 + [args] 29 33 + [{] 33 34 + [2] 34 35 + [}] 35 36 + [;] 36 37 +L760 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L761 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['exps'] 35 41 + [)] 41 42 + [)] 43 44 +L763 + [data] 13 17 + [.] 17 18 + [exponents] 18 27 + [=] 28 29 + [args] 30 34 + [{] 34 35 + [2] 35 36 + [}] 36 37 + [;] 37 38 +L764 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L765 + [elseif] 9 15 + [(] 16 17 + [any] 18 21 + [(] 21 22 + [strcmpi] 22 29 + [(] 29 30 + [args] 30 34 + [{] 34 35 + [1] 35 36 + [}] 36 37 + [,] 37 38 + ['chebkind'] 39 49 + [)] 49 50 + [)] 50 51 + [)] 52 53 +L767 + [if] 13 15 + [(] 16 17 + [(] 18 19 + [isnumeric] 19 28 + [(] 28 29 + [args] 29 33 + [{] 33 34 + [2] 34 35 + [}] 35 36 + [)] 36 37 + [&&] 38 40 + [(] 41 42 + [args] 42 46 + [{] 46 47 + [2] 47 48 + [}] 48 49 + [==] 50 52 + [1] 53 54 + [)] 54 55 + [)] 55 56 + [||] 57 59 + [.] 60 61 + [.] 61 62 + [.] 62 63 +L768 + [(] 22 23 + [ischar] 23 29 + [(] 29 30 + [args] 30 34 + [{] 34 35 + [2] 35 36 + [}] 36 37 + [)] 37 38 + [&&] 39 41 + [strncmpi] 42 50 + [(] 50 51 + [args] 51 55 + [{] 55 56 + [2] 56 57 + [}] 57 58 + [,] 58 59 + ['1st'] 60 65 + [,] 65 66 + [1] 67 68 + [)] 68 69 + [)] 69 70 + [)] 71 72 +L769 + [keywordPrefs] 17 29 + [.] 29 30 + [tech] 30 34 + [=] 35 36 + [@] 37 38 + [chebtech1] 38 47 + [;] 47 48 +L770 + [elseif] 13 19 + [(] 20 21 + [(] 22 23 + [isnumeric] 23 32 + [(] 32 33 + [args] 33 37 + [{] 37 38 + [2] 38 39 + [}] 39 40 + [)] 40 41 + [&&] 42 44 + [(] 45 46 + [args] 46 50 + [{] 50 51 + [2] 51 52 + [}] 52 53 + [==] 54 56 + [2] 57 58 + [)] 58 59 + [)] 59 60 + [||] 61 63 + [.] 64 65 + [.] 65 66 + [.] 66 67 +L771 + [(] 22 23 + [ischar] 23 29 + [(] 29 30 + [args] 30 34 + [{] 34 35 + [2] 35 36 + [}] 36 37 + [)] 37 38 + [&&] 39 41 + [strncmpi] 42 50 + [(] 50 51 + [args] 51 55 + [{] 55 56 + [2] 56 57 + [}] 57 58 + [,] 58 59 + ['2nd'] 60 65 + [,] 65 66 + [1] 67 68 + [)] 68 69 + [)] 69 70 + [)] 71 72 +L772 + [keywordPrefs] 17 29 + [.] 29 30 + [tech] 30 34 + [=] 35 36 + [@] 37 38 + [chebtech2] 38 47 + [;] 47 48 +L773 + [else] 13 17 +L774 + [error] 17 22 + [(] 22 23 + ['CHEBFUN:CHEBFUN:parseInputs:badCh[ 23 64 + [,] 64 65 + [.] 66 67 + [.] 67 68 + [.] 68 69 +L775 + ['Invalid value for ''chebkind'' op[ 21 61 + [)] 61 62 + [;] 62 63 +L776 + [end] 13 16 +L777 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L778 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['resampling'] 35 47 + [)] 47 48 + [)] 49 50 +L780 + [if] 13 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [2] 31 32 + [}] 32 33 + [,] 33 34 + ['on'] 35 39 + [)] 39 40 + [)] 41 42 +L781 + [keywordPrefs] 17 29 + [.] 29 30 + [techPrefs] 30 39 + [.] 39 40 + [refinementFunction] 40 58 + [=] 59 60 + ['resampling'] 61 73 + [;] 73 74 +L782 + [elseif] 13 19 + [(] 20 21 + [strcmpi] 22 29 + [(] 29 30 + [args] 30 34 + [{] 34 35 + [2] 35 36 + [}] 36 37 + [,] 37 38 + ['off'] 39 44 + [)] 44 45 + [)] 46 47 +L783 + [keywordPrefs] 17 29 + [.] 29 30 + [techPrefs] 30 39 + [.] 39 40 + [refinementFunction] 40 58 + [=] 59 60 + ['nested'] 61 69 + [;] 69 70 +L784 + [end] 13 16 +L785 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L786 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['maxdegree'] 35 46 + [)] 46 47 + [)] 48 49 +L788 + [keywordPrefs] 13 25 + [.] 25 26 + [techPrefs] 26 35 + [.] 35 36 + [maxLength] 36 45 + [=] 46 47 + [args] 48 52 + [{] 52 53 + [2] 53 54 + [}] 54 55 + [;] 55 56 +L789 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L790 + [elseif] 9 15 + [(] 16 17 + [any] 18 21 + [(] 21 22 + [strcmpi] 22 29 + [(] 29 30 + [args] 30 34 + [{] 34 35 + [1] 35 36 + [}] 36 37 + [,] 37 38 + [{] 39 40 + ['splitLength'] 40 53 + [,] 53 54 + ['splitdegree'] 55 68 + [}] 68 69 + [)] 69 70 + [)] 70 71 + [)] 72 73 +L792 + [keywordPrefs] 13 25 + [.] 25 26 + [splitPrefs] 26 36 + [.] 36 37 + [splitLength] 37 48 + [=] 49 50 + [args] 51 55 + [{] 55 56 + [2] 56 57 + [}] 57 58 + [;] 58 59 +L793 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L794 + [elseif] 9 15 + [(] 16 17 + [strcmpi] 18 25 + [(] 25 26 + [args] 26 30 + [{] 30 31 + [1] 31 32 + [}] 32 33 + [,] 33 34 + ['splitMaxLength'] 35 51 + [)] 51 52 + [)] 53 54 +L796 + [keywordPrefs] 13 25 + [.] 25 26 + [splitPrefs] 26 36 + [.] 36 37 + [splitMaxLength] 37 51 + [=] 52 53 + [args] 54 58 + [{] 58 59 + [2] 59 60 + [}] 60 61 + [;] 61 62 +L797 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L798 + [elseif] 9 15 + [(] 16 17 + [ischar] 18 24 + [(] 24 25 + [args] 25 29 + [{] 29 30 + [1] 30 31 + [}] 31 32 + [)] 32 33 + [)] 34 35 +L800 + [if] 13 15 + [(] 16 17 + [length] 18 24 + [(] 24 25 + [args] 25 29 + [)] 29 30 + [<] 31 32 + [2] 33 34 + [)] 35 36 +L801 + [error] 17 22 + [(] 22 23 + ['CHEBFUN:CHEBFUN:parseInputs:noPre[ 23 64 + [,] 64 65 + [.] 66 67 + [.] 67 68 + [.] 68 69 +L802 + [\[] 21 22 + ['Value for '''] 22 36 + [args] 37 41 + [{] 41 42 + [1] 42 43 + [}] 43 44 + [''' preference was not supplied.'] 45 78 + [\]] 78 79 + [)] 79 80 + [;] 80 81 +L803 + [end] 13 16 +L804 + [keywordPrefs] 13 25 + [.] 25 26 + [(] 26 27 + [args] 27 31 + [{] 31 32 + [1] 32 33 + [}] 33 34 + [)] 34 35 + [=] 36 37 + [args] 38 42 + [{] 42 43 + [2] 43 44 + [}] 44 45 + [;] 45 46 +L805 + [args] 13 17 + [(] 17 18 + [1] 18 19 + [:] 19 20 + [2] 20 21 + [)] 21 22 + [=] 23 24 + [\[] 25 26 + [\]] 26 27 + [;] 27 28 +L806 + [else] 9 13 +L807 + [if] 13 15 + [(] 16 17 + [isnumeric] 18 27 + [(] 27 28 + [args] 28 32 + [{] 32 33 + [1] 33 34 + [}] 34 35 + [)] 35 36 + [)] 37 38 +L808 + [error] 17 22 + [(] 22 23 + ['CHEBFUN:CHEBFUN:parseInputs:badIn[ 23 68 + [,] 68 69 + [.] 70 71 + [.] 71 72 + [.] 72 73 +L809 + [\[] 21 22 + ['Could not parse input argument se[ 22 66 + [.] 67 68 + [.] 68 69 + [.] 69 70 +L810 + ['(Perhaps the construction domain [ 22 75 + [.] 76 77 + [.] 77 78 + [.] 78 79 +L811 + ['argument?)'] 22 34 + [\]] 34 35 + [)] 35 36 + [;] 36 37 +L812 + [else] 13 17 +L813 + [error] 17 22 + [(] 22 23 + ['CHEBFUN:CHEBFUN:parseInputs:badIn[ 23 61 + [,] 61 62 + [.] 63 64 + [.] 64 65 + [.] 65 66 +L814 + ['Could not parse input argument se[ 21 63 + [)] 63 64 + [;] 64 65 +L815 + [end] 13 16 +L816 + [end] 9 12 +L817 + [end] 5 8 +L821 + [if] 5 7 + [(] 8 9 + [prefWasPassed] 10 23 + [)] 24 25 +L822 + [pref] 9 13 + [=] 14 15 + [chebfunpref] 16 27 + [(] 27 28 + [pref] 28 32 + [,] 32 33 + [keywordPrefs] 34 46 + [)] 46 47 + [;] 47 48 +L823 + [else] 5 9 +L824 + [pref] 9 13 + [=] 14 15 + [chebfunpref] 16 27 + [(] 27 28 + [keywordPrefs] 28 40 + [)] 40 41 + [;] 41 42 +L825 + [end] 5 8 +L828 + [if] 5 7 + [(] 8 9 + [~] 10 11 + [domainWasPassed] 11 26 + [||] 27 29 + [isempty] 30 37 + [(] 37 38 + [dom] 38 41 + [)] 41 42 + [)] 43 44 +L829 + [if] 9 11 + [(] 12 13 + [isa] 14 17 + [(] 17 18 + [op] 18 20 + [,] 20 21 + ['chebfun'] 22 31 + [)] 31 32 + [)] 33 34 +L830 + [dom] 13 16 + [=] 17 18 + [\[] 19 20 + [op] 21 23 + [.] 23 24 + [domain] 24 30 + [(] 30 31 + [1] 31 32 + [)] 32 33 + [op] 34 36 + [.] 36 37 + [domain] 37 43 + [(] 43 44 + [end] 44 47 + [)] 47 48 + [\]] 49 50 + [;] 50 51 +L831 + [else] 9 13 +L832 + [dom] 13 16 + [=] 17 18 + [pref] 19 23 + [.] 23 24 + [domain] 24 30 + [;] 30 31 +L833 + [end] 9 12 +L834 + [end] 5 8 +L835 + [numIntervals] 5 17 + [=] 18 19 + [numel] 20 25 + [(] 25 26 + [dom] 26 29 + [)] 29 30 + [-] 31 32 + [1] 33 34 + [;] 34 35 +L838 + [if] 5 7 + [(] 8 9 + [isPeriodic] 10 20 + [)] 21 22 +L840 + [pref] 9 13 + [.] 13 14 + [tech] 14 18 + [=] 19 20 + [@] 21 22 + [trigtech] 22 30 + [;] 30 31 +L841 + [pref] 9 13 + [.] 13 14 + [splitting] 14 23 + [=] 24 25 + [false] 26 31 + [;] 31 32 +L842 + [if] 9 11 + [(] 12 13 + [numel] 14 19 + [(] 19 20 + [dom] 20 23 + [)] 23 24 + [>] 25 26 + [2] 27 28 + [)] 29 30 +L843 + [error] 13 18 + [(] 18 19 + ['CHEBFUN:parseInputs:periodic'] 19 49 + [,] 49 50 + [.] 51 52 + [.] 52 53 + [.] 53 54 +L844 + ['''periodic'' or ''trig'' option i[ 17 88 + [)] 88 89 + [;] 89 90 +L845 + [end] 9 12 +L846 + [end] 5 8 +L849 + [if] 5 7 + [(] 8 9 + [iscell] 10 16 + [(] 16 17 + [op] 17 19 + [)] 19 20 + [)] 21 22 +L850 + [for] 9 12 + [k] 13 14 + [=] 15 16 + [1] 17 18 + [:] 18 19 + [numel] 19 24 + [(] 24 25 + [op] 25 27 + [)] 27 28 +L851 + [op] 13 15 + [{] 15 16 + [k] 16 17 + [}] 17 18 + [=] 19 20 + [parseOp] 21 28 + [(] 28 29 + [op] 29 31 + [{] 31 32 + [k] 32 33 + [}] 33 34 + [)] 34 35 + [;] 35 36 +L852 + [end] 9 12 +L853 + [else] 5 9 +L854 + [op] 9 11 + [=] 12 13 + [parseOp] 14 21 + [(] 21 22 + [op] 22 24 + [)] 24 25 + [;] 25 26 +L855 + [end] 5 8 +L857 + [function] 5 13 + [op] 14 16 + [=] 17 18 + [parseOp] 19 26 + [(] 26 27 + [op] 27 29 + [)] 29 30 +L859 + [if] 9 11 + [(] 12 13 + [ischar] 14 20 + [(] 20 21 + [op] 21 23 + [)] 23 24 + [)] 25 26 +L860 + [op] 13 15 + [=] 16 17 + [str2op] 18 24 + [(] 24 25 + [op] 25 27 + [)] 27 28 + [;] 28 29 +L861 + [end] 9 12 +L862 + [if] 9 11 + [(] 12 13 + [doVectorCheck] 14 27 + [&&] 28 30 + [isa] 31 34 + [(] 34 35 + [op] 35 37 + [,] 37 38 + ['function_handle'] 39 56 + [)] 56 57 + [)] 58 59 +L863 + [op] 13 15 + [=] 16 17 + [vectorCheck] 18 29 + [(] 29 30 + [op] 30 32 + [,] 32 33 + [dom] 34 37 + [,] 37 38 + [vectorize] 39 48 + [)] 48 49 + [;] 49 50 +L864 + [end] 9 12 +L865 + [if] 9 11 + [(] 12 13 + [isa] 14 17 + [(] 17 18 + [op] 18 20 + [,] 20 21 + ['chebfun'] 22 31 + [)] 31 32 + [)] 33 34 +L866 + [op] 13 15 + [=] 16 17 + [@] 18 19 + [(] 19 20 + [x] 20 21 + [)] 21 22 + [feval] 23 28 + [(] 28 29 + [op] 29 31 + [,] 31 32 + [x] 33 34 + [)] 34 35 + [;] 35 36 +L867 + [end] 9 12 +L868 + [if] 9 11 + [(] 12 13 + [isa] 14 17 + [(] 17 18 + [op] 18 20 + [,] 20 21 + ['function_handle'] 22 39 + [)] 39 40 + [&&] 41 43 + [strcmp] 44 50 + [(] 50 51 + [pref] 51 55 + [.] 55 56 + [tech] 56 60 + [,] 60 61 + ['funqui'] 62 70 + [)] 70 71 + [)] 72 73 +L869 + [if] 13 15 + [(] 16 17 + [isfield] 18 25 + [(] 25 26 + [pref] 26 30 + [.] 30 31 + [techPrefs] 31 40 + [,] 40 41 + ['fixedLength'] 42 55 + [)] 55 56 + [&&] 57 59 + [.] 60 61 + [.] 61 62 + [.] 62 63 +L870 + [~] 18 19 + [isnan] 19 24 + [(] 24 25 + [pref] 25 29 + [.] 29 30 + [techPrefs] 30 39 + [.] 39 40 + [fixedLength] 40 51 + [)] 51 52 + [)] 53 54 +L871 + [x] 17 18 + [=] 19 20 + [linspace] 21 29 + [(] 29 30 + [dom] 30 33 + [(] 33 34 + [1] 34 35 + [)] 35 36 + [,] 36 37 + [dom] 38 41 + [(] 41 42 + [end] 42 45 + [)] 45 46 + [,] 46 47 + [pref] 48 52 + [.] 52 53 + [techPrefs] 53 62 + [.] 62 63 + [fixedLength] 63 74 + [)] 74 75 + [.'] 75 77 + [;] 77 78 +L872 + [op] 17 19 + [=] 20 21 + [feval] 22 27 + [(] 27 28 + [op] 28 30 + [,] 30 31 + [x] 32 33 + [)] 33 34 + [;] 34 35 +L873 + [pref] 17 21 + [.] 21 22 + [techPrefs] 22 31 + [.] 31 32 + [fixedLength] 32 43 + [=] 44 45 + [NaN] 46 49 + [;] 49 50 +L874 + [end] 13 16 +L875 + [end] 9 12 +L876 + [end] 5 8 +L879 + [if] 5 7 + [(] 8 9 + [any] 10 13 + [(] 13 14 + [data] 14 18 + [.] 18 19 + [exponents] 19 28 + [)] 28 29 + [||] 30 32 + [~] 33 34 + [isempty] 34 41 + [(] 41 42 + [data] 42 46 + [.] 46 47 + [singType] 47 55 + [)] 55 56 + [)] 57 58 +L880 + [pref] 9 13 + [.] 13 14 + [blowup] 14 20 + [=] 21 22 + [true] 23 27 + [;] 27 28 +L881 + [end] 5 8 +L883 + [if] 5 7 + [(] 8 9 + [numel] 10 15 + [(] 15 16 + [data] 16 20 + [.] 20 21 + [singType] 21 29 + [)] 29 30 + [==] 31 33 + [1] 34 35 + [)] 36 37 +L884 + [singType] 9 17 + [=] 18 19 + [data] 20 24 + [.] 24 25 + [singType] 25 33 + [{] 33 34 + [1] 34 35 + [}] 35 36 + [;] 36 37 +L885 + [data] 9 13 + [.] 13 14 + [singType] 14 22 + [=] 23 24 + [cell] 25 29 + [(] 29 30 + [1] 30 31 + [,] 31 32 + [2] 33 34 + [*] 34 35 + [numIntervals] 35 47 + [)] 47 48 + [;] 48 49 +L886 + [for] 9 12 + [j] 13 14 + [=] 15 16 + [1] 17 18 + [:] 18 19 + [2] 19 20 + [*] 20 21 + [numIntervals] 21 33 +L887 + [data] 13 17 + [.] 17 18 + [singType] 18 26 + [{] 26 27 + [j] 27 28 + [}] 28 29 + [=] 30 31 + [singType] 32 40 + [;] 40 41 +L888 + [end] 9 12 +L889 + [elseif] 5 11 + [(] 12 13 + [~] 14 15 + [isempty] 15 22 + [(] 22 23 + [data] 23 27 + [.] 27 28 + [singType] 28 36 + [)] 36 37 + [&&] 38 40 + [.] 41 42 + [.] 42 43 + [.] 43 44 +L890 + [(] 13 14 + [numel] 14 19 + [(] 19 20 + [data] 20 24 + [.] 24 25 + [singType] 25 33 + [)] 33 34 + [~=] 35 37 + [2] 38 39 + [*] 39 40 + [numIntervals] 40 52 + [)] 52 53 + [)] 54 55 +L893 + [error] 9 14 + [(] 14 15 + ['CHEBFUN:CHEBFUN:parseInputs:badEx[ 15 57 + [,] 57 58 + [.] 59 60 + [.] 60 61 + [.] 61 62 +L894 + ['The number of the exponents is in[ 13 60 + [)] 60 61 + [;] 61 62 +L895 + [end] 5 8 +L897 + [if] 5 7 + [(] 8 9 + [~] 10 11 + [isempty] 11 18 + [(] 18 19 + [data] 19 23 + [.] 23 24 + [exponents] 24 33 + [)] 33 34 + [)] 35 36 +L898 + [exps] 9 13 + [=] 14 15 + [data] 16 20 + [.] 20 21 + [exponents] 21 30 + [;] 30 31 +L899 + [nExps] 9 14 + [=] 15 16 + [numel] 17 22 + [(] 22 23 + [exps] 23 27 + [)] 27 28 + [;] 28 29 +L900 + [if] 9 11 + [(] 12 13 + [nExps] 14 19 + [==] 20 22 + [1] 23 24 + [)] 25 26 +L903 + [exps] 13 17 + [=] 18 19 + [exps] 20 24 + [*] 24 25 + [ones] 25 29 + [(] 29 30 + [1] 30 31 + [,] 31 32 + [2] 33 34 + [*] 34 35 + [numIntervals] 35 47 + [)] 47 48 + [;] 48 49 +L904 + [elseif] 9 15 + [(] 16 17 + [nExps] 18 23 + [==] 24 26 + [2] 27 28 + [)] 29 30 +L907 + [exps] 13 17 + [=] 18 19 + [\[] 20 21 + [exps] 21 25 + [(] 25 26 + [1] 26 27 + [)] 27 28 + [zeros] 29 34 + [(] 34 35 + [1] 35 36 + [,] 36 37 + [2] 38 39 + [*] 39 40 + [(] 40 41 + [numIntervals] 41 53 + [-] 53 54 + [1] 54 55 + [)] 55 56 + [)] 56 57 + [exps] 58 62 + [(] 62 63 + [2] 63 64 + [)] 64 65 + [\]] 65 66 + [;] 66 67 +L908 + [elseif] 9 15 + [(] 16 17 + [nExps] 18 23 + [==] 24 26 + [numIntervals] 27 39 + [+] 40 41 + [1] 42 43 + [)] 44 45 +L912 + [exps] 13 17 + [=] 18 19 + [exps] 20 24 + [(] 24 25 + [ceil] 25 29 + [(] 29 30 + [1] 30 31 + [:] 31 32 + [0.5] 32 35 + [:] 35 36 + [nExps] 36 41 + [-] 42 43 + [0.5] 44 47 + [)] 47 48 + [)] 48 49 + [;] 49 50 +L913 + [elseif] 9 15 + [(] 15 16 + [nExps] 17 22 + [~=] 23 25 + [2] 26 27 + [*] 27 28 + [numIntervals] 28 40 + [)] 41 42 +L915 + [error] 13 18 + [(] 18 19 + ['CHEBFUN:CHEBFUN:chebfun:parseInpu[ 19 56 + [,] 56 57 + [.] 58 59 + [.] 59 60 + [.] 60 61 +L916 + ['Invalid length for vector of expo[ 17 58 + [)] 58 59 + [;] 59 60 +L917 + [end] 9 12 +L918 + [data] 9 13 + [.] 13 14 + [exponents] 14 23 + [=] 24 25 + [exps] 26 30 + [;] 30 31 +L919 + [end] 5 8 +L922 + [dom] 5 8 + [=] 9 10 + [double] 11 17 + [(] 17 18 + [dom] 18 21 + [)] 21 22 + [;] 22 23 +L924 + [end] 1 4 +L926 + [function] 1 9 + [op] 10 12 + [=] 13 14 + [vectorCheck] 15 26 + [(] 26 27 + [op] 27 29 + [,] 29 30 + [dom] 31 34 + [,] 34 35 + [vectorize] 36 45 + [)] 45 46 +L932 + [y] 1 2 + [=] 3 4 + [dom] 5 8 + [(] 8 9 + [\[] 9 10 + [1] 10 11 + [end] 12 15 + [\]] 15 16 + [)] 16 17 + [;] 17 18 +L934 + [if] 1 3 + [(] 4 5 + [y] 6 7 + [(] 7 8 + [1] 8 9 + [)] 9 10 + [>] 11 12 + [0] 13 14 + [)] 15 16 +L935 + [y] 5 6 + [(] 6 7 + [1] 7 8 + [)] 8 9 + [=] 10 11 + [1.01] 12 16 + [*] 16 17 + [y] 17 18 + [(] 18 19 + [1] 19 20 + [)] 20 21 + [;] 21 22 +L936 + [else] 1 5 +L937 + [y] 5 6 + [(] 6 7 + [1] 7 8 + [)] 8 9 + [=] 10 11 + [.99] 12 15 + [*] 15 16 + [y] 16 17 + [(] 17 18 + [1] 18 19 + [)] 19 20 + [;] 20 21 +L938 + [end] 1 4 +L940 + [if] 1 3 + [(] 4 5 + [y] 6 7 + [(] 7 8 + [end] 8 11 + [)] 11 12 + [>] 13 14 + [0] 15 16 + [)] 17 18 +L941 + [y] 5 6 + [(] 6 7 + [end] 7 10 + [)] 10 11 + [=] 12 13 + [.99] 14 17 + [*] 17 18 + [y] 18 19 + [(] 19 20 + [end] 20 23 + [)] 23 24 + [;] 24 25 +L942 + [else] 1 5 +L943 + [y] 5 6 + [(] 6 7 + [end] 7 10 + [)] 10 11 + [=] 12 13 + [1.01] 14 18 + [*] 18 19 + [y] 19 20 + [(] 20 21 + [end] 21 24 + [)] 24 25 + [;] 25 26 +L944 + [end] 1 4 +L946 + [y] 1 2 + [=] 3 4 + [y] 5 6 + [(] 6 7 + [:] 7 8 + [)] 8 9 + [;] 9 10 +L948 + [if] 1 3 + [(] 4 5 + [vectorize] 6 15 + [)] 16 17 +L949 + [op] 5 7 + [=] 8 9 + [vec] 10 13 + [(] 13 14 + [op] 14 16 + [,] 16 17 + [y] 18 19 + [(] 19 20 + [1] 20 21 + [)] 21 22 + [)] 22 23 + [;] 23 24 +L950 + [end] 1 4 +L952 + [try] 1 4 +L954 + [v] 5 6 + [=] 7 8 + [op] 9 11 + [(] 11 12 + [y] 12 13 + [)] 13 14 + [;] 14 15 +L957 + [sv] 5 7 + [=] 8 9 + [size] 10 14 + [(] 14 15 + [v] 15 16 + [)] 16 17 + [;] 17 18 +L958 + [sy] 5 7 + [=] 8 9 + [size] 10 14 + [(] 14 15 + [y] 15 16 + [)] 16 17 + [;] 17 18 +L961 + [if] 5 7 + [(] 8 9 + [sv] 10 12 + [(] 12 13 + [1] 13 14 + [)] 14 15 + [==] 16 18 + [sy] 19 21 + [(] 21 22 + [1] 22 23 + [)] 23 24 + [)] 25 26 +L967 + [if] 9 11 + [(] 12 13 + [sv] 14 16 + [(] 16 17 + [2] 17 18 + [)] 18 19 + [==] 20 22 + [sy] 23 25 + [(] 25 26 + [1] 26 27 + [)] 27 28 + [)] 29 30 +L968 + [v] 13 14 + [=] 15 16 + [op] 17 19 + [(] 19 20 + [y] 20 21 + [(] 21 22 + [1] 22 23 + [)] 23 24 + [)] 24 25 + [;] 25 26 +L969 + [if] 13 15 + [(] 16 17 + [size] 18 22 + [(] 22 23 + [v] 23 24 + [,] 24 25 + [1] 26 27 + [)] 27 28 + [>] 29 30 + [1] 31 32 + [)] 33 34 +L970 + [op] 17 19 + [=] 20 21 + [@] 22 23 + [(] 23 24 + [x] 24 25 + [)] 25 26 + [op] 27 29 + [(] 29 30 + [x] 30 31 + [)] 31 32 + [.'] 32 34 + [;] 34 35 +L971 + [warning] 17 24 + [(] 24 25 + ['CHEBFUN:CHEBFUN:vectorCheck:trans[ 25 64 + [,] 64 65 + [.] 65 66 + [.] 66 67 + [.] 67 68 +L972 + [\[] 21 22 + ['Chebfun input should return a COL[ 22 69 + [,] 69 70 + [.] 71 72 + [.] 72 73 + [.] 73 74 +L973 + ['Attempting to transpose.'] 22 48 + [\]] 48 49 + [)] 49 50 +L974 + [end] 13 16 +L975 + [end] 9 12 +L977 + [elseif] 5 11 + [(] 12 13 + [all] 14 17 + [(] 17 18 + [sv] 19 21 + [==] 22 24 + [1] 25 26 + [)] 27 28 + [)] 29 30 +L979 + [op] 9 11 + [=] 12 13 + [@] 14 15 + [(] 15 16 + [x] 16 17 + [)] 17 18 + [repmat] 19 25 + [(] 25 26 + [op] 26 28 + [(] 28 29 + [x] 29 30 + [)] 30 31 + [,] 31 32 + [length] 33 39 + [(] 39 40 + [x] 40 41 + [)] 41 42 + [,] 42 43 + [1] 44 45 + [)] 45 46 + [;] 46 47 +L981 + [elseif] 5 11 + [(] 12 13 + [any] 14 17 + [(] 17 18 + [sv] 18 20 + [==] 21 23 + [sy] 24 26 + [(] 26 27 + [1] 27 28 + [)] 28 29 + [)] 29 30 + [)] 31 32 +L983 + [if] 9 11 + [(] 12 13 + [any] 14 17 + [(] 17 18 + [sv] 18 20 + [)] 20 21 + [==] 22 24 + [1] 25 26 + [)] 27 28 +L985 + [v] 13 14 + [=] 15 16 + [op] 17 19 + [(] 19 20 + [y] 20 21 + [(] 21 22 + [1] 22 23 + [)] 23 24 + [)] 24 25 + [;] 25 26 +L986 + [if] 13 15 + [(] 16 17 + [all] 18 21 + [(] 21 22 + [size] 22 26 + [(] 26 27 + [v] 27 28 + [)] 28 29 + [==] 30 32 + [sv] 33 35 + [)] 35 36 + [)] 37 38 +L988 + [op] 17 19 + [=] 20 21 + [@] 22 23 + [(] 23 24 + [x] 24 25 + [)] 25 26 + [repmat] 27 33 + [(] 33 34 + [op] 34 36 + [(] 36 37 + [x] 37 38 + [)] 38 39 + [,] 39 40 + [length] 41 47 + [(] 47 48 + [x] 48 49 + [)] 49 50 + [,] 50 51 + [1] 52 53 + [)] 53 54 + [;] 54 55 +L989 + [return] 17 23 +L990 + [end] 13 16 +L991 + [end] 9 12 +L994 + [op] 9 11 + [=] 12 13 + [@] 14 15 + [(] 15 16 + [x] 16 17 + [)] 17 18 + [op] 19 21 + [(] 21 22 + [x] 22 23 + [)] 23 24 + [.'] 24 26 + [;] 26 27 +L995 + [warning] 9 16 + [(] 16 17 + ['CHEBFUN:CHEBFUN:vectorCheck:trans[ 17 56 + [,] 56 57 + [.] 57 58 + [.] 58 59 + [.] 59 60 +L996 + [\[] 17 18 + ['Chebfun input should return a COL[ 18 65 + [,] 65 66 + [.] 67 68 + [.] 68 69 + [.] 69 70 +L997 + ['Attempting to transpose.'] 18 44 + [\]] 44 45 + [)] 45 46 +L999 + [elseif] 5 11 + [(] 12 13 + [any] 14 17 + [(] 17 18 + [sv] 18 20 + [==] 21 23 + [1] 24 25 + [)] 25 26 + [)] 27 28 +L1001 + [op] 9 11 + [=] 12 13 + [@] 14 15 + [(] 15 16 + [x] 16 17 + [)] 17 18 + [repmat] 19 25 + [(] 25 26 + [op] 26 28 + [(] 28 29 + [x] 29 30 + [)] 30 31 + [,] 31 32 + [length] 33 39 + [(] 39 40 + [x] 40 41 + [)] 41 42 + [,] 42 43 + [1] 44 45 + [)] 45 46 + [;] 46 47 +L1003 + [end] 5 8 +L1005 + [catch] 1 6 + [ME] 7 9 +L1008 + [if] 5 7 + [(] 8 9 + [vectorize] 10 19 + [)] 20 21 +L1010 + [rethrow] 9 16 + [(] 16 17 + [ME] 17 19 + [)] 19 20 +L1012 + [else] 5 9 +L1014 + [op] 9 11 + [=] 12 13 + [vectorCheck] 14 25 + [(] 25 26 + [op] 26 28 + [,] 28 29 + [dom] 30 33 + [,] 33 34 + [1] 35 36 + [)] 36 37 + [;] 37 38 +L1015 + [warning] 9 16 + [(] 16 17 + ['CHEBFUN:CHEBFUN:vectorcheck:vecto[ 17 56 + [,] 56 57 + [.] 57 58 + [.] 58 59 + [.] 59 60 +L1016 + [\[] 9 10 + ['Function failed to evaluate on ar[ 10 58 + [,] 58 59 + [.] 59 60 + [.] 60 61 + [.] 61 62 +L1017 + ['Vectorizing the function may spee[ 9 65 + [,] 65 66 + [.] 66 67 + [.] 67 68 + [.] 68 69 +L1018 + ['and avoid the need to loop over a[ 9 60 + [,] 60 61 + [.] 61 62 + [.] 62 63 + [.] 63 64 +L1019 + ['Use ''vectorize'' flag in the CHE[ 9 67 + [,] 67 68 + [.] 69 70 + [.] 70 71 + [.] 71 72 +L1020 + ['to avoid this warning message.'] 9 41 + [\]] 41 42 + [)] 42 43 +L1022 + [end] 5 8 +L1024 + [end] 1 4 +L1026 + [end] 1 4 +L1028 + [function] 1 9 + [g] 10 11 + [=] 12 13 + [vec] 14 17 + [(] 17 18 + [op] 18 20 + [,] 20 21 + [y] 22 23 + [)] 23 24 +L1036 + [opy] 5 8 + [=] 9 10 + [op] 11 13 + [(] 13 14 + [y] 14 15 + [)] 15 16 + [;] 16 17 +L1037 + [if] 5 7 + [(] 8 9 + [any] 10 13 + [(] 13 14 + [size] 14 18 + [(] 18 19 + [opy] 19 22 + [)] 22 23 + [>] 24 25 + [1] 26 27 + [)] 27 28 + [)] 29 30 +L1039 + [g] 9 10 + [=] 11 12 + [@] 13 14 + [loopWrapperArray] 14 30 + [;] 30 31 +L1040 + [else] 5 9 +L1042 + [g] 9 10 + [=] 11 12 + [@] 13 14 + [loopWrapperScalar] 14 31 + [;] 31 32 +L1043 + [end] 5 8 +L1048 + [function] 5 13 + [v] 14 15 + [=] 16 17 + [loopWrapperScalar] 18 35 + [(] 35 36 + [x] 36 37 + [)] 37 38 +L1049 + [v] 9 10 + [=] 11 12 + [zeros] 13 18 + [(] 18 19 + [size] 19 23 + [(] 23 24 + [x] 24 25 + [)] 25 26 + [)] 26 27 + [;] 27 28 +L1050 + [for] 9 12 + [j] 13 14 + [=] 15 16 + [1] 17 18 + [:] 18 19 + [numel] 19 24 + [(] 24 25 + [v] 25 26 + [)] 26 27 +L1051 + [v] 13 14 + [(] 14 15 + [j] 15 16 + [)] 16 17 + [=] 18 19 + [op] 20 22 + [(] 22 23 + [x] 23 24 + [(] 24 25 + [j] 25 26 + [)] 26 27 + [)] 27 28 + [;] 28 29 +L1052 + [end] 9 12 +L1053 + [end] 5 8 +L1056 + [function] 5 13 + [v] 14 15 + [=] 16 17 + [loopWrapperArray] 18 34 + [(] 34 35 + [x] 35 36 + [)] 36 37 +L1057 + [numCol] 9 15 + [=] 16 17 + [size] 18 22 + [(] 22 23 + [op] 23 25 + [(] 25 26 + [x] 26 27 + [(] 27 28 + [1] 28 29 + [)] 29 30 + [)] 30 31 + [,] 31 32 + [2] 33 34 + [)] 34 35 + [;] 35 36 +L1058 + [numRow] 9 15 + [=] 16 17 + [size] 18 22 + [(] 22 23 + [x] 23 24 + [,] 24 25 + [1] 26 27 + [)] 27 28 + [;] 28 29 +L1059 + [v] 9 10 + [=] 11 12 + [zeros] 13 18 + [(] 18 19 + [numRow] 19 25 + [,] 25 26 + [numCol] 27 33 + [)] 33 34 + [;] 34 35 +L1060 + [for] 9 12 + [j] 13 14 + [=] 15 16 + [1] 17 18 + [:] 18 19 + [numRow] 19 25 +L1061 + [v] 13 14 + [(] 14 15 + [j] 15 16 + [,] 16 17 + [:] 17 18 + [)] 18 19 + [=] 20 21 + [op] 22 24 + [(] 24 25 + [x] 25 26 + [(] 26 27 + [j] 27 28 + [)] 28 29 + [)] 29 30 + [;] 30 31 +L1062 + [end] 9 12 +L1063 + [end] 5 8 +L1065 + [end] 1 4 +EOF diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/specialComments.m b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/specialComments.m new file mode 100644 index 0000000000..14a6146f6f --- /dev/null +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/specialComments.m @@ -0,0 +1,8 @@ +% CPD-OFF +function g = vec(op, y) + opy = op(y); + if ( any(size(opy) > 1) ) + g = @loopWrapperArray; + end + % CPD-ON +end \ No newline at end of file diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/specialComments.txt b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/specialComments.txt new file mode 100644 index 0000000000..a28bcc357f --- /dev/null +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/specialComments.txt @@ -0,0 +1,4 @@ + [Image] or [Truncated image[ Bcol Ecol +L8 + [end] 1 4 +EOF diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index c0d5f42eb6..4e494e779f 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -82,10 +82,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-objectivec/src/test/java/net/sourceforge/pmd/cpd/ObjectiveCTokenizerTest.java b/pmd-objectivec/src/test/java/net/sourceforge/pmd/cpd/ObjectiveCTokenizerTest.java index 7fdd53a4ca..00d676bb5d 100644 --- a/pmd-objectivec/src/test/java/net/sourceforge/pmd/cpd/ObjectiveCTokenizerTest.java +++ b/pmd-objectivec/src/test/java/net/sourceforge/pmd/cpd/ObjectiveCTokenizerTest.java @@ -4,34 +4,41 @@ package net.sourceforge.pmd.cpd; -import java.io.IOException; -import java.nio.charset.StandardCharsets; +import java.util.Properties; -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -public class ObjectiveCTokenizerTest extends AbstractTokenizerTest { +public class ObjectiveCTokenizerTest extends CpdTextComparisonTest { - private static final String FILENAME = "AFHTTPRequestOperation.m"; - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new ObjectiveCTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), FILENAME)); + public ObjectiveCTokenizerTest() { + super(".m"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(ObjectiveCTokenizer.class.getResourceAsStream(FILENAME), StandardCharsets.UTF_8); + protected String getResourcePrefix() { + return "../lang/objc/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new ObjectiveCTokenizer(); } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 884; - super.tokenizeTest(); + public void testLongSample() { + doTest("big_sample"); + } + + @Test + public void testUnicodeEscape() { + doTest("unicodeEscapeInString"); + } + + @Test + public void testUnicodeCharInIdent() { + doTest("unicodeCharInIdent"); } } diff --git a/pmd-objectivec/src/test/java/net/sourceforge/pmd/cpd/UTF8EscapesInStringLiteralObjCTokenizerTest.java b/pmd-objectivec/src/test/java/net/sourceforge/pmd/cpd/UTF8EscapesInStringLiteralObjCTokenizerTest.java deleted file mode 100644 index 8a4491742e..0000000000 --- a/pmd-objectivec/src/test/java/net/sourceforge/pmd/cpd/UTF8EscapesInStringLiteralObjCTokenizerTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Before; -import org.junit.Test; - -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; - -//Tests if the ObjectiveC tokenizer supports UTF-8 escapes in string literals -public class UTF8EscapesInStringLiteralObjCTokenizerTest extends AbstractTokenizerTest { - - private static final String FILENAME = "FileWithUTF8EscapeInStringLiteral.m"; - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new ObjectiveCTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), FILENAME)); - } - - @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(ObjectiveCTokenizer.class.getResourceAsStream(FILENAME), StandardCharsets.UTF_8); - } - - @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 45; - super.tokenizeTest(); - } -} diff --git a/pmd-objectivec/src/test/java/net/sourceforge/pmd/cpd/UnicodeObjectiveCTokenizerTest.java b/pmd-objectivec/src/test/java/net/sourceforge/pmd/cpd/UnicodeObjectiveCTokenizerTest.java deleted file mode 100644 index 2c18f73fa8..0000000000 --- a/pmd-objectivec/src/test/java/net/sourceforge/pmd/cpd/UnicodeObjectiveCTokenizerTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.cpd; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Before; -import org.junit.Test; - -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; - -//Tests if the ObjectiveC tokenizer supports identifiers with unicode characters -public class UnicodeObjectiveCTokenizerTest extends AbstractTokenizerTest { - - private static final String FILENAME = "NCClient.m"; - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new ObjectiveCTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), FILENAME)); - } - - @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(ObjectiveCTokenizer.class.getResourceAsStream(FILENAME), StandardCharsets.UTF_8); - } - - @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 10; - super.tokenizeTest(); - } - - @Test - public void testIgnoreBetweenSpecialComments() throws IOException { - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader( - "// CPD-OFF" + PMD.EOL - + "static SecCertificateRef gNСServerLogonCertificate;" + PMD.EOL - + "// CPD-ON" + PMD.EOL - + "@end" + PMD.EOL - )); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - assertEquals(2, tokens.size()); // 2 tokens: "@end" + EOF - } -} diff --git a/pmd-objectivec/src/test/resources/net/sourceforge/pmd/cpd/AFHTTPRequestOperation.m b/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/big_sample.m similarity index 100% rename from pmd-objectivec/src/test/resources/net/sourceforge/pmd/cpd/AFHTTPRequestOperation.m rename to pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/big_sample.m diff --git a/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/big_sample.txt b/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/big_sample.txt new file mode 100644 index 0000000000..2d91fee542 --- /dev/null +++ b/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/big_sample.txt @@ -0,0 +1,1022 @@ + [Image] or [Truncated image[ Bcol Ecol +L28 + [static] 1 7 + [dispatch_queue_t] 8 24 + [http_request_operation_processing_[ 25 64 + [(] 64 65 + [)] 65 66 + [{] 67 68 +L29 + [static] 5 11 + [dispatch_queue_t] 12 28 + [af_http_request_operation_processi[ 29 71 + [;] 71 72 +L30 + [static] 5 11 + [dispatch_once_t] 12 27 + [onceToken] 28 37 + [;] 37 38 +L31 + [dispatch_once] 5 18 + [(] 18 19 + [&] 19 20 + [onceToken] 20 29 + [,] 29 30 + [^] 31 32 + [{] 32 33 +L32 + [af_http_request_operation_processi[ 9 51 + [=] 52 53 + [dispatch_queue_create] 54 75 + [(] 75 76 + ["com.alamofire.networking.http-req[ 76 126 + [,] 126 127 + [DISPATCH_QUEUE_CONCURRENT] 128 153 + [)] 153 154 + [;] 154 155 +L33 + [}] 5 6 + [)] 6 7 + [;] 7 8 +L35 + [return] 5 11 + [af_http_request_operation_processi[ 12 54 + [;] 54 55 +L36 + [}] 1 2 +L38 + [static] 1 7 + [dispatch_group_t] 8 24 + [http_request_operation_completion_[ 25 64 + [(] 64 65 + [)] 65 66 + [{] 67 68 +L39 + [static] 5 11 + [dispatch_group_t] 12 28 + [af_http_request_operation_completi[ 29 71 + [;] 71 72 +L40 + [static] 5 11 + [dispatch_once_t] 12 27 + [onceToken] 28 37 + [;] 37 38 +L41 + [dispatch_once] 5 18 + [(] 18 19 + [&] 19 20 + [onceToken] 20 29 + [,] 29 30 + [^] 31 32 + [{] 32 33 +L42 + [af_http_request_operation_completi[ 9 51 + [=] 52 53 + [dispatch_group_create] 54 75 + [(] 75 76 + [)] 76 77 + [;] 77 78 +L43 + [}] 5 6 + [)] 6 7 + [;] 7 8 +L45 + [return] 5 11 + [af_http_request_operation_completi[ 12 54 + [;] 54 55 +L46 + [}] 1 2 +L50 + [@interface] 1 11 + [AFURLConnectionOperation] 12 36 + [(] 37 38 + [)] 38 39 +L51 + [@property] 1 10 + [(] 11 12 + [readwrite] 12 21 + [,] 21 22 + [nonatomic] 23 32 + [,] 32 33 + [strong] 34 40 + [)] 40 41 + [NSURLRequest] 42 54 + [*] 55 56 + [request] 56 63 + [;] 63 64 +L52 + [@property] 1 10 + [(] 11 12 + [readwrite] 12 21 + [,] 21 22 + [nonatomic] 23 32 + [,] 32 33 + [strong] 34 40 + [)] 40 41 + [NSURLResponse] 42 55 + [*] 56 57 + [response] 57 65 + [;] 65 66 +L53 + [@end] 1 5 +L55 + [@interface] 1 11 + [AFHTTPRequestOperation] 12 34 + [(] 35 36 + [)] 36 37 +L56 + [@property] 1 10 + [(] 11 12 + [readwrite] 12 21 + [,] 21 22 + [nonatomic] 23 32 + [,] 32 33 + [strong] 34 40 + [)] 40 41 + [NSHTTPURLResponse] 42 59 + [*] 60 61 + [response] 61 69 + [;] 69 70 +L57 + [@property] 1 10 + [(] 11 12 + [readwrite] 12 21 + [,] 21 22 + [nonatomic] 23 32 + [,] 32 33 + [strong] 34 40 + [)] 40 41 + [id] 42 44 + [responseObject] 45 59 + [;] 59 60 +L58 + [@property] 1 10 + [(] 11 12 + [readwrite] 12 21 + [,] 21 22 + [nonatomic] 23 32 + [,] 32 33 + [strong] 34 40 + [)] 40 41 + [NSError] 42 49 + [*] 50 51 + [responseSerializationError] 51 77 + [;] 77 78 +L59 + [@property] 1 10 + [(] 11 12 + [readwrite] 12 21 + [,] 21 22 + [nonatomic] 23 32 + [,] 32 33 + [strong] 34 40 + [)] 40 41 + [NSRecursiveLock] 42 57 + [*] 58 59 + [lock] 59 63 + [;] 63 64 +L60 + [@end] 1 5 +L62 + [@implementation] 1 16 + [AFHTTPRequestOperation] 17 39 +L63 + [@dynamic] 1 9 + [lock] 10 14 + [;] 14 15 +L65 + [-] 1 2 + [(] 3 4 + [instancetype] 4 16 + [)] 16 17 + [initWithRequest] 17 32 + [:] 32 33 + [(] 33 34 + [NSURLRequest] 34 46 + [*] 47 48 + [)] 48 49 + [urlRequest] 49 59 + [{] 60 61 +L66 + [self] 5 9 + [=] 10 11 + [\[] 12 13 + [super] 13 18 + [initWithRequest] 19 34 + [:] 34 35 + [urlRequest] 35 45 + [\]] 45 46 + [;] 46 47 +L67 + [if] 5 7 + [(] 8 9 + [!] 9 10 + [self] 10 14 + [)] 14 15 + [{] 16 17 +L68 + [return] 9 15 + [nil] 16 19 + [;] 19 20 +L69 + [}] 5 6 +L71 + [self] 5 9 + [.] 9 10 + [responseSerializer] 10 28 + [=] 29 30 + [\[] 31 32 + [AFHTTPResponseSerializer] 32 56 + [serializer] 57 67 + [\]] 67 68 + [;] 68 69 +L73 + [return] 5 11 + [self] 12 16 + [;] 16 17 +L74 + [}] 1 2 +L76 + [-] 1 2 + [(] 3 4 + [void] 4 8 + [)] 8 9 + [setResponseSerializer] 9 30 + [:] 30 31 + [(] 31 32 + [AFHTTPResponseSerializer] 32 56 + [<] 57 58 + [AFURLResponseSerialization] 58 84 + [>] 84 85 + [*] 86 87 + [)] 87 88 + [responseSerializer] 88 106 + [{] 107 108 +L77 + [NSParameterAssert] 5 22 + [(] 22 23 + [responseSerializer] 23 41 + [)] 41 42 + [;] 42 43 +L79 + [\[] 5 6 + [self] 6 10 + [.] 10 11 + [lock] 11 15 + [lock] 16 20 + [\]] 20 21 + [;] 21 22 +L80 + [_responseSerializer] 5 24 + [=] 25 26 + [responseSerializer] 27 45 + [;] 45 46 +L81 + [self] 5 9 + [.] 9 10 + [responseObject] 10 24 + [=] 25 26 + [nil] 27 30 + [;] 30 31 +L82 + [self] 5 9 + [.] 9 10 + [responseSerializationError] 10 36 + [=] 37 38 + [nil] 39 42 + [;] 42 43 +L83 + [\[] 5 6 + [self] 6 10 + [.] 10 11 + [lock] 11 15 + [unlock] 16 22 + [\]] 22 23 + [;] 23 24 +L84 + [}] 1 2 +L86 + [-] 1 2 + [(] 3 4 + [id] 4 6 + [)] 6 7 + [responseObject] 7 21 + [{] 22 23 +L87 + [\[] 5 6 + [self] 6 10 + [.] 10 11 + [lock] 11 15 + [lock] 16 20 + [\]] 20 21 + [;] 21 22 +L88 + [if] 5 7 + [(] 8 9 + [!] 9 10 + [_responseObject] 10 25 + [&&] 26 28 + [\[] 29 30 + [self] 30 34 + [isFinished] 35 45 + [\]] 45 46 + [&&] 47 49 + [!] 50 51 + [self] 51 55 + [.] 55 56 + [error] 56 61 + [)] 61 62 + [{] 63 64 +L89 + [NSError] 9 16 + [*] 17 18 + [error] 18 23 + [=] 24 25 + [nil] 26 29 + [;] 29 30 +L90 + [self] 9 13 + [.] 13 14 + [responseObject] 14 28 + [=] 29 30 + [\[] 31 32 + [self] 32 36 + [.] 36 37 + [responseSerializer] 37 55 + [responseObjectForResponse] 56 81 + [:] 81 82 + [self] 82 86 + [.] 86 87 + [response] 87 95 + [data] 96 100 + [:] 100 101 + [self] 101 105 + [.] 105 106 + [responseData] 106 118 + [error] 119 124 + [:] 124 125 + [&] 125 126 + [error] 126 131 + [\]] 131 132 + [;] 132 133 +L91 + [if] 9 11 + [(] 12 13 + [error] 13 18 + [)] 18 19 + [{] 20 21 +L92 + [self] 13 17 + [.] 17 18 + [responseSerializationError] 18 44 + [=] 45 46 + [error] 47 52 + [;] 52 53 +L93 + [}] 9 10 +L94 + [}] 5 6 +L95 + [\[] 5 6 + [self] 6 10 + [.] 10 11 + [lock] 11 15 + [unlock] 16 22 + [\]] 22 23 + [;] 23 24 +L97 + [return] 5 11 + [_responseObject] 12 27 + [;] 27 28 +L98 + [}] 1 2 +L100 + [-] 1 2 + [(] 3 4 + [NSError] 4 11 + [*] 12 13 + [)] 13 14 + [error] 14 19 + [{] 20 21 +L101 + [if] 5 7 + [(] 8 9 + [_responseSerializationError] 9 36 + [)] 36 37 + [{] 38 39 +L102 + [return] 9 15 + [_responseSerializationError] 16 43 + [;] 43 44 +L103 + [}] 5 6 + [else] 7 11 + [{] 12 13 +L104 + [return] 9 15 + [\[] 16 17 + [super] 17 22 + [error] 23 28 + [\]] 28 29 + [;] 29 30 +L105 + [}] 5 6 +L106 + [}] 1 2 +L110 + [-] 1 2 + [(] 3 4 + [void] 4 8 + [)] 8 9 + [setCompletionBlockWithSuccess] 9 38 + [:] 38 39 + [success] 103 110 +L111 + [failure] 31 38 + [:] 38 39 + [failure] 100 107 +L112 + [{] 1 2 +L117 + [self] 5 9 + [.] 9 10 + [completionBlock] 10 25 + [=] 26 27 + [^] 28 29 + [{] 29 30 +L118 + [if] 9 11 + [(] 12 13 + [self] 13 17 + [.] 17 18 + [completionGroup] 18 33 + [)] 33 34 + [{] 35 36 +L119 + [dispatch_group_enter] 13 33 + [(] 33 34 + [self] 34 38 + [.] 38 39 + [completionGroup] 39 54 + [)] 54 55 + [;] 55 56 +L120 + [}] 9 10 +L122 + [dispatch_async] 9 23 + [(] 23 24 + [http_request_operation_processing_[ 24 63 + [(] 63 64 + [)] 64 65 + [,] 65 66 + [^] 67 68 + [{] 68 69 +L123 + [if] 13 15 + [(] 16 17 + [self] 17 21 + [.] 21 22 + [error] 22 27 + [)] 27 28 + [{] 29 30 +L124 + [if] 17 19 + [(] 20 21 + [failure] 21 28 + [)] 28 29 + [{] 30 31 +L125 + [dispatch_group_async] 21 41 + [(] 41 42 + [self] 42 46 + [.] 46 47 + [completionGroup] 47 62 + [?] 63 64 + [:] 64 65 + [http_request_operation_completion_[ 66 105 + [(] 105 106 + [)] 106 107 + [,] 107 108 + [self] 109 113 + [.] 113 114 + [completionQueue] 114 129 + [?] 130 131 + [:] 131 132 + [dispatch_get_main_queue] 133 156 + [(] 156 157 + [)] 157 158 + [,] 158 159 + [^] 160 161 + [{] 161 162 +L126 + [failure] 25 32 + [(] 32 33 + [self] 33 37 + [,] 37 38 + [self] 39 43 + [.] 43 44 + [error] 44 49 + [)] 49 50 + [;] 50 51 +L127 + [}] 21 22 + [)] 22 23 + [;] 23 24 +L128 + [}] 17 18 +L129 + [}] 13 14 + [else] 15 19 + [{] 20 21 +L130 + [id] 17 19 + [responseObject] 20 34 + [=] 35 36 + [self] 37 41 + [.] 41 42 + [responseObject] 42 56 + [;] 56 57 +L131 + [if] 17 19 + [(] 20 21 + [self] 21 25 + [.] 25 26 + [error] 26 31 + [)] 31 32 + [{] 33 34 +L132 + [if] 21 23 + [(] 24 25 + [failure] 25 32 + [)] 32 33 + [{] 34 35 +L133 + [dispatch_group_async] 25 45 + [(] 45 46 + [self] 46 50 + [.] 50 51 + [completionGroup] 51 66 + [?] 67 68 + [:] 68 69 + [http_request_operation_completion_[ 70 109 + [(] 109 110 + [)] 110 111 + [,] 111 112 + [self] 113 117 + [.] 117 118 + [completionQueue] 118 133 + [?] 134 135 + [:] 135 136 + [dispatch_get_main_queue] 137 160 + [(] 160 161 + [)] 161 162 + [,] 162 163 + [^] 164 165 + [{] 165 166 +L134 + [failure] 29 36 + [(] 36 37 + [self] 37 41 + [,] 41 42 + [self] 43 47 + [.] 47 48 + [error] 48 53 + [)] 53 54 + [;] 54 55 +L135 + [}] 25 26 + [)] 26 27 + [;] 27 28 +L136 + [}] 21 22 +L137 + [}] 17 18 + [else] 19 23 + [{] 24 25 +L138 + [if] 21 23 + [(] 24 25 + [success] 25 32 + [)] 32 33 + [{] 34 35 +L139 + [dispatch_group_async] 25 45 + [(] 45 46 + [self] 46 50 + [.] 50 51 + [completionGroup] 51 66 + [?] 67 68 + [:] 68 69 + [http_request_operation_completion_[ 70 109 + [(] 109 110 + [)] 110 111 + [,] 111 112 + [self] 113 117 + [.] 117 118 + [completionQueue] 118 133 + [?] 134 135 + [:] 135 136 + [dispatch_get_main_queue] 137 160 + [(] 160 161 + [)] 161 162 + [,] 162 163 + [^] 164 165 + [{] 165 166 +L140 + [success] 29 36 + [(] 36 37 + [self] 37 41 + [,] 41 42 + [responseObject] 43 57 + [)] 57 58 + [;] 58 59 +L141 + [}] 25 26 + [)] 26 27 + [;] 27 28 +L142 + [}] 21 22 +L143 + [}] 17 18 +L144 + [}] 13 14 +L146 + [if] 13 15 + [(] 16 17 + [self] 17 21 + [.] 21 22 + [completionGroup] 22 37 + [)] 37 38 + [{] 39 40 +L147 + [dispatch_group_leave] 17 37 + [(] 37 38 + [self] 38 42 + [.] 42 43 + [completionGroup] 43 58 + [)] 58 59 + [;] 59 60 +L148 + [}] 13 14 +L149 + [}] 9 10 + [)] 10 11 + [;] 11 12 +L150 + [}] 5 6 + [;] 6 7 +L152 + [}] 1 2 +L156 + [-] 1 2 + [(] 3 4 + [void] 4 8 + [)] 8 9 + [pause] 9 14 + [{] 15 16 +L157 + [\[] 5 6 + [super] 6 11 + [pause] 12 17 + [\]] 17 18 + [;] 18 19 +L159 + [u_int64_t] 5 14 + [offset] 15 21 + [=] 22 23 + [0] 24 25 + [;] 25 26 +L160 + [if] 5 7 + [(] 8 9 + [\[] 9 10 + [self] 10 14 + [.] 14 15 + [outputStream] 15 27 + [propertyForKey] 28 42 + [:] 42 43 + [NSStreamFileCurrentOffsetKey] 43 71 + [\]] 71 72 + [)] 72 73 + [{] 74 75 +L161 + [offset] 9 15 + [=] 16 17 + [\[] 18 19 + [(] 19 20 + [NSNumber] 20 28 + [*] 29 30 + [)] 30 31 + [\[] 31 32 + [self] 32 36 + [.] 36 37 + [outputStream] 37 49 + [propertyForKey] 50 64 + [:] 64 65 + [NSStreamFileCurrentOffsetKey] 65 93 + [\]] 93 94 + [unsignedLongLongValue] 95 116 + [\]] 116 117 + [;] 117 118 +L162 + [}] 5 6 + [else] 7 11 + [{] 12 13 +L163 + [offset] 9 15 + [=] 16 17 + [\[] 18 19 + [(] 19 20 + [NSData] 20 26 + [*] 27 28 + [)] 28 29 + [\[] 29 30 + [self] 30 34 + [.] 34 35 + [outputStream] 35 47 + [propertyForKey] 48 62 + [:] 62 63 + [NSStreamDataWrittenToMemoryStreamK[ 63 99 + [\]] 99 100 + [length] 101 107 + [\]] 107 108 + [;] 108 109 +L164 + [}] 5 6 +L166 + [NSMutableURLRequest] 5 24 + [*] 25 26 + [mutableURLRequest] 26 43 + [=] 44 45 + [\[] 46 47 + [self] 47 51 + [.] 51 52 + [request] 52 59 + [mutableCopy] 60 71 + [\]] 71 72 + [;] 72 73 +L167 + [if] 5 7 + [(] 8 9 + [\[] 9 10 + [self] 10 14 + [.] 14 15 + [response] 15 23 + [respondsToSelector] 24 42 + [:] 42 43 + [@selector] 43 52 + [(] 52 53 + [allHeaderFields] 53 68 + [)] 68 69 + [\]] 69 70 + [&&] 71 73 + [\[] 74 75 + [\[] 75 76 + [self] 76 80 + [.] 80 81 + [response] 81 89 + [allHeaderFields] 90 105 + [\]] 105 106 + [valueForKey] 107 118 + [:] 118 119 + [@"ETag"] 119 126 + [\]] 126 127 + [)] 127 128 + [{] 129 130 +L168 + [\[] 9 10 + [mutableURLRequest] 10 27 + [setValue] 28 36 + [:] 36 37 + [\[] 37 38 + [\[] 38 39 + [self] 39 43 + [.] 43 44 + [response] 44 52 + [allHeaderFields] 53 68 + [\]] 68 69 + [valueForKey] 70 81 + [:] 81 82 + [@"ETag"] 82 89 + [\]] 89 90 + [forHTTPHeaderField] 91 109 + [:] 109 110 + [@"If-Range"] 110 121 + [\]] 121 122 + [;] 122 123 +L169 + [}] 5 6 +L170 + [\[] 5 6 + [mutableURLRequest] 6 23 + [setValue] 24 32 + [:] 32 33 + [\[] 33 34 + [NSString] 34 42 + [stringWithFormat] 43 59 + [:] 59 60 + [@"bytes=%llu-"] 60 74 + [,] 74 75 + [offset] 76 82 + [\]] 82 83 + [forHTTPHeaderField] 84 102 + [:] 102 103 + [@"Range"] 103 111 + [\]] 111 112 + [;] 112 113 +L171 + [self] 5 9 + [.] 9 10 + [request] 10 17 + [=] 18 19 + [mutableURLRequest] 20 37 + [;] 37 38 +L172 + [}] 1 2 +L176 + [+] 1 2 + [(] 3 4 + [BOOL] 4 8 + [)] 8 9 + [supportsSecureCoding] 9 29 + [{] 30 31 +L177 + [return] 5 11 + [YES] 12 15 + [;] 15 16 +L178 + [}] 1 2 +L180 + [-] 1 2 + [(] 3 4 + [id] 4 6 + [)] 6 7 + [initWithCoder] 7 20 + [:] 20 21 + [(] 21 22 + [NSCoder] 22 29 + [*] 30 31 + [)] 31 32 + [decoder] 32 39 + [{] 40 41 +L181 + [self] 5 9 + [=] 10 11 + [\[] 12 13 + [super] 13 18 + [initWithCoder] 19 32 + [:] 32 33 + [decoder] 33 40 + [\]] 40 41 + [;] 41 42 +L182 + [if] 5 7 + [(] 8 9 + [!] 9 10 + [self] 10 14 + [)] 14 15 + [{] 16 17 +L183 + [return] 9 15 + [nil] 16 19 + [;] 19 20 +L184 + [}] 5 6 +L186 + [self] 5 9 + [.] 9 10 + [responseSerializer] 10 28 + [=] 29 30 + [\[] 31 32 + [decoder] 32 39 + [decodeObjectOfClass] 40 59 + [:] 59 60 + [\[] 60 61 + [AFHTTPResponseSerializer] 61 85 + [class] 86 91 + [\]] 91 92 + [forKey] 93 99 + [:] 99 100 + [NSStringFromSelector] 100 120 + [(] 120 121 + [@selector] 121 130 + [(] 130 131 + [responseSerializer] 131 149 + [)] 149 150 + [)] 150 151 + [\]] 151 152 + [;] 152 153 +L188 + [return] 5 11 + [self] 12 16 + [;] 16 17 +L189 + [}] 1 2 +L191 + [-] 1 2 + [(] 3 4 + [void] 4 8 + [)] 8 9 + [encodeWithCoder] 9 24 + [:] 24 25 + [(] 25 26 + [NSCoder] 26 33 + [*] 34 35 + [)] 35 36 + [coder] 36 41 + [{] 42 43 +L192 + [\[] 5 6 + [super] 6 11 + [encodeWithCoder] 12 27 + [:] 27 28 + [coder] 28 33 + [\]] 33 34 + [;] 34 35 +L194 + [\[] 5 6 + [coder] 6 11 + [encodeObject] 12 24 + [:] 24 25 + [self] 25 29 + [.] 29 30 + [responseSerializer] 30 48 + [forKey] 49 55 + [:] 55 56 + [NSStringFromSelector] 56 76 + [(] 76 77 + [@selector] 77 86 + [(] 86 87 + [responseSerializer] 87 105 + [)] 105 106 + [)] 106 107 + [\]] 107 108 + [;] 108 109 +L195 + [}] 1 2 +L199 + [-] 1 2 + [(] 3 4 + [id] 4 6 + [)] 6 7 + [copyWithZone] 7 19 + [:] 19 20 + [(] 20 21 + [NSZone] 21 27 + [*] 28 29 + [)] 29 30 + [zone] 30 34 + [{] 35 36 +L200 + [AFHTTPRequestOperation] 5 27 + [*] 28 29 + [operation] 29 38 + [=] 39 40 + [\[] 41 42 + [super] 42 47 + [copyWithZone] 48 60 + [:] 60 61 + [zone] 61 65 + [\]] 65 66 + [;] 66 67 +L202 + [operation] 5 14 + [.] 14 15 + [responseSerializer] 15 33 + [=] 34 35 + [\[] 36 37 + [self] 37 41 + [.] 41 42 + [responseSerializer] 42 60 + [copyWithZone] 61 73 + [:] 73 74 + [zone] 74 78 + [\]] 78 79 + [;] 79 80 +L203 + [operation] 5 14 + [.] 14 15 + [completionQueue] 15 30 + [=] 31 32 + [self] 33 37 + [.] 37 38 + [completionQueue] 38 53 + [;] 53 54 +L204 + [operation] 5 14 + [.] 14 15 + [completionGroup] 15 30 + [=] 31 32 + [self] 33 37 + [.] 37 38 + [completionGroup] 38 53 + [;] 53 54 +L206 + [return] 5 11 + [operation] 12 21 + [;] 21 22 +L207 + [}] 1 2 +L209 + [@end] 1 5 +EOF diff --git a/pmd-objectivec/src/test/resources/net/sourceforge/pmd/cpd/NCClient.m b/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/unicodeCharInIdent.m similarity index 100% rename from pmd-objectivec/src/test/resources/net/sourceforge/pmd/cpd/NCClient.m rename to pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/unicodeCharInIdent.m diff --git a/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/unicodeCharInIdent.txt b/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/unicodeCharInIdent.txt new file mode 100644 index 0000000000..cb5eaba553 --- /dev/null +++ b/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/unicodeCharInIdent.txt @@ -0,0 +1,14 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [@] 1 2 + [import] 2 8 + [UIKit] 9 14 + [;] 14 15 +L4 + [static] 1 7 + [SecCertificateRef] 8 25 + [gNСServerLogonCertificate] 26 51 + [;] 51 52 +L6 + [@end] 1 5 +EOF diff --git a/pmd-objectivec/src/test/resources/net/sourceforge/pmd/cpd/FileWithUTF8EscapeInStringLiteral.m b/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/unicodeEscapeInString.m similarity index 100% rename from pmd-objectivec/src/test/resources/net/sourceforge/pmd/cpd/FileWithUTF8EscapeInStringLiteral.m rename to pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/unicodeEscapeInString.m diff --git a/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/unicodeEscapeInString.txt b/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/unicodeEscapeInString.txt new file mode 100644 index 0000000000..910762c55a --- /dev/null +++ b/pmd-objectivec/src/test/resources/net/sourceforge/pmd/lang/objc/cpd/testdata/unicodeEscapeInString.txt @@ -0,0 +1,52 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [@property] 1 10 + [(] 11 12 + [nonatomic] 12 21 + [,] 21 22 + [strong] 23 29 + [)] 29 30 + [UIButton] 31 39 + [*] 40 41 + [copyrightsButton] 41 57 + [;] 57 58 +L3 + [-] 1 2 + [(] 3 4 + [void] 4 8 + [)] 8 9 + [setupCopyrightsButton] 9 30 + [{] 31 32 +L4 + [self] 5 9 + [.] 9 10 + [copyrightsButton] 10 26 + [=] 27 28 + [\[] 29 30 + [\[] 30 31 + [UIButton] 31 39 + [alloc] 40 45 + [\]] 45 46 + [initWithFrame] 47 60 + [:] 60 61 + [CGRectZero] 61 71 + [\]] 71 72 + [;] 72 73 +L5 + [\[] 5 6 + [self] 6 10 + [.] 10 11 + [copyrightsButton] 11 27 + [setTitle] 28 36 + [:] 36 37 + [@"\\u00a9"] 37 46 + [forState] 47 55 + [:] 55 56 + [UIControlStateNormal] 56 76 + [\]] 76 77 + [;] 77 78 +L6 + [}] 1 2 +L8 + [@end] 1 5 +EOF diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/cpd/PLSQLTokenizerTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/cpd/PLSQLTokenizerTest.java index 06726f3c80..397d078aec 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/cpd/PLSQLTokenizerTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/cpd/PLSQLTokenizerTest.java @@ -4,53 +4,36 @@ package net.sourceforge.pmd.cpd; -import static org.junit.Assert.assertEquals; +import java.util.Properties; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.PMD; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -public class PLSQLTokenizerTest extends AbstractTokenizerTest { +public class PLSQLTokenizerTest extends CpdTextComparisonTest { - private static final String FILENAME = "sample-plsql.sql"; - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new PLSQLTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), FILENAME)); + public PLSQLTokenizerTest() { + super(".sql"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(PLSQLTokenizer.class.getResourceAsStream(FILENAME), StandardCharsets.UTF_8); + protected String getResourcePrefix() { + return "../lang/plsql/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new PLSQLTokenizer(); + } + + + @Test + public void testSimple() { + doTest("sample-plsql"); } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 1422; - super.tokenizeTest(); - } - - @Test - public void testIgnoreBetweenSpecialComments() throws IOException { - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("-- CPD-OFF" + PMD.EOL - + "CREATE OR REPLACE" + PMD.EOL - + "PACKAGE \"test_schema\".\"BANK_DATA\"" + PMD.EOL - + "IS" + PMD.EOL - + "pi CONSTANT NUMBER := 3.1415;" + PMD.EOL - + "--CPD-ON" + PMD.EOL - + "END;" - )); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - assertEquals(3, tokens.size()); // 3 tokens: "END" + ";" + EOF + public void testSpecialComments() { + doTest("specialComments"); } } diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/cpd/sample-plsql.sql b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.sql similarity index 100% rename from pmd-plsql/src/test/resources/net/sourceforge/pmd/cpd/sample-plsql.sql rename to pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.sql diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.txt new file mode 100644 index 0000000000..74e9b756e6 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.txt @@ -0,0 +1,1729 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [CREATE] 1 7 + [OR] 8 10 + [REPLACE] 11 18 +L2 + [PACKAGE] 1 8 + ["test_schema"] 9 22 + [.] 22 23 + ["BANK_DATA"] 23 34 +L3 + [IS] 1 3 +L19 + [pi] 1 3 + [CONSTANT] 5 13 + [NUMBER] 14 20 + [:] 21 22 + [=] 22 23 + [3.1415] 24 30 + [;] 30 31 +L20 + [c] 1 2 + [CONSTANT] 5 13 + [NUMBER] 14 20 + [:] 21 22 + [=] 22 23 + [3.2e9] 24 29 + [;] 29 30 +L21 + [d] 1 2 + [CONSTANT] 5 13 + [NUMBER] 14 20 + [:] 21 22 + [=] 22 23 + [3.2E9] 24 29 + [;] 29 30 +L22 + [year_created] 1 13 + [CONSTANT] 14 22 + [NUMBER] 23 29 + [:] 30 31 + [=] 31 32 + [2001] 33 37 + [;] 37 38 +L23 + [author] 1 7 + [CONSTANT] 9 17 + [VARCHAR2] 18 26 + [(] 26 27 + [100] 27 30 + [)] 30 31 + [:] 32 33 + [=] 33 34 + ['altumano ''the wolf'''] 35 58 + [;] 58 59 +L24 + [date_created] 1 13 + [CONSTANT] 15 23 + [DATE] 24 28 + [:] 29 30 + [=] 30 31 + ['29-oct-01'] 32 43 + [;] 43 44 +L29 + [TYPE] 1 5 + [assc_array] 6 16 + [IS] 17 19 + [TABLE] 20 25 + [OF] 26 28 + [INTEGER] 29 36 + [INDEX] 37 42 + [BY] 43 45 + [VARCHAR2] 46 54 + [(] 54 55 + [30] 55 57 + [)] 57 58 + [;] 58 59 +L34 + [TYPE] 1 5 + [bank_type] 6 15 + [IS] 16 18 + [RECORD] 19 25 + [(] 26 27 +L35 + [id] 3 5 + [VARCHAR2] 30 38 + [(] 38 39 + [20] 39 41 + [)] 41 42 + [,] 42 43 +L36 + [name] 3 7 + [VARCHAR2] 30 38 + [(] 38 39 + [100] 39 42 + [)] 42 43 + [,] 43 44 +L37 + [address] 3 10 + [VARCHAR2] 30 38 + [(] 38 39 + [105] 39 42 + [)] 42 43 + [,] 43 44 +L38 + [location] 3 11 + [VARCHAR2] 30 38 + [(] 38 39 + [35] 39 41 + [)] 41 42 + [,] 42 43 +L39 + [bic] 3 6 + [VARCHAR2] 30 38 + [(] 38 39 + [20] 39 41 + [)] 41 42 + [,] 42 43 +L40 + [auth_key] 3 11 + [VARCHAR2] 30 38 + [(] 38 39 + [1] 39 40 + [)] 40 41 + [,] 41 42 +L41 + [contact] 3 10 + [VARCHAR2] 30 38 + [(] 38 39 + [100] 39 42 + [)] 42 43 + [,] 43 44 +L42 + [phone] 3 8 + [VARCHAR2] 30 38 + [(] 38 39 + [50] 39 41 + [)] 41 42 + [,] 42 43 +L43 + [fax] 3 6 + [VARCHAR2] 30 38 + [(] 38 39 + [50] 39 41 + [)] 41 42 + [,] 42 43 +L44 + [telex] 3 8 + [VARCHAR2] 30 38 + [(] 38 39 + [100] 39 42 + [)] 42 43 + [,] 43 44 +L45 + [medium] 3 9 + [VARCHAR2] 30 38 + [(] 38 39 + [255] 39 42 + [)] 42 43 + [,] 43 44 +L46 + [mod_time] 3 11 + [DATE] 30 34 + [,] 34 35 +L47 + [app_user] 3 11 + [VARCHAR2] 30 38 + [(] 38 39 + [20] 39 41 + [)] 41 42 + [,] 42 43 +L48 + [db_user] 3 10 + [VARCHAR2] 30 38 + [(] 38 39 + [20] 39 41 + [)] 41 42 + [,] 42 43 +L49 + [customer_id] 3 14 + [VARCHAR2] 30 38 + [(] 38 39 + [20] 39 41 + [)] 41 42 +L50 + [)] 1 2 + [;] 2 3 +L54 + [TYPE] 1 5 + [bank_table] 6 16 + [IS] 17 19 + [TABLE] 20 25 + [OF] 26 28 + [bank_type] 29 38 + [INDEX] 39 44 + [BY] 45 47 + [BINARY_INTEGER] 48 62 + [;] 62 63 +L58 + [TYPE] 1 5 + [ref_type] 6 14 + [IS] 15 17 + [REF] 18 21 + [CURSOR] 22 28 + [RETURN] 29 35 + [bank_type] 36 45 + [;] 45 46 +L63 + [SUBTYPE] 1 8 + [files_record] 9 21 + [IS] 22 24 + [files] 25 30 + [%] 30 31 + [ROWTYPE] 31 38 + [;] 38 39 +L66 + [current_pi] 1 11 + [NUMBER] 12 18 + [:] 19 20 + [=] 20 21 + [3.1415] 22 28 + [;] 28 29 +L67 + [current_year] 1 13 + [NUMBER] 14 20 + [:] 21 22 + [=] 22 23 + [2002] 24 28 + [;] 28 29 +L68 + [current_author] 1 15 + [VARCHAR2] 16 24 + [(] 24 25 + [100] 25 28 + [)] 28 29 + [:] 30 31 + [=] 31 32 + ['\\altumano\\ `the wolf` äöüõç'] 33 62 + [;] 62 63 +L69 + [current_date] 1 13 + [DATE] 15 19 + [:] 20 21 + [=] 21 22 + ['24-feb-02'] 23 34 + [;] 34 35 +L72 + [cursor] 1 7 + [cur1] 8 12 + [(] 12 13 + [a] 13 14 + [varchar2] 15 23 + [,] 23 24 + [b] 25 26 + [number] 27 33 + [,] 33 34 + [c] 35 36 + [date] 37 41 + [,] 41 42 + [d] 43 44 + [boolean] 45 52 + [)] 52 53 + [return] 54 60 + [customer] 61 69 + [%] 69 70 + [rowtype] 70 77 + [;] 77 78 +L73 + [cursor] 1 7 + [cur2] 8 12 + [(] 12 13 + [a] 13 14 + [varchar2] 15 23 + [,] 23 24 + [b] 25 26 + [number] 27 33 + [,] 33 34 + [c] 35 36 + [date] 37 41 + [,] 41 42 + [d] 43 44 + [boolean] 45 52 + [)] 52 53 + [is] 54 56 + [select] 57 63 + [*] 64 65 + [from] 66 70 + [customer] 71 79 + [where] 80 85 + [id] 86 88 + [=] 89 90 + ['1'] 91 94 + [;] 94 95 +L86 + [FUNCTION] 1 9 + [Get] 10 13 + [(] 14 15 +L87 + [p_id] 3 7 + [VARCHAR2] 21 29 + [,] 29 30 +L88 + [r_bank_rec] 3 13 + [OUT] 21 24 + [bank_type] 25 34 + [,] 34 35 +L89 + [r_message] 3 12 + [OUT] 21 24 + [VARCHAR2] 25 33 + [)] 33 34 +L90 + [RETURN] 1 7 + [NUMBER] 8 14 + [;] 14 15 +L93 + [PROCEDURE] 1 10 + [Without_Parameters] 11 29 + [;] 29 30 +L96 + [FUNCTION] 1 9 + [Get_Without_Parameters] 10 32 + [;] 32 33 +L112 + [PROCEDURE] 1 10 + [Get_By_ID] 11 20 + [(] 21 22 +L113 + [p_id] 3 7 + [IN] 21 23 + [VARCHAR2] 24 32 + [,] 32 33 +L114 + [r_records] 3 12 + [IN] 21 23 + [OUT] 24 27 + [bank_table] 28 38 + [)] 38 39 + [;] 39 40 +L123 + [PROCEDURE] 1 10 + [Get_by_BIC] 11 21 + [(] 22 23 +L124 + [p_bic] 3 8 + [VARCHAR2] 21 29 + [,] 29 30 +L125 + [r_bank_rec] 3 13 + [OUT] 21 24 + [bank_type] 25 34 + [,] 34 35 +L126 + [r_result] 3 11 + [OUT] 21 24 + [NUMBER] 25 31 + [,] 31 32 +L127 + [r_message] 3 12 + [OUT] 21 24 + [VARCHAR2] 25 33 + [)] 33 34 + [;] 34 35 +L130 + [PROCEDURE] 1 10 + [Get_By_BIC] 11 21 + [(] 22 23 +L131 + [p_bic] 3 8 + [VARCHAR2] 21 29 + [,] 29 30 +L132 + [r_record] 3 11 + [IN] 21 23 + [OUT] 24 27 + [bank_type] 28 37 + [)] 37 38 + [;] 38 39 +L145 + [FUNCTION] 1 9 + [Get_Table] 10 19 + [(] 20 21 +L146 + [p_id] 3 7 + [VARCHAR2] 21 29 + [,] 29 30 +L147 + [r_bank_tab] 3 13 + [IN] 21 23 + [OUT] 24 27 + [bank_table] 28 38 + [,] 38 39 +L148 + [r_result] 3 11 + [OUT] 21 24 + [NUMBER] 25 31 + [,] 31 32 +L149 + [r_message] 3 12 + [OUT] 21 24 + [VARCHAR2] 25 33 + [)] 33 34 +L150 + [RETURN] 1 7 + [varchar2] 8 16 + [;] 16 17 +L162 + [PROCEDURE] 1 10 + [Search] 11 17 + [(] 18 19 +L163 + [p_id] 3 7 + [VARCHAR2] 21 29 + [,] 29 30 +L164 + [p_bic] 3 8 + [VARCHAR2] 21 29 + [,] 29 30 +L165 + [p_name] 3 9 + [VARCHAR2] 21 29 + [,] 29 30 +L166 + [p_address] 3 12 + [VARCHAR2] 21 29 + [,] 29 30 +L167 + [p_location] 3 13 + [VARCHAR2] 21 29 + [,] 29 30 +L168 + [r_bank_tab] 3 13 + [IN] 21 23 + [OUT] 24 27 + [bank_table] 28 38 + [,] 38 39 +L169 + [r_result] 3 11 + [OUT] 21 24 + [NUMBER] 25 31 + [,] 31 32 +L170 + [r_message] 3 12 + [OUT] 21 24 + [VARCHAR2] 25 33 + [)] 33 34 + [;] 34 35 +L176 + [PROCEDURE] 1 10 + [Get] 11 14 + [(] 15 16 +L177 + [p_id] 3 7 + [VARCHAR2] 21 29 + [,] 29 30 +L178 + [p_bic] 3 8 + [VARCHAR2] 21 29 + [,] 29 30 +L179 + [p_name] 3 9 + [VARCHAR2] 21 29 + [,] 29 30 +L180 + [p_address] 3 12 + [VARCHAR2] 21 29 + [,] 29 30 +L181 + [p_location] 3 13 + [VARCHAR2] 21 29 + [,] 29 30 +L182 + [r_bank_tab] 3 13 + [IN] 21 23 + [OUT] 24 27 + [bank_table] 28 38 + [)] 38 39 + [;] 39 40 +L190 + [PROCEDURE] 1 10 + [Get_By_Criteria] 11 26 + [(] 27 28 +L191 + [p_criteria] 3 13 + [bank_type] 21 30 + [,] 30 31 +L192 + [r_bank_tab] 3 13 + [IN] 21 23 + [OUT] 24 27 + [bank_table] 28 38 + [,] 38 39 +L193 + [r_result] 3 11 + [OUT] 21 24 + [NUMBER] 25 31 + [,] 31 32 +L194 + [r_message] 3 12 + [OUT] 21 24 + [VARCHAR2] 25 33 + [)] 33 34 + [;] 34 35 +L197 + [PROCEDURE] 1 10 + [Ins] 11 14 + [(] 15 16 +L198 + [p_data] 3 9 + [IN] 21 23 + [bank_type] 24 33 + [)] 33 34 + [;] 34 35 +L201 + [PROCEDURE] 1 10 + [Ins_Table] 11 20 + [(] 21 22 +L202 + [p_data] 3 9 + [IN] 21 23 + [bank_table] 24 34 + [)] 34 35 + [;] 35 36 +L205 + [PROCEDURE] 1 10 + [Upd] 11 14 + [(] 15 16 +L206 + [p_data] 3 9 + [IN] 21 23 + [bank_type] 24 33 + [)] 33 34 + [;] 34 35 +L213 + [PROCEDURE] 1 10 + [Upd_Table] 11 20 + [(] 21 22 +L214 + [p_data] 3 9 + [IN] 21 23 + [bank_table] 24 34 + [)] 34 35 + [;] 35 36 +L217 + [PROCEDURE] 1 10 + [Del] 11 14 + [(] 15 16 +L218 + [p_data] 3 9 + [IN] 21 23 + [bank_type] 24 33 + [)] 33 34 + [;] 34 35 +L221 + [PROCEDURE] 1 10 + [Del_Table] 11 20 + [(] 21 22 +L222 + [p_data] 3 9 + [IN] 21 23 + [bank_table] 24 34 + [)] 34 35 + [;] 35 36 +L225 + [PROCEDURE] 1 10 + [Lck] 11 14 + [(] 15 16 +L226 + [p_data] 3 9 + [IN] 21 23 + [bank_type] 24 33 + [)] 33 34 + [;] 34 35 +L229 + [PROCEDURE] 1 10 + [Lck_Table] 11 20 + [(] 21 22 +L230 + [p_data] 3 9 + [IN] 21 23 + [bank_table] 24 34 + [)] 34 35 + [;] 35 36 +L233 + [PROCEDURE] 1 10 + [Get_Our] 11 18 + [(] 19 20 +L234 + [r_ourbank] 3 12 + [OUT] 21 24 + [bank_data] 25 34 + [.] 34 35 + [bank_type] 35 44 + [,] 44 45 +L235 + [r_result] 3 11 + [OUT] 21 24 + [NUMBER] 25 31 + [,] 31 32 +L236 + [r_message] 3 12 + [OUT] 21 24 + [VARCHAR2] 25 33 + [)] 33 34 + [;] 34 35 +L240 + [END] 1 4 + [;] 4 5 +L241 + [/] 1 2 +L243 + [CREATE] 1 7 + [OR] 8 10 + [REPLACE] 11 18 +L244 + [PACKAGE] 1 8 + [Advice_Data] 9 20 +L245 + [IS] 1 3 +L257 + [SUBTYPE] 1 8 + [advice_type_record] 9 27 + [IS] 28 30 + [advice_type] 31 42 + [%] 42 43 + [ROWTYPE] 43 50 + [;] 50 51 +L258 + [TYPE] 1 5 + [advice_type_table] 6 23 + [IS] 24 26 + [TABLE] 27 32 + [OF] 33 35 + [advice_type_record] 36 54 + [INDEX] 55 60 + [BY] 61 63 + [BINARY_INTEGER] 64 78 + [;] 78 79 +L260 + [SUBTYPE] 1 8 + [advice_medium_record] 9 29 + [IS] 30 32 + [advice_medium] 33 46 + [%] 46 47 + [ROWTYPE] 47 54 + [;] 54 55 +L261 + [TYPE] 1 5 + [advice_medium_table] 6 25 + [IS] 26 28 + [TABLE] 29 34 + [OF] 35 37 + [advice_medium_record] 38 58 + [INDEX] 59 64 + [BY] 65 67 + [BINARY_INTEGER] 68 82 + [;] 82 83 +L263 + [SUBTYPE] 1 8 + [advice_record] 9 22 + [IS] 23 25 + [advices] 26 33 + [%] 33 34 + [ROWTYPE] 34 41 + [;] 41 42 +L264 + [TYPE] 1 5 + [advice_table] 6 18 + [IS] 19 21 + [TABLE] 22 27 + [OF] 28 30 + [advice_record] 31 44 + [INDEX] 45 50 + [BY] 51 53 + [BINARY_INTEGER] 54 68 + [;] 68 69 +L266 + [SUBTYPE] 1 8 + [sw_advice_record] 9 25 + [IS] 26 28 + [sw_advice] 29 38 + [%] 38 39 + [ROWTYPE] 39 46 + [;] 46 47 +L267 + [TYPE] 1 5 + [sw_advice_table] 6 21 + [IS] 22 24 + [TABLE] 25 30 + [OF] 31 33 + [sw_advice_record] 34 50 + [INDEX] 51 56 + [BY] 57 59 + [BINARY_INTEGER] 60 74 + [;] 74 75 +L269 + [SUBTYPE] 1 8 + [files_record] 9 21 + [IS] 22 24 + [files] 25 30 + [%] 30 31 + [ROWTYPE] 31 38 + [;] 38 39 +L270 + [TYPE] 1 5 + [files_table] 6 17 + [IS] 18 20 + [TABLE] 21 26 + [OF] 27 29 + [files_record] 30 42 + [INDEX] 43 48 + [BY] 49 51 + [BINARY_INTEGER] 52 66 + [;] 66 67 +L273 + [FUNCTION] 1 9 + [Get_Advice_Types] 10 26 + [(] 27 28 +L274 + [r_list] 3 9 + [OUT] 21 24 + [advice_type_table] 25 42 + [)] 42 43 +L275 + [RETURN] 1 7 + [NUMBER] 8 14 + [;] 14 15 +L289 + [PROCEDURE] 1 10 + [Get_Advice_Defaults] 11 30 + [(] 31 32 +L290 + [p_sector] 3 11 + [VARCHAR2] 21 29 + [,] 29 30 +L291 + [p_dir] 3 8 + [VARCHAR2] 21 29 + [,] 29 30 +L292 + [p_type] 3 9 + [VARCHAR2] 21 29 + [,] 29 30 +L293 + [def_medium] 3 13 + [OUT] 21 24 + [VARCHAR2] 25 33 + [,] 33 34 +L294 + [def_medium_option] 3 20 + [OUT] 21 24 + [VARCHAR2] 25 33 + [,] 33 34 +L295 + [def_party] 3 12 + [OUT] 21 24 + [VARCHAR2] 25 33 + [,] 33 34 +L296 + [party_fixed] 3 14 + [OUT] 21 24 + [VARCHAR2] 25 33 + [,] 33 34 +L297 + [r_result] 3 11 + [OUT] 21 24 + [NUMBER] 25 31 + [,] 31 32 +L298 + [r_message] 3 12 + [OUT] 21 24 + [VARCHAR2] 25 33 + [)] 33 34 + [;] 34 35 +L302 + [FUNCTION] 1 9 + [Get_Advice_Type_Name] 10 30 + [(] 31 32 +L303 + [p_type] 3 9 + [VARCHAR2] 21 29 + [)] 29 30 +L304 + [RETURN] 1 7 + [VARCHAR2] 8 16 + [;] 16 17 +L314 + [PROCEDURE] 1 10 + [Get_Advice_Medium] 11 28 + [(] 29 30 +L315 + [p_adv_type] 3 13 + [VARCHAR2] 21 29 + [,] 29 30 +L316 + [p_medium] 3 11 + [VARCHAR2] 21 29 + [,] 29 30 +L317 + [p_medium_option] 3 18 + [VARCHAR2] 21 29 + [,] 29 30 +L318 + [r_rec] 3 8 + [IN] 21 23 + [OUT] 24 27 + [advice_medium_record] 28 48 + [,] 48 49 +L319 + [r_result] 3 11 + [IN] 21 23 + [OUT] 24 27 + [NUMBER] 28 34 + [,] 34 35 +L320 + [r_message] 3 12 + [IN] 21 23 + [OUT] 24 27 + [VARCHAR2] 28 36 + [)] 36 37 + [;] 37 38 +L323 + [PROCEDURE] 1 10 + [Get] 11 14 + [(] 15 16 +L324 + [p_contract_id] 3 16 + [VARCHAR2] 21 29 + [,] 29 30 +L325 + [p_step_seq] 3 13 + [NUMBER] 21 27 + [,] 27 28 +L326 + [p_seq] 3 8 + [NUMBER] 21 27 + [,] 27 28 +L327 + [r_rec] 3 8 + [IN] 21 23 + [OUT] 24 27 + [advice_record] 28 41 + [,] 41 42 +L328 + [r_result] 3 11 + [IN] 21 23 + [OUT] 24 27 + [NUMBER] 28 34 + [,] 34 35 +L329 + [r_message] 3 12 + [IN] 21 23 + [OUT] 24 27 + [VARCHAR2] 28 36 + [)] 36 37 + [;] 37 38 +L332 + [PROCEDURE] 1 10 + [List_Advices] 11 23 + [(] 24 25 +L333 + [p_contract_id] 3 16 + [VARCHAR2] 21 29 + [,] 29 30 +L334 + [p_step_seq] 3 13 + [NUMBER] 21 27 + [,] 27 28 +L335 + [p_in_out] 3 11 + [VARCHAR2] 21 29 + [,] 29 30 +L336 + [r_result] 3 11 + [IN] 21 23 + [OUT] 24 27 + [NUMBER] 28 34 + [,] 34 35 +L337 + [r_message] 3 12 + [IN] 21 23 + [OUT] 24 27 + [VARCHAR2] 28 36 + [,] 36 37 +L338 + [r_list] 3 9 + [IN] 21 23 + [OUT] 24 27 + [advice_table] 28 40 + [)] 40 41 + [;] 41 42 +L341 + [PROCEDURE] 1 10 + [Ins] 11 14 + [(] 15 16 +L342 + [p] 3 4 + [IN] 23 25 + [OUT] 26 29 + [advice_record] 30 43 + [,] 43 44 +L343 + [r_result] 3 11 + [OUT] 23 26 + [NUMBER] 27 33 + [,] 33 34 +L344 + [r_message] 3 12 + [OUT] 23 26 + [VARCHAR2] 27 35 + [)] 35 36 + [;] 36 37 +L347 + [PROCEDURE] 1 10 + [Del] 11 14 + [(] 15 16 +L348 + [p] 3 4 + [IN] 23 25 + [OUT] 26 29 + [advice_record] 30 43 + [,] 43 44 +L349 + [r_result] 3 11 + [OUT] 23 26 + [NUMBER] 27 33 + [,] 33 34 +L350 + [r_message] 3 12 + [OUT] 23 26 + [VARCHAR2] 27 35 + [)] 35 36 + [;] 36 37 +L353 + [PROCEDURE] 1 10 + [Ins_SW_Advice] 11 24 + [(] 25 26 +L354 + [p] 3 4 + [IN] 23 25 + [OUT] 26 29 + [sw_advice_record] 30 46 + [,] 46 47 +L355 + [r_result] 3 11 + [OUT] 23 26 + [NUMBER] 27 33 + [,] 33 34 +L356 + [r_message] 3 12 + [OUT] 23 26 + [VARCHAR2] 27 35 + [)] 35 36 + [;] 36 37 +L359 + [PROCEDURE] 1 10 + [Get_SW_Advice] 11 24 + [(] 25 26 +L360 + [p_id] 3 7 + [VARCHAR2] 21 29 + [,] 29 30 +L361 + [r_list] 3 9 + [IN] 21 23 + [OUT] 24 27 + [sw_advice_table] 28 43 + [,] 43 44 +L362 + [r_result] 3 11 + [IN] 21 23 + [OUT] 24 27 + [NUMBER] 28 34 + [,] 34 35 +L363 + [r_message] 3 12 + [IN] 21 23 + [OUT] 24 27 + [VARCHAR2] 28 36 + [)] 36 37 + [;] 37 38 +L366 + [PROCEDURE] 1 10 + [Ins_File] 11 19 + [(] 20 21 +L367 + [p] 3 4 + [IN] 23 25 + [OUT] 26 29 + [files_record] 30 42 + [,] 42 43 +L368 + [r_result] 3 11 + [OUT] 23 26 + [NUMBER] 27 33 + [,] 33 34 +L369 + [r_message] 3 12 + [OUT] 23 26 + [VARCHAR2] 27 35 + [)] 35 36 + [;] 36 37 +L372 + [PROCEDURE] 1 10 + [Get_Files] 11 20 + [(] 21 22 +L373 + [p_doc_id] 3 11 + [VARCHAR2] 21 29 + [,] 29 30 +L374 + [r_list] 3 9 + [IN] 21 23 + [OUT] 24 27 + [files_table] 28 39 + [,] 39 40 +L375 + [r_result] 3 11 + [IN] 21 23 + [OUT] 24 27 + [NUMBER] 28 34 + [,] 34 35 +L376 + [r_message] 3 12 + [IN] 21 23 + [OUT] 24 27 + [VARCHAR2] 28 36 + [)] 36 37 + [;] 37 38 +L386 + [PROCEDURE] 1 10 + [CFR_Advice_Out] 11 25 + [(] 26 27 +L387 + [p_contract_id] 3 16 + [VARCHAR2] 21 29 + [,] 29 30 +L388 + [p_step] 3 9 + [NUMBER] 21 27 + [,] 27 28 +L389 + [p_app_user] 3 13 + [VARCHAR2] 21 29 + [,] 29 30 +L390 + [r_result] 3 11 + [IN] 21 23 + [OUT] 24 27 + [NUMBER] 28 34 + [,] 34 35 +L391 + [r_message] 3 12 + [IN] 21 23 + [OUT] 24 27 + [VARCHAR2] 28 36 + [)] 36 37 + [;] 37 38 +L401 + [PROCEDURE] 1 10 + [CFR_Advice_In] 11 24 + [(] 25 26 +L402 + [p_contract_id] 3 16 + [VARCHAR2] 21 29 + [,] 29 30 +L403 + [p_step] 3 9 + [NUMBER] 21 27 + [,] 27 28 +L404 + [p_app_user] 3 13 + [VARCHAR2] 21 29 + [,] 29 30 +L405 + [r_result] 3 11 + [IN] 21 23 + [OUT] 24 27 + [NUMBER] 28 34 + [,] 34 35 +L406 + [r_message] 3 12 + [IN] 21 23 + [OUT] 24 27 + [VARCHAR2] 28 36 + [)] 36 37 + [;] 37 38 +L416 + [PROCEDURE] 1 10 + [Release_Advice_Out] 11 29 + [(] 30 31 +L417 + [p_contract_id] 3 16 + [VARCHAR2] 21 29 + [,] 29 30 +L418 + [p_step] 3 9 + [NUMBER] 21 27 + [,] 27 28 +L419 + [p_app_user] 3 13 + [VARCHAR2] 21 29 + [,] 29 30 +L420 + [r_result] 3 11 + [IN] 21 23 + [OUT] 24 27 + [NUMBER] 28 34 + [,] 34 35 +L421 + [r_message] 3 12 + [IN] 21 23 + [OUT] 24 27 + [VARCHAR2] 28 36 + [)] 36 37 + [;] 37 38 +L431 + [PROCEDURE] 1 10 + [Release_Advice_In] 11 28 + [(] 29 30 +L432 + [p_contract_id] 3 16 + [VARCHAR2] 21 29 + [,] 29 30 +L433 + [p_step] 3 9 + [NUMBER] 21 27 + [,] 27 28 +L434 + [p_app_user] 3 13 + [VARCHAR2] 21 29 + [,] 29 30 +L435 + [r_result] 3 11 + [IN] 21 23 + [OUT] 24 27 + [NUMBER] 28 34 + [,] 34 35 +L436 + [r_message] 3 12 + [IN] 21 23 + [OUT] 24 27 + [VARCHAR2] 28 36 + [)] 36 37 + [;] 37 38 +L438 + [END] 1 4 + [;] 4 5 +L439 + [/] 1 2 +L442 + [CREATE] 1 7 + [OR] 8 10 + [REPLACE] 11 18 +L443 + [PACKAGE] 1 8 + [CUSTOMER_DATA] 9 22 +L444 + [IS] 1 3 +L458 + [record_locked] 1 14 + [EXCEPTION] 15 24 + [;] 24 25 +L460 + [TYPE] 1 5 + [customer_type] 6 19 + [IS] 20 22 + [RECORD] 23 29 + [(] 30 31 +L461 + [id] 3 5 + [VARCHAR2] 29 37 + [(] 37 38 + [20] 38 40 + [)] 40 41 + [,] 41 42 +L462 + [name] 3 7 + [VARCHAR2] 29 37 + [(] 37 38 + [100] 38 41 + [)] 41 42 + [,] 42 43 +L463 + [short_name] 3 13 + [VARCHAR2] 29 37 + [(] 37 38 + [35] 38 40 + [)] 40 41 + [,] 41 42 +L464 + [db_id] 3 8 + [VARCHAR2] 29 37 + [(] 37 38 + [20] 38 40 + [)] 40 41 + [,] 41 42 +L465 + [sub_cust_code] 3 16 + [VARCHAR2] 29 37 + [(] 37 38 + [20] 38 40 + [)] 40 41 + [,] 41 42 +L466 + [sub_account] 3 14 + [VARCHAR2] 29 37 + [(] 37 38 + [30] 38 40 + [)] 40 41 + [,] 41 42 +L467 + [regno] 3 8 + [VARCHAR2] 29 37 + [(] 37 38 + [50] 38 40 + [)] 40 41 + [,] 41 42 +L468 + [residence] 3 12 + [VARCHAR2] 29 37 + [(] 37 38 + [10] 38 40 + [)] 40 41 + [,] 41 42 +L469 + [ct_type] 3 10 + [VARCHAR2] 29 37 + [(] 37 38 + [10] 38 40 + [)] 40 41 + [,] 41 42 +L470 + [ct_entity] 3 12 + [VARCHAR2] 29 37 + [(] 37 38 + [10] 38 40 + [)] 40 41 + [,] 41 42 +L471 + [language] 3 11 + [VARCHAR2] 29 37 + [(] 37 38 + [10] 38 40 + [)] 40 41 + [,] 41 42 +L472 + [business_type] 3 16 + [VARCHAR2] 29 37 + [(] 37 38 + [10] 38 40 + [)] 40 41 + [,] 41 42 +L473 + [tax_code] 3 11 + [VARCHAR2] 29 37 + [(] 37 38 + [10] 38 40 + [)] 40 41 +L474 + [)] 1 2 + [;] 2 3 +L475 + [TYPE] 1 5 + [customer_table] 6 20 + [IS] 21 23 + [TABLE] 24 29 + [OF] 30 32 + [customer_type] 33 46 + [INDEX] 47 52 + [BY] 53 55 + [BINARY_INTEGER] 56 70 + [;] 70 71 +L477 + [SUBTYPE] 1 8 + [loan_customer_type] 9 27 + [IS] 28 30 + [loan_customers] 31 45 + [%] 45 46 + [ROWTYPE] 46 53 + [;] 53 54 +L478 + [TYPE] 1 5 + [loan_customer_table] 6 25 + [IS] 26 28 + [TABLE] 29 34 + [OF] 35 37 + [loan_customer_type] 38 56 + [INDEX] 57 62 + [BY] 63 65 + [BINARY_INTEGER] 66 80 + [;] 80 81 +L481 + [PROCEDURE] 1 10 + [Get_Record] 11 21 + [(] 22 23 +L482 + [p_id] 3 7 + [VARCHAR2] 21 29 + [,] 29 30 +L483 + [r] 3 4 + [OUT] 21 24 + [customer_type] 25 38 + [,] 38 39 +L484 + [r_result] 3 11 + [IN] 21 23 + [OUT] 24 27 + [NUMBER] 28 34 + [,] 34 35 +L485 + [r_message] 3 12 + [IN] 21 23 + [OUT] 24 27 + [VARCHAR2] 28 36 + [)] 36 37 + [;] 37 38 +L488 + [PROCEDURE] 1 10 + [Get_By_Id] 11 20 + [(] 21 22 +L489 + [p_id] 3 7 + [IN] 21 23 + [VARCHAR2] 24 32 + [,] 32 33 +L490 + [r_records] 3 12 + [IN] 21 23 + [OUT] 24 27 + [customer_table] 28 42 + [)] 42 43 + [;] 43 44 +L493 + [PROCEDURE] 1 10 + [Get_By_Criteria] 11 26 + [(] 27 28 +L494 + [p_criteria] 3 13 + [IN] 21 23 + [customer_type] 24 37 + [,] 37 38 +L495 + [r_records] 3 12 + [IN] 21 23 + [OUT] 24 27 + [customer_table] 28 42 + [)] 42 43 + [;] 43 44 +L498 + [PROCEDURE] 1 10 + [Get] 11 14 + [(] 15 16 +L499 + [p_id] 3 7 + [IN] 21 23 + [VARCHAR2] 24 32 + [,] 32 33 +L500 + [p_name] 3 9 + [IN] 21 23 + [VARCHAR2] 24 32 + [,] 32 33 +L501 + [p_short_name] 3 15 + [IN] 21 23 + [VARCHAR2] 24 32 + [,] 32 33 +L502 + [p_cust_code] 3 14 + [IN] 21 23 + [VARCHAR2] 24 32 + [,] 32 33 +L503 + [p_account] 3 12 + [IN] 21 23 + [VARCHAR2] 24 32 + [,] 32 33 +L504 + [p_regno] 3 10 + [IN] 21 23 + [VARCHAR2] 24 32 + [,] 32 33 +L505 + [r_records] 3 12 + [IN] 21 23 + [OUT] 24 27 + [customer_table] 28 42 + [)] 42 43 + [;] 43 44 +L508 + [PROCEDURE] 1 10 + [Search_By_Account] 11 28 + [(] 29 30 +L509 + [p_account] 3 12 + [VARCHAR2] 21 29 + [,] 29 30 +L510 + [r_record] 3 11 + [IN] 21 23 + [OUT] 24 27 + [customer_type] 28 41 + [,] 41 42 +L511 + [r_result] 3 11 + [OUT] 21 24 + [NUMBER] 25 31 + [,] 31 32 +L512 + [r_message] 3 12 + [OUT] 21 24 + [VARCHAR2] 25 33 + [)] 33 34 + [;] 34 35 +L515 + [PROCEDURE] 1 10 + [Ins] 11 14 + [(] 15 16 +L516 + [p_data] 3 9 + [IN] 21 23 + [customer_table] 24 38 + [)] 38 39 + [;] 39 40 +L519 + [PROCEDURE] 1 10 + [Upd] 11 14 + [(] 15 16 +L520 + [p_data] 3 9 + [IN] 21 23 + [customer_table] 24 38 + [)] 38 39 + [;] 39 40 +L523 + [PROCEDURE] 1 10 + [Del] 11 14 + [(] 15 16 +L524 + [p_data] 3 9 + [IN] 21 23 + [customer_table] 24 38 + [)] 38 39 + [;] 39 40 +L527 + [PROCEDURE] 1 10 + [Lck] 11 14 + [(] 15 16 +L528 + [p_data] 3 9 + [IN] 21 23 + [customer_table] 24 38 + [)] 38 39 + [;] 39 40 +L537 + [PROCEDURE] 1 10 + [Get_Loan_Customer] 11 28 + [(] 29 30 +L538 + [p_id] 3 7 + [VARCHAR2] 21 29 + [,] 29 30 +L539 + [r] 3 4 + [OUT] 21 24 + [loan_customer_type] 25 43 + [,] 43 44 +L540 + [r_result] 3 11 + [OUT] 21 24 + [NUMBER] 25 31 + [,] 31 32 +L541 + [r_message] 3 12 + [OUT] 21 24 + [VARCHAR2] 25 33 + [)] 33 34 + [;] 34 35 +L543 + [END] 1 4 + [;] 4 5 +L544 + [/] 1 2 +L546 + [CREATE] 1 7 + [OR] 8 10 + [REPLACE] 11 18 +L547 + [Package] 1 8 + [EXEC_SP] 12 19 +L548 + [IS] 1 3 +L562 + [DATEFORMAT] 1 11 + [constant] 12 20 + [VARCHAR2] 21 29 + [(] 29 30 + [100] 30 33 + [)] 33 34 + [:] 35 36 + [=] 36 37 + ['dd.mm.yyyy hh24:mi:ss'] 38 61 + [;] 61 62 +L563 + [TYPE] 1 5 + [string_array] 6 18 + [IS] 19 21 + [TABLE] 22 27 + [OF] 28 30 + [VARCHAR2] 31 39 + [(] 39 40 + [32000] 40 45 + [)] 45 46 + [INDEX] 47 52 + [BY] 53 55 + [BINARY_INTEGER] 56 70 + [;] 70 71 +L565 + [PROCEDURE] 1 10 + [Exec_SP] 11 18 + [(] 19 20 +L566 + [sp_name] 3 10 + [VARCHAR2] 15 23 + [,] 23 24 +L567 + [sp_package] 3 13 + [VARCHAR2] 15 23 + [,] 23 24 +L568 + [sp_schema] 3 12 + [VARCHAR2] 15 23 + [,] 23 24 +L569 + [sp_type] 3 10 + [VARCHAR2] 15 23 + [,] 23 24 +L570 + [arg_names] 3 12 + [IN] 15 17 + [OUT] 18 21 + [string_array] 22 34 + [,] 34 35 +L571 + [arg_types] 3 12 + [IN] 15 17 + [OUT] 18 21 + [string_array] 22 34 + [,] 34 35 +L572 + [arg_pass] 3 11 + [IN] 15 17 + [OUT] 18 21 + [string_array] 22 34 + [,] 34 35 +L573 + [arg_values] 3 13 + [IN] 15 17 + [OUT] 18 21 + [string_array] 22 34 + [,] 34 35 +L574 + [error_code] 3 13 + [OUT] 15 18 + [NUMBER] 19 25 + [,] 25 26 +L575 + [error_msg] 3 12 + [OUT] 15 18 + [VARCHAR2] 19 27 + [)] 27 28 + [;] 28 29 +L577 + [END] 1 4 + [;] 4 5 +L578 + [/] 1 2 +L580 + [CREATE] 1 7 + [OR] 8 10 + [REPLACE] 11 18 +L581 + [PACKAGE] 1 8 + [LOBS_DATA] 9 18 +L582 + [IS] 1 3 +L597 + [FUNCTION] 1 9 + [put] 10 13 + [(] 13 14 +L598 + [p_value] 3 10 + [IN] 17 19 + [VARCHAR2] 20 28 + [)] 28 29 +L599 + [RETURN] 1 7 + [NUMBER] 8 14 + [;] 14 15 +L602 + [FUNCTION] 1 9 + [get] 10 13 + [(] 13 14 +L603 + [p_id] 3 7 + [IN] 17 19 + [VARCHAR2] 20 28 + [)] 28 29 +L604 + [RETURN] 1 7 + [VARCHAR2] 8 16 + [;] 16 17 +L607 + [PROCEDURE] 1 10 + [remove] 11 17 + [(] 17 18 +L608 + [p_id] 3 7 + [IN] 17 19 + [VARCHAR2] 20 28 + [)] 28 29 + [;] 29 30 +L610 + [FUNCTION] 1 9 + [HH_get_info] 10 21 +L611 + [(] 1 2 + [erty_id_in] 3 13 + [IN] 14 16 + [HH_t] 17 21 + [.] 21 22 + [a_id] 22 26 + [%] 26 27 + [TYPE] 27 31 + [DEFAULT] 33 40 + [NULL] 41 45 +L612 + [,] 1 2 + [df_id_in] 3 11 + [IN] 14 16 + [HH_t] 17 21 + [.] 21 22 + [b_id] 22 26 + [%] 26 27 + [TYPE] 27 31 + [DEFAULT] 33 40 + [NULL] 41 45 +L613 + [,] 1 2 + [fghj_id_in] 3 13 + [IN] 14 16 + [HH_t] 17 21 + [.] 21 22 + [c_id] 22 26 + [%] 26 27 + [TYPE] 27 31 + [DEFAULT] 33 40 + [vk_asdgfh_pa] 41 53 + [.] 53 54 + [some_function] 54 67 + [(] 67 68 + [)] 68 69 +L614 + [,] 1 2 + [cascade_in] 3 13 + [IN] 14 16 + [NUMBER] 17 23 + [DEFAULT] 33 40 + [vk_asdgfh_pa] 41 53 + [.] 53 54 + [some_constant] 54 67 +L615 + [)] 1 2 +L616 + [RETURN] 1 7 + [vk_types_pa] 8 19 + [.] 19 20 + [type_rg_info_rec] 20 36 + [;] 36 37 +L618 + [PROCEDURE] 1 10 + [start_batch_job] 11 26 + [(] 27 28 + [p_interval] 28 38 + [IN] 39 41 + [dba_jobs] 42 50 + [.] 50 51 + [interval] 51 59 + [%] 59 60 + [TYPE] 60 64 + [)] 64 65 + [;] 65 66 +L620 + [procedure] 1 10 + [out] 11 14 + [(] 14 15 + [cursor] 15 21 + [VARCHAR2] 22 30 + [)] 30 31 + [;] 31 32 +L622 + [PROCEDURE] 1 10 + [refresh_all] 11 22 + [(] 22 23 + [kehtib] 23 29 + [date] 30 34 + [default] 35 42 + [last_day] 43 51 + [(] 51 52 + [add_months] 52 62 + [(] 62 63 + [trunc] 63 68 + [(] 68 69 + [sysdate] 69 76 + [)] 76 77 + [,] 77 78 + [1] 78 79 + [)] 79 80 + [)] 80 81 + [+] 81 82 + [1] 82 83 + [)] 83 84 + [;] 84 85 +L624 + [END] 1 4 + [;] 4 5 +EOF diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/specialComments.sql b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/specialComments.sql new file mode 100644 index 0000000000..0b11220420 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/specialComments.sql @@ -0,0 +1,7 @@ +-- CPD-OFF +CREATE OR REPLACE +PACKAGE "test_schema"."BANK_DATA" +IS +pi CONSTANT NUMBER := 3.1415; +--CPD-ON +END; \ No newline at end of file diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/specialComments.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/specialComments.txt new file mode 100644 index 0000000000..e326249516 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/specialComments.txt @@ -0,0 +1,5 @@ + [Image] or [Truncated image[ Bcol Ecol +L7 + [END] 1 4 + [;] 4 5 +EOF diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 75ec4479aa..aff839ee0c 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -82,10 +82,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java b/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java index 7a15fea69c..3a58771bc9 100644 --- a/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java +++ b/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java @@ -4,64 +4,41 @@ package net.sourceforge.pmd.cpd; -import static org.junit.Assert.assertEquals; +import java.util.Properties; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -public class PythonTokenizerTest extends AbstractTokenizerTest { +public class PythonTokenizerTest extends CpdTextComparisonTest { - private static final String FILENAME = "sample-python.py"; - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new PythonTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), FILENAME)); + public PythonTokenizerTest() { + super(".py"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(PythonTokenizer.class.getResourceAsStream(FILENAME), StandardCharsets.UTF_8); + protected String getResourcePrefix() { + return "../lang/python/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new PythonTokenizer(); + } + + + @Test + public void sampleTest() { + doTest("sample_python"); } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 1218; - super.tokenizeTest(); + public void specialComments() { + doTest("special_comments"); } @Test - public void testIgnoreBetweenSpecialComments() throws IOException { - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("import logging\n" - + "# CPD-OFF\n" - + "logger = logging.getLogger('django.request')\n" - + "class BaseHandler(object):\n" - + " def __init__(self):\n" - + " self._request_middleware = None\n" - + " # CPD-ON\n" - )); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); - TokenEntry.getEOF(); - assertEquals(3, tokens.size()); // 3 tokens: "import" + "logging" + EOF - } - - @Test - public void testBackticks() throws IOException { - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader("test = 'hello'\n" - + "quoted = `test`\n" - + "print quoted\n" - )); - Tokens tokens = new Tokens(); - tokenizer.tokenize(sourceCode, tokens); // should not result in parse error - TokenEntry.getEOF(); - assertEquals(3, tokens.getTokens().get(tokens.getTokens().size() - 2).getBeginLine()); + public void testBackticks() { + doTest("backticks"); } } diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/backticks.py b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/backticks.py new file mode 100644 index 0000000000..d15b836a08 --- /dev/null +++ b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/backticks.py @@ -0,0 +1,3 @@ +test = 'hello' +quoted = `test` +print quoted diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/backticks.txt b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/backticks.txt new file mode 100644 index 0000000000..7201cd151c --- /dev/null +++ b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/backticks.txt @@ -0,0 +1,15 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [test] 1 5 + [=] 6 7 + ['hello'] 8 15 +L2 + [quoted] 1 7 + [=] 8 9 + [`] 10 11 + [test] 11 15 + [`] 15 16 +L3 + [print] 1 6 + [quoted] 7 13 +EOF diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/cpd/sample-python.py b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_python.py similarity index 100% rename from pmd-python/src/test/resources/net/sourceforge/pmd/cpd/sample-python.py rename to pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_python.py diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_python.txt b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_python.txt new file mode 100644 index 0000000000..78ff3f66c6 --- /dev/null +++ b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_python.txt @@ -0,0 +1,1419 @@ + [Image] or [Truncated image[ Bcol Ecol +L3 + [from] 1 5 + [__future__] 6 16 + [import] 17 23 + [unicode_literals] 24 40 +L5 + [import] 1 7 + [logging] 8 15 +L6 + [import] 1 7 + [sys] 8 11 +L7 + [import] 1 7 + [types] 8 13 +L9 + [from] 1 5 + [django] 6 12 + [import] 13 19 + [http] 20 24 +L10 + [from] 1 5 + [django] 6 12 + [.] 12 13 + [conf] 13 17 + [import] 18 24 + [settings] 25 33 +L11 + [from] 1 5 + [django] 6 12 + [.] 12 13 + [core] 13 17 + [import] 18 24 + [urlresolvers] 25 37 +L12 + [from] 1 5 + [django] 6 12 + [.] 12 13 + [core] 13 17 + [import] 18 24 + [signals] 25 32 +L13 + [from] 1 5 + [django] 6 12 + [.] 12 13 + [core] 13 17 + [.] 17 18 + [exceptions] 18 28 + [import] 29 35 + [MiddlewareNotUsed] 36 53 + [,] 53 54 + [PermissionDenied] 55 71 + [,] 71 72 + [SuspiciousOperation] 73 92 +L14 + [from] 1 5 + [django] 6 12 + [.] 12 13 + [db] 13 15 + [import] 16 22 + [connections] 23 34 + [,] 34 35 + [transaction] 36 47 +L15 + [from] 1 5 + [django] 6 12 + [.] 12 13 + [http] 13 17 + [.] 17 18 + [multipartparser] 18 33 + [import] 34 40 + [MultiPartParserError] 41 61 +L16 + [from] 1 5 + [django] 6 12 + [.] 12 13 + [utils] 13 18 + [.] 18 19 + [encoding] 19 27 + [import] 28 34 + [force_text] 35 45 +L17 + [from] 1 5 + [django] 6 12 + [.] 12 13 + [utils] 13 18 + [.] 18 19 + [module_loading] 19 33 + [import] 34 40 + [import_string] 41 54 +L18 + [from] 1 5 + [django] 6 12 + [.] 12 13 + [utils] 13 18 + [import] 19 25 + [six] 26 29 +L19 + [from] 1 5 + [django] 6 12 + [.] 12 13 + [views] 13 18 + [import] 19 25 + [debug] 26 31 +L21 + [logger] 1 7 + [=] 8 9 + [logging] 10 17 + [.] 17 18 + [getLogger] 18 27 + [(] 27 28 + ['django.request'] 28 44 + [)] 44 45 +L24 + [class] 1 6 + [BaseHandler] 7 18 + [(] 18 19 + [object] 19 25 + [)] 25 26 + [:] 26 27 +L26 + [response_fixes] 5 19 + [=] 20 21 + [\[] 22 23 +L27 + [http] 9 13 + [.] 13 14 + [fix_location_header] 14 33 + [,] 33 34 +L28 + [http] 9 13 + [.] 13 14 + [conditional_content_removal] 14 41 + [,] 41 42 +L29 + [\]] 5 6 +L31 + [def] 5 8 + [__init__] 9 17 + [(] 17 18 + [self] 18 22 + [)] 22 23 + [:] 23 24 +L32 + [self] 9 13 + [.] 13 14 + [_request_middleware] 14 33 + [=] 34 35 + [None] 36 40 +L33 + [self] 9 13 + [.] 13 14 + [_view_middleware] 14 30 + [=] 31 32 + [None] 33 37 +L34 + [self] 9 13 + [.] 13 14 + [_template_response_middleware] 14 43 + [=] 44 45 + [None] 46 50 +L35 + [self] 9 13 + [.] 13 14 + [_response_middleware] 14 34 + [=] 35 36 + [None] 37 41 +L36 + [self] 9 13 + [.] 13 14 + [_exception_middleware] 14 35 + [=] 36 37 + [None] 38 42 +L38 + [def] 5 8 + [load_middleware] 9 24 + [(] 24 25 + [self] 25 29 + [)] 29 30 + [:] 30 31 +L39 + ["""\n Populate middleware l[ 9 12 +L44 + [self] 9 13 + [.] 13 14 + [_view_middleware] 14 30 + [=] 31 32 + [\[] 33 34 + [\]] 34 35 +L45 + [self] 9 13 + [.] 13 14 + [_template_response_middleware] 14 43 + [=] 44 45 + [\[] 46 47 + [\]] 47 48 +L46 + [self] 9 13 + [.] 13 14 + [_response_middleware] 14 34 + [=] 35 36 + [\[] 37 38 + [\]] 38 39 +L47 + [self] 9 13 + [.] 13 14 + [_exception_middleware] 14 35 + [=] 36 37 + [\[] 38 39 + [\]] 39 40 +L49 + [request_middleware] 9 27 + [=] 28 29 + [\[] 30 31 + [\]] 31 32 +L50 + [for] 9 12 + [middleware_path] 13 28 + [in] 29 31 + [settings] 32 40 + [.] 40 41 + [MIDDLEWARE_CLASSES] 41 59 + [:] 59 60 +L51 + [mw_class] 13 21 + [=] 22 23 + [import_string] 24 37 + [(] 37 38 + [middleware_path] 38 53 + [)] 53 54 +L52 + [try] 13 16 + [:] 16 17 +L53 + [mw_instance] 17 28 + [=] 29 30 + [mw_class] 31 39 + [(] 39 40 + [)] 40 41 +L54 + [except] 13 19 + [MiddlewareNotUsed] 20 37 + [as] 38 40 + [exc] 41 44 + [:] 44 45 +L55 + [if] 17 19 + [settings] 20 28 + [.] 28 29 + [DEBUG] 29 34 + [:] 34 35 +L56 + [if] 21 23 + [six] 24 27 + [.] 27 28 + [text_type] 28 37 + [(] 37 38 + [exc] 38 41 + [)] 41 42 + [:] 42 43 +L57 + [logger] 25 31 + [.] 31 32 + [debug] 32 37 + [(] 37 38 + ['MiddlewareNotUsed(%r): %s'] 38 65 + [,] 65 66 + [middleware_path] 67 82 + [,] 82 83 + [exc] 84 87 + [)] 87 88 +L58 + [else] 21 25 + [:] 25 26 +L59 + [logger] 25 31 + [.] 31 32 + [debug] 32 37 + [(] 37 38 + ['MiddlewareNotUsed: %r'] 38 61 + [,] 61 62 + [middleware_path] 63 78 + [)] 78 79 +L60 + [continue] 17 25 +L62 + [if] 13 15 + [hasattr] 16 23 + [(] 23 24 + [mw_instance] 24 35 + [,] 35 36 + ['process_request'] 37 54 + [)] 54 55 + [:] 55 56 +L63 + [request_middleware] 17 35 + [.] 35 36 + [append] 36 42 + [(] 42 43 + [mw_instance] 43 54 + [.] 54 55 + [process_request] 55 70 + [)] 70 71 +L64 + [if] 13 15 + [hasattr] 16 23 + [(] 23 24 + [mw_instance] 24 35 + [,] 35 36 + ['process_view'] 37 51 + [)] 51 52 + [:] 52 53 +L65 + [self] 17 21 + [.] 21 22 + [_view_middleware] 22 38 + [.] 38 39 + [append] 39 45 + [(] 45 46 + [mw_instance] 46 57 + [.] 57 58 + [process_view] 58 70 + [)] 70 71 +L66 + [if] 13 15 + [hasattr] 16 23 + [(] 23 24 + [mw_instance] 24 35 + [,] 35 36 + ['process_template_response'] 37 64 + [)] 64 65 + [:] 65 66 +L67 + [self] 17 21 + [.] 21 22 + [_template_response_middleware] 22 51 + [.] 51 52 + [insert] 52 58 + [(] 58 59 + [0] 59 60 + [,] 60 61 + [mw_instance] 62 73 + [.] 73 74 + [process_template_response] 74 99 + [)] 99 100 +L68 + [if] 13 15 + [hasattr] 16 23 + [(] 23 24 + [mw_instance] 24 35 + [,] 35 36 + ['process_response'] 37 55 + [)] 55 56 + [:] 56 57 +L69 + [self] 17 21 + [.] 21 22 + [_response_middleware] 22 42 + [.] 42 43 + [insert] 43 49 + [(] 49 50 + [0] 50 51 + [,] 51 52 + [mw_instance] 53 64 + [.] 64 65 + [process_response] 65 81 + [)] 81 82 +L70 + [if] 13 15 + [hasattr] 16 23 + [(] 23 24 + [mw_instance] 24 35 + [,] 35 36 + ['process_exception'] 37 56 + [)] 56 57 + [:] 57 58 +L71 + [self] 17 21 + [.] 21 22 + [_exception_middleware] 22 43 + [.] 43 44 + [insert] 44 50 + [(] 50 51 + [0] 51 52 + [,] 52 53 + [mw_instance] 54 65 + [.] 65 66 + [process_exception] 66 83 + [)] 83 84 +L75 + [self] 9 13 + [.] 13 14 + [_request_middleware] 14 33 + [=] 34 35 + [request_middleware] 36 54 +L77 + [def] 5 8 + [make_view_atomic] 9 25 + [(] 25 26 + [self] 26 30 + [,] 30 31 + [view] 32 36 + [)] 36 37 + [:] 37 38 +L78 + [non_atomic_requests] 9 28 + [=] 29 30 + [getattr] 31 38 + [(] 38 39 + [view] 39 43 + [,] 43 44 + ['_non_atomic_requests'] 45 67 + [,] 67 68 + [set] 69 72 + [(] 72 73 + [)] 73 74 + [)] 74 75 +L79 + [for] 9 12 + [db] 13 15 + [in] 16 18 + [connections] 19 30 + [.] 30 31 + [all] 31 34 + [(] 34 35 + [)] 35 36 + [:] 36 37 +L80 + [if] 13 15 + [(] 16 17 + [db] 17 19 + [.] 19 20 + [settings_dict] 20 33 + [\[] 33 34 + ['ATOMIC_REQUESTS'] 34 51 + [\]] 51 52 +L81 + [and] 21 24 + [db] 25 27 + [.] 27 28 + [alias] 28 33 + [not] 34 37 + [in] 38 40 + [non_atomic_requests] 41 60 + [)] 60 61 + [:] 61 62 +L82 + [view] 17 21 + [=] 22 23 + [transaction] 24 35 + [.] 35 36 + [atomic] 36 42 + [(] 42 43 + [using] 43 48 + [=] 48 49 + [db] 49 51 + [.] 51 52 + [alias] 52 57 + [)] 57 58 + [(] 58 59 + [view] 59 63 + [)] 63 64 +L83 + [return] 9 15 + [view] 16 20 +L85 + [def] 5 8 + [get_exception_response] 9 31 + [(] 31 32 + [self] 32 36 + [,] 36 37 + [request] 38 45 + [,] 45 46 + [resolver] 47 55 + [,] 55 56 + [status_code] 57 68 + [)] 68 69 + [:] 69 70 +L86 + [try] 9 12 + [:] 12 13 +L87 + [callback] 13 21 + [,] 21 22 + [param_dict] 23 33 + [=] 34 35 + [resolver] 36 44 + [.] 44 45 + [resolve_error_handler] 45 66 + [(] 66 67 + [status_code] 67 78 + [)] 78 79 +L88 + [response] 13 21 + [=] 22 23 + [callback] 24 32 + [(] 32 33 + [request] 33 40 + [,] 40 41 + [**] 42 44 + [param_dict] 44 54 + [)] 54 55 +L89 + [except] 9 15 + [:] 15 16 +L90 + [signals] 13 20 + [.] 20 21 + [got_request_exception] 21 42 + [.] 42 43 + [send] 43 47 + [(] 47 48 + [sender] 48 54 + [=] 54 55 + [self] 55 59 + [.] 59 60 + [__class__] 60 69 + [,] 69 70 + [request] 71 78 + [=] 78 79 + [request] 79 86 + [)] 86 87 +L91 + [response] 13 21 + [=] 22 23 + [self] 24 28 + [.] 28 29 + [handle_uncaught_exception] 29 54 + [(] 54 55 + [request] 55 62 + [,] 62 63 + [resolver] 64 72 + [,] 72 73 + [sys] 74 77 + [.] 77 78 + [exc_info] 78 86 + [(] 86 87 + [)] 87 88 + [)] 88 89 +L93 + [return] 9 15 + [response] 16 24 +L95 + [def] 5 8 + [get_response] 9 21 + [(] 21 22 + [self] 22 26 + [,] 26 27 + [request] 28 35 + [)] 35 36 + [:] 36 37 +L96 + ["Returns an HttpResponse object fo[ 9 67 +L102 + [urlconf] 9 16 + [=] 17 18 + [settings] 19 27 + [.] 27 28 + [ROOT_URLCONF] 28 40 +L103 + [urlresolvers] 9 21 + [.] 21 22 + [set_urlconf] 22 33 + [(] 33 34 + [urlconf] 34 41 + [)] 41 42 +L104 + [resolver] 9 17 + [=] 18 19 + [urlresolvers] 20 32 + [.] 32 33 + [RegexURLResolver] 33 49 + [(] 49 50 + [r'^/'] 50 55 + [,] 55 56 + [urlconf] 57 64 + [)] 64 65 +L105 + [try] 9 12 + [:] 12 13 +L106 + [response] 13 21 + [=] 22 23 + [None] 24 28 +L108 + [for] 13 16 + [middleware_method] 17 34 + [in] 35 37 + [self] 38 42 + [.] 42 43 + [_request_middleware] 43 62 + [:] 62 63 +L109 + [response] 17 25 + [=] 26 27 + [middleware_method] 28 45 + [(] 45 46 + [request] 46 53 + [)] 53 54 +L110 + [if] 17 19 + [response] 20 28 + [:] 28 29 +L111 + [break] 21 26 +L113 + [if] 13 15 + [response] 16 24 + [is] 25 27 + [None] 28 32 + [:] 32 33 +L114 + [if] 17 19 + [hasattr] 20 27 + [(] 27 28 + [request] 28 35 + [,] 35 36 + ['urlconf'] 37 46 + [)] 46 47 + [:] 47 48 +L116 + [urlconf] 21 28 + [=] 29 30 + [request] 31 38 + [.] 38 39 + [urlconf] 39 46 +L117 + [urlresolvers] 21 33 + [.] 33 34 + [set_urlconf] 34 45 + [(] 45 46 + [urlconf] 46 53 + [)] 53 54 +L118 + [resolver] 21 29 + [=] 30 31 + [urlresolvers] 32 44 + [.] 44 45 + [RegexURLResolver] 45 61 + [(] 61 62 + [r'^/'] 62 67 + [,] 67 68 + [urlconf] 69 76 + [)] 76 77 +L120 + [resolver_match] 17 31 + [=] 32 33 + [resolver] 34 42 + [.] 42 43 + [resolve] 43 50 + [(] 50 51 + [request] 51 58 + [.] 58 59 + [path_info] 59 68 + [)] 68 69 +L121 + [callback] 17 25 + [,] 25 26 + [callback_args] 27 40 + [,] 40 41 + [callback_kwargs] 42 57 + [=] 58 59 + [resolver_match] 60 74 +L122 + [request] 17 24 + [.] 24 25 + [resolver_match] 25 39 + [=] 40 41 + [resolver_match] 42 56 +L125 + [for] 17 20 + [middleware_method] 21 38 + [in] 39 41 + [self] 42 46 + [.] 46 47 + [_view_middleware] 47 63 + [:] 63 64 +L126 + [response] 21 29 + [=] 30 31 + [middleware_method] 32 49 + [(] 49 50 + [request] 50 57 + [,] 57 58 + [callback] 59 67 + [,] 67 68 + [callback_args] 69 82 + [,] 82 83 + [callback_kwargs] 84 99 + [)] 99 100 +L127 + [if] 21 23 + [response] 24 32 + [:] 32 33 +L128 + [break] 25 30 +L130 + [if] 13 15 + [response] 16 24 + [is] 25 27 + [None] 28 32 + [:] 32 33 +L131 + [wrapped_callback] 17 33 + [=] 34 35 + [self] 36 40 + [.] 40 41 + [make_view_atomic] 41 57 + [(] 57 58 + [callback] 58 66 + [)] 66 67 +L132 + [try] 17 20 + [:] 20 21 +L133 + [response] 21 29 + [=] 30 31 + [wrapped_callback] 32 48 + [(] 48 49 + [request] 49 56 + [,] 56 57 + [*] 58 59 + [callback_args] 59 72 + [,] 72 73 + [**] 74 76 + [callback_kwargs] 76 91 + [)] 91 92 +L134 + [except] 17 23 + [Exception] 24 33 + [as] 34 36 + [e] 37 38 + [:] 38 39 +L138 + [for] 21 24 + [middleware_method] 25 42 + [in] 43 45 + [self] 46 50 + [.] 50 51 + [_exception_middleware] 51 72 + [:] 72 73 +L139 + [response] 25 33 + [=] 34 35 + [middleware_method] 36 53 + [(] 53 54 + [request] 54 61 + [,] 61 62 + [e] 63 64 + [)] 64 65 +L140 + [if] 25 27 + [response] 28 36 + [:] 36 37 +L141 + [break] 29 34 +L142 + [if] 21 23 + [response] 24 32 + [is] 33 35 + [None] 36 40 + [:] 40 41 +L143 + [raise] 25 30 +L146 + [if] 13 15 + [response] 16 24 + [is] 25 27 + [None] 28 32 + [:] 32 33 +L147 + [if] 17 19 + [isinstance] 20 30 + [(] 30 31 + [callback] 31 39 + [,] 39 40 + [types] 41 46 + [.] 46 47 + [FunctionType] 47 59 + [)] 59 60 + [:] 60 61 +L148 + [view_name] 21 30 + [=] 31 32 + [callback] 33 41 + [.] 41 42 + [__name__] 42 50 +L149 + [else] 17 21 + [:] 21 22 +L150 + [view_name] 21 30 + [=] 31 32 + [callback] 33 41 + [.] 41 42 + [__class__] 42 51 + [.] 51 52 + [__name__] 52 60 + [+] 61 62 + ['.__call__'] 63 74 +L151 + [raise] 17 22 + [ValueError] 23 33 + [(] 33 34 + ["The view %s.%s didn't return an H[ 34 114 +L152 + [%] 34 35 + [(] 36 37 + [callback] 37 45 + [.] 45 46 + [__module__] 46 56 + [,] 56 57 + [view_name] 58 67 + [)] 67 68 + [)] 68 69 +L156 + [if] 13 15 + [hasattr] 16 23 + [(] 23 24 + [response] 24 32 + [,] 32 33 + ['render'] 34 42 + [)] 42 43 + [and] 44 47 + [callable] 48 56 + [(] 56 57 + [response] 57 65 + [.] 65 66 + [render] 66 72 + [)] 72 73 + [:] 73 74 +L157 + [for] 17 20 + [middleware_method] 21 38 + [in] 39 41 + [self] 42 46 + [.] 46 47 + [_template_response_middleware] 47 76 + [:] 76 77 +L158 + [response] 21 29 + [=] 30 31 + [middleware_method] 32 49 + [(] 49 50 + [request] 50 57 + [,] 57 58 + [response] 59 67 + [)] 67 68 +L160 + [if] 21 23 + [response] 24 32 + [is] 33 35 + [None] 36 40 + [:] 40 41 +L161 + [raise] 25 30 + [ValueError] 31 41 + [(] 41 42 +L162 + ["%s.process_template_response didn[ 29 77 +L163 + ["HttpResponse object. It returned [ 29 77 +L164 + [%] 29 30 + [(] 31 32 + [middleware_method] 32 49 + [.] 49 50 + [__self__] 50 58 + [.] 58 59 + [__class__] 59 68 + [.] 68 69 + [__name__] 69 77 + [)] 77 78 + [)] 78 79 +L165 + [response] 17 25 + [=] 26 27 + [response] 28 36 + [.] 36 37 + [render] 37 43 + [(] 43 44 + [)] 44 45 +L167 + [except] 9 15 + [http] 16 20 + [.] 20 21 + [Http404] 21 28 + [as] 29 31 + [e] 32 33 + [:] 33 34 +L168 + [logger] 13 19 + [.] 19 20 + [warning] 20 27 + [(] 27 28 + ['Not Found: %s'] 28 43 + [,] 43 44 + [request] 45 52 + [.] 52 53 + [path] 53 57 + [,] 57 58 +L169 + [extra] 25 30 + [=] 30 31 + [{] 31 32 +L170 + ['status_code'] 29 42 + [:] 42 43 + [404] 44 47 + [,] 47 48 +L171 + ['request'] 29 38 + [:] 38 39 + [request] 40 47 +L172 + [}] 25 26 + [)] 26 27 +L173 + [if] 13 15 + [settings] 16 24 + [.] 24 25 + [DEBUG] 25 30 + [:] 30 31 +L174 + [response] 17 25 + [=] 26 27 + [debug] 28 33 + [.] 33 34 + [technical_404_response] 34 56 + [(] 56 57 + [request] 57 64 + [,] 64 65 + [e] 66 67 + [)] 67 68 +L175 + [else] 13 17 + [:] 17 18 +L176 + [response] 17 25 + [=] 26 27 + [self] 28 32 + [.] 32 33 + [get_exception_response] 33 55 + [(] 55 56 + [request] 56 63 + [,] 63 64 + [resolver] 65 73 + [,] 73 74 + [404] 75 78 + [)] 78 79 +L178 + [except] 9 15 + [PermissionDenied] 16 32 + [:] 32 33 +L179 + [logger] 13 19 + [.] 19 20 + [warning] 20 27 + [(] 27 28 +L180 + ['Forbidden (Permission denied): %s[ 17 52 + [,] 52 53 + [request] 54 61 + [.] 61 62 + [path] 62 66 + [,] 66 67 +L181 + [extra] 17 22 + [=] 22 23 + [{] 23 24 +L182 + ['status_code'] 21 34 + [:] 34 35 + [403] 36 39 + [,] 39 40 +L183 + ['request'] 21 30 + [:] 30 31 + [request] 32 39 +L184 + [}] 17 18 + [)] 18 19 +L185 + [response] 13 21 + [=] 22 23 + [self] 24 28 + [.] 28 29 + [get_exception_response] 29 51 + [(] 51 52 + [request] 52 59 + [,] 59 60 + [resolver] 61 69 + [,] 69 70 + [403] 71 74 + [)] 74 75 +L187 + [except] 9 15 + [MultiPartParserError] 16 36 + [:] 36 37 +L188 + [logger] 13 19 + [.] 19 20 + [warning] 20 27 + [(] 27 28 +L189 + ['Bad request (Unable to parse requ[ 17 65 + [,] 65 66 + [request] 67 74 + [.] 74 75 + [path] 75 79 + [,] 79 80 +L190 + [extra] 17 22 + [=] 22 23 + [{] 23 24 +L191 + ['status_code'] 21 34 + [:] 34 35 + [400] 36 39 + [,] 39 40 +L192 + ['request'] 21 30 + [:] 30 31 + [request] 32 39 +L193 + [}] 17 18 + [)] 18 19 +L194 + [response] 13 21 + [=] 22 23 + [self] 24 28 + [.] 28 29 + [get_exception_response] 29 51 + [(] 51 52 + [request] 52 59 + [,] 59 60 + [resolver] 61 69 + [,] 69 70 + [400] 71 74 + [)] 74 75 +L196 + [except] 9 15 + [SuspiciousOperation] 16 35 + [as] 36 38 + [e] 39 40 + [:] 40 41 +L199 + [security_logger] 13 28 + [=] 29 30 + [logging] 31 38 + [.] 38 39 + [getLogger] 39 48 + [(] 48 49 + ['django.security.%s'] 49 69 + [%] 70 71 +L200 + [e] 29 30 + [.] 30 31 + [__class__] 31 40 + [.] 40 41 + [__name__] 41 49 + [)] 49 50 +L201 + [security_logger] 13 28 + [.] 28 29 + [error] 29 34 + [(] 34 35 +L202 + [force_text] 17 27 + [(] 27 28 + [e] 28 29 + [)] 29 30 + [,] 30 31 +L203 + [extra] 17 22 + [=] 22 23 + [{] 23 24 +L204 + ['status_code'] 21 34 + [:] 34 35 + [400] 36 39 + [,] 39 40 +L205 + ['request'] 21 30 + [:] 30 31 + [request] 32 39 +L206 + [}] 17 18 + [)] 18 19 +L207 + [if] 13 15 + [settings] 16 24 + [.] 24 25 + [DEBUG] 25 30 + [:] 30 31 +L208 + [return] 17 23 + [debug] 24 29 + [.] 29 30 + [technical_500_response] 30 52 + [(] 52 53 + [request] 53 60 + [,] 60 61 + [*] 62 63 + [sys] 63 66 + [.] 66 67 + [exc_info] 67 75 + [(] 75 76 + [)] 76 77 + [,] 77 78 + [status_code] 79 90 + [=] 90 91 + [400] 91 94 + [)] 94 95 +L210 + [response] 13 21 + [=] 22 23 + [self] 24 28 + [.] 28 29 + [get_exception_response] 29 51 + [(] 51 52 + [request] 52 59 + [,] 59 60 + [resolver] 61 69 + [,] 69 70 + [400] 71 74 + [)] 74 75 +L212 + [except] 9 15 + [SystemExit] 16 26 + [:] 26 27 +L214 + [raise] 13 18 +L216 + [except] 9 15 + [:] 15 16 +L218 + [signals] 13 20 + [.] 20 21 + [got_request_exception] 21 42 + [.] 42 43 + [send] 43 47 + [(] 47 48 + [sender] 48 54 + [=] 54 55 + [self] 55 59 + [.] 59 60 + [__class__] 60 69 + [,] 69 70 + [request] 71 78 + [=] 78 79 + [request] 79 86 + [)] 86 87 +L219 + [response] 13 21 + [=] 22 23 + [self] 24 28 + [.] 28 29 + [handle_uncaught_exception] 29 54 + [(] 54 55 + [request] 55 62 + [,] 62 63 + [resolver] 64 72 + [,] 72 73 + [sys] 74 77 + [.] 77 78 + [exc_info] 78 86 + [(] 86 87 + [)] 87 88 + [)] 88 89 +L221 + [try] 9 12 + [:] 12 13 +L223 + [for] 13 16 + [middleware_method] 17 34 + [in] 35 37 + [self] 38 42 + [.] 42 43 + [_response_middleware] 43 63 + [:] 63 64 +L224 + [response] 17 25 + [=] 26 27 + [middleware_method] 28 45 + [(] 45 46 + [request] 46 53 + [,] 53 54 + [response] 55 63 + [)] 63 64 +L226 + [if] 17 19 + [response] 20 28 + [is] 29 31 + [None] 32 36 + [:] 36 37 +L227 + [raise] 21 26 + [ValueError] 27 37 + [(] 37 38 +L228 + ["%s.process_response didn't return[ 25 64 +L229 + ["HttpResponse object. It returned [ 25 73 +L230 + [%] 25 26 + [(] 27 28 + [middleware_method] 28 45 + [.] 45 46 + [__self__] 46 54 + [.] 54 55 + [__class__] 55 64 + [.] 64 65 + [__name__] 65 73 + [)] 73 74 + [)] 74 75 +L231 + [response] 13 21 + [=] 22 23 + [self] 24 28 + [.] 28 29 + [apply_response_fixes] 29 49 + [(] 49 50 + [request] 50 57 + [,] 57 58 + [response] 59 67 + [)] 67 68 +L232 + [except] 9 15 + [:] 15 16 +L233 + [signals] 13 20 + [.] 20 21 + [got_request_exception] 21 42 + [.] 42 43 + [send] 43 47 + [(] 47 48 + [sender] 48 54 + [=] 54 55 + [self] 55 59 + [.] 59 60 + [__class__] 60 69 + [,] 69 70 + [request] 71 78 + [=] 78 79 + [request] 79 86 + [)] 86 87 +L234 + [response] 13 21 + [=] 22 23 + [self] 24 28 + [.] 28 29 + [handle_uncaught_exception] 29 54 + [(] 54 55 + [request] 55 62 + [,] 62 63 + [resolver] 64 72 + [,] 72 73 + [sys] 74 77 + [.] 77 78 + [exc_info] 78 86 + [(] 86 87 + [)] 87 88 + [)] 88 89 +L236 + [response] 9 17 + [.] 17 18 + [_closable_objects] 18 35 + [.] 35 36 + [append] 36 42 + [(] 42 43 + [request] 43 50 + [)] 50 51 +L238 + [return] 9 15 + [response] 16 24 +L240 + [def] 5 8 + [handle_uncaught_exception] 9 34 + [(] 34 35 + [self] 35 39 + [,] 39 40 + [request] 41 48 + [,] 48 49 + [resolver] 50 58 + [,] 58 59 + [exc_info] 60 68 + [)] 68 69 + [:] 69 70 +L241 + ["""\n Processing for any ot[ 9 12 +L250 + [if] 9 11 + [settings] 12 20 + [.] 20 21 + [DEBUG_PROPAGATE_EXCEPTIONS] 21 47 + [:] 47 48 +L251 + [raise] 13 18 +L253 + [logger] 9 15 + [.] 15 16 + [error] 16 21 + [(] 21 22 + ['Internal Server Error: %s'] 22 49 + [,] 49 50 + [request] 51 58 + [.] 58 59 + [path] 59 63 + [,] 63 64 +L254 + [exc_info] 13 21 + [=] 21 22 + [exc_info] 22 30 + [,] 30 31 +L255 + [extra] 13 18 + [=] 18 19 + [{] 19 20 +L256 + ['status_code'] 17 30 + [:] 30 31 + [500] 32 35 + [,] 35 36 +L257 + ['request'] 17 26 + [:] 26 27 + [request] 28 35 +L258 + [}] 13 14 +L259 + [)] 9 10 +L261 + [if] 9 11 + [settings] 12 20 + [.] 20 21 + [DEBUG] 21 26 + [:] 26 27 +L262 + [return] 13 19 + [debug] 20 25 + [.] 25 26 + [technical_500_response] 26 48 + [(] 48 49 + [request] 49 56 + [,] 56 57 + [*] 58 59 + [exc_info] 59 67 + [)] 67 68 +L265 + [if] 9 11 + [resolver] 12 20 + [.] 20 21 + [urlconf_module] 21 35 + [is] 36 38 + [None] 39 43 + [:] 43 44 +L266 + [six] 13 16 + [.] 16 17 + [reraise] 17 24 + [(] 24 25 + [*] 25 26 + [exc_info] 26 34 + [)] 34 35 +L268 + [callback] 9 17 + [,] 17 18 + [param_dict] 19 29 + [=] 30 31 + [resolver] 32 40 + [.] 40 41 + [resolve_error_handler] 41 62 + [(] 62 63 + [500] 63 66 + [)] 66 67 +L269 + [return] 9 15 + [callback] 16 24 + [(] 24 25 + [request] 25 32 + [,] 32 33 + [**] 34 36 + [param_dict] 36 46 + [)] 46 47 +L271 + [def] 5 8 + [apply_response_fixes] 9 29 + [(] 29 30 + [self] 30 34 + [,] 34 35 + [request] 36 43 + [,] 43 44 + [response] 45 53 + [)] 53 54 + [:] 54 55 +L272 + ["""\n Applies each of the f[ 9 12 +L277 + [for] 9 12 + [func] 13 17 + [in] 18 20 + [self] 21 25 + [.] 25 26 + [response_fixes] 26 40 + [:] 40 41 +L278 + [response] 13 21 + [=] 22 23 + [func] 24 28 + [(] 28 29 + [request] 29 36 + [,] 36 37 + [response] 38 46 + [)] 46 47 +L279 + [return] 9 15 + [response] 16 24 +EOF diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/special_comments.py b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/special_comments.py new file mode 100644 index 0000000000..c4f117fc4b --- /dev/null +++ b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/special_comments.py @@ -0,0 +1,7 @@ +import logging +# CPD-OFF +logger = logging.getLogger('django.request') +class BaseHandler(object): + def __init__(self): + self._request_middleware = None + # CPD-ON diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/special_comments.txt b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/special_comments.txt new file mode 100644 index 0000000000..385ab93be5 --- /dev/null +++ b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/special_comments.txt @@ -0,0 +1,5 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [import] 1 7 + [logging] 8 15 +EOF diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index c678fc0a8c..ebac64b7f3 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -26,10 +26,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-ruby/src/test/java/net/sourceforge/pmd/cpd/RubyTokenizerTest.java b/pmd-ruby/src/test/java/net/sourceforge/pmd/cpd/RubyTokenizerTest.java index decb493bf8..b4398fdf36 100644 --- a/pmd-ruby/src/test/java/net/sourceforge/pmd/cpd/RubyTokenizerTest.java +++ b/pmd-ruby/src/test/java/net/sourceforge/pmd/cpd/RubyTokenizerTest.java @@ -4,36 +4,31 @@ package net.sourceforge.pmd.cpd; -import java.io.IOException; -import java.nio.charset.StandardCharsets; +import java.util.Properties; -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -public class RubyTokenizerTest extends AbstractTokenizerTest { +public class RubyTokenizerTest extends CpdTextComparisonTest { - @Before - @Override - public void buildTokenizer() { - this.tokenizer = new RubyTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), "server.rb")); + public RubyTokenizerTest() { + super(".rb"); } @Override - public String getSampleCode() { - try { - return IOUtils.toString(RubyTokenizerTest.class.getResourceAsStream("server.rb"), StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } + protected String getResourcePrefix() { + return "../lang/ruby/cpd/testdata"; } + @Override + public Tokenizer newTokenizer(Properties properties) { + return new RubyTokenizer(); + } + + @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 30; - super.tokenizeTest(); + public void testSimple() { + doTest("server"); } } diff --git a/pmd-ruby/src/test/resources/net/sourceforge/pmd/cpd/server.rb b/pmd-ruby/src/test/resources/net/sourceforge/pmd/lang/ruby/cpd/testdata/server.rb similarity index 89% rename from pmd-ruby/src/test/resources/net/sourceforge/pmd/cpd/server.rb rename to pmd-ruby/src/test/resources/net/sourceforge/pmd/lang/ruby/cpd/testdata/server.rb index fcff68239c..7e71208c69 100644 --- a/pmd-ruby/src/test/resources/net/sourceforge/pmd/cpd/server.rb +++ b/pmd-ruby/src/test/resources/net/sourceforge/pmd/lang/ruby/cpd/testdata/server.rb @@ -1,7 +1,7 @@ require "socket" -gs = TCPServer.open(0) -addr = gs.addr +gs = TCPServer.open(0) +addr = gs.addr addr.shift while true diff --git a/pmd-ruby/src/test/resources/net/sourceforge/pmd/lang/ruby/cpd/testdata/server.txt b/pmd-ruby/src/test/resources/net/sourceforge/pmd/lang/ruby/cpd/testdata/server.txt new file mode 100644 index 0000000000..f4d30eaacb --- /dev/null +++ b/pmd-ruby/src/test/resources/net/sourceforge/pmd/lang/ruby/cpd/testdata/server.txt @@ -0,0 +1,44 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [require] 1 8 + ["socket"] 9 17 +L3 + [gs] 1 3 + [=] 4 5 + [tcpserver.open] 7 21 + [0] 22 23 +L4 + [addr] 1 5 + [=] 7 8 + [gs.addr] 9 16 +L5 + [addr.shift] 1 11 +L7 + [true] 7 11 +L8 + [ns] 3 5 + [=] 6 7 + [gs.accept] 8 17 +L9 + [print] 3 8 + [ns] 9 11 + [" is accepted"] 13 27 +L10 + [thread.start] 3 15 +L11 + [s] 5 6 + [=] 7 8 + [ns] 9 11 + [ # save to dynamic variable] 33 59 +L12 + [s.gets] 11 17 +L13 + [s.write] 7 14 + [$_] 15 17 +L15 + [print] 5 10 + [s] 11 12 + [" is gone [ 14 37 +L19 + [s.close] 5 12 +EOF diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/cpd/ScalaTokenizer.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/cpd/ScalaTokenizer.java index 3900fc3bd6..b619951613 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/cpd/ScalaTokenizer.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/cpd/ScalaTokenizer.java @@ -11,6 +11,7 @@ import org.apache.commons.lang3.StringUtils; import net.sourceforge.pmd.lang.LanguageRegistry; import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.ast.TokenMgrError; import net.sourceforge.pmd.lang.scala.ScalaLanguageHandler; import net.sourceforge.pmd.lang.scala.ScalaLanguageModule; @@ -19,6 +20,7 @@ import scala.meta.Dialect; import scala.meta.inputs.Input; import scala.meta.inputs.Position; import scala.meta.internal.tokenizers.ScalametaTokenizer; +import scala.meta.tokenizers.TokenizeException; import scala.meta.tokens.Token; /** @@ -74,12 +76,26 @@ public class ScalaTokenizer implements Tokenizer { Token token; while ((token = filter.getNextToken()) != null) { - String tokenText = token.text() != null ? token.text() : token.name(); - Position tokenPosition = token.pos(); - TokenEntry cpdToken = new TokenEntry(tokenText, filename, tokenPosition.startLine(), - tokenPosition.startColumn(), tokenPosition.endColumn()); + if (StringUtils.isEmpty(token.text())) { + continue; + } + Position pos = token.pos(); + TokenEntry cpdToken = new TokenEntry(token.text(), + filename, + pos.startLine() + 1, + pos.startColumn() + 1, + pos.endColumn() + 2); tokenEntries.add(cpdToken); } + } catch (Exception e) { + if (e instanceof TokenizeException) { // NOPMD + // cannot catch it as it's a checked exception and Scala sneaky throws + TokenizeException tokE = (TokenizeException) e; + Position pos = tokE.pos(); + throw new TokenMgrError(pos.startLine() + 1, pos.startColumn() + 1, filename, "Scalameta threw", tokE); + } else { + throw e; + } } finally { tokenEntries.add(TokenEntry.getEOF()); } diff --git a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/cpd/ScalaTokenizerTest.java b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/cpd/ScalaTokenizerTest.java index df2992f700..6e2decfb8b 100644 --- a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/cpd/ScalaTokenizerTest.java +++ b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/cpd/ScalaTokenizerTest.java @@ -4,71 +4,41 @@ package net.sourceforge.pmd.cpd; -import java.io.File; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; +import java.util.Properties; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; import org.junit.Test; +import org.junit.rules.ExpectedException; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; +import net.sourceforge.pmd.lang.ast.TokenMgrError; -public class ScalaTokenizerTest extends AbstractTokenizerTest { +public class ScalaTokenizerTest extends CpdTextComparisonTest { - private static final Charset ENCODING = StandardCharsets.UTF_8; + @org.junit.Rule + public ExpectedException ex = ExpectedException.none(); - private static final String FILENAME = "/tokenizerFiles/sample-LiftActor.scala"; - - private File tempFile; - - @Before - @Override - public void buildTokenizer() throws IOException { - createTempFileOnDisk(); - this.tokenizer = new ScalaTokenizer(); - } - - private void createTempFileOnDisk() throws IOException { - this.tempFile = File.createTempFile("scala-tokenizer-test-", ".scala"); - FileUtils.writeStringToFile(tempFile, getSampleCode(), ENCODING); + public ScalaTokenizerTest() { + super(".scala"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(getClass().getResourceAsStream(FILENAME), ENCODING); + protected String getResourcePrefix() { + return "../lang/scala/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new ScalaTokenizer(); } @Test - public void tokenizeTest() throws IOException { - this.sourceCode = new SourceCode(new SourceCode.FileCodeLoader(tempFile, "UTF-8")); - this.expectedTokenCount = 2472; - super.tokenizeTest(); + public void testSample() { + doTest("sample-LiftActor"); } @Test - public void tokenizeFailTest() throws IOException { - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader( - " object Main { " - + " def main(args: Array[String]): Unit = { " - + " println(\"Hello, World!) " //unclosed string literal - + " }" - + "}")); - try { - super.tokenizeTest(); - Assert.fail(); - } catch (Exception e) { - // intentional - } - } - - @After - public void cleanUp() { - FileUtils.deleteQuietly(this.tempFile); - this.tempFile = null; + public void tokenizeFailTest() { + ex.expect(TokenMgrError.class); + doTest("unlexable_sample"); } } diff --git a/pmd-scala-modules/pmd-scala-common/src/test/resources/tokenizerFiles/sample-LiftActor.scala b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/sample-LiftActor.scala similarity index 100% rename from pmd-scala-modules/pmd-scala-common/src/test/resources/tokenizerFiles/sample-LiftActor.scala rename to pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/sample-LiftActor.scala diff --git a/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/sample-LiftActor.txt b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/sample-LiftActor.txt new file mode 100644 index 0000000000..734b8e68a6 --- /dev/null +++ b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/sample-LiftActor.txt @@ -0,0 +1,2890 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [/* Example source code copied from[ 1 5 +L19 + [package] 1 9 + [net] 9 13 + [.] 12 14 + [liftweb] 13 21 +L20 + [package] 1 9 + [actor] 9 15 +L22 + [import] 1 8 + [common] 8 15 + [.] 14 16 + [_] 15 17 +L24 + [trait] 1 7 + [ILAExecute] 7 18 + [{] 18 20 +L25 + [def] 3 7 + [execute] 7 15 + [(] 14 16 + [f] 15 17 + [:] 16 18 + [(] 18 20 + [)] 19 21 + [=>] 21 24 + [Unit] 24 29 + [)] 28 30 + [:] 29 31 + [Unit] 31 36 +L26 + [def] 3 7 + [shutdown] 7 16 + [(] 15 17 + [)] 16 18 + [:] 17 19 + [Unit] 19 24 +L27 + [}] 1 3 +L29 + [/**\n * The definition of a schedu[ 1 5 +L32 + [trait] 1 7 + [LAScheduler] 7 19 + [{] 19 21 +L33 + [/**\n * Execute some code on ano[ 3 7 +L38 + [def] 3 7 + [execute] 7 15 + [(] 14 16 + [f] 15 17 + [:] 16 18 + [(] 18 20 + [)] 19 21 + [=>] 21 24 + [Unit] 24 29 + [)] 28 30 + [:] 29 31 + [Unit] 31 36 +L39 + [}] 1 3 +L41 + [object] 1 8 + [LAScheduler] 8 20 + [extends] 20 28 + [LAScheduler] 28 40 + [with] 40 45 + [Loggable] 45 54 + [{] 54 56 +L42 + [@] 3 5 + [volatile] 4 13 +L43 + [var] 3 7 + [onSameThread] 7 20 + [=] 20 22 + [false] 22 28 +L45 + [/**\n * Set this variable to the[ 3 7 +L48 + [@] 3 5 + [volatile] 4 13 + [var] 13 17 + [threadPoolSize] 17 32 + [=] 32 34 + [16] 34 37 + [// issue 194] 37 50 +L50 + [@] 3 5 + [volatile] 4 13 + [var] 13 17 + [maxThreadPoolSize] 17 35 + [=] 35 37 + [threadPoolSize] 37 52 + [*] 52 54 + [25] 54 57 +L52 + [/**\n * If it's Full, then creat[ 3 7 +L57 + [@] 3 5 + [volatile] 4 13 + [var] 13 17 + [blockingQueueSize] 17 35 + [:] 34 36 + [Box] 36 40 + [\[] 39 41 + [Int] 40 44 + [\]] 43 45 + [=] 45 47 + [Full] 47 52 + [(] 51 53 + [200000] 52 59 + [)] 58 60 +L59 + [@] 3 5 + [volatile] 4 13 +L60 + [var] 3 7 + [createExecutor] 7 22 + [:] 21 23 + [(] 23 25 + [)] 24 26 + [=>] 26 29 + [ILAExecute] 29 40 + [=] 40 42 + [(] 42 44 + [)] 43 45 + [=>] 45 48 + [{] 48 50 +L61 + [new] 5 9 + [ILAExecute] 9 20 + [{] 20 22 +L62 + [import] 7 14 + [java] 14 19 + [.] 18 20 + [util] 19 24 + [.] 23 25 + [concurrent] 24 35 + [.] 34 36 + [_] 35 37 +L64 + [private] 7 15 + [val] 15 19 + [es] 19 22 + [=] 22 24 + [// Executors.newFixedThreadPool(th[ 24 72 +L65 + [new] 9 13 + [ThreadPoolExecutor] 13 32 + [(] 31 33 + [threadPoolSize] 32 47 + [,] 46 48 +L66 + [maxThreadPoolSize] 32 50 + [,] 49 51 +L67 + [60] 32 35 + [,] 34 36 +L68 + [TimeUnit] 32 41 + [.] 40 42 + [SECONDS] 41 49 + [,] 48 50 +L69 + [blockingQueueSize] 32 50 + [match] 50 56 + [{] 56 58 +L70 + [case] 34 39 + [Full] 39 44 + [(] 43 45 + [x] 44 46 + [)] 45 47 + [=>] 47 50 +L71 + [new] 36 40 + [ArrayBlockingQueue] 40 59 + [(] 58 60 + [x] 59 61 + [)] 60 62 +L72 + [case] 34 39 + [_] 39 41 + [=>] 41 44 + [new] 44 48 + [LinkedBlockingQueue] 48 68 +L73 + [}] 32 34 + [)] 33 35 +L75 + [def] 7 11 + [execute] 11 19 + [(] 18 20 + [f] 19 21 + [:] 20 22 + [(] 22 24 + [)] 23 25 + [=>] 25 28 + [Unit] 28 33 + [)] 32 34 + [:] 33 35 + [Unit] 35 40 + [=] 40 42 +L76 + [es] 7 10 + [.] 9 11 + [execute] 10 18 + [(] 17 19 + [new] 18 22 + [Runnable] 22 31 + [{] 30 32 + [def] 31 35 + [run] 35 39 + [(] 38 40 + [)] 39 41 + [{] 41 43 +L77 + [try] 9 13 + [{] 13 15 +L78 + [f] 11 13 + [(] 12 14 + [)] 13 15 +L79 + [}] 9 11 + [catch] 11 17 + [{] 17 19 +L80 + [case] 11 16 + [e] 16 18 + [:] 17 19 + [Exception] 19 29 + [=>] 29 32 + [logger] 32 39 + [.] 38 40 + [error] 39 45 + [(] 44 46 + ["Lift Actor Scheduler"] 45 68 + [,] 67 69 + [e] 69 71 + [)] 70 72 +L81 + [}] 9 11 +L82 + [}] 7 9 + [}] 8 10 + [)] 9 11 +L84 + [def] 7 11 + [shutdown] 11 20 + [(] 19 21 + [)] 20 22 + [:] 21 23 + [Unit] 23 28 + [=] 28 30 + [{] 30 32 +L85 + [es] 9 12 + [.] 11 13 + [shutdown] 12 21 + [(] 20 22 + [)] 21 23 +L86 + [}] 7 9 +L87 + [}] 5 7 +L88 + [}] 3 5 +L90 + [@] 3 5 + [volatile] 4 13 +L91 + [var] 3 7 + [exec] 7 12 + [:] 11 13 + [ILAExecute] 13 24 + [=] 24 26 + [_] 26 28 +L93 + [/**\n * Execute some code on ano[ 3 7 +L98 + [def] 3 7 + [execute] 7 15 + [(] 14 16 + [f] 15 17 + [:] 16 18 + [(] 18 20 + [)] 19 21 + [=>] 21 24 + [Unit] 24 29 + [)] 28 30 + [{] 30 32 +L99 + [synchronized] 5 18 + [{] 18 20 +L100 + [if] 7 10 + [(] 10 12 + [exec] 11 16 + [eq] 16 19 + [null] 19 24 + [)] 23 25 + [{] 25 27 +L101 + [exec] 9 14 + [=] 14 16 + [createExecutor] 16 31 + [(] 30 32 + [)] 31 33 +L102 + [}] 7 9 +L103 + [exec] 7 12 + [.] 11 13 + [execute] 12 20 + [(] 19 21 + [f] 20 22 + [)] 21 23 +L104 + [}] 5 7 +L105 + [}] 3 5 +L107 + [def] 3 7 + [shutdown] 7 16 + [(] 15 17 + [)] 16 18 + [{] 18 20 +L108 + [synchronized] 5 18 + [{] 18 20 +L109 + [if] 7 10 + [(] 10 12 + [exec] 11 16 + [ne] 16 19 + [null] 19 24 + [)] 23 25 + [{] 25 27 +L110 + [exec] 9 14 + [.] 13 15 + [shutdown] 14 23 + [(] 22 24 + [)] 23 25 +L111 + [}] 7 9 +L113 + [exec] 7 12 + [=] 12 14 + [null] 14 19 +L114 + [}] 5 7 +L115 + [}] 3 5 +L116 + [}] 1 3 +L118 + [trait] 1 7 + [SpecializedLiftActor] 7 28 + [\[] 27 29 + [T] 28 30 + [\]] 29 31 + [extends] 31 39 + [SimpleActor] 39 51 + [\[] 50 52 + [T] 51 53 + [\]] 52 54 + [{] 55 57 +L119 + [@] 3 5 + [volatile] 4 13 + [private] 13 21 + [\[] 20 22 + [this] 21 26 + [\]] 25 27 + [var] 27 31 + [processing] 31 42 + [=] 42 44 + [false] 44 50 +L120 + [private] 3 11 + [\[] 10 12 + [this] 11 16 + [\]] 15 17 + [val] 17 21 + [baseMailbox] 21 33 + [:] 32 34 + [MailboxItem] 34 46 + [=] 46 48 + [new] 48 52 + [SpecialMailbox] 52 67 +L121 + [@] 3 5 + [volatile] 4 13 + [private] 13 21 + [\[] 20 22 + [this] 21 26 + [\]] 25 27 + [var] 27 31 + [msgList] 31 39 + [:] 38 40 + [List] 40 45 + [\[] 44 46 + [T] 45 47 + [\]] 46 48 + [=] 48 50 + [Nil] 50 54 +L122 + [@] 3 5 + [volatile] 4 13 + [private] 13 21 + [\[] 20 22 + [this] 21 26 + [\]] 25 27 + [var] 27 31 + [priorityMsgList] 31 47 + [:] 46 48 + [List] 48 53 + [\[] 52 54 + [T] 53 55 + [\]] 54 56 + [=] 56 58 + [Nil] 58 62 +L123 + [@] 3 5 + [volatile] 4 13 + [private] 13 21 + [\[] 20 22 + [this] 21 26 + [\]] 25 27 + [var] 27 31 + [startCnt] 31 40 + [=] 40 42 + [0] 42 44 +L125 + [private] 3 11 + [class] 11 17 + [MailboxItem] 17 29 + [(] 28 30 + [val] 29 33 + [item] 33 38 + [:] 37 39 + [T] 39 41 + [)] 40 42 + [{] 42 44 +L126 + [var] 5 9 + [next] 9 14 + [:] 13 15 + [MailboxItem] 15 27 + [=] 27 29 + [_] 29 31 +L127 + [var] 5 9 + [prev] 9 14 + [:] 13 15 + [MailboxItem] 15 27 + [=] 27 29 + [_] 29 31 +L129 + [/*\n def find(f: MailboxItem =>[ 5 8 +L134 + [def] 5 9 + [remove] 9 16 + [(] 15 17 + [)] 16 18 + [{] 18 20 +L135 + [val] 7 11 + [newPrev] 11 19 + [=] 19 21 + [prev] 21 26 +L136 + [prev] 7 12 + [.] 11 13 + [next] 12 17 + [=] 17 19 + [next] 19 24 +L137 + [next] 7 12 + [.] 11 13 + [prev] 12 17 + [=] 17 19 + [prev] 19 24 +L138 + [}] 5 7 +L140 + [def] 5 9 + [insertAfter] 9 21 + [(] 20 22 + [newItem] 21 29 + [:] 28 30 + [MailboxItem] 30 42 + [)] 41 43 + [:] 42 44 + [MailboxItem] 44 56 + [=] 56 58 + [{] 58 60 +L141 + [next] 7 12 + [.] 11 13 + [prev] 12 17 + [=] 17 19 + [newItem] 19 27 +L142 + [newItem] 7 15 + [.] 14 16 + [prev] 15 20 + [=] 20 22 + [this] 22 27 +L143 + [newItem] 7 15 + [.] 14 16 + [next] 15 20 + [=] 20 22 + [this] 22 27 + [.] 26 28 + [next] 27 32 +L144 + [next] 7 12 + [=] 12 14 + [newItem] 14 22 +L145 + [newItem] 7 15 +L146 + [}] 5 7 +L148 + [def] 5 9 + [insertBefore] 9 22 + [(] 21 23 + [newItem] 22 30 + [:] 29 31 + [MailboxItem] 31 43 + [)] 42 44 + [:] 43 45 + [MailboxItem] 45 57 + [=] 57 59 + [{] 59 61 +L149 + [prev] 7 12 + [.] 11 13 + [next] 12 17 + [=] 17 19 + [newItem] 19 27 +L150 + [newItem] 7 15 + [.] 14 16 + [prev] 15 20 + [=] 20 22 + [this] 22 27 + [.] 26 28 + [prev] 27 32 +L151 + [newItem] 7 15 + [.] 14 16 + [next] 15 20 + [=] 20 22 + [this] 22 27 +L152 + [prev] 7 12 + [=] 12 14 + [newItem] 14 22 +L153 + [newItem] 7 15 +L154 + [}] 5 7 +L155 + [}] 3 5 +L157 + [private] 3 11 + [class] 11 17 + [SpecialMailbox] 17 32 + [extends] 32 40 + [MailboxItem] 40 52 + [(] 51 53 + [null] 52 57 + [.] 56 58 + [asInstanceOf] 57 70 + [\[] 69 71 + [T] 70 72 + [\]] 71 73 + [)] 72 74 + [{] 74 76 +L158 + [// override def find(f: MailboxIte[ 5 79 +L159 + [next] 5 10 + [=] 10 12 + [this] 12 17 +L160 + [prev] 5 10 + [=] 10 12 + [this] 12 17 +L161 + [}] 3 5 +L163 + [private] 3 11 + [def] 11 15 + [findMailboxItem] 15 31 + [(] 30 32 + [start] 31 37 + [:] 36 38 + [MailboxItem] 38 50 + [,] 49 51 + [f] 51 53 + [:] 52 54 + [MailboxItem] 54 66 + [=>] 66 69 + [Boolean] 69 77 + [)] 76 78 + [:] 77 79 + [Box] 79 83 + [\[] 82 84 + [MailboxItem] 83 95 + [\]] 94 96 + [=] 96 98 +L164 + [start] 5 11 + [match] 11 17 + [{] 17 19 +L165 + [case] 7 12 + [x] 12 14 + [:] 13 15 + [SpecialMailbox] 15 30 + [=>] 30 33 + [Empty] 33 39 +L166 + [case] 7 12 + [x] 12 14 + [if] 14 17 + [f] 17 19 + [(] 18 20 + [x] 19 21 + [)] 20 22 + [=>] 22 25 + [Full] 25 30 + [(] 29 31 + [x] 30 32 + [)] 31 33 +L167 + [case] 7 12 + [x] 12 14 + [=>] 14 17 + [findMailboxItem] 17 33 + [(] 32 34 + [x] 33 35 + [.] 34 36 + [next] 35 40 + [,] 39 41 + [f] 41 43 + [)] 42 44 +L168 + [}] 5 7 +L170 + [/**\n * Send a message to the Ac[ 3 7 +L175 + [def] 3 7 + [send] 7 12 + [(] 11 13 + [msg] 12 16 + [:] 15 17 + [T] 17 19 + [)] 18 20 + [:] 19 21 + [Unit] 21 26 + [=] 26 28 + [this] 28 33 + [!] 33 35 + [msg] 35 39 +L177 + [/**\n * Send a message to the Ac[ 3 7 +L182 + [def] 3 7 + [!] 7 9 + [(] 8 10 + [msg] 9 13 + [:] 12 14 + [T] 14 16 + [)] 15 17 + [:] 16 18 + [Unit] 18 23 + [=] 23 25 + [{] 25 27 +L183 + [val] 5 9 + [toDo] 9 14 + [:] 13 15 + [(] 15 17 + [)] 16 18 + [=>] 18 21 + [Unit] 21 26 + [=] 26 28 + [baseMailbox] 28 40 + [.] 39 41 + [synchronized] 40 53 + [{] 53 55 +L184 + [msgList] 7 15 + [::=] 15 19 + [msg] 19 23 +L185 + [if] 7 10 + [(] 10 12 + [!] 11 13 + [processing] 12 23 + [)] 22 24 + [{] 24 26 +L186 + [if] 9 12 + [(] 12 14 + [LAScheduler] 13 25 + [.] 24 26 + [onSameThread] 25 38 + [)] 37 39 + [{] 39 41 +L187 + [processing] 11 22 + [=] 22 24 + [true] 24 29 +L188 + [(] 11 13 + [)] 12 14 + [=>] 14 17 + [processMailbox] 17 32 + [(] 31 33 + [true] 32 37 + [)] 36 38 +L189 + [}] 9 11 + [else] 11 16 + [{] 16 18 +L190 + [if] 11 14 + [(] 14 16 + [startCnt] 15 24 + [==] 24 27 + [0] 27 29 + [)] 28 30 + [{] 30 32 +L191 + [startCnt] 13 22 + [+=] 22 25 + [1] 25 27 +L192 + [(] 13 15 + [)] 14 16 + [=>] 16 19 + [LAScheduler] 19 31 + [.] 30 32 + [execute] 31 39 + [(] 38 40 + [(] 39 41 + [)] 40 42 + [=>] 42 45 + [processMailbox] 45 60 + [(] 59 61 + [false] 60 66 + [)] 65 67 + [)] 66 68 +L193 + [}] 11 13 + [else] 13 18 +L194 + [(] 11 13 + [)] 12 14 + [=>] 14 17 + [{] 17 19 + [}] 18 20 +L195 + [}] 9 11 +L196 + [}] 7 9 +L197 + [else] 7 12 + [(] 12 14 + [)] 13 15 + [=>] 15 18 + [{] 18 20 + [}] 19 21 +L198 + [}] 5 7 +L199 + [toDo] 5 10 + [(] 9 11 + [)] 10 12 +L200 + [}] 3 5 +L202 + [/**\n * This method inserts the [ 3 7 +L207 + [protected] 3 13 + [def] 13 17 + [insertMsgAtHeadOfQueue_!] 17 42 + [(] 41 43 + [msg] 42 46 + [:] 45 47 + [T] 47 49 + [)] 48 50 + [:] 49 51 + [Unit] 51 56 + [=] 56 58 + [{] 58 60 +L208 + [val] 6 10 + [toDo] 10 15 + [:] 14 16 + [(] 16 18 + [)] 17 19 + [=>] 19 22 + [Unit] 22 27 + [=] 27 29 + [baseMailbox] 29 41 + [.] 40 42 + [synchronized] 41 54 + [{] 54 56 +L209 + [this] 7 12 + [.] 11 13 + [priorityMsgList] 12 28 + [::=] 28 32 + [msg] 32 36 +L210 + [if] 7 10 + [(] 10 12 + [!] 11 13 + [processing] 12 23 + [)] 22 24 + [{] 24 26 +L211 + [if] 9 12 + [(] 12 14 + [LAScheduler] 13 25 + [.] 24 26 + [onSameThread] 25 38 + [)] 37 39 + [{] 39 41 +L212 + [processing] 11 22 + [=] 22 24 + [true] 24 29 +L213 + [(] 11 13 + [)] 12 14 + [=>] 14 17 + [processMailbox] 17 32 + [(] 31 33 + [true] 32 37 + [)] 36 38 +L214 + [}] 9 11 + [else] 11 16 + [{] 16 18 +L215 + [if] 11 14 + [(] 14 16 + [startCnt] 15 24 + [==] 24 27 + [0] 27 29 + [)] 28 30 + [{] 30 32 +L216 + [startCnt] 13 22 + [+=] 22 25 + [1] 25 27 +L217 + [(] 13 15 + [)] 14 16 + [=>] 16 19 + [LAScheduler] 19 31 + [.] 30 32 + [execute] 31 39 + [(] 38 40 + [(] 39 41 + [)] 40 42 + [=>] 42 45 + [processMailbox] 45 60 + [(] 59 61 + [false] 60 66 + [)] 65 67 + [)] 66 68 +L218 + [}] 11 13 + [else] 13 18 +L219 + [(] 11 13 + [)] 12 14 + [=>] 14 17 + [{] 17 19 + [}] 18 20 +L220 + [}] 9 11 +L221 + [}] 7 9 +L222 + [else] 7 12 + [(] 12 14 + [)] 13 15 + [=>] 15 18 + [{] 18 20 + [}] 19 21 +L223 + [}] 5 7 +L224 + [toDo] 5 10 + [(] 9 11 + [)] 10 12 +L225 + [}] 3 5 +L227 + [private] 3 11 + [def] 11 15 + [processMailbox] 15 30 + [(] 29 31 + [ignoreProcessing] 30 47 + [:] 46 48 + [Boolean] 48 56 + [)] 55 57 + [{] 57 59 +L228 + [around] 5 12 + [{] 12 14 +L229 + [proc2] 7 13 + [(] 12 14 + [ignoreProcessing] 13 30 + [)] 29 31 +L230 + [}] 5 7 +L231 + [}] 3 5 +L233 + [/**\n * A list of LoanWrappers t[ 3 7 +L236 + [protected] 3 13 + [def] 13 17 + [aroundLoans] 17 29 + [:] 28 30 + [List] 30 35 + [\[] 34 36 + [CommonLoanWrapper] 35 53 + [\]] 52 54 + [=] 54 56 + [Nil] 56 60 +L238 + [/**\n * You can wrap calls aroun[ 3 7 +L242 + [protected] 3 13 + [def] 13 17 + [around] 17 24 + [\[] 23 25 + [R] 24 26 + [\]] 25 27 + [(] 26 28 + [f] 27 29 + [:] 28 30 + [=>] 30 33 + [R] 33 35 + [)] 34 36 + [:] 35 37 + [R] 37 39 + [=] 39 41 + [aroundLoans] 41 53 + [match] 53 59 + [{] 59 61 +L243 + [case] 5 10 + [Nil] 10 14 + [=>] 14 17 + [f] 17 19 +L244 + [case] 5 10 + [xs] 10 13 + [=>] 13 16 + [CommonLoanWrapper] 16 34 + [(] 33 35 + [xs] 34 37 + [)] 36 38 + [(] 37 39 + [f] 38 40 + [)] 39 41 +L245 + [}] 3 5 +L246 + [private] 3 11 + [def] 11 15 + [proc2] 15 21 + [(] 20 22 + [ignoreProcessing] 21 38 + [:] 37 39 + [Boolean] 39 47 + [)] 46 48 + [{] 48 50 +L247 + [var] 5 9 + [clearProcessing] 9 25 + [=] 25 27 + [true] 27 32 +L248 + [baseMailbox] 5 17 + [.] 16 18 + [synchronized] 17 30 + [{] 30 32 +L249 + [if] 7 10 + [(] 10 12 + [!] 11 13 + [ignoreProcessing] 12 29 + [&&] 29 32 + [processing] 32 43 + [)] 42 44 + [return] 44 51 +L250 + [processing] 7 18 + [=] 18 20 + [true] 20 25 +L251 + [if] 7 10 + [(] 10 12 + [startCnt] 11 20 + [>] 20 22 + [0] 22 24 + [)] 23 25 + [startCnt] 25 34 + [=] 34 36 + [0] 36 38 +L252 + [}] 5 7 +L254 + [val] 5 9 + [eh] 9 12 + [=] 12 14 + [exceptionHandler] 14 31 +L256 + [def] 5 9 + [putListIntoMB] 9 23 + [(] 22 24 + [)] 23 25 + [:] 24 26 + [Unit] 26 31 + [=] 31 33 + [{] 33 35 +L257 + [if] 7 10 + [(] 10 12 + [!] 11 13 + [priorityMsgList] 12 28 + [.] 27 29 + [isEmpty] 28 36 + [)] 35 37 + [{] 37 39 +L258 + [priorityMsgList] 7 23 + [.] 22 24 + [foldRight] 23 33 + [(] 32 34 + [baseMailbox] 33 45 + [)] 44 46 + [(] 45 47 + [(] 46 48 + [msg] 47 51 + [,] 50 52 + [mb] 52 55 + [)] 54 56 + [=>] 56 59 + [mb] 59 62 + [.] 61 63 + [insertAfter] 62 74 + [(] 73 75 + [new] 74 78 + [MailboxItem] 78 90 + [(] 89 91 + [msg] 90 94 + [)] 93 95 + [)] 94 96 + [)] 95 97 +L259 + [priorityMsgList] 7 23 + [=] 23 25 + [Nil] 25 29 +L260 + [}] 7 9 +L262 + [if] 7 10 + [(] 10 12 + [!] 11 13 + [msgList] 12 20 + [.] 19 21 + [isEmpty] 20 28 + [)] 27 29 + [{] 29 31 +L263 + [msgList] 7 15 + [.] 14 16 + [foldLeft] 15 24 + [(] 23 25 + [baseMailbox] 24 36 + [)] 35 37 + [(] 36 38 + [(] 37 39 + [mb] 38 41 + [,] 40 42 + [msg] 42 46 + [)] 45 47 + [=>] 47 50 + [mb] 50 53 + [.] 52 54 + [insertBefore] 53 66 + [(] 65 67 + [new] 66 70 + [MailboxItem] 70 82 + [(] 81 83 + [msg] 82 86 + [)] 85 87 + [)] 86 88 + [)] 87 89 +L264 + [msgList] 7 15 + [=] 15 17 + [Nil] 17 21 +L265 + [}] 7 9 +L266 + [}] 5 7 +L268 + [try] 5 9 + [{] 9 11 +L269 + [while] 7 13 + [(] 13 15 + [true] 14 19 + [)] 18 20 + [{] 20 22 +L270 + [baseMailbox] 9 21 + [.] 20 22 + [synchronized] 21 34 + [{] 34 36 +L271 + [putListIntoMB] 11 25 + [(] 24 26 + [)] 25 27 +L272 + [}] 9 11 +L274 + [var] 13 17 + [keepOnDoingHighPriory] 17 39 + [=] 39 41 + [true] 41 46 +L276 + [while] 13 19 + [(] 19 21 + [keepOnDoingHighPriory] 20 42 + [)] 41 43 + [{] 43 45 +L277 + [val] 15 19 + [hiPriPfBox] 19 30 + [=] 30 32 + [highPriorityReceive] 32 52 +L278 + [hiPriPfBox] 15 26 + [.] 25 27 + [map] 26 30 + [{] 29 31 +L279 + [hiPriPf] 17 25 + [=>] 25 28 +L280 + [findMailboxItem] 19 35 + [(] 34 36 + [baseMailbox] 35 47 + [.] 46 48 + [next] 47 52 + [,] 51 53 + [mb] 53 56 + [=>] 56 59 + [testTranslate] 59 73 + [(] 72 74 + [hiPriPf] 73 81 + [.] 80 82 + [isDefinedAt] 81 93 + [)] 92 94 + [(] 93 95 + [mb] 94 97 + [.] 96 98 + [item] 97 102 + [)] 101 103 + [)] 102 104 + [match] 104 110 + [{] 110 112 +L281 + [case] 21 26 + [Full] 26 31 + [(] 30 32 + [mb] 31 34 + [)] 33 35 + [=>] 35 38 +L282 + [mb] 23 26 + [.] 25 27 + [remove] 26 33 + [(] 32 34 + [)] 33 35 +L283 + [try] 23 27 + [{] 27 29 +L284 + [execTranslate] 25 39 + [(] 38 40 + [hiPriPf] 39 47 + [)] 46 48 + [(] 47 49 + [mb] 48 51 + [.] 50 52 + [item] 51 56 + [)] 55 57 +L285 + [}] 23 25 + [catch] 25 31 + [{] 31 33 +L286 + [case] 25 30 + [e] 30 32 + [:] 31 33 + [Exception] 33 43 + [=>] 43 46 + [if] 46 49 + [(] 49 51 + [eh] 50 53 + [.] 52 54 + [isDefinedAt] 53 65 + [(] 64 66 + [e] 65 67 + [)] 66 68 + [)] 67 69 + [eh] 69 72 + [(] 71 73 + [e] 72 74 + [)] 73 75 +L287 + [}] 23 25 +L288 + [case] 21 26 + [_] 26 28 + [=>] 28 31 +L289 + [baseMailbox] 23 35 + [.] 34 36 + [synchronized] 35 48 + [{] 48 50 +L290 + [if] 25 28 + [(] 28 30 + [msgList] 29 37 + [.] 36 38 + [isEmpty] 37 45 + [)] 44 46 + [{] 46 48 +L291 + [keepOnDoingHighPriory] 27 49 + [=] 49 51 + [false] 51 57 +L292 + [}] 25 27 +L293 + [else] 25 30 + [{] 30 32 +L294 + [putListIntoMB] 27 41 + [(] 40 42 + [)] 41 43 +L295 + [}] 25 27 +L296 + [}] 23 25 +L297 + [}] 19 21 +L298 + [}] 15 17 + [.] 16 18 + [openOr] 17 24 + [{] 23 25 + [keepOnDoingHighPriory] 24 46 + [=] 46 48 + [false] 48 54 + [}] 53 55 +L299 + [}] 13 15 +L301 + [val] 13 17 + [pf] 17 20 + [=] 20 22 + [messageHandler] 22 37 +L303 + [findMailboxItem] 9 25 + [(] 24 26 + [baseMailbox] 25 37 + [.] 36 38 + [next] 37 42 + [,] 41 43 + [mb] 43 46 + [=>] 46 49 + [testTranslate] 49 63 + [(] 62 64 + [pf] 63 66 + [.] 65 67 + [isDefinedAt] 66 78 + [)] 77 79 + [(] 78 80 + [mb] 79 82 + [.] 81 83 + [item] 82 87 + [)] 86 88 + [)] 87 89 + [match] 89 95 + [{] 95 97 +L304 + [case] 11 16 + [Full] 16 21 + [(] 20 22 + [mb] 21 24 + [)] 23 25 + [=>] 25 28 +L305 + [mb] 13 16 + [.] 15 17 + [remove] 16 23 + [(] 22 24 + [)] 23 25 +L306 + [try] 13 17 + [{] 17 19 +L307 + [execTranslate] 15 29 + [(] 28 30 + [pf] 29 32 + [)] 31 33 + [(] 32 34 + [mb] 33 36 + [.] 35 37 + [item] 36 41 + [)] 40 42 +L308 + [}] 13 15 + [catch] 15 21 + [{] 21 23 +L309 + [case] 15 20 + [e] 20 22 + [:] 21 23 + [Exception] 23 33 + [=>] 33 36 + [if] 36 39 + [(] 39 41 + [eh] 40 43 + [.] 42 44 + [isDefinedAt] 43 55 + [(] 54 56 + [e] 55 57 + [)] 56 58 + [)] 57 59 + [eh] 59 62 + [(] 61 63 + [e] 62 64 + [)] 63 65 +L310 + [}] 13 15 +L311 + [case] 11 16 + [_] 16 18 + [=>] 18 21 +L312 + [baseMailbox] 13 25 + [.] 24 26 + [synchronized] 25 38 + [{] 38 40 +L313 + [if] 15 18 + [(] 18 20 + [msgList] 19 27 + [.] 26 28 + [isEmpty] 27 35 + [)] 34 36 + [{] 36 38 +L314 + [processing] 17 28 + [=] 28 30 + [false] 30 36 +L315 + [clearProcessing] 17 33 + [=] 33 35 + [false] 35 41 +L316 + [return] 17 24 +L317 + [}] 15 17 +L318 + [else] 15 20 + [{] 20 22 +L319 + [putListIntoMB] 17 31 + [(] 30 32 + [)] 31 33 +L320 + [}] 15 17 +L321 + [}] 13 15 +L322 + [}] 9 11 +L323 + [}] 7 9 +L324 + [}] 5 7 + [catch] 7 13 + [{] 13 15 +L325 + [case] 7 12 + [exception] 12 22 + [:] 21 23 + [Throwable] 23 33 + [=>] 33 36 +L326 + [if] 9 12 + [(] 12 14 + [eh] 13 16 + [.] 15 17 + [isDefinedAt] 16 28 + [(] 27 29 + [exception] 28 38 + [)] 37 39 + [)] 38 40 +L327 + [eh] 11 14 + [(] 13 15 + [exception] 14 24 + [)] 23 25 +L329 + [throw] 9 15 + [exception] 15 25 +L330 + [}] 5 7 + [finally] 7 15 + [{] 15 17 +L331 + [if] 7 10 + [(] 10 12 + [clearProcessing] 11 27 + [)] 26 28 + [{] 28 30 +L332 + [baseMailbox] 9 21 + [.] 20 22 + [synchronized] 21 34 + [{] 34 36 +L333 + [processing] 11 22 + [=] 22 24 + [false] 24 30 +L334 + [}] 9 11 +L335 + [}] 7 9 +L336 + [}] 5 7 +L337 + [}] 3 5 +L339 + [protected] 3 13 + [def] 13 17 + [testTranslate] 17 31 + [(] 30 32 + [f] 31 33 + [:] 32 34 + [T] 34 36 + [=>] 36 39 + [Boolean] 39 47 + [)] 46 48 + [(] 47 49 + [v] 48 50 + [:] 49 51 + [T] 51 53 + [)] 52 54 + [:] 53 55 + [Boolean] 55 63 + [=] 63 65 + [f] 65 67 + [(] 66 68 + [v] 67 69 + [)] 68 70 +L341 + [protected] 3 13 + [def] 13 17 + [execTranslate] 17 31 + [(] 30 32 + [f] 31 33 + [:] 32 34 + [T] 34 36 + [=>] 36 39 + [Unit] 39 44 + [)] 43 45 + [(] 44 46 + [v] 45 47 + [:] 46 48 + [T] 48 50 + [)] 49 51 + [:] 50 52 + [Unit] 52 57 + [=] 57 59 + [f] 59 61 + [(] 60 62 + [v] 61 63 + [)] 62 64 +L343 + [protected] 3 13 + [def] 13 17 + [messageHandler] 17 32 + [:] 31 33 + [PartialFunction] 33 49 + [\[] 48 50 + [T] 49 51 + [,] 50 52 + [Unit] 52 57 + [\]] 56 58 +L345 + [protected] 3 13 + [def] 13 17 + [highPriorityReceive] 17 37 + [:] 36 38 + [Box] 38 42 + [\[] 41 43 + [PartialFunction] 42 58 + [\[] 57 59 + [T] 58 60 + [,] 59 61 + [Unit] 61 66 + [\]] 65 67 + [\]] 66 68 + [=] 68 70 + [Empty] 70 76 +L347 + [protected] 3 13 + [def] 13 17 + [exceptionHandler] 17 34 + [:] 33 35 + [PartialFunction] 35 51 + [\[] 50 52 + [Throwable] 51 61 + [,] 60 62 + [Unit] 62 67 + [\]] 66 68 + [=] 68 70 + [{] 70 72 +L348 + [case] 5 10 + [e] 10 12 + [=>] 12 15 + [ActorLogger] 15 27 + [.] 26 28 + [error] 27 33 + [(] 32 34 + ["Actor threw an exception"] 33 60 + [,] 59 61 + [e] 61 63 + [)] 62 64 +L349 + [}] 3 5 +L350 + [}] 1 3 +L352 + [/**\n * A SpecializedLiftActor des[ 1 5 +L362 + [class] 1 7 + [MockSpecializedLiftActor] 7 32 + [\[] 31 33 + [T] 32 34 + [\]] 33 35 + [extends] 35 43 + [SpecializedLiftActor] 43 64 + [\[] 63 65 + [T] 64 66 + [\]] 65 67 + [{] 67 69 +L363 + [private] 3 11 + [\[] 10 12 + [this] 11 16 + [\]] 15 17 + [var] 17 21 + [messagesReceived] 21 38 + [:] 37 39 + [List] 39 44 + [\[] 43 45 + [T] 44 46 + [\]] 45 47 + [=] 47 49 + [Nil] 49 53 +L365 + [/**\n * Send a message to the mo[ 3 7 +L369 + [override] 3 12 + [def] 12 16 + [!] 16 18 + [(] 17 19 + [msg] 18 22 + [:] 21 23 + [T] 23 25 + [)] 24 26 + [:] 25 27 + [Unit] 27 32 + [=] 32 34 + [{] 34 36 +L370 + [messagesReceived] 5 22 + [.] 21 23 + [synchronized] 22 35 + [{] 35 37 +L371 + [messagesReceived] 7 24 + [::=] 24 28 + [msg] 28 32 +L372 + [}] 5 7 +L373 + [}] 3 5 +L375 + [// We aren't required to implement[ 3 80 +L376 + [// since the message handler never[ 3 44 +L377 + [override] 3 12 + [def] 12 16 + [messageHandler] 16 31 + [:] 30 32 + [PartialFunction] 32 48 + [\[] 47 49 + [T] 48 50 + [,] 49 51 + [Unit] 51 56 + [\]] 55 57 + [=] 57 59 + [{] 59 61 +L378 + [case] 5 10 + [_] 10 12 + [=>] 12 15 +L379 + [}] 3 5 +L381 + [/**\n * Test to see if this acto[ 3 7 +L384 + [def] 3 7 + [hasReceivedMessage_?] 7 28 + [(] 27 29 + [msg] 28 32 + [:] 31 33 + [T] 33 35 + [)] 34 36 + [:] 35 37 + [Boolean] 37 45 + [=] 45 47 + [messagesReceived] 47 64 + [.] 63 65 + [contains] 64 73 + [(] 72 74 + [msg] 73 77 + [)] 76 78 +L386 + [/**\n * Returns the list of mess[ 3 7 +L389 + [def] 3 7 + [messages] 7 16 + [:] 15 17 + [List] 17 22 + [\[] 21 23 + [T] 22 24 + [\]] 23 25 + [=] 25 27 + [messagesReceived] 27 44 +L391 + [/**\n * Return the number of mes[ 3 7 +L394 + [def] 3 7 + [messageCount] 7 20 + [:] 19 21 + [Int] 21 25 + [=] 25 27 + [messagesReceived] 27 44 + [.] 43 45 + [size] 44 49 +L395 + [}] 1 3 +L397 + [object] 1 8 + [ActorLogger] 8 20 + [extends] 20 28 + [Logger] 28 35 + [{] 35 37 +L398 + [}] 1 3 +L400 + [private] 1 9 + [final] 9 15 + [case] 15 20 + [class] 20 26 + [MsgWithResp] 26 38 + [(] 37 39 + [msg] 38 42 + [:] 41 43 + [Any] 43 47 + [,] 46 48 + [future] 48 55 + [:] 54 56 + [LAFuture] 56 65 + [\[] 64 66 + [Any] 65 69 + [\]] 68 70 + [)] 69 71 +L402 + [trait] 1 7 + [LiftActor] 7 17 + [extends] 17 25 + [SpecializedLiftActor] 25 46 + [\[] 45 47 + [Any] 46 50 + [\]] 49 51 +L403 + [with] 1 6 + [GenericActor] 6 19 + [\[] 18 20 + [Any] 19 23 + [\]] 22 24 +L404 + [with] 1 6 + [ForwardableActor] 6 23 + [\[] 22 24 + [Any] 23 27 + [,] 26 28 + [Any] 28 32 + [\]] 31 33 + [{] 33 35 +L405 + [@] 3 5 + [volatile] 4 13 +L406 + [private] 3 11 + [\[] 10 12 + [this] 11 16 + [\]] 15 17 + [var] 17 21 + [responseFuture] 21 36 + [:] 35 37 + [LAFuture] 37 46 + [\[] 45 47 + [Any] 46 50 + [\]] 49 51 + [=] 51 53 + [null] 53 58 +L410 + [protected] 3 13 + [final] 13 19 + [def] 19 23 + [forwardMessageTo] 23 40 + [(] 39 41 + [msg] 40 44 + [:] 43 45 + [Any] 45 49 + [,] 48 50 + [forwardTo] 50 60 + [:] 59 61 + [TypedActor] 61 72 + [\[] 71 73 + [Any] 72 76 + [,] 75 77 + [Any] 77 81 + [\]] 80 82 + [)] 81 83 + [{] 83 85 +L411 + [if] 5 8 + [(] 8 10 + [null] 9 14 + [ne] 14 17 + [responseFuture] 17 32 + [)] 31 33 + [{] 33 35 +L412 + [forwardTo] 7 17 + [match] 17 23 + [{] 23 25 +L413 + [case] 9 14 + [la] 14 17 + [:] 16 18 + [LiftActor] 18 28 + [=>] 28 31 + [la] 31 34 + [!] 34 36 + [MsgWithResp] 36 48 + [(] 47 49 + [msg] 48 52 + [,] 51 53 + [responseFuture] 53 68 + [)] 67 69 +L414 + [case] 9 14 + [other] 14 20 + [=>] 20 23 +L415 + [reply] 11 17 + [(] 16 18 + [other] 17 23 + [!?] 23 26 + [msg] 26 30 + [)] 29 31 +L416 + [}] 7 9 +L417 + [}] 5 7 + [else] 7 12 + [forwardTo] 12 22 + [!] 22 24 + [msg] 24 28 +L418 + [}] 3 5 +L420 + [/**\n * Send a message to the Act[ 3 6 +L425 + [def] 3 7 + [sendAndGetFuture] 7 24 + [(] 23 25 + [msg] 24 28 + [:] 27 29 + [Any] 29 33 + [)] 32 34 + [:] 33 35 + [LAFuture] 35 44 + [\[] 43 45 + [Any] 44 48 + [\]] 47 49 + [=] 49 51 + [this] 51 56 + [!<] 56 59 + [msg] 59 63 +L427 + [/**\n * Send a message to the Act[ 3 6 +L431 + [def] 3 7 + [!<] 7 10 + [(] 9 11 + [msg] 10 14 + [:] 13 15 + [Any] 15 19 + [)] 18 20 + [:] 19 21 + [LAFuture] 21 30 + [\[] 29 31 + [Any] 30 34 + [\]] 33 35 + [=] 35 37 + [{] 37 39 +L432 + [val] 5 9 + [future] 9 16 + [=] 16 18 + [new] 18 22 + [LAFuture] 22 31 + [\[] 30 32 + [Any] 31 35 + [\]] 34 36 +L433 + [this] 5 10 + [!] 10 12 + [MsgWithResp] 12 24 + [(] 23 25 + [msg] 24 28 + [,] 27 29 + [future] 29 36 + [)] 35 37 +L434 + [future] 5 12 +L435 + [}] 3 5 +L437 + [/**\n * Send a message to the Act[ 3 6 +L442 + [def] 3 7 + [sendAndGetReply] 7 23 + [(] 22 24 + [msg] 23 27 + [:] 26 28 + [Any] 28 32 + [)] 31 33 + [:] 32 34 + [Any] 34 38 + [=] 38 40 + [this] 40 45 + [!?] 45 48 + [msg] 48 52 +L444 + [/**\n * Send a message to the Act[ 3 6 +L448 + [def] 3 7 + [!?] 7 10 + [(] 9 11 + [msg] 10 14 + [:] 13 15 + [Any] 15 19 + [)] 18 20 + [:] 19 21 + [Any] 21 25 + [=] 25 27 + [{] 27 29 +L449 + [val] 5 9 + [future] 9 16 + [=] 16 18 + [new] 18 22 + [LAFuture] 22 31 + [\[] 30 32 + [Any] 31 35 + [\]] 34 36 +L450 + [this] 5 10 + [!] 10 12 + [MsgWithResp] 12 24 + [(] 23 25 + [msg] 24 28 + [,] 27 29 + [future] 29 36 + [)] 35 37 +L451 + [future] 5 12 + [.] 11 13 + [get] 12 16 +L452 + [}] 3 5 +L455 + [/**\n * Send a message to the Act[ 3 6 +L461 + [def] 3 7 + [sendAndGetReply] 7 23 + [(] 22 24 + [timeout] 23 31 + [:] 30 32 + [Long] 32 37 + [,] 36 38 + [msg] 38 42 + [:] 41 43 + [Any] 43 47 + [)] 46 48 + [:] 47 49 + [Any] 49 53 + [=] 53 55 + [this] 55 60 + [.] 59 61 + [!?] 60 63 + [(] 62 64 + [timeout] 63 71 + [,] 70 72 + [msg] 72 76 + [)] 75 77 +L463 + [/**\n * Send a message to the Act[ 3 6 +L468 + [def] 3 7 + [!?] 7 10 + [(] 9 11 + [timeout] 10 18 + [:] 17 19 + [Long] 19 24 + [,] 23 25 + [message] 25 33 + [:] 32 34 + [Any] 34 38 + [)] 37 39 + [:] 38 40 + [Box] 40 44 + [\[] 43 45 + [Any] 44 48 + [\]] 47 49 + [=] 49 51 +L469 + [this] 5 10 + [!!] 10 13 + [(] 13 15 + [message] 14 22 + [,] 21 23 + [timeout] 23 31 + [)] 30 32 +L472 + [/**\n * Send a message to the A[ 5 8 +L477 + [def] 3 7 + [!!] 7 10 + [(] 9 11 + [msg] 10 14 + [:] 13 15 + [Any] 15 19 + [,] 18 20 + [timeout] 20 28 + [:] 27 29 + [Long] 29 34 + [)] 33 35 + [:] 34 36 + [Box] 36 40 + [\[] 39 41 + [Any] 40 44 + [\]] 43 45 + [=] 45 47 + [{] 47 49 +L478 + [val] 5 9 + [future] 9 16 + [=] 16 18 + [new] 18 22 + [LAFuture] 22 31 + [\[] 30 32 + [Any] 31 35 + [\]] 34 36 +L479 + [this] 5 10 + [!] 10 12 + [MsgWithResp] 12 24 + [(] 23 25 + [msg] 24 28 + [,] 27 29 + [future] 29 36 + [)] 35 37 +L480 + [future] 5 12 + [.] 11 13 + [get] 12 16 + [(] 15 17 + [timeout] 16 24 + [)] 23 25 +L481 + [}] 3 5 +L483 + [/**\n * Send a message to the Act[ 3 6 +L487 + [def] 3 7 + [!!] 7 10 + [(] 9 11 + [msg] 10 14 + [:] 13 15 + [Any] 15 19 + [)] 18 20 + [:] 19 21 + [Box] 21 25 + [\[] 24 26 + [Any] 25 29 + [\]] 28 30 + [=] 30 32 + [{] 32 34 +L488 + [val] 5 9 + [future] 9 16 + [=] 16 18 + [new] 18 22 + [LAFuture] 22 31 + [\[] 30 32 + [Any] 31 35 + [\]] 34 36 +L489 + [this] 5 10 + [!] 10 12 + [MsgWithResp] 12 24 + [(] 23 25 + [msg] 24 28 + [,] 27 29 + [future] 29 36 + [)] 35 37 +L490 + [Full] 5 10 + [(] 9 11 + [future] 10 17 + [.] 16 18 + [get] 17 21 + [)] 20 22 +L491 + [}] 3 5 +L493 + [override] 3 12 + [protected] 12 22 + [def] 22 26 + [testTranslate] 26 40 + [(] 39 41 + [f] 40 42 + [:] 41 43 + [Any] 43 47 + [=>] 47 50 + [Boolean] 50 58 + [)] 57 59 + [(] 58 60 + [v] 59 61 + [:] 60 62 + [Any] 62 66 + [)] 65 67 + [=] 67 69 + [v] 69 71 + [match] 71 77 + [{] 77 79 +L494 + [case] 5 10 + [MsgWithResp] 10 22 + [(] 21 23 + [msg] 22 26 + [,] 25 27 + [_] 27 29 + [)] 28 30 + [=>] 30 33 + [f] 33 35 + [(] 34 36 + [msg] 35 39 + [)] 38 40 +L495 + [case] 5 10 + [v] 10 12 + [=>] 12 15 + [f] 15 17 + [(] 16 18 + [v] 17 19 + [)] 18 20 +L496 + [}] 3 5 +L498 + [override] 3 12 + [protected] 12 22 + [def] 22 26 + [execTranslate] 26 40 + [(] 39 41 + [f] 40 42 + [:] 41 43 + [Any] 43 47 + [=>] 47 50 + [Unit] 50 55 + [)] 54 56 + [(] 55 57 + [v] 56 58 + [:] 57 59 + [Any] 59 63 + [)] 62 64 + [=] 64 66 + [v] 66 68 + [match] 68 74 + [{] 74 76 +L499 + [case] 5 10 + [MsgWithResp] 10 22 + [(] 21 23 + [msg] 22 26 + [,] 25 27 + [future] 27 34 + [)] 33 35 + [=>] 35 38 +L500 + [responseFuture] 7 22 + [=] 22 24 + [future] 24 31 +L501 + [try] 7 11 + [{] 11 13 +L502 + [f] 9 11 + [(] 10 12 + [msg] 11 15 + [)] 14 16 +L503 + [}] 7 9 + [finally] 9 17 + [{] 17 19 +L504 + [responseFuture] 9 24 + [=] 24 26 + [null] 26 31 +L505 + [}] 7 9 +L506 + [case] 5 10 + [v] 10 12 + [=>] 12 15 + [f] 15 17 + [(] 16 18 + [v] 17 19 + [)] 18 20 +L507 + [}] 3 5 +L509 + [/**\n * The Actor should call thi[ 3 6 +L513 + [protected] 3 13 + [def] 13 17 + [reply] 17 23 + [(] 22 24 + [v] 23 25 + [:] 24 26 + [Any] 26 30 + [)] 29 31 + [{] 31 33 +L514 + [if] 5 8 + [(] 8 10 + [null] 9 14 + [ne] 14 17 + [responseFuture] 17 32 + [)] 31 33 + [{] 33 35 +L515 + [responseFuture] 7 22 + [.] 21 23 + [satisfy] 22 30 + [(] 29 31 + [v] 30 32 + [)] 31 33 +L516 + [}] 5 7 +L517 + [}] 3 5 +L518 + [}] 1 3 +L520 + [/**\n * A MockLiftActor for use in[ 1 5 +L529 + [class] 1 7 + [MockLiftActor] 7 21 + [extends] 21 29 + [MockSpecializedLiftActor] 29 54 + [\[] 53 55 + [Any] 54 58 + [\]] 57 59 + [with] 59 64 + [LiftActor] 64 74 +L531 + [import] 1 8 + [java] 8 13 + [.] 12 14 + [lang] 13 18 + [.] 17 19 + [reflect] 18 26 + [.] 25 27 + [_] 26 28 +L533 + [object] 1 8 + [LiftActorJ] 8 19 + [{] 19 21 +L534 + [private] 3 11 + [var] 11 15 + [methods] 15 23 + [:] 22 24 + [Map] 24 28 + [\[] 27 29 + [Class] 28 34 + [\[] 33 35 + [_] 34 36 + [\]] 35 37 + [,] 36 38 + [DispatchVendor] 38 53 + [\]] 52 54 + [=] 54 56 + [Map] 56 60 + [(] 59 61 + [)] 60 62 +L536 + [def] 3 7 + [calculateHandler] 7 24 + [(] 23 25 + [what] 24 29 + [:] 28 30 + [LiftActorJ] 30 41 + [)] 40 42 + [:] 41 43 + [PartialFunction] 43 59 + [\[] 58 60 + [Any] 59 63 + [,] 62 64 + [Unit] 64 69 + [\]] 68 70 + [=] 70 72 +L537 + [synchronized] 5 18 + [{] 18 20 +L538 + [val] 7 11 + [clz] 11 15 + [=] 15 17 + [what] 17 22 + [.] 21 23 + [getClass] 22 31 +L539 + [methods] 7 15 + [.] 14 16 + [get] 15 19 + [(] 18 20 + [clz] 19 23 + [)] 22 24 + [match] 24 30 + [{] 30 32 +L540 + [case] 9 14 + [Some] 14 19 + [(] 18 20 + [pf] 19 22 + [)] 21 23 + [=>] 23 26 + [pf] 26 29 + [.] 28 30 + [vend] 29 34 + [(] 33 35 + [what] 34 39 + [)] 38 40 +L541 + [case] 9 14 + [_] 14 16 + [=>] 16 19 + [{] 19 21 +L542 + [val] 11 15 + [pf] 15 18 + [=] 18 20 + [buildPF] 20 28 + [(] 27 29 + [clz] 28 32 + [)] 31 33 +L543 + [methods] 11 19 + [+=] 19 22 + [clz] 22 26 + [->] 26 29 + [pf] 29 32 +L544 + [pf] 11 14 + [.] 13 15 + [vend] 14 19 + [(] 18 20 + [what] 19 24 + [)] 23 25 +L545 + [}] 9 11 +L546 + [}] 7 9 +L547 + [}] 5 7 +L549 + [private] 3 11 + [def] 11 15 + [getBaseClasses] 15 30 + [(] 29 31 + [clz] 30 34 + [:] 33 35 + [Class] 35 41 + [\[] 40 42 + [_] 41 43 + [\]] 42 44 + [)] 43 45 + [:] 44 46 + [List] 46 51 + [\[] 50 52 + [Class] 51 57 + [\[] 56 58 + [_] 57 59 + [\]] 58 60 + [\]] 59 61 + [=] 61 63 + [clz] 63 67 + [match] 67 73 + [{] 73 75 +L550 + [case] 5 10 + [null] 10 15 + [=>] 15 18 + [Nil] 18 22 +L551 + [case] 5 10 + [clz] 10 14 + [=>] 14 17 + [clz] 17 21 + [::] 21 24 + [getBaseClasses] 24 39 + [(] 38 40 + [clz] 39 43 + [.] 42 44 + [getSuperclass] 43 57 + [)] 56 58 +L552 + [}] 3 5 +L554 + [private] 3 11 + [def] 11 15 + [receiver] 15 24 + [(] 23 25 + [in] 24 27 + [:] 26 28 + [Method] 28 35 + [)] 34 36 + [:] 35 37 + [Boolean] 37 45 + [=] 45 47 + [{] 47 49 +L555 + [in] 5 8 + [.] 7 9 + [getParameterTypes] 8 26 + [(] 25 27 + [)] 26 28 + [.] 27 29 + [length] 28 35 + [==] 35 38 + [1] 38 40 + [&&] 40 43 +L556 + [(] 5 7 + [in] 6 9 + [.] 8 10 + [getAnnotation] 9 23 + [(] 22 24 + [classOf] 23 31 + [\[] 30 32 + [JavaActorBase] 31 45 + [.] 44 46 + [Receive] 45 53 + [\]] 52 54 + [)] 53 55 + [!=] 55 58 + [null] 58 63 + [)] 62 64 +L557 + [}] 3 5 +L559 + [private] 3 11 + [def] 11 15 + [buildPF] 15 23 + [(] 22 24 + [clz] 23 27 + [:] 26 28 + [Class] 28 34 + [\[] 33 35 + [_] 34 36 + [\]] 35 37 + [)] 36 38 + [:] 37 39 + [DispatchVendor] 39 54 + [=] 54 56 + [{] 56 58 +L560 + [val] 5 9 + [methods] 9 17 + [=] 17 19 + [getBaseClasses] 19 34 + [(] 33 35 + [clz] 34 38 + [)] 37 39 + [.] 38 40 +L561 + [flatMap] 5 13 + [(] 12 14 + [_] 13 15 + [.] 14 16 + [getDeclaredMethods] 15 34 + [.] 33 35 + [toList] 34 41 + [.] 40 42 + [filter] 41 48 + [(] 47 49 + [receiver] 48 57 + [)] 56 58 + [)] 57 59 +L563 + [val] 5 9 + [clzMap] 9 16 + [:] 15 17 + [Map] 17 21 + [\[] 20 22 + [Class] 21 27 + [\[] 26 28 + [_] 27 29 + [\]] 28 30 + [,] 29 31 + [Method] 31 38 + [\]] 37 39 + [=] 39 41 +L564 + [Map] 7 11 + [(] 10 12 + [methods] 11 19 + [.] 18 20 + [map] 19 23 + [{] 22 24 + [m] 23 25 + [=>] 25 28 +L565 + [m] 9 11 + [.] 10 12 + [setAccessible] 11 25 + [(] 24 26 + [true] 25 30 + [)] 29 31 + [// access private and protected me[ 31 71 +L566 + [m] 9 11 + [.] 10 12 + [getParameterTypes] 11 29 + [(] 28 30 + [)] 29 31 + [.] 30 32 + [apply] 31 37 + [(] 36 38 + [0] 37 39 + [)] 38 40 + [->] 40 43 + [m] 43 45 + [}] 44 46 + [:] 46 48 + [_] 47 49 + [*] 48 50 + [)] 49 51 +L568 + [new] 5 9 + [DispatchVendor] 9 24 + [(] 23 25 + [clzMap] 24 31 + [)] 30 32 +L569 + [}] 3 5 +L570 + [}] 1 3 +L572 + [private] 1 9 + [final] 9 15 + [class] 15 21 + [DispatchVendor] 21 36 + [(] 35 37 + [map] 36 40 + [:] 39 41 + [Map] 41 45 + [\[] 44 46 + [Class] 45 51 + [\[] 50 52 + [_] 51 53 + [\]] 52 54 + [,] 53 55 + [Method] 55 62 + [\]] 61 63 + [)] 62 64 + [{] 64 66 +L573 + [private] 3 11 + [val] 11 15 + [baseMap] 15 23 + [:] 22 24 + [Map] 24 28 + [\[] 27 29 + [Class] 28 34 + [\[] 33 35 + [_] 34 36 + [\]] 35 37 + [,] 36 38 + [Option] 38 45 + [\[] 44 46 + [Method] 45 52 + [\]] 51 53 + [\]] 52 54 + [=] 54 56 +L574 + [Map] 5 9 + [(] 8 10 + [map] 9 13 + [.] 12 14 + [map] 13 17 + [{] 16 18 + [case] 17 22 + [(] 22 24 + [k] 23 25 + [,] 24 26 + [v] 25 27 + [)] 26 28 + [=>] 28 31 + [(] 31 33 + [k] 32 34 + [,] 33 35 + [Some] 35 40 + [(] 39 41 + [v] 40 42 + [)] 41 43 + [)] 42 44 + [}] 43 45 + [.] 44 46 + [toList] 45 52 + [:] 52 54 + [_] 53 55 + [*] 54 56 + [)] 55 57 +L576 + [def] 3 7 + [vend] 7 12 + [(] 11 13 + [actor] 12 18 + [:] 17 19 + [LiftActorJ] 19 30 + [)] 29 31 + [:] 30 32 + [PartialFunction] 32 48 + [\[] 47 49 + [Any] 48 52 + [,] 51 53 + [Unit] 53 58 + [\]] 57 59 + [=] 59 61 +L577 + [new] 5 9 + [PartialFunction] 9 25 + [\[] 24 26 + [Any] 25 29 + [,] 28 30 + [Unit] 30 35 + [\]] 34 36 + [{] 36 38 +L578 + [var] 7 11 + [theMap] 11 18 + [:] 17 19 + [Map] 19 23 + [\[] 22 24 + [Class] 23 29 + [\[] 28 30 + [_] 29 31 + [\]] 30 32 + [,] 31 33 + [Option] 33 40 + [\[] 39 41 + [Method] 40 47 + [\]] 46 48 + [\]] 47 49 + [=] 49 51 + [baseMap] 51 59 +L580 + [def] 7 11 + [findClass] 11 21 + [(] 20 22 + [clz] 21 25 + [:] 24 26 + [Class] 26 32 + [\[] 31 33 + [_] 32 34 + [\]] 33 35 + [)] 34 36 + [:] 35 37 + [Option] 37 44 + [\[] 43 45 + [Method] 44 51 + [\]] 50 52 + [=] 52 54 +L581 + [theMap] 9 16 + [.] 15 17 + [find] 16 21 + [(] 20 22 + [_] 21 23 + [.] 22 24 + [_1] 23 26 + [.] 25 27 + [isAssignableFrom] 26 43 + [(] 42 44 + [clz] 43 47 + [)] 46 48 + [)] 47 49 + [.] 48 50 + [flatMap] 49 57 + [(] 56 58 + [_] 57 59 + [.] 58 60 + [_2] 59 62 + [)] 61 63 +L583 + [def] 7 11 + [isDefinedAt] 11 23 + [(] 22 24 + [v] 23 25 + [:] 24 26 + [Any] 26 30 + [)] 29 31 + [:] 30 32 + [Boolean] 32 40 + [=] 40 42 + [{] 42 44 +L584 + [val] 9 13 + [clz] 13 17 + [=] 17 19 + [v] 19 21 + [.] 20 22 + [asInstanceOf] 21 34 + [\[] 33 35 + [Object] 34 41 + [\]] 40 42 + [.] 41 43 + [getClass] 42 51 +L585 + [theMap] 9 16 + [.] 15 17 + [get] 16 20 + [(] 19 21 + [clz] 20 24 + [)] 23 25 + [match] 25 31 + [{] 31 33 +L586 + [case] 11 16 + [Some] 16 21 + [(] 20 22 + [Some] 21 26 + [(] 25 27 + [_] 26 28 + [)] 27 29 + [)] 28 30 + [=>] 30 33 + [true] 33 38 +L587 + [case] 11 16 + [None] 16 21 + [=>] 21 24 + [{] 24 26 +L588 + [val] 13 17 + [answer] 17 24 + [=] 24 26 + [findClass] 26 36 + [(] 35 37 + [clz] 36 40 + [)] 39 41 +L589 + [theMap] 13 20 + [+=] 20 23 + [clz] 23 27 + [->] 27 30 + [answer] 30 37 +L590 + [answer] 13 20 + [.] 19 21 + [isDefined] 20 30 +L591 + [}] 11 13 +L592 + [case] 11 16 + [_] 16 18 + [=>] 18 21 + [false] 21 27 +L593 + [}] 9 11 +L594 + [}] 7 9 +L596 + [def] 7 11 + [apply] 11 17 + [(] 16 18 + [v] 17 19 + [:] 18 20 + [Any] 20 24 + [)] 23 25 + [:] 24 26 + [Unit] 26 31 + [=] 31 33 + [{] 33 35 +L597 + [val] 9 13 + [o] 13 15 + [:] 14 16 + [Object] 16 23 + [=] 23 25 + [v] 25 27 + [.] 26 28 + [asInstanceOf] 27 40 + [\[] 39 41 + [Object] 40 47 + [\]] 46 48 +L598 + [val] 9 13 + [meth] 13 18 + [=] 18 20 + [theMap] 20 27 + [(] 26 28 + [o] 27 29 + [.] 28 30 + [getClass] 29 38 + [)] 37 39 + [.] 38 40 + [get] 39 43 +L599 + [meth] 9 14 + [.] 13 15 + [invoke] 14 21 + [(] 20 22 + [actor] 21 27 + [,] 26 28 + [o] 28 30 + [)] 29 31 + [match] 31 37 + [{] 37 39 +L600 + [case] 11 16 + [null] 16 21 + [=>] 21 24 +L601 + [case] 11 16 + [x] 16 18 + [=>] 18 21 + [actor] 21 27 + [.] 26 28 + [internalReply] 27 41 + [(] 40 42 + [x] 41 43 + [)] 42 44 +L602 + [}] 9 11 +L603 + [}] 7 9 +L604 + [}] 5 7 +L605 + [}] 1 3 +L607 + [/**\n * Java versions of Actors sh[ 1 5 +L612 + [class] 1 7 + [LiftActorJ] 7 18 + [extends] 18 26 + [JavaActorBase] 26 40 + [with] 40 45 + [LiftActor] 45 55 + [{] 55 57 +L613 + [protected] 3 13 + [lazy] 13 18 + [val] 18 22 + [_messageHandler] 22 38 + [:] 37 39 + [PartialFunction] 39 55 + [\[] 54 56 + [Any] 55 59 + [,] 58 60 + [Unit] 60 65 + [\]] 64 66 + [=] 66 68 +L614 + [calculateJavaMessageHandler] 5 33 +L616 + [protected] 3 13 + [def] 13 17 + [calculateJavaMessageHandler] 17 45 + [=] 45 47 + [LiftActorJ] 47 58 + [.] 57 59 + [calculateHandler] 58 75 + [(] 74 76 + [this] 75 80 + [)] 79 81 +L618 + [protected] 3 13 + [def] 13 17 + [messageHandler] 17 32 + [=] 32 34 + [_messageHandler] 34 50 +L620 + [private] 3 11 + [\[] 10 12 + [actor] 11 17 + [\]] 16 18 + [def] 18 22 + [internalReply] 22 36 + [(] 35 37 + [v] 36 38 + [:] 37 39 + [Any] 39 43 + [)] 42 44 + [=] 44 46 + [reply] 46 52 + [(] 51 53 + [v] 52 54 + [)] 53 55 +L621 + [}] 1 3 +EOF diff --git a/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/unlexable_sample.scala b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/unlexable_sample.scala new file mode 100644 index 0000000000..941ef4a352 --- /dev/null +++ b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/unlexable_sample.scala @@ -0,0 +1,5 @@ +object Main { + def main(args: Array[String]): Unit = { + println("Hello, World!) // unclosed literal + } +} \ No newline at end of file diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 058ae2d356..7c5ed21512 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -30,16 +30,19 @@ antlr-cleanup generate-sources - - - - - - - run + + + + + + + + + + @@ -75,10 +78,20 @@ junit test + + org.junit.vintage + junit-vintage-engine + test + net.sourceforge.pmd pmd-test test + + net.sourceforge.pmd + pmd-lang-test + test + diff --git a/pmd-swift/src/main/ant/antlr4.xml b/pmd-swift/src/main/ant/antlr4.xml deleted file mode 100644 index 14b0522aa4..0000000000 --- a/pmd-swift/src/main/ant/antlr4.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - diff --git a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 index a39c2a80c6..45699d16d3 100644 --- a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 +++ b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 @@ -35,27 +35,28 @@ grammar Swift; @header { import net.sourceforge.pmd.lang.ast.impl.antlr4.*; +import net.sourceforge.pmd.lang.ast.AstVisitor; } +@parser::members { -@classMembers { + static final AntlrNameDictionary DICO = new SwiftNameDictionary(VOCABULARY, ruleNames); @Override - public TerminalNode createTerminalNode(ParserRuleContext parent, Token t) { - return new PmdAntlrTerminalNodeImpl(t); - } + public SwiftTerminalNode createPmdTerminal(ParserRuleContext parent, Token t) { + return new SwiftTerminalNode(t); + } @Override - public ErrorNode createErrorNode(ParserRuleContext parent, Token t) { - return new PmdAntlrErrorNodeImpl(t); - } - + public SwiftErrorNode createPmdError(ParserRuleContext parent, Token t) { + return new SwiftErrorNode(t); + } } options { - contextSuperClass = AntlrBaseNode; - superClass = PmdAntlrParserBase; + contextSuperClass = 'SwiftInnerNode'; + superClass = 'AntlrGeneratedParserBase'; } topLevel : statements? EOF ; diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java index 86277df629..8f30d7e816 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java @@ -5,8 +5,10 @@ package net.sourceforge.pmd.lang.swift; import net.sourceforge.pmd.RuleContext; +import net.sourceforge.pmd.lang.ast.AstVisitor; +import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrBaseRule; -import net.sourceforge.pmd.lang.swift.ast.SwiftBaseVisitor; +import net.sourceforge.pmd.lang.swift.ast.SwiftInnerNode; public abstract class AbstractSwiftRule extends AntlrBaseRule { @@ -15,5 +17,15 @@ public abstract class AbstractSwiftRule extends AntlrBaseRule { } @Override - public abstract SwiftBaseVisitor buildVisitor(RuleContext ruleCtx); + public void addRuleChainVisit(Class nodeClass) { + // note that this is made unnecessary by #2490 + if (SwiftInnerNode.class.isAssignableFrom(nodeClass)) { + addRuleChainVisit(nodeClass.getSimpleName().substring("Sw".length())); + return; + } + super.addRuleChainVisit(nodeClass); + } + + @Override + public abstract AstVisitor buildVisitor(); } diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java index 585e3c68ae..cd24a18167 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java @@ -7,11 +7,12 @@ package net.sourceforge.pmd.lang.swift; import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler; import net.sourceforge.pmd.lang.Parser; import net.sourceforge.pmd.lang.ParserOptions; +import net.sourceforge.pmd.lang.swift.ast.PmdSwiftParser; public class SwiftHandler extends AbstractPmdLanguageVersionHandler { @Override public Parser getParser(final ParserOptions parserOptions) { - return new SwiftParserAdapter(parserOptions); + return new PmdSwiftParser(parserOptions); } } diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftParserAdapter.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftParserAdapter.java deleted file mode 100644 index 495ca21c6e..0000000000 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftParserAdapter.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.swift; - -import java.io.IOException; -import java.io.Reader; - -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.Lexer; - -import net.sourceforge.pmd.lang.ParserOptions; -import net.sourceforge.pmd.lang.ast.RootNode; -import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrBaseParser; -import net.sourceforge.pmd.lang.swift.ast.SwiftLexer; -import net.sourceforge.pmd.lang.swift.ast.SwiftParser; - -/** - * Adapter for the SwiftParser. - */ -public class SwiftParserAdapter extends AntlrBaseParser { - - public SwiftParserAdapter(final ParserOptions parserOptions) { - super(parserOptions); - } - - @Override - protected RootNode getRootNode(final SwiftParser parser) { - return parser.topLevel(); - } - - @Override - protected Lexer getLexer(final Reader source) throws IOException { - return new SwiftLexer(CharStreams.fromReader(source)); - } - - @Override - protected SwiftParser getParser(final Lexer lexer) { - return new SwiftParser(new CommonTokenStream(lexer)); - } - -} diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java new file mode 100644 index 0000000000..2cba64edc8 --- /dev/null +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java @@ -0,0 +1,34 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.swift.ast; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.Lexer; + +import net.sourceforge.pmd.lang.ParserOptions; +import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrBaseParser; +import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwTopLevel; + +/** + * Adapter for the SwiftParser. + */ +public final class PmdSwiftParser extends AntlrBaseParser { + + public PmdSwiftParser(final ParserOptions parserOptions) { + super(parserOptions); + } + + @Override + protected SwTopLevel parse(final Lexer lexer) { + SwiftParser parser = new SwiftParser(new CommonTokenStream(lexer)); + return parser.topLevel(); + } + + @Override + protected Lexer getLexer(final CharStream source) { + return new SwiftLexer(source); + } +} diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftErrorNode.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftErrorNode.java new file mode 100644 index 0000000000..bcd48d13f6 --- /dev/null +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftErrorNode.java @@ -0,0 +1,17 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.swift.ast; + +import org.antlr.v4.runtime.Token; + +import net.sourceforge.pmd.lang.ast.impl.antlr4.BaseAntlrErrorNode; + +public final class SwiftErrorNode extends BaseAntlrErrorNode implements SwiftNode { + + SwiftErrorNode(Token token) { + super(token); + } + +} diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java new file mode 100644 index 0000000000..ea082bfbdc --- /dev/null +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java @@ -0,0 +1,42 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.swift.ast; + +import org.antlr.v4.runtime.ParserRuleContext; + +import net.sourceforge.pmd.lang.ast.AstVisitor; +import net.sourceforge.pmd.lang.ast.impl.antlr4.BaseAntlrInnerNode; + +public abstract class SwiftInnerNode + extends BaseAntlrInnerNode implements SwiftNode { + + SwiftInnerNode() { + super(); + } + + SwiftInnerNode(ParserRuleContext parent, int invokingStateNumber) { + super(parent, invokingStateNumber); + } + + @Override + public R acceptVisitor(AstVisitor visitor, P data) { + if (visitor instanceof SwiftVisitor) { + // some of the generated antlr nodes have no accept method... + return ((SwiftVisitor) visitor).visitSwiftNode(this, data); + } + return visitor.visitNode(this, data); + } + + + @Override // override to make visible in package + protected PmdAsAntlrInnerNode asAntlrNode() { + return super.asAntlrNode(); + } + + @Override + public String getXPathNodeName() { + return SwiftParser.DICO.getXPathNameOfRule(getRuleIndex()); + } +} diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftNameDictionary.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftNameDictionary.java new file mode 100644 index 0000000000..484090caf7 --- /dev/null +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftNameDictionary.java @@ -0,0 +1,42 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.swift.ast; + +import org.antlr.v4.runtime.Vocabulary; +import org.apache.commons.lang3.StringUtils; +import org.checkerframework.checker.nullness.qual.Nullable; + +import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrNameDictionary; + + +final class SwiftNameDictionary extends AntlrNameDictionary { + + SwiftNameDictionary(Vocabulary vocab, String[] ruleNames) { + super(vocab, ruleNames); + } + + @Override + protected @Nullable String nonAlphaNumName(String name) { + { // limit scope of 'sup', which would be null outside of here anyway + String sup = super.nonAlphaNumName(name); + if (sup != null) { + return sup; + } + } + + if (name.charAt(0) == '#' && StringUtils.isAlphanumeric(name.substring(1))) { + return "directive-" + name.substring(1); + } + + switch (name) { + case "unowned(safe)": return "unowned-safe"; + case "unowned(unsafe)": return "unowned-unsafe"; + case "getter:": return "getter"; + case "setter:": return "setter"; + case "OSXApplicationExtension\u00AD": return "OSXApplicationExtension-"; + default: return null; + } + } +} diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftNode.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftNode.java new file mode 100644 index 0000000000..b2bfcecd3c --- /dev/null +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftNode.java @@ -0,0 +1,16 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.swift.ast; + +import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrNode; + + +/** + * Supertype of all swift nodes. + */ +public interface SwiftNode extends AntlrNode { + + +} diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftTerminalNode.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftTerminalNode.java new file mode 100644 index 0000000000..2329adcdff --- /dev/null +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftTerminalNode.java @@ -0,0 +1,30 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.swift.ast; + +import org.antlr.v4.runtime.Token; +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.ast.impl.antlr4.BaseAntlrTerminalNode; + +public final class SwiftTerminalNode extends BaseAntlrTerminalNode implements SwiftNode { + + SwiftTerminalNode(Token token) { + super(token); + } + + @Override + public @NonNull String getText() { + String constImage = SwiftParser.DICO.getConstantImageOfToken(getFirstAntlrToken()); + return constImage == null ? getFirstAntlrToken().getText() + : constImage; + } + + @Override + public String getXPathNodeName() { + return SwiftParser.DICO.getXPathNameOfToken(getFirstAntlrToken().getType()); + } + +} diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftVisitorBase.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftVisitorBase.java new file mode 100644 index 0000000000..b875929589 --- /dev/null +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftVisitorBase.java @@ -0,0 +1,14 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.swift.ast; + +import net.sourceforge.pmd.lang.ast.AstVisitorBase; + +/** + * Base class for swift visitors. + */ +public abstract class SwiftVisitorBase extends AstVisitorBase implements SwiftVisitor { + +} diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/ProhibitedInterfaceBuilderRule.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/ProhibitedInterfaceBuilderRule.java deleted file mode 100644 index f3e3e9ac00..0000000000 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/ProhibitedInterfaceBuilderRule.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.swift.rule.bestpractices; - -import java.util.List; - -import net.sourceforge.pmd.RuleContext; -import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.swift.AbstractSwiftRule; -import net.sourceforge.pmd.lang.swift.ast.SwiftBaseVisitor; -import net.sourceforge.pmd.lang.swift.ast.SwiftParser.AttributeContext; -import net.sourceforge.pmd.lang.swift.ast.SwiftParser.FunctionHeadContext; -import net.sourceforge.pmd.lang.swift.ast.SwiftParser.VariableDeclarationHeadContext; - -public class ProhibitedInterfaceBuilderRule extends AbstractSwiftRule { - - private static final String IBACTION = "@IBAction"; - private static final String IBOUTLET = "@IBOutlet"; - - public ProhibitedInterfaceBuilderRule() { - super(); - addRuleChainVisit(FunctionHeadContext.class); - addRuleChainVisit(VariableDeclarationHeadContext.class); - } - - @Override - public SwiftBaseVisitor buildVisitor(RuleContext ruleCtx) { - return new SwiftBaseVisitor() { - - @Override - public Void visitFunctionHead(FunctionHeadContext ctx) { - if (ctx == null || ctx.attributes() == null) { - return null; - } - - return visitDeclarationHead(ctx, ctx.attributes().attribute(), IBACTION); - } - - @Override - public Void visitVariableDeclarationHead(final VariableDeclarationHeadContext ctx) { - if (ctx == null || ctx.attributes() == null) { - return null; - } - - return visitDeclarationHead(ctx, ctx.attributes().attribute(), IBOUTLET); - } - - private Void visitDeclarationHead(final Node node, final List attributes, - final String match) { - - final boolean violate = attributes.stream().anyMatch(atr -> match.equals(atr.getText())); - if (violate) { - addViolation(ruleCtx, node); - } - - return null; - } - }; - } -} diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java index 2b8497a918..5c49fb5669 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java @@ -7,11 +7,15 @@ package net.sourceforge.pmd.lang.swift.rule.bestpractices; import java.util.List; import net.sourceforge.pmd.RuleContext; +import net.sourceforge.pmd.lang.ast.AstVisitor; import net.sourceforge.pmd.lang.swift.AbstractSwiftRule; -import net.sourceforge.pmd.lang.swift.ast.SwiftBaseVisitor; -import net.sourceforge.pmd.lang.swift.ast.SwiftParser; -import net.sourceforge.pmd.lang.swift.ast.SwiftParser.FunctionDeclarationContext; -import net.sourceforge.pmd.lang.swift.ast.SwiftParser.InitializerDeclarationContext; +import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwAttribute; +import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwAttributes; +import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwCodeBlock; +import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwFunctionDeclaration; +import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwInitializerDeclaration; +import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwStatement; +import net.sourceforge.pmd.lang.swift.ast.SwiftVisitorBase; public class UnavailableFunctionRule extends AbstractSwiftRule { @@ -20,22 +24,22 @@ public class UnavailableFunctionRule extends AbstractSwiftRule { public UnavailableFunctionRule() { super(); - addRuleChainVisit(FunctionDeclarationContext.class); - addRuleChainVisit(InitializerDeclarationContext.class); + addRuleChainVisit(SwFunctionDeclaration.class); + addRuleChainVisit(SwInitializerDeclaration.class); } @Override - public SwiftBaseVisitor buildVisitor(RuleContext ruleCtx) { - return new SwiftBaseVisitor() { + public AstVisitor buildVisitor() { + return new SwiftVisitorBase() { @Override - public Void visitFunctionDeclaration(final FunctionDeclarationContext ctx) { + public Void visitFunctionDeclaration(final SwFunctionDeclaration ctx, RuleContext ruleCtx) { if (ctx == null) { return null; } if (shouldIncludeUnavailableModifier(ctx.functionBody().codeBlock())) { - final SwiftParser.AttributesContext attributes = ctx.functionHead().attributes(); + final SwAttributes attributes = ctx.functionHead().attributes(); if (attributes == null || !hasUnavailableModifier(attributes.attribute())) { addViolation(ruleCtx, ctx); } @@ -45,13 +49,13 @@ public class UnavailableFunctionRule extends AbstractSwiftRule { } @Override - public Void visitInitializerDeclaration(final InitializerDeclarationContext ctx) { + public Void visitInitializerDeclaration(final SwInitializerDeclaration ctx, RuleContext ruleCtx) { if (ctx == null) { return null; } if (shouldIncludeUnavailableModifier(ctx.initializerBody().codeBlock())) { - final SwiftParser.AttributesContext attributes = ctx.initializerHead().attributes(); + final SwAttributes attributes = ctx.initializerHead().attributes(); if (attributes == null || !hasUnavailableModifier(attributes.attribute())) { addViolation(ruleCtx, ctx); } @@ -60,18 +64,18 @@ public class UnavailableFunctionRule extends AbstractSwiftRule { return null; } - private boolean shouldIncludeUnavailableModifier(final SwiftParser.CodeBlockContext ctx) { + private boolean shouldIncludeUnavailableModifier(final SwCodeBlock ctx) { if (ctx == null || ctx.statements() == null) { return false; } - final List statements = ctx.statements().statement(); + final List statements = ctx.statements().statement(); - return statements.size() == 1 && FATAL_ERROR.equals(statements.get(0).getStart().getText()); + return statements.size() == 1 && FATAL_ERROR.equals(statements.get(0).getFirstAntlrToken().getText()); } - private boolean hasUnavailableModifier(final List attributes) { - return attributes.stream().anyMatch(atr -> AVAILABLE_UNAVAILABLE.equals(atr.getText())); + private boolean hasUnavailableModifier(final List attributes) { + return attributes.stream().anyMatch(atr -> AVAILABLE_UNAVAILABLE.equals(atr.joinTokenText())); } }; } diff --git a/pmd-swift/src/main/resources/category/swift/bestpractices.xml b/pmd-swift/src/main/resources/category/swift/bestpractices.xml index 4dbc5672c5..f2b3c972ab 100644 --- a/pmd-swift/src/main/resources/category/swift/bestpractices.xml +++ b/pmd-swift/src/main/resources/category/swift/bestpractices.xml @@ -13,7 +13,7 @@ Rules which enforce generally accepted best practices. since="7.0" language="swift" message="Creating views using Interface Builder should be avoided." - class="net.sourceforge.pmd.lang.swift.rule.bestpractices.ProhibitedInterfaceBuilderRule" + class="net.sourceforge.pmd.lang.rule.XPathRule" externalInfoUrl="http://pmd.github.io/pmd/pmd_rules_swift_bestpractices.html#prohibitedinterfacebuilder"> Creating views using Interface Builder should be avoided. @@ -22,6 +22,16 @@ Rules which enforce generally accepted best practices. Consider building views programmatically. 2 + + + + + //VariableDeclarationHead/Attributes/Attribute[AttributeName/Identifier/T-Identifier[@Text = "IBOutlet"]] + | + //FunctionHead/Attributes/Attribute[AttributeName/Identifier/T-Identifier[@Text = "IBAction"]] + + + @@ -55,7 +55,7 @@ NSNumber() as? Int // no violation diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/cpd/Issue628Test.java b/pmd-swift/src/test/java/net/sourceforge/pmd/cpd/Issue628Test.java deleted file mode 100644 index 0a4c24e6b9..0000000000 --- a/pmd-swift/src/test/java/net/sourceforge/pmd/cpd/Issue628Test.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - - -package net.sourceforge.pmd.cpd; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; -import org.junit.Assert; -import org.junit.Test; - -public class Issue628Test { - - @Test - public void tokenize() throws IOException { - SwiftTokenizer tokenizer = new SwiftTokenizer(); - String code = IOUtils.toString(Issue628Test.class.getResourceAsStream("Issue628.swift"), StandardCharsets.UTF_8); - SourceCode sourceCode = new SourceCode(new SourceCode.StringCodeLoader(code)); - final Tokens tokenEntries = new Tokens(); - // must not throw an exception - tokenizer.tokenize(sourceCode, tokenEntries); - Assert.assertEquals(6, tokenEntries.size()); - Assert.assertEquals(4394, tokenEntries.getTokens().get(3).toString().length()); - } -} diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/cpd/SwiftTokenizerTest.java b/pmd-swift/src/test/java/net/sourceforge/pmd/cpd/SwiftTokenizerTest.java index ad9c2dbda0..9dbafead40 100644 --- a/pmd-swift/src/test/java/net/sourceforge/pmd/cpd/SwiftTokenizerTest.java +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/cpd/SwiftTokenizerTest.java @@ -4,56 +4,51 @@ package net.sourceforge.pmd.cpd; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collection; +import java.util.Properties; -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -@RunWith(Parameterized.class) -public class SwiftTokenizerTest extends AbstractTokenizerTest { +public class SwiftTokenizerTest extends CpdTextComparisonTest { - private final String filename; - private final int nExpectedTokens; - - public SwiftTokenizerTest(String filename, int nExpectedTokens) { - this.filename = filename; - this.nExpectedTokens = nExpectedTokens; - } - - @Parameterized.Parameters - public static Collection data() { - return Arrays.asList( - new Object[] { "Swift5.2.swift", 90 }, - new Object[] { "Swift5.1.swift", 242 }, - new Object[] { "Swift5.0.swift", 172 }, - new Object[] { "Swift4.2.swift", 91 }, - new Object[] { "BTree.swift", 4239 } - ); - } - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new SwiftTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), this.filename)); + public SwiftTokenizerTest() { + super(".swift"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(SwiftTokenizer.class.getResourceAsStream(this.filename), StandardCharsets.UTF_8); + protected String getResourcePrefix() { + return "../lang/swift/cpd/testdata"; + } + + @Override + public Tokenizer newTokenizer(Properties properties) { + return new SwiftTokenizer(); + } + + + @Test + public void testSwift42() { + doTest("Swift4.2"); } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = nExpectedTokens; - super.tokenizeTest(); + public void testSwift50() { + doTest("Swift5.0"); + } + + @Test + public void testSwift51() { + doTest("Swift5.1"); + } + + @Test + public void testSwift52() { + doTest("Swift5.2"); + } + + @Test + public void testStackoverflowOnLongLiteral() { + doTest("Issue628"); } } diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/BaseSwiftTreeDumpTest.java b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/BaseSwiftTreeDumpTest.java new file mode 100644 index 0000000000..caafefa012 --- /dev/null +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/BaseSwiftTreeDumpTest.java @@ -0,0 +1,27 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.swift.ast; + + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.ast.test.BaseTreeDumpTest; +import net.sourceforge.pmd.lang.ast.test.NodePrintersKt; + +/** + * + */ +public class BaseSwiftTreeDumpTest extends BaseTreeDumpTest { + + public BaseSwiftTreeDumpTest() { + super(NodePrintersKt.getSimpleNodePrinter(), ".swift"); + } + + @NonNull + @Override + public SwiftParsingHelper getParser() { + return SwiftParsingHelper.DEFAULT.withResourceContext(getClass(), "testdata"); + } +} diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/SwiftParserTests.java b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/SwiftParserTests.java new file mode 100644 index 0000000000..16063ed179 --- /dev/null +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/SwiftParserTests.java @@ -0,0 +1,24 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.swift.ast; + +import org.junit.Test; + +/** + * + */ +public class SwiftParserTests extends BaseSwiftTreeDumpTest { + + @Test + public void testSimpleSwift() { + doTest("Simple"); + } + + @Test + public void testBtree() { + doTest("BTree"); + } + +} diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/SwiftParsingHelper.java b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/SwiftParsingHelper.java new file mode 100644 index 0000000000..ebfb36b62d --- /dev/null +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/ast/SwiftParsingHelper.java @@ -0,0 +1,30 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.swift.ast; + +import org.jetbrains.annotations.NotNull; + +import net.sourceforge.pmd.lang.ast.test.BaseParsingHelper; +import net.sourceforge.pmd.lang.swift.SwiftLanguageModule; +import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwTopLevel; + +/** + * + */ +public class SwiftParsingHelper extends BaseParsingHelper { + + public static final SwiftParsingHelper DEFAULT = new SwiftParsingHelper(Params.getDefaultNoProcess()); + + + public SwiftParsingHelper(@NotNull Params params) { + super(SwiftLanguageModule.NAME, SwTopLevel.class, params); + } + + @NotNull + @Override + protected SwiftParsingHelper clone(@NotNull Params params) { + return new SwiftParsingHelper(params); + } +} diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/BTree.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/BTree.swift new file mode 100644 index 0000000000..ceefe4f25e --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/BTree.swift @@ -0,0 +1,1015 @@ +// Downloaded on 2016/03/02 from https://github.com/lorentey/BTree/blame/master/Sources/BTree.swift +// +// BTree.swift +// BTree +// +// Created by Károly Lőrentey on 2016-02-19. +// Copyright © 2015–2016 Károly Lőrentey. +// + +/// B-trees are search trees that provide an ordered key-value store with excellent performance characteristics. +public struct BTree { + public typealias Element = (Key, Payload) + internal typealias Node = BTreeNode + + internal var root: Node + + internal init(_ root: Node) { + self.root = root + } + + /// Initialize a new b-tree with no elements. + /// + /// - Parameter order: The maximum number of children for tree nodes. + public init(order: Int = Node.defaultOrder) { + self.root = Node(order: order) + } + + /// The order of this tree, i.e., the maximum number of children for tree nodes. + public var order: Int { return root.order } + /// The depth of this tree. Depth starts at 0 for a tree that has a single root node. + public var depth: Int { return root.depth } +} + +//MAKE: Uniquing + +public extension BTree { + internal var isUnique: Bool { + mutating get { + return isUniquelyReferenced(&root) + } + } + + internal mutating func makeUnique() { + guard !isUnique else { return } + root = root.clone() + } +} + +//MARK: SequenceType + +extension BTree: SequenceType { + public typealias Generator = BTreeGenerator + + /// Returns true iff this tree has no elements. + public var isEmpty: Bool { return root.count == 0 } + + /// Returns a generator over the elements of this b-tree. Elements are sorted by key. + public func generate() -> Generator { + return Generator(BTreeStrongPath(root: root, position: 0)) + } + + /// Returns a generator starting at a specific index. + public func generate(from index: Index) -> Generator { + index.state.expectRoot(root) + return Generator(BTreeStrongPath(root: root, slotsFrom: index.state)) + } + + /// Returns a generator starting at a specific position. + public func generate(fromPosition position: Int) -> Generator { + return Generator(BTreeStrongPath(root: root, position: position)) + } + + /// Returns a generator starting at the element with the specified key. + /// If the tree contains no such element, the generator is positioned at the first element with a larger key. + /// If there are multiple elements with the same key, `selector` indicates which matching element to find. + public func generate(from key: Key, choosing selector: BTreeKeySelector = Any) -> Generator { + return Generator(BTreeStrongPath(root: root, key: key, choosing: selector)) + } + + /// Call `body` on each element in self in the same order as a for-in loop. + public func forEach(@noescape body: (Element) throws -> ()) rethrows { + try root.forEach(body) + } + + /// A version of `forEach` that allows `body` to interrupt iteration by returning `false`. + /// + /// - Returns: `true` iff `body` returned true for all elements in the tree. + public func forEach(@noescape body: (Element) throws -> Bool) rethrows -> Bool { + return try root.forEach(body) + } +} + +//MARK: CollectionType + +extension BTree: CollectionType { + public typealias Index = BTreeIndex + public typealias SubSequence = BTree + + /// The index of the first element of this tree. Elements are sorted by key. + /// + /// - Complexity: O(log(`count`)) + public var startIndex: Index { + return Index(BTreeWeakPath(startOf: root)) + } + + /// The index after the last element of this tree. (Equals `startIndex` when the tree is empty.) + /// + /// - Complexity: O(1) + public var endIndex: Index { + return Index(BTreeWeakPath(endOf: root)) + } + + /// The number of elements in this tree. + public var count: Int { + return root.count + } + + /// Returns the element at `index`. + /// + /// - Complexity: O(1) + public subscript(index: Index) -> Element { + get { + index.state.expectRoot(self.root) + return index.state.element + } + } + + /// Returns a tree consisting of elements in the specified range of indexes. + /// + /// - Complexity: O(log(`count`)) + public subscript(range: Range) -> BTree { + get { + return subtree(with: range) + } + } +} + +//MARK: Lookups + +/// When the tree contains multiple elements with the same key, you can use a key selector to specify +/// that you want to use the first or last matching element, or that you don't care which element you get. +/// (The latter is sometimes faster.) +public enum BTreeKeySelector { + /// Look for the first element that matches the key, or insert a new element before existing matches. + case First + /// Look for the last element that matches the key, or insert a new element after existing matches. + case Last + /// Look for the first element that has a greater key, or insert a new element after existing matches. + case After + /// Accept any element that matches the key. This is sometimes faster, because the search may stop before reaching + /// a leaf node. + case Any +} + +public extension BTree { + + /// Returns the first element in this tree, or `nil` if the tree is empty. + /// + /// - Complexity: O(log(`count`)) + public var first: Element? { + return root.first + } + + /// Returns the last element in this tree, or `nil` if the tree is empty. + /// + /// - Complexity: O(log(`count`)) + public var last: Element? { + return root.last + } + + /// Returns the element at `position`. + /// + /// - Requires: `position >= 0 && position < count` + /// - Complexity: O(log(`count`)) + @warn_unused_result + public func elementAtPosition(position: Int) -> Element { + precondition(position >= 0 && position < count) + var position = position + var node = root + while !node.isLeaf { + let slot = node.slotOfPosition(position) + if slot.match { + return node.elements[slot.index] + } + let child = node.children[slot.index] + position -= slot.position - child.count + node = child + } + return node.elements[position] + } + + /// Returns the payload of an element of this tree with the specified key, or `nil` if there is no such element. + /// If there are multiple elements with the same key, `selector` indicates which matching element to find. + /// + /// - Complexity: O(log(`count`)) + @warn_unused_result + public func payloadOf(key: Key, choosing selector: BTreeKeySelector = Any) -> Payload? { + switch selector { + case Any: + var node = root + while true { + let slot = node.slotOf(key, choosing: .First) + if let m = slot.match { + return node.elements[m].1 + } + if node.isLeaf { + break + } + node = node.children[slot.descend] + } + return nil + default: + var node = root + var lastmatch: Payload? = nil + while true { + let slot = node.slotOf(key, choosing: selector) + if let m = slot.match { + lastmatch = node.elements[m].1 + } + if node.isLeaf { + break + } + node = node.children[slot.descend] + } + return lastmatch + } + } + + /// Returns an index to an element in this tree with the specified key, or `nil` if there is no such element. + /// If there are multiple elements with the same key, `selector` indicates which matching element to find. + /// + /// - Complexity: O(log(`count`)) + @warn_unused_result + public func indexOf(key: Key, choosing selector: BTreeKeySelector = Any) -> Index? { + let path = BTreeWeakPath(root: root, key: key, choosing: selector) + guard !path.isAtEnd && (selector == .After || path.key == key) else { return nil } + return Index(path) + } + + /// Returns the position of the first element in this tree with the specified key, or `nil` if there is no such element. + /// If there are multiple elements with the same key, `selector` indicates which matching element to find. + /// + /// - Complexity: O(log(`count`)) + @warn_unused_result + public func positionOf(key: Key, choosing selector: BTreeKeySelector = Any) -> Int? { + var node = root + var position = 0 + var match: Int? = nil + while !node.isLeaf { + let slot = node.slotOf(key, choosing: selector) + let child = node.children[slot.descend] + if let m = slot.match { + let p = node.positionOfSlot(m) + match = position + p + position += p - (m == slot.descend ? node.children[m].count : 0) + } + else { + position += node.positionOfSlot(slot.descend) - child.count + } + node = child + } + let slot = node.slotOf(key, choosing: selector) + if let m = slot.match { + return position + m + } + return match + } + + /// Returns the position of the element at `index`. + /// + /// - Complexity: O(1) + @warn_unused_result + public func positionOfIndex(index: Index) -> Int { + index.state.expectRoot(root) + return index.state.position + } + + /// Returns the index of the element at `position`. + /// + /// - Requires: `position >= 0 && position <= count` + /// - Complexity: O(log(`count`)) + @warn_unused_result + public func indexOfPosition(position: Int) -> Index { + return Index(BTreeWeakPath(root: root, position: position)) + } +} + + +//MARK: Editing + +extension BTree { + /// Edit the tree at a path that is to be discovered on the way down, ensuring that all nodes on the path are + /// uniquely held by this tree. + /// This is a simple (but not easy, alas) interface that allows implementing basic editing operations using + /// recursion without adding a separate method on `BTreeNode` for each operation. + /// + /// Editing is split into two phases: the descent phase and the ascend phase. + /// + /// - During descent, the `descend` closure is called repeatedly to get the next child slot to drill down into. + /// When the closure returns `nil`, the phase stops and the ascend phase begins. + /// - During ascend, the `ascend` closure is called for each node for which `descend` returned non-nil, in reverse + /// order. + /// + /// - Parameter descend: A closure that, when given a node, returns the child slot toward which the editing should + /// continue descending, or `nil` if the descent should stop. The closure may set outside references to the + /// node it gets, and may modify the node as it likes; however, it shouldn't modify anything in the tree outside + /// the node's subtree, and it should not set outside references to the node's descendants. + /// - Parameter ascend: A closure that processes a step of ascending back towards the root. It receives a parent node + /// and the child slot from which this step is ascending. The closure may set outside references to the + /// node it gets, and may modify the subtree as it likes; however, it shouldn't modify anything in the tree outside + /// the node's subtree. + internal mutating func edit(@noescape descend descend: Node -> Int?, @noescape ascend: (Node, Int) -> Void) { + makeUnique() + root.edit(descend: descend, ascend: ascend) + } +} + +//MARK: Insertion + +extension BTree { + /// Insert the specified element into the tree at `position`. + /// + /// - Requires: The key of the supplied element does not violate the b-tree's ordering requirement. + /// (This is only verified in non-optimized builds.) + /// - Note: When you need to perform multiple modifications on the same tree, + /// `BTreeCursor` provides an alternative interface that's often more efficient. + /// - Complexity: O(log(`count`)) + public mutating func insert(element: Element, at position: Int) { + precondition(position >= 0 && position <= count) + makeUnique() + var pos = count - position + var splinter: BTreeSplinter? = nil + var element = element + edit( + descend: { node in + let slot = node.slotOfPosition(node.count - pos) + assert(slot.index == 0 || node.elements[slot.index - 1].0 <= element.0) + assert(slot.index == node.elements.count || node.elements[slot.index].0 >= element.0) + if !slot.match { + // Continue descending. + pos -= node.count - slot.position + return slot.index + } + if node.isLeaf { + // Found the insertion point. Insert, then start ascending. + node.insert(element, inSlot: slot.index) + if node.isTooLarge { + splinter = node.split() + } + return nil + } + // For internal nodes, put the new element in place of the old at the same position, + // then continue descending toward the next position, inserting the old element. + element = node.setElementInSlot(slot.index, to: element) + pos = node.children[slot.index + 1].count + return slot.index + 1 + }, + ascend: { node, slot in + node.count += 1 + if let s = splinter { + node.insert(s, inSlot: slot) + splinter = node.isTooLarge ? node.split() : nil + } + } + ) + if let s = splinter { + root = Node(left: root, separator: s.separator, right: s.node) + } + } + + /// Set the payload at `position`, and return the payload originally stored there. + /// + /// - Requires: `position < count` + /// - Note: When you need to perform multiple modifications on the same tree, + /// `BTreeCursor` provides an alternative interface that's often more efficient. + /// - Complexity: O(log(`count`)) + public mutating func setPayloadAt(position: Int, to payload: Payload) -> Payload { + precondition(position >= 0 && position < count) + makeUnique() + var pos = count - position + var old: Payload? = nil + edit( + descend: { node in + let slot = node.slotOfPosition(node.count - pos) + if !slot.match { + // Continue descending. + pos -= node.count - slot.position + return slot.index + } + old = node.elements[slot.index].1 + node.elements[slot.index].1 = payload + return nil + }, + ascend: { node, slot in + } + ) + return old! + } + + /// Insert `element` into the tree as a new element. + /// If the tree already contains elements with the same key, `selector` specifies where to put the new element. + /// + /// - Note: When you need to perform multiple modifications on the same tree, + /// `BTreeCursor` provides an alternative interface that's often more efficient. + /// - Complexity: O(log(`count`)) + public mutating func insert(element: Element, at selector: BTreeKeySelector = Any) { + makeUnique() + let selector: BTreeKeySelector = (selector == .First ? .First : .After) + var splinter: BTreeSplinter? = nil + edit( + descend: { node in + let slot = node.slotOf(element.0, choosing: selector) + if !node.isLeaf { + return slot.descend + } + node.insert(element, inSlot: slot.descend) + if node.isTooLarge { + splinter = node.split() + } + return nil + }, + ascend: { node, slot in + node.count += 1 + if let s = splinter { + node.insert(s, inSlot: slot) + splinter = node.isTooLarge ? node.split() : nil + } + } + ) + if let s = splinter { + root = Node(left: root, separator: s.separator, right: s.node) + } + } + + /// Insert `element` into the tree, replacing an element with the same key if there is one. + /// If the tree already contains multiple elements with the same key, `selector` specifies which one to replace. + /// + /// - Note: When you need to perform multiple modifications on the same tree, + /// `BTreeCursor` provides an alternative interface that's often more efficient. + /// - Complexity: O(log(`count`)) + public mutating func insertOrReplace(element: Element, at selector: BTreeKeySelector = Any) -> Payload? { + let selector = (selector == .After ? .Last : selector) + makeUnique() + var old: Payload? = nil + var match: (node: Node, slot: Int)? = nil + var splinter: BTreeSplinter? = nil + edit( + descend: { node in + let slot = node.slotOf(element.0, choosing: selector) + if node.isLeaf { + if let m = slot.match { + // We found the element we want to replace. + old = node.setElementInSlot(m, to: element).1 + match = nil + } + else if old == nil && match == nil { + // The tree contains no matching elements; insert a new one. + node.insert(element, inSlot: slot.descend) + if node.isTooLarge { + splinter = node.split() + } + } + return nil + } + if let m = slot.match { + if selector == Any { + // When we don't care about which element to replace, we stop the descent at the first match. + old = node.setElementInSlot(m, to: element).1 + return nil + } + // Otherwise remember this match and replace it during ascend if it's the last one. + match = (node, m) + } + return slot.descend + }, + ascend: { node, slot in + if let m = match { + // We're looking for the node that contains the last match. + if m.node === node { + // Found it; replace the matching element and cancel the search. + old = node.setElementInSlot(m.slot, to: element).1 + match = nil + } + } + else if old == nil { + // We're ascending from an insertion. + node.count += 1 + if let s = splinter { + node.insert(s, inSlot: slot) + splinter = node.isTooLarge ? node.split() : nil + } + } + } + ) + if let s = splinter { + root = Node(left: root, separator: s.separator, right: s.node) + } + return old + } +} + +//MARK: Removal + +extension BTree { + /// Remove and return the first element. + /// + /// - Complexity: O(log(`count`)) + public mutating func removeFirst() -> Element { + return removeAt(0) + } + + /// Remove and return the last element. + /// + /// - Complexity: O(log(`count`)) + public mutating func removeLast() -> Element { + return removeAt(count - 1) + } + + /// Remove and return the first element, or return `nil` if the tree is empty. + /// + /// - Complexity: O(log(`count`)) + public mutating func popFirst() -> Element? { + guard !isEmpty else { return nil } + return removeAt(0) + } + + /// Remove and return the first element, or return `nil` if the tree is empty. + /// + /// - Complexity: O(log(`count`)) + public mutating func popLast() -> Element? { + guard !isEmpty else { return nil } + return removeAt(count - 1) + } + + /// Remove and return the element at the specified position. + /// + /// - Note: When you need to perform multiple modifications on the same tree, + /// `BTreeCursor` provides an alternative interface that's often more efficient. + /// - Complexity: O(log(`count`)) + public mutating func removeAt(position: Int) -> Element { + precondition(position >= 0 && position < count) + makeUnique() + var pos = count - position + var matching: (node: Node, slot: Int)? = nil + var old: Element? = nil + edit( + descend: { node in + let slot = node.slotOfPosition(node.count - pos) + if !slot.match { + // No match yet; continue descending. + assert(!node.isLeaf) + pos -= node.count - slot.position + return slot.index + } + if node.isLeaf { + // The position we're looking for is in a leaf node; we can remove it directly. + old = node.removeSlot(slot.index) + return nil + } + // When the position happens to fall into an internal node, remember the match and continue + // removing the next position (which is guaranteed to be in a leaf node). + // We'll replace the removed element with this one during the ascend. + matching = (node, slot.index) + pos = node.children[slot.index + 1].count + return slot.index + 1 + }, + ascend: { node, slot in + node.count -= 1 + if let m = matching where m.node === node { + // We've removed the element at the next position; put it back in place of the + // element we actually want to remove. + old = node.setElementInSlot(m.slot, to: old!) + matching = nil + } + if node.children[slot].isTooSmall { + node.fixDeficiency(slot) + } + } + ) + if root.children.count == 1 { + assert(root.elements.count == 0) + root = root.children[0] + } + return old! + } + + /// Remove an element with the specified key, if it exists. + /// If there are multiple elements with the same key, `selector` indicates which matching element to remove. + /// + /// - Returns: The removed element, or `nil` if there was no element with `key` in the tree. + /// - Note: When you need to perform multiple modifications on the same tree, + /// `BTreeCursor` provides an alternative interface that's often more efficient. + /// - Complexity: O(log(`count`)) + public mutating func remove(key: Key, at selector: BTreeKeySelector = Any) -> Element? { + let selector = (selector == .After ? .Last : selector) + makeUnique() + var old: Element? = nil + var matching: (node: Node, slot: Int)? = nil + edit( + descend: { node in + let slot = node.slotOf(key, choosing: selector) + if node.isLeaf { + if let m = slot.match { + old = node.removeSlot(m) + matching = nil + } + else if matching != nil { + old = node.removeSlot(slot.descend == node.elements.count ? slot.descend - 1 : slot.descend) + } + return nil + } + if let m = slot.match { + matching = (node, m) + } + return slot.descend + }, + ascend: { node, slot in + if let o = old { + node.count -= 1 + if let m = matching where m.node === node { + old = node.setElementInSlot(m.slot, to: o) + matching = nil + } + if node.children[slot].isTooSmall { + node.fixDeficiency(slot) + } + } + } + ) + if root.children.count == 1 { + assert(root.elements.count == 0) + root = root.children[0] + } + return old + } + + /// Remove and return the element referenced by the given index. + /// + /// - Complexity: O(log(`count`)) + public mutating func removeAtIndex(index: Index) -> Element { + return withCursorAt(index) { cursor in + return cursor.remove() + } + } + + /// Remove all elements from this tree. + public mutating func removeAll() { + root = Node(order: root.order) + } +} + +//MARK: Subtree extraction + +extension BTree { + /// Returns a subtree containing the initial `maxLength` elements in this tree. + /// + /// If `maxLength` exceeds `self.count`, the result contains all the elements of `self`. + /// + /// - Complexity: O(log(`count`)) + public func prefix(maxLength: Int) -> BTree { + precondition(maxLength >= 0) + if maxLength == 0 { + return BTree(order: order) + } + if maxLength >= count { + return self + } + return BTreeStrongPath(root: root, position: maxLength).prefix() + } + + /// Returns a subtree containing all but the last `n` elements. + /// + /// - Complexity: O(log(`count`)) + public func dropLast(n: Int) -> BTree { + precondition(n >= 0) + return prefix(max(0, count - n)) + } + + /// Returns a subtree containing all elements before the specified index. + /// + /// - Complexity: O(log(`count`)) + public func prefixUpTo(end: Index) -> BTree { + end.state.expectRoot(root) + if end.state.isAtEnd { + return self + } + return end.state.prefix() + } + + /// Returns a subtree containing all elements whose key is less than `key`. + /// + /// - Complexity: O(log(`count`)) + public func prefixUpTo(end: Key) -> BTree { + let path = BTreeStrongPath(root: root, key: end, choosing: .First) + if path.isAtEnd { + return self + } + return path.prefix() + } + + /// Returns a subtree containing all elements at or before the specified index. + /// + /// - Complexity: O(log(`count`)) + public func prefixThrough(stop: Index) -> BTree { + return prefixUpTo(stop.successor()) + } + + /// Returns a subtree containing all elements whose key is less than or equal to `key`. + /// + /// - Complexity: O(log(`count`)) + public func prefixThrough(stop: Key) -> BTree { + let path = BTreeStrongPath(root: root, key: stop, choosing: .After) + if path.isAtEnd { + return self + } + return path.prefix() + } + + /// Returns a tree containing the final `maxLength` elements in this tree. + /// + /// If `maxLength` exceeds `self.count`, the result contains all the elements of `self`. + /// + /// - Complexity: O(log(`count`)) + public func suffix(maxLength: Int) -> BTree { + precondition(maxLength >= 0) + if maxLength == 0 { + return BTree(order: order) + } + if maxLength >= count { + return self + } + return BTreeStrongPath(root: root, position: count - maxLength - 1).suffix() + } + + /// Returns a subtree containing all but the first `n` elements. + /// + /// - Complexity: O(log(`count`)) + public func dropFirst(n: Int) -> BTree { + precondition(n >= 0) + return suffix(max(0, count - n)) + } + + /// Returns a subtree containing all elements at or after the specified index. + /// + /// - Complexity: O(log(`count`)) + public func suffixFrom(start: Index) -> BTree { + start.state.expectRoot(root) + if start.state.position == 0 { + return self + } + return start.predecessor().state.suffix() + } + + /// Returns a subtree containing all elements whose key is greater than or equal to `key`. + /// + /// - Complexity: O(log(`count`)) + public func suffixFrom(start: Key) -> BTree { + var path = BTreeStrongPath(root: root, key: start, choosing: .First) + if path.isAtStart { + return self + } + path.moveBackward() + return path.suffix() + } + + /// Return a subtree consisting of elements in the specified range of indexes. + /// + /// - Complexity: O(log(`count`)) + @warn_unused_result + public func subtree(with range: Range) -> BTree { + range.startIndex.state.expectRoot(root) + range.endIndex.state.expectRoot(root) + let start = range.startIndex.state.position + let end = range.endIndex.state.position + precondition(0 <= start && start <= end && end <= self.count) + if start == end { + return BTree(order: self.order) + } + if start == 0 { + return prefixUpTo(range.endIndex) + } + return suffixFrom(range.startIndex).prefix(end - start) + } + + /// Return a subtree consisting of elements in the specified range of positions. + /// + /// - Complexity: O(log(`count`)) + @warn_unused_result + public func subtree(with positions: Range) -> BTree { + precondition(positions.startIndex >= 0 && positions.endIndex <= count) + if positions.count == 0 { + return BTree(order: order) + } + return dropFirst(positions.startIndex).prefix(positions.count) + } + + /// Return a subtree consisting of all elements with keys greater than or equal to `start` but less than `end`. + /// + /// - Complexity: O(log(`count`)) + @warn_unused_result + public func subtree(from start: Key, to end: Key) -> BTree { + precondition(start <= end) + return suffixFrom(start).prefixUpTo(end) + } + + /// Return a submap consisting of all elements with keys greater than or equal to `start` but less than or equal to `end`. + /// + /// - Complexity: O(log(`count`)) + @warn_unused_result + public func subtree(from start: Key, through stop: Key) -> BTree { + precondition(start <= stop) + return suffixFrom(start).prefixThrough(stop) + } +} + +//MARK: Bulk loading + +extension BTree { + /// Create a new b-tree from elements of an unsorted sequence, using a stable sort algorithm. + /// + /// - Parameter elements: An unsorted sequence of arbitrary length. + /// - Parameter order: The desired b-tree order. If not specified (recommended), the default order is used. + /// - Complexity: O(count * log(`count`)) + /// - SeeAlso: `init(sortedElements:order:fillFactor:)` for a (faster) variant that can be used if the sequence is already sorted. + public init(_ elements: S, dropDuplicates: Bool = false, order: Int = Node.defaultOrder) { + self.init(Node(order: order)) + withCursorAtEnd { cursor in + for element in elements { + cursor.move(to: element.0, choosing: .Last) + let match = !cursor.isAtEnd && cursor.key == element.0 + if match { + if dropDuplicates { + cursor.element = element + } + else { + cursor.insertAfter(element) + } + } + else { + cursor.insert(element) + } + } + } + } + + /// Create a new b-tree from elements of a sequence sorted by key. + /// + /// - Parameter sortedElements: A sequence of arbitrary length, sorted by key. + /// - Parameter order: The desired b-tree order. If not specified (recommended), the default order is used. + /// - Parameter fillFactor: The desired fill factor in each node of the new tree. Must be between 0.5 and 1.0. + /// If not specified, a value of 1.0 is used, i.e., nodes will be loaded with as many elements as possible. + /// - Complexity: O(count) + /// - SeeAlso: `init(elements:order:fillFactor:)` for a (slower) unsorted variant. + public init(sortedElements elements: S, dropDuplicates: Bool = false, order: Int = Node.defaultOrder, fillFactor: Double = 1) { + var generator = elements.generate() + self.init(order: order, fillFactor: fillFactor, dropDuplicates: dropDuplicates, next: { generator.next() }) + } + + internal init(order: Int = Node.defaultOrder, fillFactor: Double = 1, dropDuplicates: Bool = false, @noescape next: () -> Element?) { + precondition(order > 1) + precondition(fillFactor >= 0.5 && fillFactor <= 1) + let keysPerNode = Int(fillFactor * Double(order - 1) + 0.5) + assert(keysPerNode >= (order - 1) / 2 && keysPerNode <= order - 1) + + var builder = BTreeBuilder(order: order, keysPerNode: keysPerNode) + if dropDuplicates { + guard var buffer = next() else { + self.init(Node(order: order)) + return + } + while let element = next() { + precondition(buffer.0 <= element.0) + if buffer.0 < element.0 { + builder.append(buffer) + } + buffer = element + } + builder.append(buffer) + } + else { + var lastKey: Key? = nil + while let element = next() { + precondition(lastKey <= element.0) + lastKey = element.0 + builder.append(element) + } + } + self.init(builder.finish()) + } +} + +/// Swift 4 news + + +extension BTree { + + // Multi-line String Literals + + func multiline() { + let star = "⭐️" + let introString = """ + A long time ago in a galaxy far, + far away.... + + You could write multi-lined strings + without "escaping" single quotes. + + The indentation of the closing quotes + below deside where the text line + begins. + + You can even dynamically add values + from properties: \(star) + """ + print(introString) // prints the string exactly as written above with the value of star + } + + // One-Sided Ranges + + func planets() { + var planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"] + let outsideAsteroidBelt = planets[4...] // Before: planets[4.. { + private var data: [Key: Value] + + init(data: [Key: Value]) { + self.data = data + } + + subscript(key: Key) -> T? { + return data[key] as? T + } +} + +func useSomeGenericSubscript() { + // Dictionary of type: [String: Any] + var earthData = GenericDictionary(data: ["name": "Earth", "population": 7500000000, "moons": 1]) + + // Automatically infers return type without "as? String" + let name: String? = earthData["name"] + + // Automatically infers return type without "as? Int" + let population: Int? = earthData["population"] +} + +extension GenericDictionary { + subscript(keys: Keys) -> [Value] where Keys.Iterator.Element == Key { + var values: [Value] = [] + for key in keys { + if let value = data[key] { + values.append(value) + } + } + return values + } +} + +func useSomeGenericFromExtension() { + // Array subscript value + let nameAndMoons = earthData[["moons", "name"]] // [1, "Earth"] + // Set subscript value + let nameAndMoons2 = earthData[Set(["moons", "name"])] // [1, "Earth"] +} + +// Associated Type Constraints + +protocol MyProtocol { + associatedtype Element + associatedtype SubSequence : Sequence where SubSequence.Iterator.Element == Iterator.Element +} + +// Class and Protocol Existential + +protocol MyProtocol { } +class View { } +class ViewSubclass: View, MyProtocol { } + +class MyClass { + var delegate: (View & MyProtocol)? +} + +let myClass = MyClass() +//myClass.delegate = View() // error: cannot assign value of type 'View' to type '(View & MyProtocol)?' +myClass.delegate = ViewSubclass() + +// 4.1 conditional + +#if canImport(SomeModule) +let someModuleImportedVersion = SomeModule.version +#endif + +#if targetEnvironment(simulator) +print("code only compiled for simulator") +#endif diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/BTree.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/BTree.txt new file mode 100644 index 0000000000..4914c8c7e6 --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/BTree.txt @@ -0,0 +1,7058 @@ ++- TopLevel + +- Statements + | +- Statement + | | +- Declaration + | | +- StructDeclaration + | | +- AccessLevelModifier + | | | +- T-public + | | +- T-struct + | | +- StructName + | | | +- Identifier + | | | +- T-Identifier + | | +- GenericParameterClause + | | | +- T-lt + | | | +- GenericParameterList + | | | | +- GenericParameter + | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-colon + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-comma + | | | | +- GenericParameter + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-gt + | | +- StructBody + | | +- T-lbrace + | | +- StructMembers + | | | +- StructMember + | | | | +- Declaration + | | | | +- TypealiasDeclaration + | | | | +- TypealiasHead + | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-typealias + | | | | | +- TypealiasName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypealiasAssignment + | | | | +- T-eq + | | | | +- SType + | | | | +- TupleType + | | | | +- T-lparen + | | | | +- TupleTypeElementList + | | | | | +- TupleTypeElement + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-comma + | | | | | +- TupleTypeElement + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rparen + | | | +- StructMember + | | | | +- Declaration + | | | | +- TypealiasDeclaration + | | | | +- TypealiasHead + | | | | | +- AccessLevelModifier + | | | | | | +- T-internal + | | | | | +- T-typealias + | | | | | +- TypealiasName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypealiasAssignment + | | | | +- T-eq + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- GenericArgumentClause + | | | | +- T-lt + | | | | +- GenericArgumentList + | | | | | +- GenericArgument + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-comma + | | | | | +- GenericArgument + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-gt + | | | +- StructMember + | | | | +- Declaration + | | | | +- VariableDeclaration + | | | | +- VariableDeclarationHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-internal + | | | | | +- T-var + | | | | +- PatternInitializerList + | | | | +- PatternInitializer + | | | | +- Pattern + | | | | +- IdentifierPattern + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypeAnnotation + | | | | +- T-colon + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- StructMember + | | | | +- Declaration + | | | | +- InitializerDeclaration + | | | | +- InitializerHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-internal + | | | | | +- T-init + | | | | +- ParameterClause + | | | | | +- T-lparen + | | | | | +- ParameterList + | | | | | | +- Parameter + | | | | | | +- ExternalParameterName + | | | | | | | +- Keyword + | | | | | | | +- T-underscore + | | | | | | +- LocalParameterName + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- TypeAnnotation + | | | | | | +- T-colon + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rparen + | | | | +- InitializerBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Keyword + | | | | | | | | +- T-self + | | | | | | | +- T-dot + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- PostfixOperator + | | | | | | +- Operator + | | | | | | +- OperatorHead + | | | | | | +- T-eq + | | | | | +- Statement + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PrimaryExpression + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rbrace + | | | +- StructMember + | | | | +- Declaration + | | | | +- InitializerDeclaration + | | | | +- InitializerHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-init + | | | | +- ParameterClause + | | | | | +- T-lparen + | | | | | +- ParameterList + | | | | | | +- Parameter + | | | | | | +- LocalParameterName + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- TypeAnnotation + | | | | | | | +- T-colon + | | | | | | | +- SType + | | | | | | | +- TypeIdentifier + | | | | | | | +- TypeName + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- DefaultArgumentClause + | | | | | | +- T-eq + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-dot + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rparen + | | | | +- InitializerBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Keyword + | | | | | | | | +- T-self + | | | | | | | +- T-dot + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- PostfixOperator + | | | | | | +- Operator + | | | | | | +- OperatorHead + | | | | | | +- T-eq + | | | | | +- Statement + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- FunctionCallArgumentClause + | | | | | +- T-lparen + | | | | | +- FunctionCallArgumentList + | | | | | | +- FunctionCallArgument + | | | | | | +- FunctionCallIdentifier + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-colon + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rparen + | | | | +- T-rbrace + | | | +- StructMember + | | | | +- Declaration + | | | | +- VariableDeclaration + | | | | +- VariableDeclarationHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-var + | | | | +- VariableName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypeAnnotation + | | | | | +- T-colon + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-dot + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rbrace + | | | +- StructMember + | | | +- Declaration + | | | +- VariableDeclaration + | | | +- VariableDeclarationHead + | | | | +- DeclarationModifiers + | | | | | +- DeclarationModifier + | | | | | +- AccessLevelModifier + | | | | | +- T-public + | | | | +- T-var + | | | +- VariableName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- TypeAnnotation + | | | | +- T-colon + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- CodeBlock + | | | +- T-lbrace + | | | +- Statements + | | | | +- Statement + | | | | +- ControlTransferStatement + | | | | +- ReturnStatement + | | | | +- T-return + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PostfixExpression + | | | | | +- PrimaryExpression + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-dot + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-rbrace + | | +- T-rbrace + | +- Statement + | | +- Declaration + | | +- ExtensionDeclaration + | | +- AccessLevelModifier + | | | +- T-public + | | +- T-extension + | | +- TypeIdentifier + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- ExtensionBody + | | +- T-lbrace + | | +- ExtensionMembers + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- VariableDeclaration + | | | | +- VariableDeclarationHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-internal + | | | | | +- T-var + | | | | +- VariableName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypeAnnotation + | | | | | +- T-colon + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- GetterSetterBlock + | | | | +- T-lbrace + | | | | +- GetterClause + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- MutationModifier + | | | | | | +- T-mutating + | | | | | +- T-get + | | | | | +- CodeBlock + | | | | | +- T-lbrace + | | | | | +- Statements + | | | | | | +- Statement + | | | | | | +- ControlTransferStatement + | | | | | | +- ReturnStatement + | | | | | | +- T-return + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PrefixOperator + | | | | | | | | +- Operator + | | | | | | | | +- OperatorHead + | | | | | | | | +- T-amp + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- T-rbrace + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | +- Declaration + | | | +- FunctionDeclaration + | | | +- FunctionHead + | | | | +- DeclarationModifiers + | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-internal + | | | | | +- DeclarationModifier + | | | | | +- MutationModifier + | | | | | +- T-mutating + | | | | +- T-func + | | | +- FunctionName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- FunctionSignature + | | | | +- ParameterClause + | | | | +- T-lparen + | | | | +- T-rparen + | | | +- FunctionBody + | | | +- CodeBlock + | | | +- T-lbrace + | | | +- Statements + | | | | +- Statement + | | | | | +- BranchStatement + | | | | | +- GuardStatement + | | | | | +- T-guard + | | | | | +- ConditionList + | | | | | | +- Condition + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PrefixOperator + | | | | | | | +- Operator + | | | | | | | +- OperatorHead + | | | | | | | +- T-bang + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-else + | | | | | +- CodeBlock + | | | | | +- T-lbrace + | | | | | +- Statements + | | | | | | +- Statement + | | | | | | +- ControlTransferStatement + | | | | | | +- ReturnStatement + | | | | | | +- T-return + | | | | | +- T-rbrace + | | | | +- Statement + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- PostfixOperator + | | | | | +- Operator + | | | | | +- OperatorHead + | | | | | +- T-eq + | | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-dot + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionCallArgumentClause + | | | | +- T-lparen + | | | | +- T-rparen + | | | +- T-rbrace + | | +- T-rbrace + | +- Statement + | | +- Declaration + | | +- ExtensionDeclaration + | | +- T-extension + | | +- TypeIdentifier + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- TypeInheritanceClause + | | | +- T-colon + | | | +- TypeInheritanceList + | | | +- TypeIdentifier + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- ExtensionBody + | | +- T-lbrace + | | +- ExtensionMembers + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- TypealiasDeclaration + | | | | +- TypealiasHead + | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-typealias + | | | | | +- TypealiasName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypealiasAssignment + | | | | +- T-eq + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- GenericArgumentClause + | | | | +- T-lt + | | | | +- GenericArgumentList + | | | | | +- GenericArgument + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-comma + | | | | | +- GenericArgument + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-gt + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- VariableDeclaration + | | | | +- VariableDeclarationHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-var + | | | | +- VariableName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypeAnnotation + | | | | | +- T-colon + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | | +- ControlTransferStatement + | | | | | | +- ReturnStatement + | | | | | | +- T-return + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-dot + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- PostfixOperator + | | | | | | +- Operator + | | | | | | +- OperatorHead + | | | | | | +- T-double-eq + | | | | | +- Statement + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PrimaryExpression + | | | | | +- LiteralExpression + | | | | | +- Literal + | | | | | +- NumericLiteral + | | | | | +- IntegerLiteral + | | | | | +- T-DecimalLiteral + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | | +- FunctionHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-func + | | | | +- FunctionName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionSignature + | | | | | +- ParameterClause + | | | | | | +- T-lparen + | | | | | | +- T-rparen + | | | | | +- FunctionResult + | | | | | +- T-rarrow + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- FunctionCallArgumentClause + | | | | | +- T-lparen + | | | | | +- FunctionCallArgumentList + | | | | | | +- FunctionCallArgument + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | | +- FunctionCallIdentifier + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-colon + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- FunctionCallArgument + | | | | | | | +- FunctionCallIdentifier + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-colon + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- LiteralExpression + | | | | | | | +- Literal + | | | | | | | +- NumericLiteral + | | | | | | | +- IntegerLiteral + | | | | | | | +- T-DecimalLiteral + | | | | | | +- T-rparen + | | | | | +- T-rparen + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | | +- FunctionHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-func + | | | | +- FunctionName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionSignature + | | | | | +- ParameterClause + | | | | | | +- T-lparen + | | | | | | +- ParameterList + | | | | | | | +- Parameter + | | | | | | | +- ExternalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- LocalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- TypeAnnotation + | | | | | | | +- T-colon + | | | | | | | +- SType + | | | | | | | +- TypeIdentifier + | | | | | | | +- TypeName + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- FunctionResult + | | | | | +- T-rarrow + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-dot + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-dot + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- FunctionCallArgumentClause + | | | | | +- T-lparen + | | | | | +- FunctionCallArgumentList + | | | | | | +- FunctionCallArgument + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | | +- FunctionCallIdentifier + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-colon + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- FunctionCallArgument + | | | | | | | +- FunctionCallIdentifier + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-colon + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-dot + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- T-rparen + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | | +- FunctionHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-func + | | | | +- FunctionName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionSignature + | | | | | +- ParameterClause + | | | | | | +- T-lparen + | | | | | | +- ParameterList + | | | | | | | +- Parameter + | | | | | | | +- ExternalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- LocalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- TypeAnnotation + | | | | | | | +- T-colon + | | | | | | | +- SType + | | | | | | | +- TypeIdentifier + | | | | | | | +- TypeName + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- FunctionResult + | | | | | +- T-rarrow + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- FunctionCallArgumentClause + | | | | | +- T-lparen + | | | | | +- FunctionCallArgumentList + | | | | | | +- FunctionCallArgument + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | | +- FunctionCallIdentifier + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-colon + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- FunctionCallArgument + | | | | | | | +- FunctionCallIdentifier + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-colon + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- T-rparen + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | | +- FunctionHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-func + | | | | +- FunctionName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionSignature + | | | | | +- ParameterClause + | | | | | | +- T-lparen + | | | | | | +- ParameterList + | | | | | | | +- Parameter + | | | | | | | | +- ExternalParameterName + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- LocalParameterName + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- TypeAnnotation + | | | | | | | | +- T-colon + | | | | | | | | +- SType + | | | | | | | | +- TypeIdentifier + | | | | | | | | +- TypeName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- Parameter + | | | | | | | +- ExternalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- LocalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- TypeAnnotation + | | | | | | | | +- T-colon + | | | | | | | | +- SType + | | | | | | | | +- TypeIdentifier + | | | | | | | | +- TypeName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- DefaultArgumentClause + | | | | | | | +- T-eq + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Keyword + | | | | | | | +- T-Any + | | | | | | +- T-rparen + | | | | | +- FunctionResult + | | | | | +- T-rarrow + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- FunctionCallArgumentClause + | | | | | +- T-lparen + | | | | | +- FunctionCallArgumentList + | | | | | | +- FunctionCallArgument + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | | +- FunctionCallIdentifier + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-colon + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- FunctionCallArgument + | | | | | | | | +- FunctionCallIdentifier + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-colon + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- FunctionCallArgument + | | | | | | | +- FunctionCallIdentifier + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-colon + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- T-rparen + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | | +- FunctionHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-func + | | | | +- FunctionName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionSignature + | | | | | +- ParameterClause + | | | | | | +- T-lparen + | | | | | | +- ParameterList + | | | | | | | +- Parameter + | | | | | | | +- Attributes + | | | | | | | | +- Attribute + | | | | | | | | +- T-at-symbol + | | | | | | | | +- AttributeName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- LocalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- TypeAnnotation + | | | | | | | +- T-colon + | | | | | | | +- SType + | | | | | | | +- FunctionType + | | | | | | | +- FunctionTypeArgumentClause + | | | | | | | | +- T-lparen + | | | | | | | | +- FunctionTypeArgumentList + | | | | | | | | | +- FunctionTypeArgument + | | | | | | | | | +- SType + | | | | | | | | | +- TypeIdentifier + | | | | | | | | | +- TypeName + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-rparen + | | | | | | | +- T-throws + | | | | | | | +- T-rarrow + | | | | | | | +- SType + | | | | | | | +- TupleType + | | | | | | | +- T-lparen + | | | | | | | +- T-rparen + | | | | | | +- T-rparen + | | | | | +- T-rethrows + | | | | +- FunctionBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- Expression + | | | | | +- TryOperator + | | | | | | +- T-try + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-dot + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- FunctionCallArgumentClause + | | | | | +- T-lparen + | | | | | +- FunctionCallArgumentList + | | | | | | +- FunctionCallArgument + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rparen + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | +- Declaration + | | | +- FunctionDeclaration + | | | +- FunctionHead + | | | | +- DeclarationModifiers + | | | | | +- DeclarationModifier + | | | | | +- AccessLevelModifier + | | | | | +- T-public + | | | | +- T-func + | | | +- FunctionName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- FunctionSignature + | | | | +- ParameterClause + | | | | | +- T-lparen + | | | | | +- ParameterList + | | | | | | +- Parameter + | | | | | | +- Attributes + | | | | | | | +- Attribute + | | | | | | | +- T-at-symbol + | | | | | | | +- AttributeName + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- LocalParameterName + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- TypeAnnotation + | | | | | | +- T-colon + | | | | | | +- SType + | | | | | | +- FunctionType + | | | | | | +- FunctionTypeArgumentClause + | | | | | | | +- T-lparen + | | | | | | | +- FunctionTypeArgumentList + | | | | | | | | +- FunctionTypeArgument + | | | | | | | | +- SType + | | | | | | | | +- TypeIdentifier + | | | | | | | | +- TypeName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-rparen + | | | | | | +- T-throws + | | | | | | +- T-rarrow + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rparen + | | | | +- T-rethrows + | | | | +- FunctionResult + | | | | +- T-rarrow + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- FunctionBody + | | | +- CodeBlock + | | | +- T-lbrace + | | | +- Statements + | | | | +- Statement + | | | | +- ControlTransferStatement + | | | | +- ReturnStatement + | | | | +- T-return + | | | | +- Expression + | | | | +- TryOperator + | | | | | +- T-try + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-dot + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionCallArgumentClause + | | | | +- T-lparen + | | | | +- FunctionCallArgumentList + | | | | | +- FunctionCallArgument + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PrimaryExpression + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rparen + | | | +- T-rbrace + | | +- T-rbrace + | +- Statement + | | +- Declaration + | | +- ExtensionDeclaration + | | +- T-extension + | | +- TypeIdentifier + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- TypeInheritanceClause + | | | +- T-colon + | | | +- TypeInheritanceList + | | | +- TypeIdentifier + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- ExtensionBody + | | +- T-lbrace + | | +- ExtensionMembers + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- TypealiasDeclaration + | | | | +- TypealiasHead + | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-typealias + | | | | | +- TypealiasName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypealiasAssignment + | | | | +- T-eq + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- GenericArgumentClause + | | | | +- T-lt + | | | | +- GenericArgumentList + | | | | | +- GenericArgument + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-comma + | | | | | +- GenericArgument + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-gt + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- TypealiasDeclaration + | | | | +- TypealiasHead + | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-typealias + | | | | | +- TypealiasName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypealiasAssignment + | | | | +- T-eq + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- GenericArgumentClause + | | | | +- T-lt + | | | | +- GenericArgumentList + | | | | | +- GenericArgument + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-comma + | | | | | +- GenericArgument + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-gt + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- VariableDeclaration + | | | | +- VariableDeclarationHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-var + | | | | +- VariableName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypeAnnotation + | | | | | +- T-colon + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- FunctionCallArgumentClause + | | | | | +- T-lparen + | | | | | +- FunctionCallArgumentList + | | | | | | +- FunctionCallArgument + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | +- FunctionCallIdentifier + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-colon + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- T-rparen + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- VariableDeclaration + | | | | +- VariableDeclarationHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-var + | | | | +- VariableName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypeAnnotation + | | | | | +- T-colon + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- FunctionCallArgumentClause + | | | | | +- T-lparen + | | | | | +- FunctionCallArgumentList + | | | | | | +- FunctionCallArgument + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | +- FunctionCallIdentifier + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-colon + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- T-rparen + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- VariableDeclaration + | | | | +- VariableDeclarationHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-var + | | | | +- VariableName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypeAnnotation + | | | | | +- T-colon + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-dot + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- SubscriptDeclaration + | | | | +- SubscriptHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-subscript + | | | | | +- ParameterClause + | | | | | +- T-lparen + | | | | | +- ParameterList + | | | | | | +- Parameter + | | | | | | +- LocalParameterName + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- TypeAnnotation + | | | | | | +- T-colon + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rparen + | | | | +- SubscriptResult + | | | | | +- T-rarrow + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- GetterSetterBlock + | | | | +- T-lbrace + | | | | +- GetterClause + | | | | | +- T-get + | | | | | +- CodeBlock + | | | | | +- T-lbrace + | | | | | +- Statements + | | | | | | +- Statement + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-dot + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- FunctionCallArgumentClause + | | | | | | | +- T-lparen + | | | | | | | +- FunctionCallArgumentList + | | | | | | | | +- FunctionCallArgument + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Keyword + | | | | | | | | | +- T-self + | | | | | | | | +- T-dot + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-rparen + | | | | | | +- Statement + | | | | | | +- ControlTransferStatement + | | | | | | +- ReturnStatement + | | | | | | +- T-return + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-dot + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-dot + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rbrace + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | +- Declaration + | | | +- SubscriptDeclaration + | | | +- SubscriptHead + | | | | +- DeclarationModifiers + | | | | | +- DeclarationModifier + | | | | | +- AccessLevelModifier + | | | | | +- T-public + | | | | +- T-subscript + | | | | +- ParameterClause + | | | | +- T-lparen + | | | | +- ParameterList + | | | | | +- Parameter + | | | | | +- LocalParameterName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- TypeAnnotation + | | | | | +- T-colon + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- GenericArgumentClause + | | | | | +- T-lt + | | | | | +- GenericArgumentList + | | | | | | +- GenericArgument + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-gt + | | | | +- T-rparen + | | | +- SubscriptResult + | | | | +- T-rarrow + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- GenericArgumentClause + | | | | +- T-lt + | | | | +- GenericArgumentList + | | | | | +- GenericArgument + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-comma + | | | | | +- GenericArgument + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-gt + | | | +- GetterSetterBlock + | | | +- T-lbrace + | | | +- GetterClause + | | | | +- T-get + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- FunctionCallArgumentClause + | | | | | +- T-lparen + | | | | | +- FunctionCallArgumentList + | | | | | | +- FunctionCallArgument + | | | | | | +- FunctionCallIdentifier + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-colon + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rparen + | | | | +- T-rbrace + | | | +- T-rbrace + | | +- T-rbrace + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Keyword + | | +- T-public + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Keyword + | | +- T-enum + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PostfixExpression + | | | +- PrimaryExpression + | | | +- Identifier + | | | +- T-Identifier + | | +- ClosureExpression + | | +- T-lbrace + | | +- Statements + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Keyword + | | | | +- T-case + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Keyword + | | | | +- T-case + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Keyword + | | | | +- T-case + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Keyword + | | | | +- T-case + | | | +- Statement + | | | +- Expression + | | | +- PrefixExpression + | | | +- PostfixExpression + | | | +- PrimaryExpression + | | | +- Keyword + | | | +- T-Any + | | +- T-rbrace + | +- Statement + | | +- Declaration + | | +- ExtensionDeclaration + | | +- AccessLevelModifier + | | | +- T-public + | | +- T-extension + | | +- TypeIdentifier + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- ExtensionBody + | | +- T-lbrace + | | +- ExtensionMembers + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- VariableDeclaration + | | | | +- VariableDeclarationHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-var + | | | | +- VariableName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypeAnnotation + | | | | | +- T-colon + | | | | | +- SType + | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-question + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-dot + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- VariableDeclaration + | | | | +- VariableDeclarationHead + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-var + | | | | +- VariableName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- TypeAnnotation + | | | | | +- T-colon + | | | | | +- SType + | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-question + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-dot + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | | +- FunctionHead + | | | | | +- Attributes + | | | | | | +- Attribute + | | | | | | +- T-at-symbol + | | | | | | +- AttributeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-func + | | | | +- FunctionName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionSignature + | | | | | +- ParameterClause + | | | | | | +- T-lparen + | | | | | | +- ParameterList + | | | | | | | +- Parameter + | | | | | | | +- LocalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- TypeAnnotation + | | | | | | | +- T-colon + | | | | | | | +- SType + | | | | | | | +- TypeIdentifier + | | | | | | | +- TypeName + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- FunctionResult + | | | | | +- T-rarrow + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- BinaryExpression + | | | | | | | | +- BinaryOperator + | | | | | | | | | +- Operator + | | | | | | | | | +- OperatorHead + | | | | | | | | | +- T-ge + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- LiteralExpression + | | | | | | | | +- Literal + | | | | | | | | +- NumericLiteral + | | | | | | | | +- IntegerLiteral + | | | | | | | | +- T-DecimalLiteral + | | | | | | | +- BinaryExpression + | | | | | | | | +- BinaryOperator + | | | | | | | | | +- Operator + | | | | | | | | | +- OperatorHead + | | | | | | | | | +- T-double-amp + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- BinaryExpression + | | | | | | | +- BinaryOperator + | | | | | | | | +- Operator + | | | | | | | | +- OperatorHead + | | | | | | | | +- T-lt + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- Statement + | | | | | | +- Declaration + | | | | | | +- VariableDeclaration + | | | | | | +- VariableDeclarationHead + | | | | | | | +- T-var + | | | | | | +- PatternInitializerList + | | | | | | +- PatternInitializer + | | | | | | +- Pattern + | | | | | | | +- IdentifierPattern + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- Initializer + | | | | | | +- T-eq + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- Statement + | | | | | | +- Declaration + | | | | | | +- VariableDeclaration + | | | | | | +- VariableDeclarationHead + | | | | | | | +- T-var + | | | | | | +- PatternInitializerList + | | | | | | +- PatternInitializer + | | | | | | +- Pattern + | | | | | | | +- IdentifierPattern + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- Initializer + | | | | | | +- T-eq + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- Statement + | | | | | | +- LoopStatement + | | | | | | +- WhileStatement + | | | | | | +- T-while + | | | | | | +- ConditionList + | | | | | | | +- Condition + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PrefixOperator + | | | | | | | | +- Operator + | | | | | | | | +- OperatorHead + | | | | | | | | +- T-bang + | | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-dot + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- CodeBlock + | | | | | | +- T-lbrace + | | | | | | +- Statements + | | | | | | | +- Statement + | | | | | | | | +- Declaration + | | | | | | | | +- ConstantDeclaration + | | | | | | | | +- T-let + | | | | | | | | +- PatternInitializerList + | | | | | | | | +- PatternInitializer + | | | | | | | | +- Pattern + | | | | | | | | | +- IdentifierPattern + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- Initializer + | | | | | | | | +- T-eq + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- FunctionCallArgumentClause + | | | | | | | | +- T-lparen + | | | | | | | | +- FunctionCallArgumentList + | | | | | | | | | +- FunctionCallArgument + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-rparen + | | | | | | | +- Statement + | | | | | | | | +- BranchStatement + | | | | | | | | +- IfStatement + | | | | | | | | +- T-if + | | | | | | | | +- ConditionList + | | | | | | | | | +- Condition + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- CodeBlock + | | | | | | | | +- T-lbrace + | | | | | | | | +- Statements + | | | | | | | | | +- Statement + | | | | | | | | | +- ControlTransferStatement + | | | | | | | | | +- ReturnStatement + | | | | | | | | | +- T-return + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- T-dot + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-lbracket + | | | | | | | | | +- TupleElementList + | | | | | | | | | | +- TupleElement + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- T-dot + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-rbracket + | | | | | | | | +- T-rbrace + | | | | | | | +- Statement + | | | | | | | | +- Declaration + | | | | | | | | +- ConstantDeclaration + | | | | | | | | +- T-let + | | | | | | | | +- PatternInitializerList + | | | | | | | | +- PatternInitializer + | | | | | | | | +- Pattern + | | | | | | | | | +- IdentifierPattern + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- Initializer + | | | | | | | | +- T-eq + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-lbracket + | | | | | | | | +- TupleElementList + | | | | | | | | | +- TupleElement + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-rbracket + | | | | | | | +- Statement + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- PostfixOperator + | | | | | | | | +- Operator + | | | | | | | | +- OperatorHead + | | | | | | | | | +- T-minus + | | | | | | | | +- OperatorCharacter + | | | | | | | | +- OperatorHead + | | | | | | | | +- T-eq + | | | | | | | +- Statement + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- PostfixOperator + | | | | | | | | +- Operator + | | | | | | | | +- OperatorHead + | | | | | | | | +- T-minus + | | | | | | | +- Statement + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-dot + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- Statement + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- PostfixOperator + | | | | | | | | +- Operator + | | | | | | | | +- OperatorHead + | | | | | | | | +- T-eq + | | | | | | | +- Statement + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rbrace + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-dot + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-lbracket + | | | | | +- TupleElementList + | | | | | | +- TupleElement + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rbracket + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | | +- FunctionHead + | | | | | +- Attributes + | | | | | | +- Attribute + | | | | | | +- T-at-symbol + | | | | | | +- AttributeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-func + | | | | +- FunctionName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionSignature + | | | | | +- ParameterClause + | | | | | | +- T-lparen + | | | | | | +- ParameterList + | | | | | | | +- Parameter + | | | | | | | | +- LocalParameterName + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- TypeAnnotation + | | | | | | | | +- T-colon + | | | | | | | | +- SType + | | | | | | | | +- TypeIdentifier + | | | | | | | | +- TypeName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- Parameter + | | | | | | | +- ExternalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- LocalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- TypeAnnotation + | | | | | | | | +- T-colon + | | | | | | | | +- SType + | | | | | | | | +- TypeIdentifier + | | | | | | | | +- TypeName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- DefaultArgumentClause + | | | | | | | +- T-eq + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Keyword + | | | | | | | +- T-Any + | | | | | | +- T-rparen + | | | | | +- FunctionResult + | | | | | +- T-rarrow + | | | | | +- SType + | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-question + | | | | +- FunctionBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | +- BranchStatement + | | | | | +- SwitchStatement + | | | | | +- T-switch + | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-lbrace + | | | | | +- SwitchCases + | | | | | | +- SwitchCase + | | | | | | | +- CaseLabel + | | | | | | | | +- T-case + | | | | | | | | +- CaseItemList + | | | | | | | | | +- CaseItem + | | | | | | | | | +- Pattern + | | | | | | | | | +- ExpressionPattern + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Keyword + | | | | | | | | | +- T-Any + | | | | | | | | +- T-colon + | | | | | | | +- Statements + | | | | | | | +- Statement + | | | | | | | | +- Declaration + | | | | | | | | +- VariableDeclaration + | | | | | | | | +- VariableDeclarationHead + | | | | | | | | | +- T-var + | | | | | | | | +- PatternInitializerList + | | | | | | | | +- PatternInitializer + | | | | | | | | +- Pattern + | | | | | | | | | +- IdentifierPattern + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- Initializer + | | | | | | | | +- T-eq + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- Statement + | | | | | | | | +- LoopStatement + | | | | | | | | +- WhileStatement + | | | | | | | | +- T-while + | | | | | | | | +- ConditionList + | | | | | | | | | +- Condition + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Keyword + | | | | | | | | | +- T-BooleanLiteral + | | | | | | | | +- CodeBlock + | | | | | | | | +- T-lbrace + | | | | | | | | +- Statements + | | | | | | | | | +- Statement + | | | | | | | | | | +- Declaration + | | | | | | | | | | +- ConstantDeclaration + | | | | | | | | | | +- T-let + | | | | | | | | | | +- PatternInitializerList + | | | | | | | | | | +- PatternInitializer + | | | | | | | | | | +- Pattern + | | | | | | | | | | | +- IdentifierPattern + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- Initializer + | | | | | | | | | | +- T-eq + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- T-dot + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- FunctionCallArgumentClause + | | | | | | | | | | +- T-lparen + | | | | | | | | | | +- FunctionCallArgumentList + | | | | | | | | | | | +- FunctionCallArgument + | | | | | | | | | | | | +- Expression + | | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- T-comma + | | | | | | | | | | | +- FunctionCallArgument + | | | | | | | | | | | +- FunctionCallIdentifier + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- T-colon + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- ImplicitMemberExpression + | | | | | | | | | | | +- T-dot + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- T-rparen + | | | | | | | | | +- Statement + | | | | | | | | | | +- BranchStatement + | | | | | | | | | | +- IfStatement + | | | | | | | | | | +- T-if + | | | | | | | | | | +- ConditionList + | | | | | | | | | | | +- Condition + | | | | | | | | | | | +- OptionalBindingCondition + | | | | | | | | | | | +- T-let + | | | | | | | | | | | +- Pattern + | | | | | | | | | | | | +- IdentifierPattern + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- Initializer + | | | | | | | | | | | +- T-eq + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- T-dot + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- CodeBlock + | | | | | | | | | | +- T-lbrace + | | | | | | | | | | +- Statements + | | | | | | | | | | | +- Statement + | | | | | | | | | | | +- ControlTransferStatement + | | | | | | | | | | | +- ReturnStatement + | | | | | | | | | | | +- T-return + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | | +- T-dot + | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | +- T-lbracket + | | | | | | | | | | | | +- TupleElementList + | | | | | | | | | | | | | +- TupleElement + | | | | | | | | | | | | | +- Expression + | | | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | +- T-rbracket + | | | | | | | | | | | +- T-dot + | | | | | | | | | | | +- T-DecimalLiteral + | | | | | | | | | | +- T-rbrace + | | | | | | | | | +- Statement + | | | | | | | | | | +- BranchStatement + | | | | | | | | | | +- IfStatement + | | | | | | | | | | +- T-if + | | | | | | | | | | +- ConditionList + | | | | | | | | | | | +- Condition + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- T-dot + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- CodeBlock + | | | | | | | | | | +- T-lbrace + | | | | | | | | | | +- Statements + | | | | | | | | | | | +- Statement + | | | | | | | | | | | +- ControlTransferStatement + | | | | | | | | | | | +- BreakStatement + | | | | | | | | | | | +- T-break + | | | | | | | | | | +- T-rbrace + | | | | | | | | | +- Statement + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- PostfixOperator + | | | | | | | | | | +- Operator + | | | | | | | | | | +- OperatorHead + | | | | | | | | | | +- T-eq + | | | | | | | | | +- Statement + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- T-dot + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-lbracket + | | | | | | | | | +- TupleElementList + | | | | | | | | | | +- TupleElement + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- T-dot + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-rbracket + | | | | | | | | +- T-rbrace + | | | | | | | +- Statement + | | | | | | | +- ControlTransferStatement + | | | | | | | +- ReturnStatement + | | | | | | | +- T-return + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Keyword + | | | | | | | +- T-NilLiteral + | | | | | | +- SwitchCase + | | | | | | +- DefaultLabel + | | | | | | | +- T-default + | | | | | | | +- T-colon + | | | | | | +- Statements + | | | | | | +- Statement + | | | | | | | +- Declaration + | | | | | | | +- VariableDeclaration + | | | | | | | +- VariableDeclarationHead + | | | | | | | | +- T-var + | | | | | | | +- PatternInitializerList + | | | | | | | +- PatternInitializer + | | | | | | | +- Pattern + | | | | | | | | +- IdentifierPattern + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- Initializer + | | | | | | | +- T-eq + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- Statement + | | | | | | | +- Declaration + | | | | | | | +- VariableDeclaration + | | | | | | | +- VariableDeclarationHead + | | | | | | | | +- T-var + | | | | | | | +- PatternInitializerList + | | | | | | | +- PatternInitializer + | | | | | | | +- Pattern + | | | | | | | | +- IdentifierPattern + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- TypeAnnotation + | | | | | | | | +- T-colon + | | | | | | | | +- SType + | | | | | | | | +- SType + | | | | | | | | | +- TypeIdentifier + | | | | | | | | | +- TypeName + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-question + | | | | | | | +- Initializer + | | | | | | | +- T-eq + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Keyword + | | | | | | | +- T-NilLiteral + | | | | | | +- Statement + | | | | | | | +- LoopStatement + | | | | | | | +- WhileStatement + | | | | | | | +- T-while + | | | | | | | +- ConditionList + | | | | | | | | +- Condition + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Keyword + | | | | | | | | +- T-BooleanLiteral + | | | | | | | +- CodeBlock + | | | | | | | +- T-lbrace + | | | | | | | +- Statements + | | | | | | | | +- Statement + | | | | | | | | | +- Declaration + | | | | | | | | | +- ConstantDeclaration + | | | | | | | | | +- T-let + | | | | | | | | | +- PatternInitializerList + | | | | | | | | | +- PatternInitializer + | | | | | | | | | +- Pattern + | | | | | | | | | | +- IdentifierPattern + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- Initializer + | | | | | | | | | +- T-eq + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- T-dot + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- FunctionCallArgumentClause + | | | | | | | | | +- T-lparen + | | | | | | | | | +- FunctionCallArgumentList + | | | | | | | | | | +- FunctionCallArgument + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- T-comma + | | | | | | | | | | +- FunctionCallArgument + | | | | | | | | | | +- FunctionCallIdentifier + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- T-colon + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-rparen + | | | | | | | | +- Statement + | | | | | | | | | +- BranchStatement + | | | | | | | | | +- IfStatement + | | | | | | | | | +- T-if + | | | | | | | | | +- ConditionList + | | | | | | | | | | +- Condition + | | | | | | | | | | +- OptionalBindingCondition + | | | | | | | | | | +- T-let + | | | | | | | | | | +- Pattern + | | | | | | | | | | | +- IdentifierPattern + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- Initializer + | | | | | | | | | | +- T-eq + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- T-dot + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- CodeBlock + | | | | | | | | | +- T-lbrace + | | | | | | | | | +- Statements + | | | | | | | | | | +- Statement + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- PostfixOperator + | | | | | | | | | | | +- Operator + | | | | | | | | | | | +- OperatorHead + | | | | | | | | | | | +- T-eq + | | | | | | | | | | +- Statement + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | +- T-dot + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- T-lbracket + | | | | | | | | | | | +- TupleElementList + | | | | | | | | | | | | +- TupleElement + | | | | | | | | | | | | +- Expression + | | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- T-rbracket + | | | | | | | | | | +- T-dot + | | | | | | | | | | +- T-DecimalLiteral + | | | | | | | | | +- T-rbrace + | | | | | | | | +- Statement + | | | | | | | | | +- BranchStatement + | | | | | | | | | +- IfStatement + | | | | | | | | | +- T-if + | | | | | | | | | +- ConditionList + | | | | | | | | | | +- Condition + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- T-dot + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- CodeBlock + | | | | | | | | | +- T-lbrace + | | | | | | | | | +- Statements + | | | | | | | | | | +- Statement + | | | | | | | | | | +- ControlTransferStatement + | | | | | | | | | | +- BreakStatement + | | | | | | | | | | +- T-break + | | | | | | | | | +- T-rbrace + | | | | | | | | +- Statement + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- PostfixOperator + | | | | | | | | | +- Operator + | | | | | | | | | +- OperatorHead + | | | | | | | | | +- T-eq + | | | | | | | | +- Statement + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-lbracket + | | | | | | | | +- TupleElementList + | | | | | | | | | +- TupleElement + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-rbracket + | | | | | | | +- T-rbrace + | | | | | | +- Statement + | | | | | | +- ControlTransferStatement + | | | | | | +- ReturnStatement + | | | | | | +- T-return + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rbrace + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | | +- FunctionHead + | | | | | +- Attributes + | | | | | | +- Attribute + | | | | | | +- T-at-symbol + | | | | | | +- AttributeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-func + | | | | +- FunctionName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionSignature + | | | | | +- ParameterClause + | | | | | | +- T-lparen + | | | | | | +- ParameterList + | | | | | | | +- Parameter + | | | | | | | | +- LocalParameterName + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- TypeAnnotation + | | | | | | | | +- T-colon + | | | | | | | | +- SType + | | | | | | | | +- TypeIdentifier + | | | | | | | | +- TypeName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- Parameter + | | | | | | | +- ExternalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- LocalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- TypeAnnotation + | | | | | | | | +- T-colon + | | | | | | | | +- SType + | | | | | | | | +- TypeIdentifier + | | | | | | | | +- TypeName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- DefaultArgumentClause + | | | | | | | +- T-eq + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Keyword + | | | | | | | +- T-Any + | | | | | | +- T-rparen + | | | | | +- FunctionResult + | | | | | +- T-rarrow + | | | | | +- SType + | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-question + | | | | +- FunctionBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | | +- Declaration + | | | | | | +- ConstantDeclaration + | | | | | | +- T-let + | | | | | | +- PatternInitializerList + | | | | | | +- PatternInitializer + | | | | | | +- Pattern + | | | | | | | +- IdentifierPattern + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- Initializer + | | | | | | +- T-eq + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | | +- FunctionCallIdentifier + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-colon + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- FunctionCallArgument + | | | | | | | | +- FunctionCallIdentifier + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-colon + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- FunctionCallArgument + | | | | | | | +- FunctionCallIdentifier + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-colon + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- Statement + | | | | | | +- BranchStatement + | | | | | | +- GuardStatement + | | | | | | +- T-guard + | | | | | | +- ConditionList + | | | | | | | +- Condition + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PrefixOperator + | | | | | | | | +- Operator + | | | | | | | | +- OperatorHead + | | | | | | | | +- T-bang + | | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- PostfixOperator + | | | | | | | | +- Operator + | | | | | | | | +- OperatorHead + | | | | | | | | +- T-double-amp + | | | | | | | +- FunctionCallArgumentClause + | | | | | | | +- T-lparen + | | | | | | | +- FunctionCallArgumentList + | | | | | | | | +- FunctionCallArgument + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- PostfixOperator + | | | | | | | | | | +- Operator + | | | | | | | | | | +- OperatorHead + | | | | | | | | | | +- T-double-eq + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- BinaryExpression + | | | | | | | | | +- BinaryOperator + | | | | | | | | | | +- Operator + | | | | | | | | | | +- OperatorHead + | | | | | | | | | | +- T-double-pipe + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- BinaryExpression + | | | | | | | | +- BinaryOperator + | | | | | | | | | +- Operator + | | | | | | | | | +- OperatorHead + | | | | | | | | | +- T-double-eq + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-rparen + | | | | | | +- T-else + | | | | | | +- CodeBlock + | | | | | | +- T-lbrace + | | | | | | +- Statements + | | | | | | | +- Statement + | | | | | | | +- ControlTransferStatement + | | | | | | | +- ReturnStatement + | | | | | | | +- T-return + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Keyword + | | | | | | | +- T-NilLiteral + | | | | | | +- T-rbrace + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- FunctionCallArgumentClause + | | | | | +- T-lparen + | | | | | +- FunctionCallArgumentList + | | | | | | +- FunctionCallArgument + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rparen + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | | +- FunctionHead + | | | | | +- Attributes + | | | | | | +- Attribute + | | | | | | +- T-at-symbol + | | | | | | +- AttributeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-func + | | | | +- FunctionName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionSignature + | | | | | +- ParameterClause + | | | | | | +- T-lparen + | | | | | | +- ParameterList + | | | | | | | +- Parameter + | | | | | | | | +- LocalParameterName + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- TypeAnnotation + | | | | | | | | +- T-colon + | | | | | | | | +- SType + | | | | | | | | +- TypeIdentifier + | | | | | | | | +- TypeName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- Parameter + | | | | | | | +- ExternalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- LocalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- TypeAnnotation + | | | | | | | | +- T-colon + | | | | | | | | +- SType + | | | | | | | | +- TypeIdentifier + | | | | | | | | +- TypeName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- DefaultArgumentClause + | | | | | | | +- T-eq + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Keyword + | | | | | | | +- T-Any + | | | | | | +- T-rparen + | | | | | +- FunctionResult + | | | | | +- T-rarrow + | | | | | +- SType + | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-question + | | | | +- FunctionBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | | +- Declaration + | | | | | | +- VariableDeclaration + | | | | | | +- VariableDeclarationHead + | | | | | | | +- T-var + | | | | | | +- PatternInitializerList + | | | | | | +- PatternInitializer + | | | | | | +- Pattern + | | | | | | | +- IdentifierPattern + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- Initializer + | | | | | | +- T-eq + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- Statement + | | | | | | +- Declaration + | | | | | | +- VariableDeclaration + | | | | | | +- VariableDeclarationHead + | | | | | | | +- T-var + | | | | | | +- PatternInitializerList + | | | | | | +- PatternInitializer + | | | | | | +- Pattern + | | | | | | | +- IdentifierPattern + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- Initializer + | | | | | | +- T-eq + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- LiteralExpression + | | | | | | +- Literal + | | | | | | +- NumericLiteral + | | | | | | +- IntegerLiteral + | | | | | | +- T-DecimalLiteral + | | | | | +- Statement + | | | | | | +- Declaration + | | | | | | +- VariableDeclaration + | | | | | | +- VariableDeclarationHead + | | | | | | | +- T-var + | | | | | | +- PatternInitializerList + | | | | | | +- PatternInitializer + | | | | | | +- Pattern + | | | | | | | +- IdentifierPattern + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- TypeAnnotation + | | | | | | | +- T-colon + | | | | | | | +- SType + | | | | | | | +- SType + | | | | | | | | +- TypeIdentifier + | | | | | | | | +- TypeName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-question + | | | | | | +- Initializer + | | | | | | +- T-eq + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Keyword + | | | | | | +- T-NilLiteral + | | | | | +- Statement + | | | | | | +- LoopStatement + | | | | | | +- WhileStatement + | | | | | | +- T-while + | | | | | | +- ConditionList + | | | | | | | +- Condition + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PrefixOperator + | | | | | | | | +- Operator + | | | | | | | | +- OperatorHead + | | | | | | | | +- T-bang + | | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-dot + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- CodeBlock + | | | | | | +- T-lbrace + | | | | | | +- Statements + | | | | | | | +- Statement + | | | | | | | | +- Declaration + | | | | | | | | +- ConstantDeclaration + | | | | | | | | +- T-let + | | | | | | | | +- PatternInitializerList + | | | | | | | | +- PatternInitializer + | | | | | | | | +- Pattern + | | | | | | | | | +- IdentifierPattern + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- Initializer + | | | | | | | | +- T-eq + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- FunctionCallArgumentClause + | | | | | | | | +- T-lparen + | | | | | | | | +- FunctionCallArgumentList + | | | | | | | | | +- FunctionCallArgument + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-comma + | | | | | | | | | +- FunctionCallArgument + | | | | | | | | | +- FunctionCallIdentifier + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-colon + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-rparen + | | | | | | | +- Statement + | | | | | | | | +- Declaration + | | | | | | | | +- ConstantDeclaration + | | | | | | | | +- T-let + | | | | | | | | +- PatternInitializerList + | | | | | | | | +- PatternInitializer + | | | | | | | | +- Pattern + | | | | | | | | | +- IdentifierPattern + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- Initializer + | | | | | | | | +- T-eq + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-lbracket + | | | | | | | | +- TupleElementList + | | | | | | | | | +- TupleElement + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-rbracket + | | | | | | | +- Statement + | | | | | | | | +- BranchStatement + | | | | | | | | +- IfStatement + | | | | | | | | +- T-if + | | | | | | | | +- ConditionList + | | | | | | | | | +- Condition + | | | | | | | | | +- OptionalBindingCondition + | | | | | | | | | +- T-let + | | | | | | | | | +- Pattern + | | | | | | | | | | +- IdentifierPattern + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- Initializer + | | | | | | | | | +- T-eq + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- CodeBlock + | | | | | | | | | +- T-lbrace + | | | | | | | | | +- Statements + | | | | | | | | | | +- Statement + | | | | | | | | | | | +- Declaration + | | | | | | | | | | | +- ConstantDeclaration + | | | | | | | | | | | +- T-let + | | | | | | | | | | | +- PatternInitializerList + | | | | | | | | | | | +- PatternInitializer + | | | | | | | | | | | +- Pattern + | | | | | | | | | | | | +- IdentifierPattern + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- Initializer + | | | | | | | | | | | +- T-eq + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | +- T-dot + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- FunctionCallArgumentClause + | | | | | | | | | | | +- T-lparen + | | | | | | | | | | | +- FunctionCallArgumentList + | | | | | | | | | | | | +- FunctionCallArgument + | | | | | | | | | | | | +- Expression + | | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- T-rparen + | | | | | | | | | | +- Statement + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- PostfixOperator + | | | | | | | | | | | +- Operator + | | | | | | | | | | | +- OperatorHead + | | | | | | | | | | | +- T-eq + | | | | | | | | | | +- Statement + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- PostfixOperator + | | | | | | | | | | | +- Operator + | | | | | | | | | | | +- OperatorHead + | | | | | | | | | | | +- T-OperatorHead + | | | | | | | | | | +- Statement + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- Statement + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- PostfixOperator + | | | | | | | | | | | +- Operator + | | | | | | | | | | | +- OperatorHead + | | | | | | | | | | | | +- T-OperatorHead + | | | | | | | | | | | +- OperatorCharacter + | | | | | | | | | | | +- OperatorHead + | | | | | | | | | | | +- T-eq + | | | | | | | | | | +- Statement + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- PostfixOperator + | | | | | | | | | | | +- Operator + | | | | | | | | | | | +- OperatorHead + | | | | | | | | | | | +- T-minus + | | | | | | | | | | +- FunctionCallArgumentClause + | | | | | | | | | | +- T-lparen + | | | | | | | | | | +- FunctionCallArgumentList + | | | | | | | | | | | +- FunctionCallArgument + | | | | | | | | | | | +- Expression + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- BinaryExpression + | | | | | | | | | | | | +- BinaryOperator + | | | | | | | | | | | | | +- Operator + | | | | | | | | | | | | | +- OperatorHead + | | | | | | | | | | | | | +- T-double-eq + | | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | +- T-dot + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- BinaryExpression + | | | | | | | | | | | +- ConditionalOperator + | | | | | | | | | | | | +- T-question + | | | | | | | | | | | | +- Expression + | | | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | | | | +- T-dot + | | | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | | | +- T-lbracket + | | | | | | | | | | | | | | +- TupleElementList + | | | | | | | | | | | | | | | +- TupleElement + | | | | | | | | | | | | | | | +- Expression + | | | | | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | | | +- T-rbracket + | | | | | | | | | | | | | +- T-dot + | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | +- T-colon + | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- LiteralExpression + | | | | | | | | | | | +- Literal + | | | | | | | | | | | +- NumericLiteral + | | | | | | | | | | | +- IntegerLiteral + | | | | | | | | | | | +- T-DecimalLiteral + | | | | | | | | | | +- T-rparen + | | | | | | | | | +- T-rbrace + | | | | | | | | +- ElseClause + | | | | | | | | +- T-else + | | | | | | | | +- CodeBlock + | | | | | | | | +- T-lbrace + | | | | | | | | +- Statements + | | | | | | | | | +- Statement + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | +- Identifier + | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | +- PostfixOperator + | | | | | | | | | | +- Operator + | | | | | | | | | | +- OperatorHead + | | | | | | | | | | | +- T-OperatorHead + | | | | | | | | | | +- OperatorCharacter + | | | | | | | | | | +- OperatorHead + | | | | | | | | | | +- T-eq + | | | | | | | | | +- Statement + | | | | | | | | | | +- Expression + | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | +- T-dot + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- FunctionCallArgumentClause + | | | | | | | | | | | +- T-lparen + | | | | | | | | | | | +- FunctionCallArgumentList + | | | | | | | | | | | | +- FunctionCallArgument + | | | | | | | | | | | | +- Expression + | | | | | | | | | | | | +- PrefixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | +- PostfixExpression + | | | | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | | +- T-dot + | | | | | | | | | | | | +- Identifier + | | | | | | | | | | | | +- T-Identifier + | | | | | | | | | | | +- T-rparen + | | | | | | | | | | +- PostfixOperator + | | | | | | | | | | +- Operator + | | | | | | | | | | +- OperatorHead + | | | | | | | | | | +- T-minus + | | | | | | | | | +- Statement + | | | | | | | | | +- Expression + | | | | | | | | | +- PrefixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PostfixExpression + | | | | | | | | | | +- PrimaryExpression + | | | | | | | | | | +- Identifier + | | | | | | | | | | +- T-Identifier + | | | | | | | | | +- T-dot + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-rbrace + | | | | | | | +- Statement + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- PostfixOperator + | | | | | | | | +- Operator + | | | | | | | | +- OperatorHead + | | | | | | | | +- T-eq + | | | | | | | +- Statement + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rbrace + | | | | | +- Statement + | | | | | | +- Declaration + | | | | | | +- ConstantDeclaration + | | | | | | +- T-let + | | | | | | +- PatternInitializerList + | | | | | | +- PatternInitializer + | | | | | | +- Pattern + | | | | | | | +- IdentifierPattern + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- Initializer + | | | | | | +- T-eq + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-dot + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-comma + | | | | | | | +- FunctionCallArgument + | | | | | | | +- FunctionCallIdentifier + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-colon + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- Statement + | | | | | | +- BranchStatement + | | | | | | +- IfStatement + | | | | | | +- T-if + | | | | | | +- ConditionList + | | | | | | | +- Condition + | | | | | | | +- OptionalBindingCondition + | | | | | | | +- T-let + | | | | | | | +- Pattern + | | | | | | | | +- IdentifierPattern + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- Initializer + | | | | | | | +- T-eq + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PrimaryExpression + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-dot + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- CodeBlock + | | | | | | +- T-lbrace + | | | | | | +- Statements + | | | | | | | +- Statement + | | | | | | | | +- ControlTransferStatement + | | | | | | | | +- ReturnStatement + | | | | | | | | +- T-return + | | | | | | | | +- Expression + | | | | | | | | +- PrefixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- PostfixOperator + | | | | | | | | +- Operator + | | | | | | | | +- OperatorHead + | | | | | | | | +- T-OperatorHead + | | | | | | | +- Statement + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rbrace + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PrimaryExpression + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | | +- FunctionHead + | | | | | +- Attributes + | | | | | | +- Attribute + | | | | | | +- T-at-symbol + | | | | | | +- AttributeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- DeclarationModifiers + | | | | | | +- DeclarationModifier + | | | | | | +- AccessLevelModifier + | | | | | | +- T-public + | | | | | +- T-func + | | | | +- FunctionName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionSignature + | | | | | +- ParameterClause + | | | | | | +- T-lparen + | | | | | | +- ParameterList + | | | | | | | +- Parameter + | | | | | | | +- LocalParameterName + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- TypeAnnotation + | | | | | | | +- T-colon + | | | | | | | +- SType + | | | | | | | +- TypeIdentifier + | | | | | | | +- TypeName + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- FunctionResult + | | | | | +- T-rarrow + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionBody + | | | | +- CodeBlock + | | | | +- T-lbrace + | | | | +- Statements + | | | | | +- Statement + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PostfixExpression + | | | | | | | | +- PostfixExpression + | | | | | | | | | +- PrimaryExpression + | | | | | | | | | +- Identifier + | | | | | | | | | +- T-Identifier + | | | | | | | | +- T-dot + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-dot + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- FunctionCallArgumentClause + | | | | | | +- T-lparen + | | | | | | +- FunctionCallArgumentList + | | | | | | | +- FunctionCallArgument + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-rparen + | | | | | +- Statement + | | | | | +- ControlTransferStatement + | | | | | +- ReturnStatement + | | | | | +- T-return + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-dot + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-dot + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rbrace + | | | +- ExtensionMember + | | | +- Declaration + | | | +- FunctionDeclaration + | | | +- FunctionHead + | | | | +- Attributes + | | | | | +- Attribute + | | | | | +- T-at-symbol + | | | | | +- AttributeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- DeclarationModifiers + | | | | | +- DeclarationModifier + | | | | | +- AccessLevelModifier + | | | | | +- T-public + | | | | +- T-func + | | | +- FunctionName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- FunctionSignature + | | | | +- ParameterClause + | | | | | +- T-lparen + | | | | | +- ParameterList + | | | | | | +- Parameter + | | | | | | +- LocalParameterName + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- TypeAnnotation + | | | | | | +- T-colon + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rparen + | | | | +- FunctionResult + | | | | +- T-rarrow + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- FunctionBody + | | | +- CodeBlock + | | | +- T-lbrace + | | | +- Statements + | | | | +- Statement + | | | | +- ControlTransferStatement + | | | | +- ReturnStatement + | | | | +- T-return + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PostfixExpression + | | | | | +- PrimaryExpression + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionCallArgumentClause + | | | | +- T-lparen + | | | | +- FunctionCallArgumentList + | | | | | +- FunctionCallArgument + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- FunctionCallArgumentClause + | | | | | +- T-lparen + | | | | | +- FunctionCallArgumentList + | | | | | | +- FunctionCallArgument + | | | | | | | +- FunctionCallIdentifier + | | | | | | | | +- Identifier + | | | | | | | | +- T-Identifier + | | | | | | | +- T-colon + | | | | | | | +- Expression + | | | | | | | +- PrefixExpression + | | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-comma + | | | | | | +- FunctionCallArgument + | | | | | | +- FunctionCallIdentifier + | | | | | | | +- Identifier + | | | | | | | +- T-Identifier + | | | | | | +- T-colon + | | | | | | +- Expression + | | | | | | +- PrefixExpression + | | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-rparen + | | | | +- T-rparen + | | | +- T-rbrace + | | +- T-rbrace + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Keyword + | | +- T-extension + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Identifier + | | +- T-Identifier + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- ClosureExpression + | | +- T-lbrace + | | +- Statements + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Keyword + | | | | +- T-internal + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- ContextSensitiveKeyword + | | | | +- T-mutating + | | | +- Statement + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | +- Statement + | | | | +- Declaration + | | | | +- FunctionDeclaration + | | | | +- Error + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Error + | | | +- Statement + | | | | +- Declaration + | | | +- Statement + | | | | +- Declaration + | | | | +- Error + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- Statement + | | | | +- LabeledStatement + | | | | +- StatementLabel + | | | | +- LabelName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-colon + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PrefixOperator + | | | | | +- Operator + | | | | | +- OperatorHead + | | | | | +- T-rarrow + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- Statement + | | | +- Expression + | | | +- PrefixExpression + | | | +- PostfixExpression + | | | +- PrimaryExpression + | | | +- Operator + | | | +- OperatorHead + | | | +- T-question + | | +- Error + | +- Statement + | | +- Declaration + | +- Statement + | | +- Declaration + | | +- Error + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- Identifier + | | +- T-Identifier + | +- Statement + | | +- LabeledStatement + | | +- StatementLabel + | | +- LabelName + | | | +- Identifier + | | | +- T-Identifier + | | +- T-colon + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- PostfixExpression + | | +- PrimaryExpression + | | +- TupleExpression + | | +- T-lparen + | | +- TupleElementList + | | | +- TupleElement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-comma + | | | +- TupleElement + | | | +- Expression + | | | +- PrefixExpression + | | | +- PostfixExpression + | | | +- PrimaryExpression + | | | +- Identifier + | | | +- T-Identifier + | | +- T-rparen + | +- Statement + | | +- Expression + | | +- PrefixExpression + | | +- Error + | +- Statement + | +- Expression + | +- PrefixExpression + | +- PostfixExpression + | +- PrimaryExpression + | +- Identifier + | +- T-Identifier + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error + +- Error diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Simple.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Simple.swift new file mode 100644 index 0000000000..87b9a81a41 --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Simple.swift @@ -0,0 +1,23 @@ +/// B-trees are search trees that provide an ordered key-value store with excellent performance characteristics. +public struct BTree { + public typealias Element = (Key, Payload) + internal typealias Node = BTreeNode + + internal var root: Node + + internal init(_ root: Node) { + self.root = root + } + + /// Initialize a new b-tree with no elements. + /// + /// - Parameter order: The maximum number of children for tree nodes. + public init(order: Int = Node.defaultOrder) { + self.root = Node(order: order) + } + + /// The order of this tree, i.e., the maximum number of children for tree nodes. + public var order: Int { return root.order } + /// The depth of this tree. Depth starts at 0 for a tree that has a single root node. + public var depth: Int { return root.depth } +} diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Simple.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Simple.txt new file mode 100644 index 0000000000..86885289da --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/Simple.txt @@ -0,0 +1,329 @@ ++- TopLevel + +- Statements + | +- Statement + | +- Declaration + | +- StructDeclaration + | +- AccessLevelModifier + | | +- T-public + | +- T-struct + | +- StructName + | | +- Identifier + | | +- T-Identifier + | +- GenericParameterClause + | | +- T-lt + | | +- GenericParameterList + | | | +- GenericParameter + | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-colon + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-comma + | | | +- GenericParameter + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- T-gt + | +- StructBody + | +- T-lbrace + | +- StructMembers + | | +- StructMember + | | | +- Declaration + | | | +- TypealiasDeclaration + | | | +- TypealiasHead + | | | | +- AccessLevelModifier + | | | | | +- T-public + | | | | +- T-typealias + | | | | +- TypealiasName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- TypealiasAssignment + | | | +- T-eq + | | | +- SType + | | | +- TupleType + | | | +- T-lparen + | | | +- TupleTypeElementList + | | | | +- TupleTypeElement + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-comma + | | | | +- TupleTypeElement + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-rparen + | | +- StructMember + | | | +- Declaration + | | | +- TypealiasDeclaration + | | | +- TypealiasHead + | | | | +- AccessLevelModifier + | | | | | +- T-internal + | | | | +- T-typealias + | | | | +- TypealiasName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- TypealiasAssignment + | | | +- T-eq + | | | +- SType + | | | +- TypeIdentifier + | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- GenericArgumentClause + | | | +- T-lt + | | | +- GenericArgumentList + | | | | +- GenericArgument + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-comma + | | | | +- GenericArgument + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-gt + | | +- StructMember + | | | +- Declaration + | | | +- VariableDeclaration + | | | +- VariableDeclarationHead + | | | | +- DeclarationModifiers + | | | | | +- DeclarationModifier + | | | | | +- AccessLevelModifier + | | | | | +- T-internal + | | | | +- T-var + | | | +- PatternInitializerList + | | | +- PatternInitializer + | | | +- Pattern + | | | +- IdentifierPattern + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- TypeAnnotation + | | | +- T-colon + | | | +- SType + | | | +- TypeIdentifier + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- StructMember + | | | +- Declaration + | | | +- InitializerDeclaration + | | | +- InitializerHead + | | | | +- DeclarationModifiers + | | | | | +- DeclarationModifier + | | | | | +- AccessLevelModifier + | | | | | +- T-internal + | | | | +- T-init + | | | +- ParameterClause + | | | | +- T-lparen + | | | | +- ParameterList + | | | | | +- Parameter + | | | | | +- ExternalParameterName + | | | | | | +- Keyword + | | | | | | +- T-underscore + | | | | | +- LocalParameterName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- TypeAnnotation + | | | | | +- T-colon + | | | | | +- SType + | | | | | +- TypeIdentifier + | | | | | +- TypeName + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rparen + | | | +- InitializerBody + | | | +- CodeBlock + | | | +- T-lbrace + | | | +- Statements + | | | | +- Statement + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Keyword + | | | | | | | +- T-self + | | | | | | +- T-dot + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- PostfixOperator + | | | | | +- Operator + | | | | | +- OperatorHead + | | | | | +- T-eq + | | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-rbrace + | | +- StructMember + | | | +- Declaration + | | | +- InitializerDeclaration + | | | +- InitializerHead + | | | | +- DeclarationModifiers + | | | | | +- DeclarationModifier + | | | | | +- AccessLevelModifier + | | | | | +- T-public + | | | | +- T-init + | | | +- ParameterClause + | | | | +- T-lparen + | | | | +- ParameterList + | | | | | +- Parameter + | | | | | +- LocalParameterName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- TypeAnnotation + | | | | | | +- T-colon + | | | | | | +- SType + | | | | | | +- TypeIdentifier + | | | | | | +- TypeName + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- DefaultArgumentClause + | | | | | +- T-eq + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PrimaryExpression + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-dot + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rparen + | | | +- InitializerBody + | | | +- CodeBlock + | | | +- T-lbrace + | | | +- Statements + | | | | +- Statement + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PostfixExpression + | | | | | | +- PostfixExpression + | | | | | | | +- PrimaryExpression + | | | | | | | +- Keyword + | | | | | | | +- T-self + | | | | | | +- T-dot + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- PostfixOperator + | | | | | +- Operator + | | | | | +- OperatorHead + | | | | | +- T-eq + | | | | +- Statement + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PostfixExpression + | | | | | +- PrimaryExpression + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- FunctionCallArgumentClause + | | | | +- T-lparen + | | | | +- FunctionCallArgumentList + | | | | | +- FunctionCallArgument + | | | | | +- FunctionCallIdentifier + | | | | | | +- Identifier + | | | | | | +- T-Identifier + | | | | | +- T-colon + | | | | | +- Expression + | | | | | +- PrefixExpression + | | | | | +- PostfixExpression + | | | | | +- PrimaryExpression + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-rparen + | | | +- T-rbrace + | | +- StructMember + | | | +- Declaration + | | | +- VariableDeclaration + | | | +- VariableDeclarationHead + | | | | +- DeclarationModifiers + | | | | | +- DeclarationModifier + | | | | | +- AccessLevelModifier + | | | | | +- T-public + | | | | +- T-var + | | | +- VariableName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- TypeAnnotation + | | | | +- T-colon + | | | | +- SType + | | | | +- TypeIdentifier + | | | | +- TypeName + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- CodeBlock + | | | +- T-lbrace + | | | +- Statements + | | | | +- Statement + | | | | +- ControlTransferStatement + | | | | +- ReturnStatement + | | | | +- T-return + | | | | +- Expression + | | | | +- PrefixExpression + | | | | +- PostfixExpression + | | | | +- PostfixExpression + | | | | | +- PrimaryExpression + | | | | | +- Identifier + | | | | | +- T-Identifier + | | | | +- T-dot + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-rbrace + | | +- StructMember + | | +- Declaration + | | +- VariableDeclaration + | | +- VariableDeclarationHead + | | | +- DeclarationModifiers + | | | | +- DeclarationModifier + | | | | +- AccessLevelModifier + | | | | +- T-public + | | | +- T-var + | | +- VariableName + | | | +- Identifier + | | | +- T-Identifier + | | +- TypeAnnotation + | | | +- T-colon + | | | +- SType + | | | +- TypeIdentifier + | | | +- TypeName + | | | +- Identifier + | | | +- T-Identifier + | | +- CodeBlock + | | +- T-lbrace + | | +- Statements + | | | +- Statement + | | | +- ControlTransferStatement + | | | +- ReturnStatement + | | | +- T-return + | | | +- Expression + | | | +- PrefixExpression + | | | +- PostfixExpression + | | | +- PostfixExpression + | | | | +- PrimaryExpression + | | | | +- Identifier + | | | | +- T-Identifier + | | | +- T-dot + | | | +- Identifier + | | | +- T-Identifier + | | +- T-rbrace + | +- T-rbrace + +- EOF diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/BTree.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/BTree.swift similarity index 100% rename from pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/BTree.swift rename to pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/BTree.swift diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/Issue628.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue628.swift similarity index 100% rename from pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/Issue628.swift rename to pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue628.swift diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue628.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue628.txt new file mode 100644 index 0000000000..a72ac8a4ac --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue628.txt @@ -0,0 +1,8 @@ + [Image] or [Truncated image[ Bcol Ecol +L4 + [var] 1 4 + [str] 5 8 + [=] 9 10 + ["Hello Hello Hello Hello Hello Hel[ 11 4405 + [;] 4405 4406 +EOF diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/Swift4.2.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift4.2.swift similarity index 100% rename from pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/Swift4.2.swift rename to pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift4.2.swift diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift4.2.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift4.2.txt new file mode 100644 index 0000000000..3df01edf44 --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift4.2.txt @@ -0,0 +1,108 @@ + [Image] or [Truncated image[ Bcol Ecol +L4 + [let] 1 4 + [diceRoll] 5 13 + [=] 14 15 + [Int] 16 19 + [.] 19 20 + [random] 20 26 + [(] 26 27 + [in] 27 29 + [:] 29 30 + [1] 31 32 + [...] 33 36 + [6] 37 38 + [)] 38 39 +L5 + [let] 1 4 + [randomUnit] 5 15 + [=] 16 17 + [Double] 18 24 + [.] 24 25 + [random] 25 31 + [(] 31 32 + [in] 32 34 + [:] 34 35 + [0] 36 37 + [..] 38 40 + [<] 40 41 + [1] 42 43 + [)] 43 44 +L6 + [let] 1 4 + [randomBool] 5 15 + [=] 16 17 + [Bool] 18 22 + [.] 22 23 + [random] 23 29 + [(] 29 30 + [)] 30 31 +L9 + [public] 1 7 + [class] 8 13 + [C] 14 15 + [{] 16 17 +L10 + [public] 3 9 + [func] 10 14 + [f] 15 16 + [(] 16 17 + [)] 17 18 + [{] 19 20 + [}] 20 21 +L11 + [}] 1 2 +L13 + [public] 1 7 + [class] 8 13 + [Cbis] 14 18 + [{] 19 20 +L14 + [@] 3 4 + [usableFromInline] 4 20 + [internal] 21 29 + [class] 30 35 + [D] 36 37 + [{] 38 39 +L15 + [@] 5 6 + [usableFromInline] 6 22 + [internal] 23 31 + [func] 32 36 + [f] 37 38 + [(] 38 39 + [)] 39 40 + [{] 41 42 + [}] 42 43 +L17 + [@] 5 6 + [inlinable] 6 15 + [internal] 16 24 + [func] 25 29 + [g] 30 31 + [(] 31 32 + [)] 32 33 + [{] 34 35 + [}] 35 36 +L18 + [}] 3 4 +L19 + [}] 1 2 +L22 + [#warning] 1 9 + [(] 9 10 + ["this is incomplete"] 10 30 + [)] 30 31 +L24 + [#if] 1 4 + [MY_BUILD_CONFIG] 5 20 + [&&] 21 23 + [MY_OTHER_BUILD_CONFIG] 24 45 +L25 + [#error] 3 9 + [(] 9 10 + ["MY_BUILD_CONFIG and MY_OTHER_BUIL[ 10 72 + [)] 72 73 +L26 + [#endif] 1 7 +EOF diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/Swift5.0.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.swift similarity index 100% rename from pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/Swift5.0.swift rename to pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.swift diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.txt new file mode 100644 index 0000000000..5a8a5f541d --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.0.txt @@ -0,0 +1,200 @@ + [Image] or [Truncated image[ Bcol Ecol +L4 + [enum] 1 5 + [Result] 6 12 + [<] 12 13 + [Success] 13 20 + [,] 20 21 + [Failure] 22 29 + [:] 29 30 + [Error] 31 36 + [>] 36 37 + [{] 38 39 +L5 + [case] 5 9 + [success] 10 17 + [(] 17 18 + [Success] 18 25 + [)] 25 26 +L6 + [case] 5 9 + [failure] 10 17 + [(] 17 18 + [Failure] 18 25 + [)] 25 26 +L7 + [}] 1 2 +L10 + [struct] 1 7 + [MyType] 8 14 + [{] 15 16 + [}] 16 17 +L11 + [#if] 1 4 + [compiler] 5 13 + [(] 13 14 + [<] 14 15 + [5.0] 15 18 + [)] 18 19 +L12 + [extension] 1 10 + [MyType] 11 17 + [:] 18 19 + [_ExpressibleByStringInterpolation] 20 53 + [{] 54 55 + [}] 56 57 +L13 + [#else] 1 6 +L14 + [extension] 1 10 + [MyType] 11 17 + [:] 18 19 + [ExpressibleByStringInterpolation] 20 52 + [{] 53 54 + [}] 55 56 +L15 + [#endif] 1 7 +L18 + [func] 1 5 + [foo] 6 9 + [(] 9 10 + [_] 10 11 + [fn] 12 14 + [:] 14 15 + [@] 16 17 + [autoclosure] 17 28 + [(] 29 30 + [)] 30 31 + [->] 32 34 + [Int] 35 38 + [)] 38 39 + [{] 40 41 + [}] 41 42 +L19 + [func] 1 5 + [bar] 6 9 + [(] 9 10 + [_] 10 11 + [fn] 12 14 + [:] 14 15 + [@] 16 17 + [autoclosure] 17 28 + [(] 29 30 + [)] 30 31 + [->] 32 34 + [Int] 35 38 + [)] 38 39 + [{] 40 41 +L21 + [foo] 3 6 + [(] 6 7 + [fn] 7 9 + [(] 9 10 + [)] 10 11 + [)] 11 12 +L22 + [}] 1 2 +L25 + [@] 1 2 + [dynamicCallable] 2 17 +L26 + [struct] 1 7 + [ToyCallable] 8 19 + [{] 20 21 +L27 + [func] 3 7 + [dynamicallyCall] 8 23 + [(] 23 24 + [withArguments] 24 37 + [:] 37 38 + [\[] 39 40 + [Int] 40 43 + [\]] 43 44 + [)] 44 45 + [{] 46 47 + [}] 47 48 +L28 + [func] 3 7 + [dynamicallyCall] 8 23 + [(] 23 24 + [withKeywordArguments] 24 44 + [:] 44 45 + [KeyValuePairs] 46 59 + [<] 59 60 + [String] 60 66 + [,] 66 67 + [Int] 68 71 + [>] 71 72 + [)] 72 73 + [{] 74 75 + [}] 75 76 +L29 + [}] 1 2 +L30 + [let] 1 4 + [toy] 5 8 + [=] 9 10 + [ToyCallable] 11 22 + [(] 22 23 + [)] 23 24 +L31 + [toy] 1 4 + [(] 4 5 + [1] 5 6 + [,] 6 7 + [2] 8 9 + [,] 9 10 + [3] 11 12 + [)] 12 13 +L32 + [toy] 1 4 + [(] 4 5 + [label] 5 10 + [:] 10 11 + [1] 12 13 + [,] 13 14 + [2] 15 16 + [)] 16 17 +L35 + [let] 1 4 + [id] 5 7 + [=] 8 9 + [\\] 10 11 + [Int] 11 14 + [.] 14 15 + [self] 15 19 +L37 + [var] 1 4 + [x] 5 6 + [=] 7 8 + [2] 9 10 +L38 + [print] 1 6 + [(] 6 7 + [x] 7 8 + [\[] 8 9 + [keyPath] 9 16 + [:] 16 17 + [id] 18 20 + [\]] 20 21 + [)] 21 22 +L39 + [x] 1 2 + [\[] 2 3 + [keyPath] 3 10 + [:] 10 11 + [id] 12 14 + [\]] 14 15 + [=] 16 17 + [3] 18 19 +L40 + [print] 1 6 + [(] 6 7 + [x] 7 8 + [\[] 8 9 + [keyPath] 9 16 + [:] 16 17 + [id] 18 20 + [\]] 20 21 + [)] 21 22 +EOF diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/Swift5.1.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.1.swift similarity index 100% rename from pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/Swift5.1.swift rename to pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.1.swift diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.1.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.1.txt new file mode 100644 index 0000000000..1906e2331d --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.1.txt @@ -0,0 +1,290 @@ + [Image] or [Truncated image[ Bcol Ecol +L6 + [import] 1 7 + [Combine] 8 15 +L7 + [class] 1 6 + [Weather] 7 14 + [{] 15 16 +L8 + [@] 5 6 + [Published] 6 15 + [var] 16 19 + [temperature] 20 31 + [:] 31 32 + [Double] 33 39 +L9 + [init] 5 9 + [(] 9 10 + [temperature] 10 21 + [:] 21 22 + [Double] 23 29 + [)] 29 30 + [{] 31 32 +L10 + [self] 9 13 + [.] 13 14 + [temperature] 14 25 + [=] 26 27 + [temperature] 28 39 +L11 + [}] 5 6 +L12 + [}] 1 2 +L14 + [let] 1 4 + [weather] 5 12 + [=] 13 14 + [Weather] 15 22 + [(] 22 23 + [temperature] 23 34 + [:] 34 35 + [20] 36 38 + [)] 38 39 +L15 + [let] 1 4 + [cancellable] 5 16 + [=] 17 18 + [weather] 19 26 + [.] 26 27 + [$] 27 28 + [temperature] 28 39 +L16 + [.] 5 6 + [sink] 6 10 + [(] 10 11 + [)] 11 12 + [{] 13 14 +L17 + [print] 9 14 + [(] 15 16 + ["Temperature now: \\($0)"] 16 40 + [)] 40 41 +L18 + [}] 1 2 +L19 + [weather] 1 8 + [.] 8 9 + [temperature] 9 20 + [=] 21 22 + [25] 23 25 +L26 + [func] 1 5 + [makeMeACollection] 6 23 + [(] 23 24 + [)] 24 25 + [->] 26 28 + [some] 29 33 + [Collection] 34 44 + [{] 45 46 +L27 + [return] 3 9 + [\[] 10 11 + [1] 11 12 + [,] 12 13 + [2] 14 15 + [,] 15 16 + [3] 17 18 + [\]] 18 19 +L28 + [}] 1 2 +L31 + [@] 1 2 + [dynamicMemberLookup] 2 21 +L32 + [struct] 1 7 + [Lens] 8 12 + [<] 12 13 + [T] 13 14 + [>] 14 15 + [{] 16 17 +L33 + [let] 3 6 + [getter:] 7 14 + [(] 15 16 + [)] 16 17 + [->] 18 20 + [T] 21 22 +L34 + [let] 3 6 + [setter:] 7 14 + [(] 15 16 + [T] 16 17 + [)] 17 18 + [->] 19 21 + [Void] 22 26 +L36 + [var] 3 6 + [value] 7 12 + [:] 12 13 + [T] 14 15 + [{] 16 17 +L37 + [get] 5 8 + [{] 9 10 +L38 + [return] 7 13 + [getter] 14 20 + [(] 20 21 + [)] 21 22 +L39 + [}] 5 6 +L40 + [set] 5 8 + [{] 9 10 +L41 + [setter] 7 13 + [(] 13 14 + [newValue] 14 22 + [)] 22 23 +L42 + [}] 5 6 +L43 + [}] 3 4 +L45 + [subscript] 3 12 + [<] 12 13 + [U] 13 14 + [>] 14 15 + [(] 15 16 + [dynamicMember] 16 29 + [keyPath] 30 37 + [:] 37 38 + [WritableKeyPath] 39 54 + [<] 54 55 + [T] 55 56 + [,] 56 57 + [U] 58 59 + [>] 59 60 + [)] 60 61 + [->] 62 64 + [Lens] 65 69 + [<] 69 70 + [U] 70 71 + [>] 71 72 + [{] 73 74 +L46 + [return] 5 11 + [Lens] 12 16 + [<] 16 17 + [U] 17 18 + [>] 18 19 + [(] 19 20 +L47 + [getter:] 9 16 + [{] 17 18 + [self] 19 23 + [.] 23 24 + [value] 24 29 + [\[] 29 30 + [keyPath] 30 37 + [:] 37 38 + [keyPath] 39 46 + [\]] 46 47 + [}] 48 49 + [,] 49 50 +L48 + [setter:] 9 16 + [{] 17 18 + [self] 19 23 + [.] 23 24 + [value] 24 29 + [\[] 29 30 + [keyPath] 30 37 + [:] 37 38 + [keyPath] 39 46 + [\]] 46 47 + [=] 48 49 + [$0] 50 52 + [}] 53 54 + [)] 54 55 +L49 + [}] 3 4 +L50 + [}] 1 2 +L53 + [struct] 1 7 + [Dog] 8 11 + [{] 12 13 +L54 + [var] 3 6 + [name] 7 11 + [=] 12 13 + ["Generic dog name"] 14 32 +L55 + [var] 3 6 + [age] 7 10 + [=] 11 12 + [0] 13 14 +L58 + [init] 3 7 + [(] 7 8 + [name] 8 12 + [:] 12 13 + [String] 14 20 + [=] 21 22 + ["Generic dog name"] 23 41 + [,] 41 42 + [age] 43 46 + [:] 46 47 + [Int] 48 51 + [=] 52 53 + [0] 54 55 + [)] 55 56 + [{] 57 58 + [}] 58 59 +L59 + [}] 1 2 +L61 + [let] 1 4 + [sparky] 5 11 + [=] 12 13 + [Dog] 14 17 + [(] 17 18 + [name] 18 22 + [:] 22 23 + ["Sparky"] 24 32 + [)] 32 33 +L65 + [enum] 1 5 + [Foo] 6 9 + [{] 10 11 + [case] 12 16 + [zero] 17 21 + [,] 21 22 + [one] 23 26 + [}] 27 28 +L67 + [let] 1 4 + [foo] 5 8 + [:] 8 9 + [Foo] 10 13 + [?] 13 14 + [=] 15 16 + [.] 17 18 + [zero] 18 22 +L69 + [switch] 1 7 + [foo] 8 11 + [{] 12 13 +L70 + [case] 3 7 + [.] 8 9 + [zero] 9 13 + [:] 13 14 + [break] 15 20 +L71 + [case] 3 7 + [.] 8 9 + [one] 9 12 + [:] 12 13 + [break] 14 19 +L72 + [case] 3 7 + [.] 8 9 + [none] 9 13 + [:] 13 14 + [break] 15 20 +L73 + [}] 1 2 +EOF diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/Swift5.2.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.2.swift similarity index 100% rename from pmd-swift/src/test/resources/net/sourceforge/pmd/cpd/Swift5.2.swift rename to pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.2.swift diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.2.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.2.txt new file mode 100644 index 0000000000..2fbbe70f9b --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Swift5.2.txt @@ -0,0 +1,111 @@ + [Image] or [Truncated image[ Bcol Ecol +L4 + [struct] 1 7 + [Adder] 8 13 + [{] 14 15 +L5 + [var] 3 6 + [base] 7 11 + [:] 11 12 + [Int] 13 16 +L6 + [func] 3 7 + [callAsFunction] 8 22 + [(] 22 23 + [_] 23 24 + [x] 25 26 + [:] 26 27 + [Int] 28 31 + [)] 31 32 + [->] 33 35 + [Int] 36 39 + [{] 40 41 +L7 + [return] 5 11 + [x] 12 13 + [+] 14 15 + [base] 16 20 +L8 + [}] 3 4 +L9 + [}] 1 2 +L10 + [var] 1 4 + [adder] 5 10 + [=] 11 12 + [Adder] 13 18 + [(] 18 19 + [base] 19 23 + [:] 23 24 + [3] 25 26 + [)] 26 27 +L11 + [adder] 1 6 + [(] 6 7 + [10] 7 9 + [)] 9 10 +L14 + [struct] 1 7 + [User] 8 12 + [{] 13 14 +L15 + [let] 3 6 + [email] 7 12 + [:] 12 13 + [String] 14 20 +L16 + [let] 3 6 + [isAdmin] 7 14 + [:] 14 15 + [Bool] 16 20 +L17 + [}] 1 2 +L19 + [users] 1 6 + [.] 6 7 + [map] 7 10 + [(] 10 11 + [\\] 11 12 + [.] 12 13 + [email] 13 18 + [)] 18 19 +L22 + [struct] 1 7 + [Subscriptable] 8 21 + [{] 22 23 +L23 + [subscript] 3 12 + [(] 12 13 + [x] 13 14 + [:] 14 15 + [Int] 16 19 + [,] 19 20 + [y] 21 22 + [:] 22 23 + [Int] 24 27 + [=] 28 29 + [0] 30 31 + [)] 31 32 + [{] 33 34 +L24 + [...] 5 8 +L25 + [}] 3 4 +L26 + [}] 1 2 +L28 + [let] 1 4 + [s] 5 6 + [=] 7 8 + [Subscriptable] 9 22 + [(] 22 23 + [)] 23 24 +L29 + [print] 1 6 + [(] 6 7 + [s] 7 8 + [\[] 8 9 + [0] 9 10 + [\]] 10 11 + [)] 11 12 +EOF diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/bestpractices/xml/ProhibitedInterfaceBuilder.xml b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/bestpractices/xml/ProhibitedInterfaceBuilder.xml index 9db71d5e35..4ddba3dc92 100644 --- a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/bestpractices/xml/ProhibitedInterfaceBuilder.xml +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/bestpractices/xml/ProhibitedInterfaceBuilder.xml @@ -1,46 +1,44 @@ - - - - Good example #1 - 0 - + + Good example #1 + 0 + - + - - Good example #2 - 0 - + Good example #2 + 0 + - + - - Bad example #1 - 1 - + Bad example #1 + 1 + - + - - Bad example #2 - 1 - + Bad example #2 + 1 + - + diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/bestpractices/xml/UnavailableFunction.xml b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/bestpractices/xml/UnavailableFunction.xml index 5f27aea528..3cf29dfe48 100644 --- a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/bestpractices/xml/UnavailableFunction.xml +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/bestpractices/xml/UnavailableFunction.xml @@ -14,9 +14,8 @@ class ViewController: UIViewController { fatalError("init(coder:) has not been implemented") } } - ]]> - - + ]]> + Good example #2 0 @@ -31,9 +30,8 @@ func jsonValue(_ jsonString: String) -> NSObject { } fatalError() } - ]]> - - + ]]> + Bad example #1 1 @@ -43,9 +41,8 @@ class ViewController: UIViewController { fatalError("init(coder:) has not been implemented") } } - ]]> - - + ]]> + Bad example #2 1 @@ -53,6 +50,6 @@ class ViewController: UIViewController { func doSomething() { fatalError("doSomething() has not been implemented") } - ]]> - + ]]> + diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/errorprone/xml/ForceTry.xml b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/errorprone/xml/ForceTry.xml index 1c9ff664ba..30e74b37a7 100644 --- a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/errorprone/xml/ForceTry.xml +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/errorprone/xml/ForceTry.xml @@ -1,26 +1,24 @@ - - - - Good example #1 - 0 - + + Good example #1 + 0 + - + ]]> + - - Bad example #1 - 1 - + Bad example #1 + 1 + - + diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/testframework/AbstractTokenizerTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/testframework/AbstractTokenizerTest.java index d5046a6469..ba9f3d3ab5 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/testframework/AbstractTokenizerTest.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/testframework/AbstractTokenizerTest.java @@ -17,7 +17,9 @@ import net.sourceforge.pmd.cpd.Tokens; /** * @author Romain PELISSE, belaran@gmail.com * + * @deprecated Use CpdTextComparisonTest in module pmd-lang-test */ +@Deprecated public abstract class AbstractTokenizerTest { protected int expectedTokenCount; diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/xml/cpd/XmlCPDTokenizerTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/xml/cpd/XmlCPDTokenizerTest.java index 6c31bc1aac..341419b374 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/xml/cpd/XmlCPDTokenizerTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/xml/cpd/XmlCPDTokenizerTest.java @@ -4,35 +4,26 @@ package net.sourceforge.pmd.xml.cpd; -import java.io.IOException; -import java.nio.charset.StandardCharsets; +import java.util.Properties; -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; -import net.sourceforge.pmd.cpd.SourceCode; -import net.sourceforge.pmd.testframework.AbstractTokenizerTest; +import net.sourceforge.pmd.cpd.Tokenizer; +import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest; -public class XmlCPDTokenizerTest extends AbstractTokenizerTest { +public class XmlCPDTokenizerTest extends CpdTextComparisonTest { - private static final String FILENAME = "hello.xml"; - - @Before - @Override - public void buildTokenizer() throws IOException { - this.tokenizer = new XmlTokenizer(); - this.sourceCode = new SourceCode(new SourceCode.StringCodeLoader(this.getSampleCode(), FILENAME)); + public XmlCPDTokenizerTest() { + super(".xml"); } @Override - public String getSampleCode() throws IOException { - return IOUtils.toString(XmlTokenizer.class.getResourceAsStream(FILENAME), StandardCharsets.UTF_8); + public Tokenizer newTokenizer(Properties properties) { + return new XmlTokenizer(); } @Test - public void tokenizeTest() throws IOException { - this.expectedTokenCount = 37; - super.tokenizeTest(); + public void tokenizeTest() { + doTest("simple"); } } diff --git a/pmd-xml/src/test/resources/net/sourceforge/pmd/xml/cpd/testdata/simple.txt b/pmd-xml/src/test/resources/net/sourceforge/pmd/xml/cpd/testdata/simple.txt new file mode 100644 index 0000000000..fde92a6615 --- /dev/null +++ b/pmd-xml/src/test/resources/net/sourceforge/pmd/xml/cpd/testdata/simple.txt @@ -0,0 +1,43 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [] 37 39 + [\n] 39 40 +L2 + [<] 1 2 + [someTag] 2 9 + [>] 9 10 + [\n\t] 10 2 +L3 + [<] 2 3 + [someOtherTag] 3 15 + [>] 15 16 + [Somehow we would like to improve t[ 16 126 + [<] 126 127 + [/] 127 128 + [someOtherTag] 128 140 + [>] 140 141 + [\n\t] 141 2 +L4 + [<] 2 3 + [someOtherTag] 3 15 + [>] 15 16 + [Somehow we would like to improve t[ 16 126 + [<] 126 127 + [/] 127 128 + [someOtherTag] 128 140 + [>] 140 141 + [\n] 141 142 +L5 + [<] 1 2 + [/] 2 3 + [someTag] 3 10 + [>] 10 11 + [\n] 11 12 +EOF diff --git a/pmd-xml/src/test/resources/net/sourceforge/pmd/xml/cpd/hello.xml b/pmd-xml/src/test/resources/net/sourceforge/pmd/xml/cpd/testdata/simple.xml similarity index 100% rename from pmd-xml/src/test/resources/net/sourceforge/pmd/xml/cpd/hello.xml rename to pmd-xml/src/test/resources/net/sourceforge/pmd/xml/cpd/testdata/simple.xml diff --git a/pom.xml b/pom.xml index 01e6c6604f..ec1fa757c0 100644 --- a/pom.xml +++ b/pom.xml @@ -110,6 +110,9 @@ ${settings.localRepository}/net/java/dev/javacc/javacc/${javacc.version}/javacc-${javacc.version}.jar ${project.build.directory}/generated-sources/javacc ${project.basedir}/../javacc-wrapper.xml + + ${project.build.directory}/generated-sources/antlr4 + ${project.basedir}/../antlr4-wrapper.xml @@ -121,6 +124,8 @@ ${antlr.version} ${project.build.sourceEncoding} + true + true