Showing preview only (1,307K chars total). Download the full file or copy to clipboard to get everything.
Repository: XenoAmess/p3c
Branch: xenoamess_maintain_fork
Commit: 79916bfd55a6
Files: 317
Total size: 1.1 MB
Directory structure:
gitextract_gvecwtd9/
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── ------.md
│ │ ├── bug_report.md
│ │ ├── feature_request.md
│ │ └── rule-issue-template.md
│ ├── dependabot.yml
│ └── workflows/
│ ├── auto-merge.yml
│ └── build.yml
├── .gitignore
├── .mvn/
│ └── wrapper/
│ ├── MavenWrapperDownloader.java
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── AGENTS.md
├── README.md
├── build.cmd
├── deploy.cmd
├── idea-plugin/
│ ├── .gitignore
│ ├── README.md
│ ├── README_cn.md
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── p3c-common/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ ├── java/
│ │ │ └── icons/
│ │ │ └── P3cIcons.java
│ │ ├── kotlin/
│ │ │ └── com/
│ │ │ └── alibaba/
│ │ │ ├── p3c/
│ │ │ │ └── idea/
│ │ │ │ ├── action/
│ │ │ │ │ ├── AliInspectionAction.kt
│ │ │ │ │ ├── PmdGlobalInspectionContextImpl.kt
│ │ │ │ │ ├── SwitchLanguageAction.kt
│ │ │ │ │ └── ToggleProjectInspectionAction.kt
│ │ │ │ ├── activity/
│ │ │ │ │ └── CommonSettingsApplicationStartupActivity.kt
│ │ │ │ ├── compatible/
│ │ │ │ │ └── inspection/
│ │ │ │ │ ├── InspectionProfileService.kt
│ │ │ │ │ └── Inspections.kt
│ │ │ │ ├── component/
│ │ │ │ │ └── AliProjectComponent.kt
│ │ │ │ ├── config/
│ │ │ │ │ ├── P3cConfig.kt
│ │ │ │ │ ├── P3cConfigurable.kt
│ │ │ │ │ └── SmartFoxProjectConfig.kt
│ │ │ │ ├── ep/
│ │ │ │ │ ├── InspectionActionExtensionPoint.kt
│ │ │ │ │ └── package-info.java
│ │ │ │ ├── i18n/
│ │ │ │ │ └── P3cBundle.kt
│ │ │ │ ├── inspection/
│ │ │ │ │ ├── AliAccessToNonThreadSafeStaticFieldFromInstanceInspection.kt
│ │ │ │ │ ├── AliArrayNamingShouldHaveBracketInspection.kt
│ │ │ │ │ ├── AliBaseInspection.kt
│ │ │ │ │ ├── AliControlFlowStatementWithoutBracesInspection.kt
│ │ │ │ │ ├── AliEqualsAvoidNullInspection.kt
│ │ │ │ │ ├── AliLocalInspectionToolProvider.kt
│ │ │ │ │ ├── AliLongLiteralsEndingWithLowercaseLInspection.kt
│ │ │ │ │ ├── AliPmdInspection.kt
│ │ │ │ │ ├── AliPmdInspectionInvoker.kt
│ │ │ │ │ ├── AliWrapperTypeEqualityInspection.kt
│ │ │ │ │ ├── DelegateLocalInspectionTool.kt
│ │ │ │ │ ├── DelegatePmdInspection.kt
│ │ │ │ │ ├── PmdRuleInspectionIdentify.kt
│ │ │ │ │ ├── RuleInspectionUtils.kt
│ │ │ │ │ └── standalone/
│ │ │ │ │ ├── AliAccessStaticViaInstanceInspection.kt
│ │ │ │ │ ├── AliDeprecationInspection.kt
│ │ │ │ │ ├── AliMissingOverrideAnnotationInspection.kt
│ │ │ │ │ └── MapOrSetKeyShouldOverrideHashCodeEqualsInspection.kt
│ │ │ │ ├── lifecycle/
│ │ │ │ │ └── P3cPluginLifecycle.kt
│ │ │ │ ├── pmd/
│ │ │ │ │ ├── AliPmdProcessor.kt
│ │ │ │ │ ├── SourceCodeProcessor.kt
│ │ │ │ │ └── index/
│ │ │ │ │ ├── InspectionDataSource.kt
│ │ │ │ │ └── InspectionRenderer.kt
│ │ │ │ ├── quickfix/
│ │ │ │ │ ├── AliQuickFix.kt
│ │ │ │ │ ├── AvoidStartWithDollarAndUnderLineNamingQuickFix.kt
│ │ │ │ │ ├── ClassMustHaveAuthorQuickFix.kt
│ │ │ │ │ ├── ConstantFieldShouldBeUpperCaseQuickFix.kt
│ │ │ │ │ ├── DecorateInspectionFix.kt
│ │ │ │ │ ├── LowerCamelCaseVariableNamingQuickFix.kt
│ │ │ │ │ └── VmQuietReferenceQuickFix.kt
│ │ │ │ ├── util/
│ │ │ │ │ ├── DocumentUtils.kt
│ │ │ │ │ ├── HighlightDisplayLevels.kt
│ │ │ │ │ ├── HighlightInfoTypes.kt
│ │ │ │ │ ├── HighlightSeverities.kt
│ │ │ │ │ ├── NumberConstants.kt
│ │ │ │ │ ├── ObjectConstants.kt
│ │ │ │ │ ├── ProblemsUtils.kt
│ │ │ │ │ ├── QuickFixes.kt
│ │ │ │ │ └── withLockNotInline.kt
│ │ │ │ └── vcs/
│ │ │ │ ├── AliCodeAnalysisCheckinHandler.kt
│ │ │ │ └── AliCodeAnalysisCheckinHandlerFactory.kt
│ │ │ └── smartfox/
│ │ │ └── idea/
│ │ │ └── common/
│ │ │ ├── activity/
│ │ │ │ └── AliBaseApplicationStartupActivity.kt
│ │ │ ├── component/
│ │ │ │ └── AliBaseProjectComponent.kt
│ │ │ └── util/
│ │ │ ├── BalloonNotifications.kt
│ │ │ ├── CommonExtensions.kt
│ │ │ └── PluginVersions.kt
│ │ └── resources/
│ │ ├── messages/
│ │ │ ├── P3cBundle.xml
│ │ │ └── P3cBundle_en.xml
│ │ ├── rulesets/
│ │ │ └── java/
│ │ │ └── ali-pmd.xml
│ │ └── tpl/
│ │ └── StaticDescriptionTemplate.ftl
│ ├── p3c-idea/
│ │ ├── build.gradle
│ │ └── src/
│ │ └── main/
│ │ └── resources/
│ │ └── META-INF/
│ │ ├── plugin.xml
│ │ └── pluginWithJava.xml
│ └── settings.gradle
├── license.txt
├── mvnw
├── mvnw.cmd
├── p3c-formatter/
│ ├── eclipse-codestyle.xml
│ └── eclipse-codetemplate.xml
├── p3c-gitbook/
│ ├── .gitignore
│ ├── MySQL数据库/
│ │ ├── ORM映射.md
│ │ ├── SQL语句.md
│ │ ├── 建表规约.md
│ │ └── 索引规约.md
│ ├── README.md
│ ├── SUMMARY.md
│ ├── book.json
│ ├── styles/
│ │ └── website.css
│ ├── 单元测试.md
│ ├── 安全规约.md
│ ├── 工程结构/
│ │ ├── 二方库依赖.md
│ │ ├── 应用分层.md
│ │ └── 服务器.md
│ ├── 异常日志/
│ │ ├── 其他.md
│ │ ├── 异常处理.md
│ │ └── 日志规约.md
│ ├── 本手册专有名词.md
│ ├── 版本历史.md
│ ├── 维护手册.md
│ └── 编程规约/
│ ├── OOP规范.md
│ ├── 代码格式.md
│ ├── 命名风格.md
│ ├── 常量定义.md
│ ├── 并发处理.md
│ ├── 控制语句.md
│ ├── 注释规约.md
│ └── 集合处理.md
├── p3c-pmd/
│ ├── .gitignore
│ ├── .mvn/
│ │ └── wrapper/
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
│ ├── README.md
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── xenoamess/
│ │ │ └── p3c/
│ │ │ └── pmd/
│ │ │ ├── I18nResources.java
│ │ │ ├── config/
│ │ │ │ └── P3cConfigDataBean.java
│ │ │ ├── fix/
│ │ │ │ └── FixClassTypeResolver.java
│ │ │ └── lang/
│ │ │ ├── AbstractAliXpathRule.java
│ │ │ ├── java/
│ │ │ │ ├── rule/
│ │ │ │ │ ├── AbstractAliRule.java
│ │ │ │ │ ├── AbstractPojoRule.java
│ │ │ │ │ ├── comment/
│ │ │ │ │ │ ├── AbstractAliCommentRule.java
│ │ │ │ │ │ ├── AbstractMethodOrInterfaceMethodMustUseJavadocRule.java
│ │ │ │ │ │ ├── AvoidCommentBehindStatementRule.java
│ │ │ │ │ │ ├── ClassMustHaveAuthorRule.java
│ │ │ │ │ │ ├── CommentsMustBeJavadocFormatRule.java
│ │ │ │ │ │ ├── EnumConstantsMustHaveCommentRule.java
│ │ │ │ │ │ └── RemoveCommentedCodeRule.java
│ │ │ │ │ ├── concurrent/
│ │ │ │ │ │ ├── AvoidCallStaticSimpleDateFormatRule.java
│ │ │ │ │ │ ├── AvoidConcurrentCompetitionRandomRule.java
│ │ │ │ │ │ ├── AvoidManuallyCreateThreadRule.java
│ │ │ │ │ │ ├── AvoidUseTimerRule.java
│ │ │ │ │ │ ├── CountDownShouldInFinallyRule.java
│ │ │ │ │ │ ├── ThreadLocalShouldRemoveRule.java
│ │ │ │ │ │ ├── ThreadPoolCreationRule.java
│ │ │ │ │ │ └── ThreadShouldSetNameRule.java
│ │ │ │ │ ├── constant/
│ │ │ │ │ │ ├── UndefineMagicConstantRule.java
│ │ │ │ │ │ └── UpperEllRule.java
│ │ │ │ │ ├── exception/
│ │ │ │ │ │ ├── AvoidReturnInFinallyRule.java
│ │ │ │ │ │ ├── MethodReturnWrapperTypeRule.java
│ │ │ │ │ │ └── TransactionMustHaveRollbackRule.java
│ │ │ │ │ ├── flowcontrol/
│ │ │ │ │ │ ├── AvoidComplexConditionRule.java
│ │ │ │ │ │ ├── AvoidNegationOperatorRule.java
│ │ │ │ │ │ ├── NeedBraceRule.java
│ │ │ │ │ │ ├── SwitchExpressionRule.java
│ │ │ │ │ │ └── SwitchStatementRule.java
│ │ │ │ │ ├── naming/
│ │ │ │ │ │ ├── AbstractClassShouldStartWithAbstractNamingRule.java
│ │ │ │ │ │ ├── ArrayNamingShouldHaveBracketRule.java
│ │ │ │ │ │ ├── AvoidStartWithDollarAndUnderLineNamingRule.java
│ │ │ │ │ │ ├── BooleanPropertyShouldNotStartWithIsRule.java
│ │ │ │ │ │ ├── ClassNamingShouldBeCamelRule.java
│ │ │ │ │ │ ├── ConstantFieldShouldBeUpperCaseRule.java
│ │ │ │ │ │ ├── ExceptionClassShouldEndWithExceptionRule.java
│ │ │ │ │ │ ├── LowerCamelCaseVariableNamingRule.java
│ │ │ │ │ │ ├── PackageNamingRule.java
│ │ │ │ │ │ ├── ServiceOrDaoClassShouldEndWithImplRule.java
│ │ │ │ │ │ └── TestClassShouldEndWithTestNamingRule.java
│ │ │ │ │ ├── oop/
│ │ │ │ │ │ ├── BigDecimalAvoidDoubleConstructorRule.java
│ │ │ │ │ │ ├── EqualsAvoidNullRule.java
│ │ │ │ │ │ ├── PojoMustOverrideToStringRule.java
│ │ │ │ │ │ ├── PojoMustUsePrimitiveFieldRule.java
│ │ │ │ │ │ ├── PojoNoDefaultValueRule.java
│ │ │ │ │ │ ├── StringConcatRule.java
│ │ │ │ │ │ └── WrapperTypeEqualityRule.java
│ │ │ │ │ ├── orm/
│ │ │ │ │ │ └── IbatisMethodQueryForListRule.java
│ │ │ │ │ ├── other/
│ │ │ │ │ │ ├── AvoidApacheBeanUtilsCopyRule.java
│ │ │ │ │ │ ├── AvoidDoubleOrFloatEqualCompareRule.java
│ │ │ │ │ │ ├── AvoidMissUseOfMathRandomRule.java
│ │ │ │ │ │ ├── AvoidNewDateGetTimeRule.java
│ │ │ │ │ │ ├── AvoidPatternCompileInMethodRule.java
│ │ │ │ │ │ ├── MethodTooLongRule.java
│ │ │ │ │ │ └── UseRightCaseForDateFormatRule.java
│ │ │ │ │ ├── set/
│ │ │ │ │ │ ├── ClassCastExceptionWithSubListToArrayListRule.java
│ │ │ │ │ │ ├── ClassCastExceptionWithToArrayRule.java
│ │ │ │ │ │ ├── CollectionInitShouldAssignCapacityRule.java
│ │ │ │ │ │ ├── ConcurrentExceptionWithModifyOriginSubListRule.java
│ │ │ │ │ │ ├── DontModifyInForeachCircleRule.java
│ │ │ │ │ │ └── UnsupportedExceptionWithModifyAsListRule.java
│ │ │ │ │ ├── util/
│ │ │ │ │ │ ├── NodeSortUtils.java
│ │ │ │ │ │ └── NodeUtils.java
│ │ │ │ │ └── xenoamess/
│ │ │ │ │ ├── additional/
│ │ │ │ │ │ ├── EqualsHashCodeRule.java
│ │ │ │ │ │ └── SneakyThrowsWithoutExceptionTypeRule.java
│ │ │ │ │ └── deprecated/
│ │ │ │ │ └── VarargsParameterRule.java
│ │ │ │ └── util/
│ │ │ │ ├── GeneratedCodeUtils.java
│ │ │ │ ├── NumberConstants.java
│ │ │ │ ├── PojoUtils.java
│ │ │ │ ├── SpiLoader.java
│ │ │ │ ├── StringAndCharConstants.java
│ │ │ │ ├── VariableUtils.java
│ │ │ │ ├── ViolationUtils.java
│ │ │ │ └── namelist/
│ │ │ │ ├── NameListConfig.java
│ │ │ │ ├── NameListService.java
│ │ │ │ └── NameListServiceImpl.java
│ │ │ └── vm/
│ │ │ └── rule/
│ │ │ └── other/
│ │ │ └── UseQuietReferenceNotationRule.java
│ │ ├── kotlin/
│ │ │ └── com/
│ │ │ └── xenoamess/
│ │ │ └── p3c/
│ │ │ └── pmd/
│ │ │ └── lang/
│ │ │ └── java/
│ │ │ └── rule/
│ │ │ └── concurrent/
│ │ │ └── LockShouldWithTryFinallyRule.kt
│ │ └── resources/
│ │ ├── META-INF/
│ │ │ └── services/
│ │ │ └── com.xenoamess.p3c.pmd.lang.java.util.namelist.NameListService
│ │ ├── messages.xml
│ │ ├── messages_en.xml
│ │ ├── p3c_config.default.x8l
│ │ └── rulesets/
│ │ ├── java/
│ │ │ ├── ali-comment.xml
│ │ │ ├── ali-concurrent.xml
│ │ │ ├── ali-constant.xml
│ │ │ ├── ali-exception.xml
│ │ │ ├── ali-flowcontrol.xml
│ │ │ ├── ali-naming.xml
│ │ │ ├── ali-oop.xml
│ │ │ ├── ali-orm.xml
│ │ │ ├── ali-other.xml
│ │ │ ├── ali-set.xml
│ │ │ ├── xenoamess-additional.xml
│ │ │ └── xenoamess-deprecated.xml
│ │ └── vm/
│ │ └── ali-other.xml
│ ├── site/
│ │ └── resources/
│ │ └── checkstyle/
│ │ ├── checkstyle-suppressions.xml
│ │ └── checkstyle.xml
│ └── test/
│ ├── java/
│ │ └── com/
│ │ └── xenoamess/
│ │ └── p3c/
│ │ └── pmd/
│ │ ├── IfVoidIsPrimitiveTest.java
│ │ ├── config/
│ │ │ └── TestConfig.java
│ │ ├── lang/
│ │ │ ├── java/
│ │ │ │ └── rule/
│ │ │ │ ├── comment/
│ │ │ │ │ └── CommentRulesTest.java
│ │ │ │ ├── concurrent/
│ │ │ │ │ └── ConcurrentRuleTest.java
│ │ │ │ ├── constant/
│ │ │ │ │ └── ConstantRulesTest.java
│ │ │ │ ├── exception/
│ │ │ │ │ └── ExceptionRulesTest.java
│ │ │ │ ├── flowcontrol/
│ │ │ │ │ └── FlowControlRuleTest.java
│ │ │ │ ├── naming/
│ │ │ │ │ └── NamingRulesTest.java
│ │ │ │ ├── oop/
│ │ │ │ │ └── OopRuleTest.java
│ │ │ │ ├── orm/
│ │ │ │ │ └── OrmRulesTest.java
│ │ │ │ ├── other/
│ │ │ │ │ ├── OtherRulesTest.java
│ │ │ │ │ └── UseRightCaseForDateFormatRuleTest.java
│ │ │ │ ├── set/
│ │ │ │ │ └── SetRulesTest.java
│ │ │ │ └── xenoamess/
│ │ │ │ ├── additional/
│ │ │ │ │ └── XenoAmessAdditionalTest.java
│ │ │ │ └── deprecated/
│ │ │ │ └── XenoAmessDeprecatedTest.java
│ │ │ └── vm/
│ │ │ └── rule/
│ │ │ └── other/
│ │ │ └── OtherRulesTest.java
│ │ └── testframework/
│ │ ├── ExtendRuleTst.java
│ │ └── ExtendSimpleAggregatorTst.java
│ └── resources/
│ └── com/
│ └── xenoamess/
│ └── p3c/
│ └── pmd/
│ └── lang/
│ ├── java/
│ │ └── rule/
│ │ ├── comment/
│ │ │ └── xml/
│ │ │ ├── AbstractMethodOrInterfaceMethodMustUseJavadocRule.xml
│ │ │ ├── AvoidCommentBehindStatementRule.xml
│ │ │ ├── ClassMustHaveAuthorRule.xml
│ │ │ ├── CommentsMustBeJavadocFormatRule.xml
│ │ │ ├── EnumConstantsMustHaveCommentRule.xml
│ │ │ └── RemoveCommentedCodeRule.xml
│ │ ├── concurrent/
│ │ │ └── xml/
│ │ │ ├── AvoidCallStaticSimpleDateFormatRule.xml
│ │ │ ├── AvoidConcurrentCompetitionRandomRule.xml
│ │ │ ├── AvoidManuallyCreateThreadRule.xml
│ │ │ ├── AvoidUseTimerRule.xml
│ │ │ ├── CountDownShouldInFinallyRule.xml
│ │ │ ├── LockShouldWithTryFinallyRule.xml
│ │ │ ├── ThreadLocalShouldRemoveRule.xml
│ │ │ ├── ThreadPoolCreationRule.xml
│ │ │ └── ThreadShouldSetNameRule.xml
│ │ ├── constant/
│ │ │ └── xml/
│ │ │ ├── UndefineMagicConstantRule.xml
│ │ │ └── UpperEllRule.xml
│ │ ├── exception/
│ │ │ └── xml/
│ │ │ ├── AvoidReturnInFinallyRule.xml
│ │ │ ├── MethodReturnWrapperTypeRule.xml
│ │ │ └── TransactionMustHaveRollbackRule.xml
│ │ ├── flowcontrol/
│ │ │ └── xml/
│ │ │ ├── AvoidComplexConditionRule.xml
│ │ │ ├── AvoidNegationOperatorRule.xml
│ │ │ ├── NeedBraceRule.xml
│ │ │ ├── SwitchExpressionRule.xml
│ │ │ └── SwitchStatementRule.xml
│ │ ├── naming/
│ │ │ └── xml/
│ │ │ ├── AbstractClassShouldStartWithAbstractNamingRule.xml
│ │ │ ├── ArrayNamingShouldHaveBracketRule.xml
│ │ │ ├── AvoidStartWithDollarAndUnderLineNamingRule.xml
│ │ │ ├── BooleanPropertyShouldNotStartWithIsRule.xml
│ │ │ ├── ClassNamingShouldBeCamelRule.xml
│ │ │ ├── ConstantFieldShouldBeUpperCaseRule.xml
│ │ │ ├── ExceptionClassShouldEndWithExceptionRule.xml
│ │ │ ├── LowerCamelCaseVariableNamingRule.xml
│ │ │ ├── PackageNamingRule.xml
│ │ │ ├── ServiceOrDaoClassShouldEndWithImplRule.xml
│ │ │ └── TestClassShouldEndWithTestNamingRule.xml
│ │ ├── oop/
│ │ │ └── xml/
│ │ │ ├── BigDecimalAvoidDoubleConstructorRule.xml
│ │ │ ├── EqualsAvoidNullRule.xml
│ │ │ ├── PojoMustOverrideToStringRule.xml
│ │ │ ├── PojoMustUsePrimitiveFieldRule.xml
│ │ │ ├── PojoNoDefaultValueRule.xml
│ │ │ ├── StringConcatRule.xml
│ │ │ └── WrapperTypeEqualityRule.xml
│ │ ├── orm/
│ │ │ └── xml/
│ │ │ └── IbatisMethodQueryForListRule.xml
│ │ ├── other/
│ │ │ ├── java/
│ │ │ │ └── UseRightCaseForDateFormatRuleExam.java
│ │ │ └── xml/
│ │ │ ├── AvoidApacheBeanUtilsCopyRule.xml
│ │ │ ├── AvoidDoubleOrFloatEqualCompareRule.xml
│ │ │ ├── AvoidMissUseOfMathRandomRule.xml
│ │ │ ├── AvoidNewDateGetTimeRule.xml
│ │ │ ├── AvoidPatternCompileInMethodRule.xml
│ │ │ ├── MethodTooLongRule.xml
│ │ │ └── UseRightCaseForDateFormatRule.xml
│ │ ├── set/
│ │ │ └── xml/
│ │ │ ├── ClassCastExceptionWithSubListToArrayListRule.xml
│ │ │ ├── ClassCastExceptionWithToArrayRule.xml
│ │ │ ├── CollectionInitShouldAssignCapacityRule.xml
│ │ │ ├── ConcurrentExceptionWithModifyOriginSubListRule.xml
│ │ │ ├── DontModifyInForeachCircleRule.xml
│ │ │ └── UnsupportedExceptionWithModifyAsListRule.xml
│ │ └── xenoamess/
│ │ ├── additional/
│ │ │ └── xml/
│ │ │ ├── EqualsHashCodeRule.xml
│ │ │ └── SneakyThrowsWithoutExceptionTypeRule.xml
│ │ └── deprecated/
│ │ └── xml/
│ │ └── VarargsParameterRule.xml
│ └── vm/
│ └── rule/
│ └── other/
│ └── xml/
│ └── UseQuietReferenceNotationRule.xml
├── p3c_config.x8l
└── sonar.cmd
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
* text=auto eol=lf
================================================
FILE: .github/ISSUE_TEMPLATE/------.md
================================================
---
name: 规约问题模板
about: 规约问题请使用该模板
title: ''
labels: ''
assignees: ''
---
## 规约原文
## 问题描述
## 修改建议
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/ISSUE_TEMPLATE/rule-issue-template.md
================================================
---
name: Rule issue template
about: Rule issue please use this template.
title: ''
labels: ''
assignees: ''
---
## Rule content
## Problem description
## Advice
================================================
FILE: .github/dependabot.yml
================================================
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
version: 2
updates:
- package-ecosystem: "maven"
directory: "/p3c-pmd/"
schedule:
interval: "daily"
target-branch: "xenoamess_maintain_fork"
open-pull-requests-limit: 100
- package-ecosystem: "gradle"
directory: "/idea-plugin/"
schedule:
interval: "daily"
target-branch: "xenoamess_maintain_fork"
open-pull-requests-limit: 100
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
target-branch: "xenoamess_maintain_fork"
open-pull-requests-limit: 100
================================================
FILE: .github/workflows/auto-merge.yml
================================================
name: Dependabot auto-merge
on:
pull_request:
permissions:
pull-requests: write
contents: write
jobs:
dependabot:
if: github.event.pull_request.user.login == 'dependabot[bot]'
runs-on: ubuntu-latest
steps:
- name: Dependabot metadata
id: meta
uses: dependabot/fetch-metadata@v2
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: Check if auto-merge applicable
id: check
run: |
if [[ "${{ steps.meta.outputs.update-type }}" == "version-update:semver-patch" ]] || \
[[ "${{ steps.meta.outputs.update-type }}" == "version-update:semver-minor" ]]; then
echo "should_merge=true" >> "$GITHUB_OUTPUT"
else
echo "should_merge=false" >> "$GITHUB_OUTPUT"
fi
- name: Approve dependabot PR
if: steps.check.outputs.should_merge == 'true'
run: gh pr review --approve "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Enable auto-merge (rebase)
if: steps.check.outputs.should_merge == 'true'
run: gh pr merge --auto --rebase "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/build.yml
================================================
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Java CI
on: [ push ]
jobs:
build:
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
strategy:
matrix:
os: [ windows-latest , ubuntu-latest , macos-latest ]
java: [ 21 ]
experimental: [ false ]
steps:
- uses: actions/checkout@v6
- uses: actions/cache@v5
with:
path: ~/.m2
key: ${{ runner.os }}-gradle-m2-${{ hashFiles('**/build.gradle') }}
restore-keys: |
${{ runner.os }}-gradle-
- uses: actions/cache@v5
with:
path: ~/.gradle/caches/
key: ${{ runner.os }}-gradle-caches-${{ hashFiles('**/build.gradle') }}
restore-keys: |
${{ runner.os }}-gradle-
- uses: actions/cache@v5
with:
path: ~/.gradle/wrapper/
key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/build.gradle') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v5
with:
java-version: ${{ matrix.java }}
distribution: adopt
- name: Build Build Build!
run: |
cd ./p3c-pmd
chmod 777 ./mvnw
./mvnw install -Penforce
cd ../
cd ./idea-plugin
chmod 777 ./gradlew
./gradlew buildPlugin -s
- name: Upload Plugin Artifact
uses: actions/upload-artifact@v7
with:
name: p3c-idea-plugin-${{ matrix.os }}-${{ matrix.java }}
path: idea-plugin/p3c-idea/build/distributions/*.zip
if-no-files-found: warn
================================================
FILE: .gitignore
================================================
# Gradle
build
.gradle
testdata/
# Java gitignore #
.class
.log
# Package Files #
*.war
*.ear
#hsf files
configuration
# maven gitignore#
target/**
.svn/
# intelliJ.gitignore #
.idea
*.iml
*.ipr
*.iws
# Eclipse git ignore#
*.pydevproject
.project
.metadata
bin/**
*/bin/**
tmp/**
tmp/**/*
configuration/**
*.tmp
*.bak
*.orig
*.swp
*~.nib
.classpath
.settings/
.loadpath
.fileTable*
.cache
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#log
*.log
*.log.*
# Windows Thumbs.db
*.db
# OSX
.DS_Store
# sass gitignore#
.sass-cache
# tcc_coverage
coverage.ec
config.client.*
temp/
*.pid
hsf.configuration/
# code coverage report
*.ec
#hsf test
*.instance
out
!/p3c-idea/src/main/kotlin/com/alibaba/smartfox/work/tools/aone/ui/AoneBranchView.kt
#versions-maven-plugin
*.versionsBackup
/idea-plugin/.intellijPlatform
================================================
FILE: .mvn/wrapper/MavenWrapperDownloader.java
================================================
/*
* Copyright 2007-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;
public class MavenWrapperDownloader {
private static final String WRAPPER_VERSION = "0.5.6";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}
================================================
FILE: .mvn/wrapper/maven-wrapper.properties
================================================
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
================================================
FILE: AGENTS.md
================================================
# P3C - Alibaba Java Coding Guidelines (XenoAmess TPM)
This is a Third-Party Maintenance (TPM) fork of the original [alibaba/p3c](https://github.com/alibaba/p3c) project, maintained by XenoAmess.
## Project Overview
P3C is a comprehensive Java coding guidelines implementation that provides:
1. **PMD Rule Implementations** (`p3c-pmd/`) - 54+ rules based on PMD for static code analysis
2. **IntelliJ IDEA Plugin** (`idea-plugin/`) - Real-time code inspection and analysis plugin
3. **Eclipse Plugin** (`eclipse-plugin/`) - Original Eclipse plugin (not actively maintained by TPM)
4. **Code Formatter Configs** (`p3c-formatter/`) - Eclipse code style templates
5. **GitBook Documentation** (`p3c-gitbook/`) - Chinese documentation for the coding guidelines
### Key Features of this TPM
- Always compatible with latest JetBrains IDEA releases/EAP versions
- Uses latest dependencies versions
- Blacklist/Whitelist configuration mechanism for rules/classes
- JSON configuration support (alternative to X8L format)
- Additional rules beyond original P3C rules
## Project Structure
```
p3c/
├── p3c-pmd/ # PMD rule implementations (Maven project)
│ ├── src/main/java/ # Java rule implementations
│ ├── src/main/resources/ # Ruleset XML files and messages
│ ├── src/test/java/ # Unit tests for rules
│ └── pom.xml # Maven configuration
├── idea-plugin/ # IntelliJ IDEA plugin (Gradle project)
│ ├── p3c-common/ # Common plugin code (Kotlin)
│ ├── p3c-idea/ # Plugin packaging and resources
│ ├── build.gradle # Root Gradle build script
│ └── settings.gradle # Gradle project settings
├── eclipse-plugin/ # Eclipse plugin (not actively maintained)
├── p3c-formatter/ # Eclipse code formatter templates
├── p3c-gitbook/ # Documentation in Chinese
├── p3c_config.x8l # Project configuration file (X8L format)
├── build.cmd # Windows build script
├── deploy.cmd # Windows deployment script
└── sonar.cmd # SonarQube analysis script
```
## Technology Stack
### p3c-pmd Module
- **Language**: Java 8
- **Build Tool**: Maven 3+
- **Core Dependencies**:
- PMD 6.55.0 (pmd-java, pmd-vm)
- Kotlin 2.3.10 (stdlib)
- X8L 2.3.9 (configuration format)
- Commons Lang3 3.20.0
- Commons IO 2.21.0
- Jackson 2.21.1
- **Testing**: JUnit 4.13.2
- **Code Quality**: Checkstyle 11.1.0, PMD Maven Plugin, JaCoCo
### idea-plugin Module
- **Language**: Kotlin (primary), Java
- **Build Tool**: Gradle with IntelliJ Platform Plugin
- **JDK Version**: Java 17 (for building)
- **Target IDEA Version**: 2024.1 (configurable via `gradle.properties`)
- **Core Dependencies**:
- Freemarker 2.3.33
- Javassist 3.30.2-GA
- p3c-pmd (local dependency)
## Build Instructions
### Prerequisites
- JDK 8+ (for p3c-pmd)
- JDK 17+ (for idea-plugin Gradle build)
- Maven 3.x
### Building p3c-pmd
```bash
cd p3c-pmd
./mvnw clean install -Dmaven.javadoc.skip=false
```
For deployment (requires GPG key):
```bash
./mvnw clean deploy -Dmaven.javadoc.skip=false -Psonatype-oss-release
```
### Building IDEA Plugin
```bash
cd idea-plugin
./gradlew clean buildPlugin
```
To run plugin in development IDE:
```bash
./gradlew runIde
```
To run with specific IDEA version:
```bash
./gradlew runIde -Pidea_version=2024.1
```
### Full Build (Windows)
Use the provided batch script:
```batch
build.cmd
```
### CI/CD
The project uses GitHub Actions (`.github/workflows/build.yml`):
- Builds on Windows, Ubuntu, and macOS
- Uses Java 17
- Builds both p3c-pmd and idea-plugin
- Uploads plugin artifacts
## Code Organization
### PMD Rules Structure
Rules are organized by category in `p3c-pmd/src/main/resources/rulesets/java/`:
| Ruleset File | Category |
|-------------|----------|
| `ali-comment.xml` | Code comments and Javadoc |
| `ali-concurrent.xml` | Concurrency and threading |
| `ali-constant.xml` | Constants conventions |
| `ali-exception.xml` | Exception handling |
| `ali-flowcontrol.xml` | Flow control statements |
| `ali-naming.xml` | Naming conventions |
| `ali-oop.xml` | Object-oriented programming |
| `ali-orm.xml` | ORM-related rules |
| `ali-other.xml` | Other miscellaneous rules |
| `ali-set.xml` | Collection usage |
| `xenoamess-additional.xml` | Additional TPM-specific rules |
| `xenoamess-deprecated.xml` | Deprecated rules |
Each rule implementation is located in `p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/` following the same category structure.
### Rule Base Classes
- `AbstractAliRule` - Base class for all Java rules with type resolution
- `AbstractAliXpathRule` - Base class for XPath-based rules
- `AbstractPojoRule` - Base class for POJO-related rules
- `AbstractAliCommentRule` - Base class for comment-related rules
### Internationalization
Message resources are in `p3c-pmd/src/main/resources/`:
- `messages.xml` - Chinese (default)
- `messages_en.xml` - English
## Configuration Mechanism
The project supports flexible configuration via `p3c_config.x8l` (or `p3c_config.json`) file.
### Configuration File Location
- For IDEA plugin: `$project_root/p3c_config.x8l`
- For Maven PMD: `$mvn_run_directory/p3c_config.x8l`
### Configuration Options
```xml
<com.alibaba.p3c.pmd.config version=0.0.1>
<!-- Rule-specific configurations -->
<rule_config>
<LowerCamelCaseVariableNamingRule>
<WHITE_LIST>DAOImpl&URL&URI>
>
>
<!-- Global rule blacklist -->
<rule_blacklist>
PackageNamingRule&SomeOtherRule>
>
<!-- Global class blacklist -->
<class_blacklist>
Console>
>
<!-- Global package blacklist -->
<package_blacklist>
com.example.legacy>
>
<!-- Rule-class pair blacklist -->
<rule_class_pair_blacklist>
<SomeClass [>SomeRule&AnotherRule>
>
>
```
### JSON Alternative
Configuration can also be done via JSON format (see `idea-plugin/README.md` for full example).
## Testing
### PMD Rule Tests
Tests are located in `p3c-pmd/src/test/java/` following the same package structure as main code.
Test resource files (XML format with test cases) are in:
`p3c-pmd/src/test/resources/com/xenoamess/p3c/pmd/lang/java/rule/<category>/xml/`
Run tests:
```bash
cd p3c-pmd
./mvnw test
```
### Test File Format
Test XML files contain test cases with code snippets and expected violations:
```xml
<test-code>
<description>test description</description>
<expected-problems>1</expected-problems>
<code>
<![CDATA[
// test code here
]]>
</code>
</test-code>
```
## Code Style Guidelines
### For Java Code
The project enforces code quality via Maven plugins:
1. **Checkstyle**: Configuration in `p3c-pmd/src/site/resources/checkstyle/checkstyle.xml`
2. **PMD**: Self-checking using its own rulesets during build
3. **Animal Sniffer**: Ensures Java 8 compatibility
4. **JaCoCo**: Code coverage reporting
Run with enforcement:
```bash
./mvnw clean install -Penforce
```
### For Kotlin Code
- Follow standard Kotlin conventions
- Use 4-space indentation
- UTF-8 encoding
## Version Information
- **Current Version**: 2.3.0
- **Group ID**: `com.xenoamess.p3c`
- **Artifact ID**: `p3c-pmd`
## Maven Dependency
```xml
<dependency>
<groupId>com.xenoamess.p3c</groupId>
<artifactId>p3c-pmd</artifactId>
<version>2.3.0</version>
</dependency>
```
## Security Considerations
1. The project uses Log4j 2.25.3 (addresses Log4Shell vulnerability)
2. All dependencies are regularly updated via dependabot
3. GPG signing is required for releases
## Contributing
- PRs should target `idea-plugin` and `p3c-pmd` modules
- Eclipse plugin PRs are not accepted (maintainer has no expertise)
- Ensure all tests pass before submitting PR
- Follow existing code style and conventions
## License
Apache License 2.0 (see `license.txt`)
## Additional Resources
- [Alibaba Java Coding Guidelines (Chinese PDF)](Java开发手册(嵩山版).pdf)
- [English Documentation](https://alibaba.github.io/Alibaba-Java-Coding-Guidelines)
- [JetBrains Plugin Page](https://plugins.jetbrains.com/plugin/14109-alibaba-java-coding-guidelines-xenoamess-tpm-)
================================================
FILE: README.md
================================================
# P3C
[](https://www.apache.org/licenses/LICENSE-2.0.html)
[](https://sonarcloud.io/dashboard?id=p3c-idea)
p3c-cmd
[](https://sonarcloud.io/dashboard?id=p3c-idea)
idea plugin(p3c-common)
## <font color="green">Notice 声明</font>
This Third-party maintenance(TPM) here is forked from original [alibaba/p3c](https://github.com/alibaba/p3c)
Follows Apache license described in [license](license.txt)
Sources can be found https://github.com/XenoAmess/p3c
Releases can be found at https://plugins.jetbrains.com/plugin/14109-alibaba-java-coding-guidelines-xenoamess-tpm-
This TPM aims to help maintain alibaba/p3c, fix bugs, and add improvements, as the original developer is too busy to handle them.
This TPM is NOT created, or maintained, or controlled by any alibaba employee, in other words it is a TPM, but not an official branch.
TPM maintainer XenoAmess have no knowledge with eclipse plugin development.
TPM maintainer XenoAmess suggest you only create pr for module idea-plugin and p3c-pmd, unless you really have a strong reason.
## <font color="green">Features 特性</font>
1. This TPM can always run on latest Jetbrains-idea release/EAP.
本第三方维护版会在任何 Jetbrains-idea release 或者EAP更新时保证可用。
2. This TPM will always use as latest dependencies as possible.
本第三方维护版会使用尽可能新的依赖版本。
3. This TPM implements a mechanism for configuring black-list/white-list for rules/classes
本第三方维护版实现有一套配置系统,可以对源码类/规则进行黑名单/白名单过滤。
4. This TPM does NOT fully obey p3c rules.
Especially for the rule who disable deprecated functions.
Maintainer XenoAmess will make sure they are usable,
but have no enough time to eliminate every deprecated functions.
本第三方维护版不完全遵循p3c,尤其是关于禁止使用deprecated函数的规则。
维护者XenoAmess会保证函数可用,但是没有充裕的时间保证消灭每一个deprecated函数。
## <font color="green">Preface 前言</font>
> We are pleased to present Alibaba Java Coding Guidelines which consolidates the best programming practices over the years from Alibaba Group's technical teams. A vast number of Java programming teams impose demanding requirements on code quality across projects as we encourage reuse and better understanding of each other's programs. We have seen many programming problems in the past. For example, defective database table structures and index designs may cause software architecture flaws and performance risks. Another example is confusing code structures being difficult to maintain. Furthermore, vulnerable code without authentication is prone to hackers’ attacks. To address these kinds of problems, we developed this document for Java developers at Alibaba.
For more information please refer the *Alibaba Java Coding Guidelines*:
- 中文版: *[阿里巴巴Java开发手册](https://github.com/alibaba/p3c/blob/master/Java%E5%BC%80%E5%8F%91%E6%89%8B%E5%86%8C%EF%BC%88%E5%B5%A9%E5%B1%B1%E7%89%88%EF%BC%89.pdf)*
- English Version: *[Alibaba Java Coding Guidelines](https://alibaba.github.io/Alibaba-Java-Coding-Guidelines)*
- 《阿里巴巴Java开发手册》书籍版天猫官方店: *[阿里巴巴Java开发手册最新版](https://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.1.4577601asIhzbW&id=628337143778&areaId=330100&user_id=1932014659&cat_id=2&is_b=1&rn=11a322ef70720cdf5e894001e4b48b55)*
- 《码出高效》书籍版天猫官方店: *[码出高效:Java开发手册](https://detail.tmall.com/item.htm?spm=a230r.1.14.40.7dee7d6bwpO82U&id=575107529181&ns=1&abbucket=20)*
## <font color="green">Introduction 介绍</font>
The project consists of 3 parts:
- [PMD implementations](p3c-pmd)
- [IntelliJ IDEA plugin](idea-plugin)
- [Eclipse plugin](eclipse-plugin)
## <font color="green">Rules 规则</font>
<font color="blue">Forty-nine rules are realized based on PMD, please refer the P3C-PMD documentation for more detailed information. Four rules are implemented within IDE plugins (IDEA and Eclipse) as follows:</font>
- ``[Mandatory]`` Using a deprecated class or method is prohibited.
Note: For example, decode(String source, String encode) should be used instead of the deprecated method decode(String encodeStr). Once an interface has been deprecated, the interface provider has the obligation to provide a new one. At the same time, client programmers have the obligation to check out what its new implementation is.
- ``[Mandatory]`` An overridden method from an interface or abstract class must be marked with @Override annotation.
Counter example: For getObject() and get0bject(), the first one has a letter 'O', and the second one has a number '0'. To accurately determine whether the overriding is successful, an @Override annotation is necessary. Meanwhile, once the method signature in the abstract class is changed, the implementation class will report a compile-time error immediately.
- ``[Mandatory]`` A static field or method should be directly referred by its class name instead of its corresponding object name.
- ``[Mandatory]`` The usage of hashCode and equals should follow:
1. Override hashCode if equals is overridden.
2. These two methods must be overridden for Set since they are used to ensure that no duplicate object will be inserted in Set.
3. These two methods must be overridden if self-defined object is used as the key of Map.
Note: String can be used as the key of Map since these two methods have been rewritten.
## <font color="green">Config Mechanism 配置机制</font>
see
[documents](idea-plugin/README.md)
[说明](idea-plugin/README_cn.md)
================================================
FILE: build.cmd
================================================
set JAVA_HOME=C:\jdk-21\
cd ./p3c-pmd
call ./mvnw clean install -Dmaven.javadoc.skip=false -e -X
cd ../
cd ./idea-plugin
set JAVA_HOME=C:\jdk-21\
cd ./p3c-common
call ../gradlew clean publishToMavenLocal
cd ../
cd ./p3c-idea
call ../gradlew clean publishToMavenLocal buildPlugin
cd ../
cd ../
================================================
FILE: deploy.cmd
================================================
set JAVA_HOME=C:\jdk-8\
cd ./p3c-pmd
call ./mvnw clean deploy -Dmaven.javadoc.skip=false -e -X -Psonatype-oss-release
cd ../
cd ./idea-plugin
set JAVA_HOME=C:\jdk-21\
cd ./p3c-common
rem call ../gradlew clean install sign uploadArchives -DossrhUsername="%ossrhUsername%" -DossrhPassword="%ossrhPassword%"
call ../gradlew publishToMavenLocal
cd ../
cd ./p3c-idea
call ../gradlew clean publishToMavenLocal buildPlugin
cd ../
cd ../
================================================
FILE: idea-plugin/.gitignore
================================================
# Gradle
build
.gradle
testdata/
# Java gitignore #
.class
.log
# Package Files #
*.war
*.ear
#hsf files
configuration
# maven gitignore#
target/**
.svn/
# intelliJ.gitignore #
.idea
*.iml
*.ipr
*.iws
# Eclipse git ignore#
*.pydevproject
.project
.metadata
bin/**
*/bin/**
tmp/**
tmp/**/*
configuration/**
*.tmp
*.bak
*.orig
*.swp
*~.nib
.classpath
.settings/
.loadpath
.fileTable*
.cache
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#log
*.log
*.log.*
# Windows Thumbs.db
*.db
# OSX
.DS_Store
# sass gitignore#
.sass-cache
# tcc_coverage
coverage.ec
config.client.*
temp/
*.pid
hsf.configuration/
# code coverage report
*.ec
#hsf test
*.instance
out
**/idea-sandbox
================================================
FILE: idea-plugin/README.md
================================================
# Idea Plugin
---
## <font color="green">Prepare</font>
- Project JDK: 11
- Gradle: 7.3(Require JDK17 for gradle)
## <font color="green">Build</font>
```
cd p3c-idea
../gradlew clean buildPlugin
```
## <font color="green">Run plugin</font>
```
cd p3c-idea
../gradlew runIde
# run specific IDEA
../gradlew runIde -Pidea_version=2018.3
```
## <font color="green">Use p3c-common as your plugin dependency</font>
```groovy
compile 'com.xenoamess.p3c.idea:p3c-common:2.3.0'
```
## [中文使用手册](README_cn.md)
## <font color="green">Install</font>
### Install from repositories
1. <font color="blue">Settings >> Plugins >> Browse repositories... </font>

2. <font color="blue"> Search plugin by keyword 'alibaba' then install 'Alibaba Java Coding Guidelines' plugin </font>

3. <font color="blue">Restart to take effect. </font>
### Install from local zip file.
1. Open https://plugins.jetbrains.com/plugin/10046-alibaba-java-coding-guidelines and download the latest version zip file.

2. Settings >> Plugins >> Install plugin from disk...,select the downloaded zip file in previous step then restart your idea

## <font color="green">Use</font>
1. <font color="blue">Switch language</font>

2. <font color="blue">Inspections</font>


3. <font color="blue">Code Analyze</font>

<font color="blue">We use the idea standard Inspection Results to show our violations.</font>

Results are grouped by tags, which include Blocker,Critical,Major,Warning,Weak Warning.
Blocker, Critical and Major will remain sync with alibaba official version, and will not be changed freely, unless especially declared.
When I see some reasonable third party rules in Community I might add them to Warning or Weak Warning.
Usually, if a third party rule can be followed in every situation, then it is tagged Warning.
Otherwise, if it cannot be followed in some special cases, then it will be tagged Weak Warning.
If you want to use pmd-maven-plugin for auto-analyze and assure,
You should set `<failurePriority>3</failurePriority>` for having same behavior than alibaba official version.
See example/use-case in `p3c-pmd/pom.xml`
<font color="blue">We can also analyze file which is modified before vcs checkin.</font>

## <font color="green">Other</font>
1. <font color="blue">[中文乱码解决方法](https://github.com/alibaba/p3c/issues/32#issuecomment-336762512)</font>
* <font color="blue">Appearance&Behavior -> Appearance -> UI Options -> Name 里面设置成微软雅黑(microsoft yahei light)</font>

* <font color="blue">Switch Language to English and restart.</font>

## Configuration mechanism
### Configuration file path
For p3c-idea-plugin, configuration file should be put at "$your_project_path/p3c_config.x8l".
For p3c-pmd for maven, configuration file should be put at "$the_dir_you_run_mvn/p3c_config.x8l".
Usually this two position be pointed at a same file.
### File format
File format be [x8l](https://github.com/cyanpotion/x8l).
Yep I write it.
### File analyze
For example at [cyan_potion](https://github.com/cyanpotion/cyan_potionp3c_config.x8l) ,
we learn about how it works.
Firstly p3c_config.x8l be at "$your_project_path/p3c_config.x8l".
```
<com.alibaba.p3c.pmd.config version=0.0.1>
<rule_config>
<LowerCamelCaseVariableNamingRule>
<WHITE_LIST [>
DAOImpl&
GLFW&
URL&
URI&
XInput&
PosX&
PosY&
AWT&
XY&
drawBoxTC&
FPS&
ID&
lastX&
lastY&
>
>
<ClassNamingShouldBeCamelRule>
<CLASS_NAMING_WHITE_LIST [>
Hbase&
HBase&
ID&
ConcurrentHashMap&
GLFW&
URL&
URI&
JXInput&
SettingFileParser_
>
>
>
<rule_blacklist [>
PackageNamingRule&
AbstractClassShouldStartWithAbstractNamingRule&
ThreadPoolCreationRule&
MethodTooLongRule&
>
<class_blacklist [>
Console
>
<package_blacklist [>
com.xenoamess.cyan_potion.base.steam
>
<rule_class_pair_blacklist>
<JamepadGamepadKeyEnum [>EnumConstantsMustHaveCommentRule>
<JXInputGamepadKeyEnum [>EnumConstantsMustHaveCommentRule>
<KeyActionEnum [>EnumConstantsMustHaveCommentRule>
<KeyboardKeyEnum [>EnumConstantsMustHaveCommentRule>
<CodePluginPosition [>EnumConstantsMustHaveCommentRule>
<ShapeRelation [>EnumConstantsMustHaveCommentRule>
<WaveData [>UndefineMagicConstantRule>
<FileUtils [>AvoidUseDeprecationRule>
<Font [>AvoidUseDeprecationRule>
<Keymap [>AvoidUseDeprecationRule>
<WorldForDemo [>AvoidUseDeprecationRule>
<GameInputManager [>LowerCamelCaseVariableNamingRule&AvoidUseDeprecationRule>
<Colors [>ConstantFieldShouldBeUpperCaseRule>
>
>
```
Root node's name MUST be "com.alibaba.p3c.pmd.config".
Attribute "version=0.0.1" is version of configuration file.
It is actually not used yet but stongly suggested force it here,
as for breaking updates.
For this repo, we opened trim for x8l file, means all readed String will be trimed first.
For example,
```
<class_blacklist>
Console
>
```
see the TextNode
```
Console
```
It will be trimmed to `Console` before used.
There can be 4 children nodes under node com.alibaba.p3c.pmd.config, as shown below.
### rule_config
Node rule_config contains detailed settings for some rules.
For example, LowerCamelCaseVariableNamingRule's attribute WHITE_LIST.
This attribute need a String List,
then we read several TextNodes under a ContentNode as a String List.
### rule_blacklist
Node rule_blacklist contains global settings for a repo,
means ban rules in this repo globally.
For example, if rule_blacklist contains PackageNamingRule,
then means in this repo we will not detect PackageNamingRule.
Rule class name in rule_blacklist CAN be SimpleName OR CanonicalName.
### class_blacklist
Node class_blacklist contains global settings for a repo,
means ban classes in this repo globally.
For example, if class_blacklist contains Console,
then means in this repo we will not detect anything for all classes whose name be Console.
BE ATTENTION, according to PMD interface reason,
class names in class_blacklist must be SimpleName.
### package_blacklist
Node package_blacklist contains global settings for a repo,
means ban packages in this repo globally.
For example, if package_blacklist contains `com.xenoamess`,
then means in this repo we will not detect anything for all classes whose package under `com.xenoamess`.
BE ATTENTION, it will also ban packages under `com.xenoamess`, like `com.xenoamess.cyan_potion`
### rule_class_pair_blacklist
Node rule_class_pair_blacklist contains settings for class/rule pairs,
means ban some rules in this repo for some classes.
For example, if rule_class_pair_blacklist contains
`<GameInputManager>LowerCamelCaseVariableNamingRule&AvoidUseDeprecationRule>`
,
then means in this repo we will not detect LowerCamelCaseVariableNamingRule nor AvoidUseDeprecationRule,
for all classes whose name be GameInputManager.
Rule class name in rule_class_pair_blacklist CAN be SimpleName OR CanonicalName.
BE ATTENTION, according to PMD interface reason,
class names in rule_class_pair_blacklist must be SimpleName.
### For the X8L Haters
If you really hate x8l you can use json configuration files.
```json
{
"com.alibaba.p3c.pmd.config": {
"_attributes": {
"version": "0.0.1"
},
"rule_config": {
"LowerCamelCaseVariableNamingRule": {
"WHITE_LIST": [
"DAOImpl",
"GLFW",
"URL",
"URI",
"XInput",
"PosX",
"PosY",
"AWT",
"XY",
"drawBoxTC",
"FPS",
"ID",
"lastX",
"lastY"
]
},
"ClassNamingShouldBeCamelRule": {
"CLASS_NAMING_WHITE_LIST": [
"Hbase",
"HBase",
"ID",
"ConcurrentHashMap",
"GLFW",
"URL",
"URI",
"JXInput",
"SettingFileParser_"
]
}
},
"rule_blacklist": [
"PackageNamingRule",
"AbstractClassShouldStartWithAbstractNamingRule",
"ThreadPoolCreationRule",
"MethodTooLongRule"
],
"class_blacklist": [
"Console"
],
"package_blacklist": [
"com.xenoamess.cyan_potion.base.steam"
],
"rule_class_pair_blacklist": {
"JamepadGamepadKeyEnum": [
"EnumConstantsMustHaveCommentRule"
],
"JXInputGamepadKeyEnum": [
"EnumConstantsMustHaveCommentRule"
],
"KeyActionEnum": [
"EnumConstantsMustHaveCommentRule"
],
"KeyboardKeyEnum": [
"EnumConstantsMustHaveCommentRule"
],
"CodePluginPosition": [
"EnumConstantsMustHaveCommentRule"
],
"ShapeRelation": [
"EnumConstantsMustHaveCommentRule"
],
"WaveData": [
"UndefineMagicConstantRule"
],
"FileUtils": [
"AvoidUseDeprecationRule"
],
"Font": [
"AvoidUseDeprecationRule"
],
"Keymap": [
"AvoidUseDeprecationRule"
],
"WorldForDemo": [
"AvoidUseDeprecationRule"
],
"GameInputManager": [
"LowerCamelCaseVariableNamingRule",
"AvoidUseDeprecationRule"
],
"Colors": [
"ConstantFieldShouldBeUpperCaseRule"
]
}
}
}
```
name it p3c_config.json
================================================
FILE: idea-plugin/README_cn.md
================================================
> 首先非常感谢大家对插件的支持与意见,英文版的文档还是略为简单,这里详细介绍一下插件的安装使用。
## 插件安装
### 通过Jetbrains官方仓库安装
1. 打开 Settings >> Plugins >> Browse repositories...

2. 在搜索框输入alibaba即可看到Alibaba Java Code Guidelines插件,点击Install进行安装,然后重启IDE生效 `注意:因为插件zip包托管在Jetbrains官方CDN上,所以是从国外的服务器进行下载,可能会出现超时的情况`

### 通过下载安装包进行安装
1. 打开[插件](https://plugins.jetbrains.com/plugin/10046-alibaba-java-coding-guidelines)页面

2. Settings >> Plugins >> Install plugin from disk...,选择刚刚下载的zip包安装,然后重启IDE

### 注意
最低支持IDEA版本为14.1(buildNumber 141.0,可以在About Intellij IDEA中查看版本信息),使用IDEA14的同学最好升级到14.1.7(<a href="https://www.jetbrains.com/idea/download/previous.html" target="_blank">历史版本传送门</a>)
插件基于JDK1.7打包,所以IDEA启动时使用的JDK版本如果是1.6的话就会报Unsupported major.minor version 51.0异常,建议大家都升级一下。
### [中文乱码解决方法](https://github.com/alibaba/p3c/issues/32#issuecomment-336762512)
1. 修改字体——Appearance&Behavior -> Appearance -> UI Options -> Name 里面设置成中文字体——如微软雅黑(microsoft yahei light)、文泉驿(linux)

2. Switch Language to English and restart.

## 插件使用
目前插件实现了开发手册中的的53条规则,大部分基于PMD实现,其中有4条规则基于IDEA实现,并且基于IDEA <a href="https://www.jetbrains.com/help/idea/code-inspection.html" target="_blank">Inspection</a>实现了实时检测功能。部分规则实现了Quick Fix功能,对于可以提供Quick Fix但没有提供的,我们会尽快实现,也欢迎有兴趣的同学加入进来一起努力。
目前插件检测有两种模式:实时检测、手动触发。
### 实时检测
实时检测功能会在开发过程中对当前文件进行检测,并以高亮的形式提示出来,同时也可以支持Quick Fix,该功能默认开启,可以通过配置关闭。
#### 结果高亮提示
<p style="text-indent:2em">检测结果高亮提示,并且鼠标放上去会弹出提示信息。</p>


#### <a href="https://www.jetbrains.com/help/idea/intention-actions.html" target="_blank">Intention</a> QuickFix功能
Alt+Enter键可呼出Intention菜单,不同的规则会提示不同信息的Quick Fix按钮

#### 关闭实时检测
在某些情况下,我们不希望对代码提示违规信息,比如我们在阅读Github开源项目代码的时候,如果界面出现一堆红色、黄色的提示,此时心里肯定是飘过一万只草泥马。这个时候我们可以通过Inspection的设置关闭实时检测功能。
1. 通过右键快速关闭(打开)所有规则的实时检测功能

2. 通过Settings >> Editor >> Inspections 进行手动设置

也可以关闭某条规则的实时检测功能或者修改提示级别。
### 代码扫描
可以通过右键菜单、Toolbar按钮、快捷键三种方式手动触发代码检测。同时结果面板中可以对部分实现了QuickFix功能的规则进行快速修复。
#### 触发扫描
在当前编辑的文件中点击右键,可以在弹出的菜单中触发对该文件的检测。

在左侧的Project目录树种点击右键,可以触发对整个工程或者选择的某个目录、文件进行检测。

如果您打开了IDE的Toolbar,也可以通过Toolbar中的按钮来触发检测,目前Toolbar的按钮触发的检测范围与您IDE当时的焦点有关,如当前编辑的文件或者是Project目录树选中的项,是不是感觉与右键菜单的检测范围类似呢。

使用快捷键(Ctrl+Shift+Alt+J)触发弹出窗口,选择检测范围;您也可自定义快捷键。


#### 扫描结果
检测结果直接使用IDEA Run Inspection By Name功能的结果界面,插件的检测结果分级为Blocker、Critical、Major、Warning、Weak Warning。默认按等级分组,方便统计每个级别错误的数量。

其中,Blocker、Critical、Major三个级别保持与阿里巴巴官方版相同,不会轻易改变。如果未来需要改变,则必须在此Readme中注明。
看见有人做了比较有道理的第三方规则的话,会是视情况加入Warning或者Weak Warning。
如无例外,一个第三方规则如果在任何情况下都能够执行,即程序员完全可以实现不违背该规则实现任何功能,则这个规则会被放入Warning。
与之相对的,如果存在特定的条件,使得若需要满足特定条件则必须违背该规则,即程序员存在必须违背该规则的场景,则这个规则会被放入Weak Warning。
如果要使用pmd maven plugin对代码进行自动检查以确保不违反阿里巴巴Java开发手册,
则请设置`<failurePriority>3</failurePriority>`,以保证与官方版本规则吻合。
使用例可见`p3c-pmd/pom.xml`
默认情况我们在结果面板需要双击具体违规项才能打开对应的源文件,开启Autoscroll To Source选项,单击面板中的文件名、或者是具体的违规项的时候IDEA会自动打开对应的源文件。

#### QuickFix
对于实现Quick Fix的规则,在结果面板中可以直接一键修复 `注意:IDEA14、15可以通过左下角的灯泡进行一键修复操作。`


#### 其他
面板中其他按钮的功能大家自行探索吧,就不一一赘述了
### 代码提交时检测
1. 在提交代码框勾选Alibaba Code Guidelines选项

2. 如果有违反手册的地方会提示是否继续提交,选择取消后会自动对修改的代码进行扫描

## 设置文件机制
### 文件目录
对于p3c idea插件来说,配置文件存放的位置为项目根目录下的p3c_config.x8l文件。
对于maven项目来说,配置文件存放的位置为运行mvn的目录下的p3c_config.x8l文件。
经常的,这两个位置指向同一个位置。
### 文件格式
文件格式为 [x8l](https://github.com/cyanpotion/x8l).
### 文件描述
举个例子,以 [cyan_potion](https://github.com/cyanpotion/cyan_potionp3c_config.x8l) 为例,
我们来看如何配置p3c_config.x8l
首先,p3c_config.x8l位于项目根目录。
```
<com.alibaba.p3c.pmd.config version=0.0.1>
<rule_config>
<LowerCamelCaseVariableNamingRule>
<WHITE_LIST [>
DAOImpl&
GLFW&
URL&
URI&
XInput&
PosX&
PosY&
AWT&
XY&
drawBoxTC&
FPS&
ID&
lastX&
lastY&
>
>
<ClassNamingShouldBeCamelRule>
<CLASS_NAMING_WHITE_LIST [>
Hbase&
HBase&
ID&
ConcurrentHashMap&
GLFW&
URL&
URI&
JXInput&
SettingFileParser_
>
>
>
<rule_blacklist [>
PackageNamingRule&
AbstractClassShouldStartWithAbstractNamingRule&
ThreadPoolCreationRule&
MethodTooLongRule&
>
<class_blacklist [>
Console
>
<package_blacklist [>
com.xenoamess.cyan_potion.base.steam
>
<rule_class_pair_blacklist>
<JamepadGamepadKeyEnum [>EnumConstantsMustHaveCommentRule>
<JXInputGamepadKeyEnum [>EnumConstantsMustHaveCommentRule>
<KeyActionEnum [>EnumConstantsMustHaveCommentRule>
<KeyboardKeyEnum [>EnumConstantsMustHaveCommentRule>
<CodePluginPosition [>EnumConstantsMustHaveCommentRule>
<ShapeRelation [>EnumConstantsMustHaveCommentRule>
<WaveData [>UndefineMagicConstantRule>
<FileUtils [>AvoidUseDeprecationRule>
<Font [>AvoidUseDeprecationRule>
<Keymap [>AvoidUseDeprecationRule>
<WorldForDemo [>AvoidUseDeprecationRule>
<GameInputManager [>LowerCamelCaseVariableNamingRule&AvoidUseDeprecationRule>
<Colors [>ConstantFieldShouldBeUpperCaseRule>
>
>
```
其中,根节点名必为com.alibaba.p3c.pmd.config 。
属性version=0.0.1为配置文件version,目前尚未实际应用,但是建议写明,以防后续破坏性更新。
对于这个项目,方便/美观起见,我们开启了trim,所有读取的String会被trim,然后再进行处理。
例如,
```
<class_blacklist>
Console
>
```
中的TextNode
```
Console
```
会被trim为`Console`然后使用。
com.alibaba.p3c.pmd.config节点下有四个子节点,以下依次讲解。
### rule_config
rule_config节点主要包括对于提供了设置属性的规则的具体设置。
如,LowerCamelCaseVariableNamingRule的WHITE_LIST属性。
该属性要求提供一字符串List,则本项目中读取一个ContentNode下多个TextNode转换为字符串List。
### rule_blacklist
rule_blacklist节点主要包括对该项目的所有类禁用某一规则。
如,rule_blacklist中含有PackageNamingRule,则表明该项目中,检测器不会检测PackageNamingRule。
rule_blacklist中的Rule类名既可以是SimpleName,也可以是CanonicalName。
### class_blacklist
class_blacklist节点主要包括对该项目中的某一类禁用所有规则。
如,class_blacklist中含有Console类,则该项目中所有名为Console的类均不会进行任何检测。
注意,由于PMD技术原因,class_blacklist中的类必须为SimpleName
### package_blacklist
package_blacklist节点主要包括对该项目中的某一个父包禁用所有规则。
如,package_blacklist中含有`com.xenoamess`包,则该项目中所有`com.xenoamess`包下的类均不会进行任何检测。
注意,形如`com.xenoamess.cyan_potion`的,`com.xenoamess`包的子包也会被禁用所有规则。
### rule_class_pair_blacklist
rule_class_pair_blacklist节点主要包括对该项目中的某一类禁用某数个规则。
如,rule_class_pair_blacklist中含有
`<GameInputManager>LowerCamelCaseVariableNamingRule&AvoidUseDeprecationRule>`
,
则该项目中所有名为GameInputManager的类中,LowerCamelCaseVariableNamingRule与AvoidUseDeprecationRule不会被检测。
Rule类名既可以是SimpleName,也可以是CanonicalName。
注意,由于PMD技术原因,被忽略检测的类名必须为SimpleName。
### 为了反X8L主义者干杯
如果你确实讨厌X8L文件格式,你可以使用等价json格式配置文件。
```json
{
"com.alibaba.p3c.pmd.config": {
"_attributes": {
"version": "0.0.1"
},
"rule_config": {
"LowerCamelCaseVariableNamingRule": {
"WHITE_LIST": [
"DAOImpl",
"GLFW",
"URL",
"URI",
"XInput",
"PosX",
"PosY",
"AWT",
"XY",
"drawBoxTC",
"FPS",
"ID",
"lastX",
"lastY"
]
},
"ClassNamingShouldBeCamelRule": {
"CLASS_NAMING_WHITE_LIST": [
"Hbase",
"HBase",
"ID",
"ConcurrentHashMap",
"GLFW",
"URL",
"URI",
"JXInput",
"SettingFileParser_"
]
}
},
"rule_blacklist": [
"PackageNamingRule",
"AbstractClassShouldStartWithAbstractNamingRule",
"ThreadPoolCreationRule",
"MethodTooLongRule"
],
"class_blacklist": [
"Console"
],
"package_blacklist": [
"com.xenoamess.cyan_potion.base.steam"
],
"rule_class_pair_blacklist": {
"JamepadGamepadKeyEnum": [
"EnumConstantsMustHaveCommentRule"
],
"JXInputGamepadKeyEnum": [
"EnumConstantsMustHaveCommentRule"
],
"KeyActionEnum": [
"EnumConstantsMustHaveCommentRule"
],
"KeyboardKeyEnum": [
"EnumConstantsMustHaveCommentRule"
],
"CodePluginPosition": [
"EnumConstantsMustHaveCommentRule"
],
"ShapeRelation": [
"EnumConstantsMustHaveCommentRule"
],
"WaveData": [
"UndefineMagicConstantRule"
],
"FileUtils": [
"AvoidUseDeprecationRule"
],
"Font": [
"AvoidUseDeprecationRule"
],
"Keymap": [
"AvoidUseDeprecationRule"
],
"WorldForDemo": [
"AvoidUseDeprecationRule"
],
"GameInputManager": [
"LowerCamelCaseVariableNamingRule",
"AvoidUseDeprecationRule"
],
"Colors": [
"ConstantFieldShouldBeUpperCaseRule"
]
}
}
}
```
文件名为p3c_config.json即可。
================================================
FILE: idea-plugin/build.gradle
================================================
static boolean shouldIncludeJava(String idea_version_string) {
if (idea_version_string.contains('-')) {
idea_version_string = idea_version_string.substring(idea_version_string.indexOf('-') + 1)
}
if (idea_version_string.contains('.')) {
idea_version_string = idea_version_string.substring(0, idea_version_string.indexOf('.'))
}
try {
int idea_version_int = Integer.parseInt(idea_version_string);
return idea_version_int >= 2019 || (idea_version_int < 1500 && idea_version_int >= 193);
} catch (Exception e) {
return true
}
}
buildscript {
project.ext {
kotlin_version = "2.3.21"
}
repositories {
mavenCentral()
mavenLocal()
maven {
url "https://oss.sonatype.org/content/repositories/snapshots/"
}
maven {
url "https://plugins.gradle.org/m2/"
}
gradlePluginPortal()
google()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$project.kotlin_version"
}
}
allprojects {
group 'com.xenoamess.p3c.idea'
apply plugin: 'kotlin'
apply plugin: 'maven-publish'
configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
repositories {
mavenCentral()
mavenLocal()
maven {
url "https://oss.sonatype.org/content/repositories/snapshots/"
}
maven {
url "https://plugins.gradle.org/m2/"
}
gradlePluginPortal()
google()
}
}
subprojects {
apply plugin: 'java'
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
compileJava.options.encoding = 'UTF-8'
kotlin {
jvmToolchain(21)
}
}
================================================
FILE: idea-plugin/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
networkTimeout=10000
retries=0
retryBackOffMs=500
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: idea-plugin/gradle.properties
================================================
# See https://github.com/JetBrains/gradle-intellij-plugin/
# See https://www.jetbrains.org/intellij/sdk/docs/reference_guide/intellij_artifacts.html
# See https://www.jetbrains.com/intellij-repository/releases/
# See https://www.jetbrains.com/intellij-repository/snapshots/
#idea_version=2022.1
idea_version=2025.1
#idea_version=181.5540.23
#idea_version=145.258.11
plugin_name=Alibaba Java Coding Guidelines(XenoAmess TPM)
systemProp.file.encoding=UTF-8
plugin_version=2.3.0
org.gradle.jvmargs='-Dfile.encoding=UTF-8'
================================================
FILE: idea-plugin/gradlew
================================================
#!/bin/sh
#
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
================================================
FILE: idea-plugin/gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables, and ensure extensions are enabled
setlocal EnableExtensions
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
"%COMSPEC%" /c exit 1
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
"%COMSPEC%" /c exit 1
:execute
@rem Setup the command line
@rem Execute Gradle
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
@rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
:exitWithErrorLevel
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
"%COMSPEC%" /c exit %ERRORLEVEL%
================================================
FILE: idea-plugin/p3c-common/build.gradle
================================================
plugins {
id 'java'
id("org.jetbrains.intellij.platform") version "2.16.0"
id "org.sonarqube" version "6.3.1.5724"
id "com.github.ben-manes.versions" version "0.54.0"
}
repositories {
mavenCentral()
intellijPlatform {
defaultRepositories()
}
}
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'signing'
javadoc {
options.tags = ["date"]
}
task javadocJar(type: Jar, dependsOn: javadoc) {
archiveClassifier.convention('javadoc');
archiveClassifier.set('javadoc');
from 'build/docs/javadoc'
}
task sourcesJar(type: Jar) {
archiveClassifier.convention('sources');
archiveClassifier.set('sources');
from sourceSets.main.allSource
}
artifacts {
archives jar
archives javadocJar
archives sourcesJar
}
sonarqube {
properties {
property "sonar.projectKey", "p3c-idea"
property "sonar.organization", "xenoamess-github"
property "sonar.host.url", "https://sonarcloud.io"
property "sonar.login", "023904832cfec46a1aa61bb7aeee156b066cb3bc"
}
}
intellijPlatform {
pluginConfiguration {
name = plugin_name
}
buildSearchableOptions = false
}
dependencies {
intellijPlatform {
create("IC", idea_version)
bundledPlugins(['com.intellij.java'])
}
implementation group: 'org.freemarker', name: 'freemarker', version: '2.3.33'
implementation("com.xenoamess.p3c:p3c-pmd:$plugin_version") {
exclude group: 'org.apache.logging.log4j'
exclude group: 'org.slf4j'
}
implementation group: 'org.javassist', name: 'javassist', version: '3.31.0-GA'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$project.kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$project.kotlin_version"
testImplementation group: 'junit', name: 'junit', version: '4.13.2'
}
version plugin_version
ext.isReleaseVersion = !version.endsWith("SNAPSHOT")
signing {
required {
isReleaseVersion && gradle.taskGraph.hasTask("uploadArchives")
}
sign configurations.archives
}
================================================
FILE: idea-plugin/p3c-common/src/main/java/icons/P3cIcons.java
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package icons;
import javax.swing.Icon;
import com.intellij.openapi.util.IconLoader;
/**
* @author caikang
* @date 2016/12/28
*/
public final class P3cIcons {
private P3cIcons() {
throw new AssertionError("icons.P3cIcons"
+ " instances for you!");
}
public static final Icon ANALYSIS_ACTION = IconLoader.getIcon("/icons/ali-ide-run.png", P3cIcons.class);
/**
* qiyong means 启用
*/
public static final Icon PROJECT_INSPECTION_ON = IconLoader.getIcon("/icons/qiyong.png", P3cIcons.class);
/**
* tingyong means 停用
*/
public static final Icon PROJECT_INSPECTION_OFF = IconLoader.getIcon("/icons/tingyong.png", P3cIcons.class);
public static final Icon LANGUAGE = IconLoader.getIcon("/icons/language.png", P3cIcons.class);
public static final Icon ALIBABA = IconLoader.getIcon("/icons/alibaba.png", P3cIcons.class);
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/action/AliInspectionAction.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.action
import com.alibaba.p3c.idea.compatible.inspection.InspectionProfileService
import com.alibaba.p3c.idea.compatible.inspection.Inspections
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.alibaba.p3c.idea.inspection.AliBaseInspection
import com.alibaba.p3c.idea.util.NumberConstants
import com.google.common.collect.Lists
import com.intellij.analysis.AnalysisScope
import com.intellij.analysis.AnalysisUIOptions
import com.intellij.analysis.BaseAnalysisActionDialog
import com.intellij.analysis.problemsView.toolWindow.ProblemsView
import com.intellij.codeInspection.InspectionManager
import com.intellij.codeInspection.InspectionsBundle
import com.intellij.codeInspection.ex.GlobalInspectionContextImpl
import com.intellij.codeInspection.ex.InspectionManagerEx
import com.intellij.codeInspection.ex.InspectionToolWrapper
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiFileSystemItem
import com.intellij.psi.PsiManager
import java.awt.event.KeyEvent
/**
* @author caikang
* @date 2016/12/11
*/
class AliInspectionAction : AnAction() {
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
val analysisUIOptions = project.getService(AnalysisUIOptions::class.java)!!
analysisUIOptions.GROUP_BY_SEVERITY = true
val managerEx = InspectionManager.getInstance(project) as InspectionManagerEx
val toolWrappers = Inspections.aliInspections(project) {
it.tool is AliBaseInspection
}
val psiElement = e.getData<PsiElement>(CommonDataKeys.PSI_ELEMENT)
val psiFile = e.getData<PsiFile>(CommonDataKeys.PSI_FILE)
val virtualFile = e.getData<VirtualFile>(CommonDataKeys.VIRTUAL_FILE)
val virtualFiles = e.getData<Array<VirtualFile>>(CommonDataKeys.VIRTUAL_FILE_ARRAY)
var analysisScope: AnalysisScope? = null
var projectDir = false
if (psiFile != null) {
analysisScope = AnalysisScope(psiFile)
projectDir = isBaseDir(psiFile.virtualFile, project)
} else if (virtualFiles != null && virtualFiles.size > NumberConstants.INTEGER_SIZE_OR_LENGTH_0) {
analysisScope = AnalysisScope(project, Lists.newArrayList<VirtualFile>(*virtualFiles))
projectDir = virtualFiles.any {
isBaseDir(it, project)
}
} else {
if (virtualFile != null && virtualFile.isDirectory) {
val psiDirectory = PsiManager.getInstance(project).findDirectory(virtualFile)
if (psiDirectory != null) {
analysisScope = AnalysisScope(psiDirectory)
projectDir = isBaseDir(virtualFile, project)
}
}
if (analysisScope == null && virtualFile != null) {
analysisScope = AnalysisScope(project, listOf(virtualFile))
projectDir = isBaseDir(virtualFile, project)
}
if (analysisScope == null) {
projectDir = true
analysisScope = AnalysisScope(project)
}
}
if (e.inputEvent is KeyEvent) {
inspectForKeyEvent(project, managerEx, toolWrappers, psiElement, psiFile, virtualFile, analysisScope)
return
}
val element = psiFile ?: psiElement
analysisScope.isIncludeTestSource = false
analysisScope.setSearchInLibraries(true)
createContext(
toolWrappers, managerEx, element,
projectDir, analysisScope
).doInspections(analysisScope)
}
private fun isBaseDir(file: VirtualFile, project: Project): Boolean {
if (file.canonicalPath == null || project.basePath == null) {
return false
}
return project.basePath == file.canonicalPath
}
private fun inspectForKeyEvent(
project: Project,
managerEx: InspectionManagerEx,
toolWrappers: List<InspectionToolWrapper<*, *>>,
psiElement: PsiElement?,
psiFile: PsiFile?,
virtualFile: VirtualFile?,
analysisScope: AnalysisScope
) {
var module: Module? = null
if (virtualFile != null && project.baseDir != virtualFile) {
module = ModuleUtilCore.findModuleForFile(virtualFile, project)
}
val uiOptions = AnalysisUIOptions.getInstance(project)
uiOptions.ANALYZE_TEST_SOURCES = false
val dialog = BaseAnalysisActionDialog(
"Select Analyze Scope",
"Analyze Scope",
project,
BaseAnalysisActionDialog.standardItems(
project,
analysisScope,
module,
psiElement
),
uiOptions,
true
)
if (!dialog.showAndGet()) {
return
}
val scope = dialog.getScope(analysisScope)
scope.setSearchInLibraries(true)
val element = psiFile ?: psiElement
createContext(
toolWrappers, managerEx, element,
dialog.isProjectScopeSelected, scope
).doInspections(scope)
}
override fun update(e: AnActionEvent) {
e.presentation.text = P3cBundle.getMessage("com.alibaba.p3c.idea.action.AliInspectionAction.text")
}
companion object {
private val logger = Logger.getInstance(AliInspectionAction::class.java)
private fun getTitle(element: PsiElement?, isProjectScopeSelected: Boolean): String? {
if (element == null) {
return null
}
if (isProjectScopeSelected) {
return "Project"
}
if (element is PsiFileSystemItem) {
return VfsUtilCore.getRelativePath(element.virtualFile, element.project.baseDir)
}
return null
}
fun createContext(
toolWrapperList: List<InspectionToolWrapper<*, *>>,
managerEx: InspectionManagerEx, psiElement: PsiElement?,
projectScopeSelected: Boolean, scope: AnalysisScope
):
GlobalInspectionContextImpl {
// remove last same scope content
val project = managerEx.project
val title = getTitle(psiElement, projectScopeSelected)
val model = InspectionProfileService.createSimpleProfile(toolWrapperList, managerEx, psiElement)
title?.let {
model.name = it
}
val inspectionContext = createNewGlobalContext(
managerEx, projectScopeSelected
)
InspectionProfileService.setExternalProfile(model, inspectionContext)
val toolWindow = ProblemsView.getToolWindow(project);
if (toolWindow != null) {
val contentManager = toolWindow.contentManager
val contentTitle = title?.let {
InspectionsBundle.message("inspection.results.for.profile.toolwindow.title", it, scope.shortenName)
}
val content = contentManager.contents.firstOrNull {
contentTitle != null && (it.tabName == contentTitle || it.tabName.endsWith(contentTitle))
}
content?.let {
contentManager.removeContent(content, true)
}
}
return inspectionContext
}
private fun createNewGlobalContext(
managerEx: InspectionManagerEx,
projectScopeSelected: Boolean
): GlobalInspectionContextImpl {
return PmdGlobalInspectionContextImpl(managerEx.project, managerEx.contentManager, projectScopeSelected)
}
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.BGT
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/action/PmdGlobalInspectionContextImpl.kt
================================================
package com.alibaba.p3c.idea.action
import com.alibaba.p3c.idea.component.AliProjectComponent
import com.alibaba.p3c.idea.ep.InspectionActionExtensionPoint
import com.alibaba.p3c.idea.inspection.AliLocalInspectionToolProvider
import com.alibaba.p3c.idea.inspection.PmdRuleInspectionIdentify
import com.alibaba.p3c.idea.pmd.AliPmdProcessor
import com.intellij.analysis.AnalysisScope
import com.intellij.codeInsight.daemon.ProblemHighlightFilter
import com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator
import com.intellij.codeInspection.ex.GlobalInspectionContextImpl
import com.intellij.codeInspection.ui.InspectionResultsView
import com.intellij.concurrency.JobLauncher
import com.intellij.concurrency.JobLauncherImpl
import com.intellij.concurrency.SensitiveProgressWrapper
import com.intellij.diagnostic.ThreadDumper
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.application.ex.ApplicationManagerEx
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.editor.Document
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.ProgressIndicatorProvider
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task.Backgroundable
import com.intellij.openapi.progress.impl.CoreProgressManager
import com.intellij.openapi.progress.util.ProgressIndicatorUtils
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.displayUrlRelativeToProject
import com.intellij.openapi.project.isProjectOrWorkspaceFile
import com.intellij.openapi.roots.FileIndex
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.EmptyRunnable
import com.intellij.openapi.util.NotNullLazyValue
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiBinaryFile
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import com.intellij.psi.SingleRootFileViewProvider
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.SearchScope
import com.intellij.psi.util.PsiUtilCore
import com.intellij.ui.content.ContentManager
import com.intellij.util.ExceptionUtil
import com.intellij.util.IncorrectOperationException
import com.intellij.util.Processor
import com.intellij.util.ReflectionUtil
import com.intellij.util.containers.ContainerUtil
import gnu.trove.THashSet
import net.sourceforge.pmd.RuleViolation
import java.util.Queue
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.BlockingQueue
import java.util.concurrent.Future
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.TimeUnit.SECONDS
/**
* @date 2020/06/19
* @author caikang
*/
class PmdGlobalInspectionContextImpl(
project: Project,
contentManager: NotNullLazyValue<ContentManager>,
private val projectScopeSelected: Boolean
) :
GlobalInspectionContextImpl(project, contentManager) {
private val logger = Logger.getInstance(PmdGlobalInspectionContextImpl::class.java)
override fun runTools(scope: AnalysisScope, runGlobalToolsOnly: Boolean, isOfflineInspections: Boolean) {
val usedTools = usedTools
val hasPmdTools = usedTools.any {
it.tool.tool is PmdRuleInspectionIdentify
}
if (hasPmdTools) {
val progressIndicator =
ProgressIndicatorProvider.getGlobalProgressIndicator()
?: throw IncorrectOperationException("Must be run under progress")
pmdNodeWarmUp(scope, progressIndicator, isOfflineInspections)
}
super.runTools(scope, runGlobalToolsOnly, isOfflineInspections)
if (myProgressIndicator.isCanceled) {
return
}
InspectionActionExtensionPoint.extension.extensions.forEach {
try {
it.doOnInspectionFinished(this, projectScopeSelected)
} catch (e: Exception) {
logger.warn(e)
}
}
}
private fun pmdNodeWarmUp(
scope: AnalysisScope,
progressIndicator: ProgressIndicator,
isOfflineInspections: Boolean
) {
val aliProjectComponent = project.getComponent(AliProjectComponent::class.java)
// run pmd inspection
val processor = Processor { file: PsiFile ->
ProgressManager.checkCanceled()
val readActionSuccess =
DumbService.getInstance(project).tryRunReadActionInSmartMode(
{
if (!file.isValid) {
return@tryRunReadActionInSmartMode true
}
val virtualFile = file.virtualFile
if (!scope.contains(virtualFile)) {
logger.info(file.name + "; scope: " + scope + "; " + virtualFile)
return@tryRunReadActionInSmartMode true
}
val path = virtualFile.canonicalPath?.lowercase() ?: ""
if (!path.endsWith(".java") && !path.endsWith(".vm")) {
return@tryRunReadActionInSmartMode true
}
doPmdProcess(file, aliProjectComponent, virtualFile)
true
}, "Inspect code is not available until indices are ready"
)
if (readActionSuccess == null || !readActionSuccess) {
throw ProcessCanceledException()
}
true
}
val headlessEnvironment = ApplicationManager.getApplication().isHeadlessEnvironment
val searchScope =
ApplicationManager.getApplication().runReadAction<SearchScope, RuntimeException> { scope.toSearchScope() }
val localScopeFiles: MutableSet<VirtualFile>? = if (searchScope is LocalSearchScope) THashSet() else null
val filesToInspect: BlockingQueue<PsiFile> = ArrayBlockingQueue(1000)
val iteratingIndicator: ProgressIndicator = SensitiveProgressWrapper(progressIndicator)
val future: Future<*> = startIterateScopeInBackground(
scope,
localScopeFiles,
headlessEnvironment,
filesToInspect,
iteratingIndicator
) as Future<*>
val dependentIndicators =
ReflectionUtil.getField(javaClass, this, List::class.java, "dependentIndicators")?.map {
it as ProgressIndicator
}?.toMutableList()
try {
val filesFailedToInspect: Queue<PsiFile> = LinkedBlockingQueue()
while (true) {
val disposable = Disposer.newDisposable()
val wrapper: ProgressIndicator = DaemonProgressIndicator()
dependentIndicators?.let {
it.add(wrapper)
}
try {
// avoid "attach listener"/"write action" race
ApplicationManager.getApplication().runReadAction {
wrapper.start()
ProgressIndicatorUtils.forceWriteActionPriority(wrapper, disposable)
// there is a chance we are racing with write action, in which case just registered listener might not be called, retry.
if (ApplicationManagerEx.getApplicationEx().isWriteActionPending) {
throw ProcessCanceledException()
}
}
// use wrapper here to cancel early when write action start but do not affect the original indicator
(JobLauncher.getInstance() as JobLauncherImpl).processQueue(
filesToInspect,
filesFailedToInspect,
wrapper,
PsiUtilCore.NULL_PSI_FILE,
processor
)
break
} catch (e: ProcessCanceledException) {
progressIndicator.checkCanceled()
assert(
isOfflineInspections || !ApplicationManager.getApplication().isReadAccessAllowed
) {
"""
Must be outside read action. PCE=
${ExceptionUtil.getThrowableText(e)}
""".trimIndent()
}
assert(
isOfflineInspections || !ApplicationManager.getApplication().isDispatchThread
) {
"""
Must be outside EDT. PCE=
${ExceptionUtil.getThrowableText(e)}
""".trimIndent()
}
// wait for write action to complete
ApplicationManager.getApplication().runReadAction(EmptyRunnable.getInstance())
} finally {
dependentIndicators?.let {
it.remove(wrapper)
}
Disposer.dispose(disposable)
}
}
} finally {
iteratingIndicator.cancel() // tell file scanning thread to stop
filesToInspect.clear() // let file scanning thread a chance to put TOMBSTONE and complete
try {
future[30, SECONDS]
} catch (e: java.lang.Exception) {
logger.error(
"""
Thread dump:
${ThreadDumper.dumpThreadsToString()}
""".trimIndent(), e
)
}
}
ProgressManager.checkCanceled()
}
private fun startIterateScopeInBackground(
scope: AnalysisScope,
localScopeFiles: MutableCollection<VirtualFile>?,
headlessEnvironment: Boolean,
outFilesToInspect: BlockingQueue<in PsiFile>,
progressIndicator: ProgressIndicator
): Future<*>? {
val task: Backgroundable = object : Backgroundable(project, "Scanning Files to Inspect") {
override fun run(indicator: ProgressIndicator) {
ApplicationManager.getApplication().runReadAction(
Runnable {
try {
val fileIndex: FileIndex = ProjectRootManager.getInstance(project).fileIndex
scope.accept { file: VirtualFile? ->
ProgressManager.checkCanceled()
if (isProjectOrWorkspaceFile(file!!) || !fileIndex.isInContent(file)) return@accept true
val psiFile =
ReadAction.compute<PsiFile?, RuntimeException> {
if (project.isDisposed) throw ProcessCanceledException()
val psi = PsiManager.getInstance(project).findFile(file)
val document =
psi?.let { shouldProcess(it, headlessEnvironment, localScopeFiles) }
if (document != null) {
return@compute psi
}
null
}
// do not inspect binary files
if (psiFile != null) {
try {
if (ApplicationManager.getApplication().isReadAccessAllowed) {
outFilesToInspect.put(psiFile)
}
} catch (e: InterruptedException) {
logger.error("psiFile interrupted : " + psiFile.name, e)
} catch (e: IllegalStateException) {
logger.info("psiFile ignored : " + psiFile.name, e)
}
}
ProgressManager.checkCanceled()
true
}
} catch (e: ProcessCanceledException) {
// ignore, but put tombstone
} finally {
try {
outFilesToInspect.put(PsiUtilCore.NULL_PSI_FILE)
} catch (e: InterruptedException) {
logger.error(e)
}
}
}
)
}
}
return (ProgressManager.getInstance() as CoreProgressManager).runProcessWithProgressAsynchronously(
task,
progressIndicator,
null
)
}
private fun shouldProcess(
file: PsiFile,
headlessEnvironment: Boolean,
localScopeFiles: MutableCollection<VirtualFile>?
): Document? {
val virtualFile = file.virtualFile ?: return null
if (isBinary(file)) return null //do not inspect binary files
if (isViewClosed && !headlessEnvironment) {
throw ProcessCanceledException()
}
if (logger.isDebugEnabled) {
logger.debug("Running local inspections on " + virtualFile.path)
}
if (SingleRootFileViewProvider.isTooLargeForIntelligence(virtualFile)) return null
if (localScopeFiles != null && !localScopeFiles.add(virtualFile)) return null
return if (!ProblemHighlightFilter.shouldProcessFileInBatch(file)) null else PsiDocumentManager.getInstance(
project
).getDocument(file)
}
private fun isBinary(file: PsiFile): Boolean {
return file is PsiBinaryFile || file.fileType.isBinary
}
private fun doPmdProcess(
file: PsiFile,
aliProjectComponent: AliProjectComponent,
virtualFile: VirtualFile
) {
val url: String = displayUrlRelativeToProject(
virtualFile,
virtualFile.presentableUrl,
project,
true,
false
)
myProgressIndicator.text = "PMD Process in $url"
val violations =
AliPmdProcessor(AliLocalInspectionToolProvider.getRuleSets()).processFile(
file,
false
)
val fileContext = aliProjectComponent.getFileContext(virtualFile)
fileContext?.let { fc ->
val ruleViolations = ContainerUtil.createConcurrentSoftValueMap<String, List<RuleViolation>>()
for (entry in violations.groupBy {
it.rule.name
}) {
ruleViolations[entry.key] = entry.value
}
fc.ruleViolations = ruleViolations
}
}
override fun close(noSuspiciousCodeFound: Boolean) {
super.close(noSuspiciousCodeFound)
InspectionActionExtensionPoint.extension.extensions.forEach {
try {
it.doOnClose(noSuspiciousCodeFound, project)
} catch (e: Exception) {
logger.warn(e)
}
}
}
override fun addView(view: InspectionResultsView) {
super.addView(view)
InspectionActionExtensionPoint.extension.extensions.forEach {
try {
it.doOnView(view)
} catch (e: Exception) {
logger.warn(e)
}
}
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/action/SwitchLanguageAction.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.action
import com.alibaba.p3c.idea.config.P3cConfig
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.alibaba.smartfox.idea.common.util.BalloonNotifications
import com.alibaba.smartfox.idea.common.util.getService
import com.intellij.notification.NotificationListener
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.application.ex.ApplicationManagerEx
import com.intellij.openapi.project.DumbAware
/**
*
*
* @author caikang
* @date 2017/06/20
*/
class SwitchLanguageAction : AnAction(), DumbAware {
private val p3cConfig = P3cConfig::class.java.getService()
private val textKey = "com.alibaba.p3c.action.switch_language.text"
override fun actionPerformed(e: AnActionEvent) {
p3cConfig.toggleLanguage()
BalloonNotifications.showSuccessNotification(P3cBundle.getMessage("$textKey.success"), e.project,
NotificationListener { notification, _ ->
notification.expire()
ApplicationManagerEx.getApplicationEx().restart(false)
}, sticky = true)
}
override fun update(e: AnActionEvent) {
e.presentation.text = P3cBundle.getMessage("$textKey.cur_${p3cConfig.locale}")
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.EDT
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/action/ToggleProjectInspectionAction.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.action
import com.alibaba.p3c.idea.compatible.inspection.InspectionProfileService
import com.alibaba.p3c.idea.compatible.inspection.Inspections
import com.alibaba.p3c.idea.config.SmartFoxProjectConfig
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.alibaba.p3c.idea.inspection.AliBaseInspection
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
import com.intellij.notification.NotificationGroupManager
import com.intellij.notification.NotificationType
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.psi.PsiManager
import icons.P3cIcons
/**
*
* Open or close inspections
* Enhanced for dynamic plugin support - allows toggling plugin without IDE restart
*
* @author caikang
* @date 2017/03/14
*/
class ToggleProjectInspectionAction : AnAction() {
val textKey = "com.alibaba.p3c.idea.action.ToggleProjectInspectionAction.text"
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
val smartFoxConfig = project.getService(SmartFoxProjectConfig::class.java)
// Toggle global plugin state
smartFoxConfig.pluginGloballyDisabled = !smartFoxConfig.pluginGloballyDisabled
// Apply the state change
applyPluginState(project, !smartFoxConfig.pluginGloballyDisabled)
// Show notification to user
val message = if (smartFoxConfig.pluginGloballyDisabled) {
P3cBundle.getMessage("com.alibaba.p3c.idea.action.ToggleProjectInspectionAction.disabled.notification")
?: "P3C plugin has been disabled"
} else {
P3cBundle.getMessage("com.alibaba.p3c.idea.action.ToggleProjectInspectionAction.enabled.notification")
?: "P3C plugin has been enabled"
}
NotificationGroupManager.getInstance()
.getNotificationGroup("P3C Notifications")
?.createNotification(message, NotificationType.INFORMATION)
?.notify(project)
}
/**
* Apply plugin enabled/disabled state
*/
private fun applyPluginState(project: com.intellij.openapi.project.Project, enable: Boolean) {
val tools = Inspections.aliInspections(project) {
it.tool is AliBaseInspection
}
// Use the existing toggle mechanism
InspectionProfileService.toggleInspection(project, tools, !enable)
// Refresh all open files to apply changes immediately
FileEditorManager.getInstance(project).openFiles.forEach { file ->
val psiFile = PsiManager.getInstance(project).findFile(file)
if (psiFile != null) {
DaemonCodeAnalyzer.getInstance(project).restart(psiFile)
}
}
}
override fun update(e: AnActionEvent) {
val project = e.project ?: return
val smartFoxConfig = project.getService(SmartFoxProjectConfig::class.java)
// Check global disabled state first, fall back to project level
val isDisabled = smartFoxConfig.pluginGloballyDisabled || smartFoxConfig.projectInspectionClosed
e.presentation.text = if (isDisabled) {
e.presentation.icon = P3cIcons.PROJECT_INSPECTION_ON
P3cBundle.getMessage("$textKey.open") ?: "Enable P3C Inspections"
} else {
e.presentation.icon = P3cIcons.PROJECT_INSPECTION_OFF
P3cBundle.getMessage("$textKey.close") ?: "Disable P3C Inspections"
}
}
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.BGT
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/activity/CommonSettingsApplicationStartupActivity.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.activity
import com.alibaba.p3c.idea.config.P3cConfig
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.alibaba.p3c.idea.util.HighlightInfoTypes
import com.alibaba.p3c.idea.util.HighlightSeverities
import com.xenoamess.p3c.pmd.I18nResources
import com.alibaba.smartfox.idea.common.activity.AliBaseApplicationStartupActivity
import com.intellij.codeInsight.daemon.impl.SeverityRegistrar
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.project.Project
/**
*
*
* @author caikang
* @date 2017/06/19
*/
class CommonSettingsApplicationStartupActivity : AliBaseApplicationStartupActivity {
companion object {
const val analyticsGroupId = "com.alibaba.p3c.analytics.action_group"
val analyticsGroupText = "$analyticsGroupId.text"
private val p3cConfig = P3cConfig()
}
override fun runActivity(project: Project) {
SeverityRegistrar.registerStandard(HighlightInfoTypes.BLOCKER, HighlightSeverities.BLOCKER)
SeverityRegistrar.registerStandard(HighlightInfoTypes.CRITICAL, HighlightSeverities.CRITICAL)
SeverityRegistrar.registerStandard(HighlightInfoTypes.MAJOR, HighlightSeverities.MAJOR)
// Shall not register WARNING and WEAK_WARNING!
// SeverityRegistrar.registerStandard(HighlightInfoTypes.WARNING, HighlightSeverities.WARNING)
// SeverityRegistrar.registerStandard(HighlightInfoTypes.WEAK_WARNING, HighlightSeverities.WEAK_WARNING)
I18nResources.changeLanguage(p3cConfig.locale)
val analyticsGroup = ActionManager.getInstance().getAction(analyticsGroupId)
analyticsGroup.templatePresentation.text = P3cBundle.getMessage(analyticsGroupText)
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/compatible/inspection/InspectionProfileService.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.compatible.inspection
import com.alibaba.smartfox.idea.common.util.PluginVersions
import com.google.common.collect.Sets
import com.intellij.codeInspection.ex.GlobalInspectionContextImpl
import com.intellij.codeInspection.ex.InspectionManagerEx
import com.intellij.codeInspection.ex.InspectionProfileImpl
import com.intellij.codeInspection.ex.InspectionToolWrapper
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.InvalidDataException
import com.intellij.openapi.util.WriteExternalException
import com.intellij.profile.codeInspection.InspectionProjectProfileManager
import com.intellij.psi.PsiElement
import org.jdom.Element
import java.util.LinkedHashSet
/**
*
*
* @author caikang
* @date 2017/03/01
*/
object InspectionProfileService {
fun createSimpleProfile(
toolWrapperList: List<InspectionToolWrapper<*, *>>,
managerEx: InspectionManagerEx,
psiElement: PsiElement?
): InspectionProfileImpl {
val profile = getProjectInspectionProfile(managerEx.project)
val allWrappers: LinkedHashSet<InspectionToolWrapper<*, *>> = Sets.newLinkedHashSet()
allWrappers.addAll(toolWrapperList)
val forCompile = allWrappers
for (toolWrapper in allWrappers) {
profile.collectDependentInspections(toolWrapper, forCompile, managerEx.project)
}
val model = when (PluginVersions.baseVersion) {
in PluginVersions.baseVersion171..Int.MAX_VALUE -> {
val clz = Class.forName("com.intellij.codeInspection.ex.InspectionProfileKt")
val method = clz.methods.first { it.name == "createSimple" }
method.invoke(null, "Alibaba Coding Guidelines", managerEx.project, allWrappers.toList())
as InspectionProfileImpl
}
PluginVersions.baseVersion163 -> {
val method = profile.javaClass.methods.first {
it.name == "createSimple"
}
method.invoke(null, "Alibaba Coding Guidelines", managerEx.project, allWrappers.toList())
as InspectionProfileImpl
}
else -> {
val method = profile.javaClass.methods.first {
it.name == "createSimple"
}
method.invoke(null, "Alibaba Coding Guidelines", managerEx.project, allWrappers.toTypedArray())
as InspectionProfileImpl
}
}
try {
val element = Element("toCopy")
for (wrapper in allWrappers) {
wrapper.tool.writeSettings(element)
val tw = if (psiElement == null) {
model.getInspectionTool(wrapper.shortName, managerEx.project)
} else {
model.getInspectionTool(wrapper.shortName, psiElement)
}
tw!!.tool.readSettings(element)
}
} catch (ignored: WriteExternalException) {
} catch (ignored: InvalidDataException) {
}
return model
}
fun toggleInspection(
project: Project,
aliInspections: List<InspectionToolWrapper<*, *>>,
closed: Boolean
) {
val profile = getProjectInspectionProfile(project)
val shortNames = aliInspections.map {
it.tool.shortName
}
profile.removeScopes(shortNames, "AlibabaCodeAnalysis", project)
val method = profile.javaClass.methods.first {
it.name == if (closed) {
"enableToolsByDefault"
} else {
"disableToolByDefault"
}
}
method.invoke(profile, shortNames, project)
profile.profileChanged()
profile.scopesChanged()
}
fun setExternalProfile(
profile: InspectionProfileImpl,
inspectionContext: GlobalInspectionContextImpl
) {
val method = inspectionContext.javaClass.methods.first {
it.name == "setExternalProfile" && it.parameterTypes.size == 1 && it.parameterTypes.first().isAssignableFrom(InspectionProfileImpl::class.java)
}
method.invoke(inspectionContext, profile)
}
fun getProjectInspectionProfile(project: Project): InspectionProfileImpl {
return InspectionProjectProfileManager.getInstance(project).currentProfile
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/compatible/inspection/Inspections.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.compatible.inspection
import com.xenoamess.p3c.pmd.lang.java.util.namelist.NameListConfig
import com.google.common.base.Splitter
import com.intellij.codeInspection.ex.InspectionProfileImpl
import com.intellij.codeInspection.ex.InspectionToolWrapper
import com.intellij.codeInspection.ex.ScopeToolState
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.JDOMExternalizerUtil
import com.xenoamess.p3c.pmd.lang.java.util.namelist.NameListServiceImpl.P3C_JSON_CONFIG_FILE_NAME
import com.xenoamess.p3c.pmd.lang.java.util.namelist.NameListServiceImpl.P3C_X8L_CONFIG_FILE_NAME
import org.apache.commons.lang3.StringUtils
import org.jdom.Element
import org.jetbrains.annotations.SystemIndependent
import java.io.File
import java.io.FilenameFilter
/**
* @author XenoAmess
*/
class P3cConfigFilenameFilter : FilenameFilter {
override fun accept(dir: File?, name: String?): Boolean {
return P3C_X8L_CONFIG_FILE_NAME.equals(name) || P3C_JSON_CONFIG_FILE_NAME.equals(name)
}
}
/**
*
*
* @author caikang
* @date 2017/03/01
*/
object Inspections {
fun aliInspections(project: Project, filter: (InspectionToolWrapper<*, *>) -> Boolean): List<InspectionToolWrapper<*, *>> {
loadPatchConfigFile(project)
val profile = InspectionProfileService.getProjectInspectionProfile(project)
return getAllTools(project, profile).filter(filter)
}
fun loadPatchConfigFile(project: Project) {
val patchConfigFile = fetchPatchConfigFile(project)
if (patchConfigFile == null) {
NameListConfig.renewNameListService()
} else {
NameListConfig.renewNameListService(patchConfigFile)
}
}
private fun fetchPatchConfigFile(project: Project): File? {
val projectBasePath: @SystemIndependent String? = project.basePath
?: return null
val projectBaseFile = File(projectBasePath)
val fileList = projectBaseFile.listFiles(P3cConfigFilenameFilter())
return if (fileList == null || fileList.isEmpty()) {
null
} else {
fileList[0]
}
}
fun addCustomTag(project: Project, tag: String) {
try {
val profile = InspectionProfileService.getProjectInspectionProfile(project)
val javaDocLocalInspection : Element = profile.getInspectionTool("JavaDoc", project)?.tool as? Element ?: return
val myAdditionalJavadocTags : String? = JDOMExternalizerUtil.readField(javaDocLocalInspection, "myAdditionalJavadocTags")
if (StringUtils.isEmpty(myAdditionalJavadocTags)) {
JDOMExternalizerUtil.writeField(javaDocLocalInspection, "myAdditionalJavadocTags", tag)
return
}
val tags = Splitter.on(',').splitToList(myAdditionalJavadocTags)
if (tags.contains(tag)) {
return
}
JDOMExternalizerUtil.writeField(javaDocLocalInspection, "myAdditionalJavadocTags", myAdditionalJavadocTags + ",$tag")
profile.profileChanged()
profile.scopesChanged()
} catch (ignored : Exception) {
}
}
private fun getAllTools(project: Project, profile: InspectionProfileImpl): List<InspectionToolWrapper<*, *>> {
val method = InspectionProfileImpl::class.java.methods.first {
it.name == "getAllTools"
}
val result = if (method.parameterTypes.isNotEmpty()) {
method.invoke(profile, project)
} else {
method.invoke(profile)
}
return (result as List<ScopeToolState>).map { it.tool }
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/component/AliProjectComponent.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.component
import com.alibaba.p3c.idea.compatible.inspection.Inspections
import com.alibaba.p3c.idea.config.P3cConfig
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.alibaba.p3c.idea.inspection.AliPmdInspectionInvoker
import com.alibaba.p3c.idea.pmd.SourceCodeProcessor
import com.alibaba.p3c.idea.util.withLockNotInline
import com.alibaba.smartfox.idea.common.component.AliBaseProjectComponent
import com.alibaba.smartfox.idea.common.util.getService
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileEvent
import com.intellij.openapi.vfs.VirtualFileListener
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.openapi.vfs.VirtualFileMoveEvent
import com.intellij.psi.PsiManager
import com.xenoamess.p3c.pmd.I18nResources
import net.sourceforge.pmd.RuleViolation
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.locks.ReentrantReadWriteLock
/**
* @author caikang
* @date 2016/12/13
*/
class AliProjectComponent : AliBaseProjectComponent {
private val listener: VirtualFileListener
private val javaExtension = ".java"
private val velocityExtension = ".vm"
private val lock = ReentrantReadWriteLock()
private val readLock = lock.readLock()
private val writeLock = lock.writeLock()
private val fileContexts = ConcurrentHashMap<String, FileContext>()
init {
listener = object : VirtualFileListener {
override fun contentsChanged(event: VirtualFileEvent) {
val path = getFilePath(event) ?: return
val project = ProjectManager.getInstance().defaultProject
PsiManager.getInstance(project).findFile(event.file) ?: return
val p3cConfig = P3cConfig::class.java.getService()
if (!p3cConfig.ruleCacheEnable) {
AliPmdInspectionInvoker.refreshFileViolationsCache(event.file)
}
if (!p3cConfig.astCacheEnable) {
SourceCodeProcessor.invalidateCache(path)
}
SourceCodeProcessor.invalidUserTrigger(path)
fileContexts[path]?.ruleViolations = null
}
override fun fileDeleted(event: VirtualFileEvent) {
val path = getFilePath(event)
path?.let {
SourceCodeProcessor.invalidateCache(it)
removeFileContext(it)
}
super.fileDeleted(event)
}
override fun fileMoved(event: VirtualFileMoveEvent) {
val path = getFilePath(event)
path?.let {
SourceCodeProcessor.invalidateCache(it)
removeFileContext(it)
}
super.fileMoved(event)
}
private fun getFilePath(event: VirtualFileEvent): String? {
val path = event.file.canonicalPath
if (path == null || !(path.endsWith(javaExtension) || path.endsWith(velocityExtension))) {
return null
}
return path
}
}
}
override fun initComponent() {
val p3cConfig = P3cConfig::class.java.getService()
I18nResources.changeLanguage(p3cConfig.locale)
val analyticsGroup = ActionManager.getInstance().getAction(analyticsGroupId)
analyticsGroup.templatePresentation.text = P3cBundle.getMessage(analyticsGroupText)
}
override fun projectOpened() {
val project = ProjectManager.getInstance().defaultProject
Inspections.addCustomTag(project, "date")
VirtualFileManager.getInstance().addVirtualFileListener(listener)
}
override fun projectClosed() {
VirtualFileManager.getInstance().removeVirtualFileListener(listener)
}
companion object {
val analyticsGroupId = "com.alibaba.p3c.analytics.action_group"
val analyticsGroupText = "$analyticsGroupId.text"
}
data class FileContext(
val lock: ReentrantReadWriteLock,
var ruleViolations: Map<String, List<RuleViolation>>? = null
)
fun removeFileContext(path: String) {
fileContexts.remove(path)
}
fun getFileContext(virtualFile: VirtualFile?): FileContext? {
val file = virtualFile?.canonicalPath ?: return null
val result = readLock.withLockNotInline {
fileContexts[file]
}
if (result != null) {
return result
}
return writeLock.withLockNotInline {
val finalContext = fileContexts[file]
if (finalContext != null) {
return@withLockNotInline finalContext
}
val lock = ReentrantReadWriteLock()
FileContext(
lock = lock
).also {
fileContexts[file] = it
}
}
}
/**
* Get the virtual file listener for cleanup purposes.
*/
fun getVirtualFileListener(): VirtualFileListener = listener
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/config/P3cConfig.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.config
import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.openapi.components.State
import com.intellij.openapi.components.Storage
import com.intellij.util.xmlb.XmlSerializerUtil
import java.util.Locale
/**
*
*
* @author caikang
* @date 2017/06/19
*/
@State(name = "P3cConfig", storages = [Storage(file = "smartfox/p3c.xml")])
class P3cConfig : PersistentStateComponent<P3cConfig> {
var astCacheTime = 1000L
var astCacheEnable = true
var ruleCacheTime = 1000L
var ruleCacheEnable = false
var analysisBeforeCheckin = false
var locale: String = ""
get() {
if (field.isEmpty()) {
val lang = Locale.getDefault().language
return if (lang != Locale.ENGLISH.language && lang != Locale.CHINESE.language) {
Locale.ENGLISH.language
} else Locale.getDefault().language
}
return field
}
fun toggleLanguage() {
locale = if (localeEn == locale) localeZh else localeEn
}
override fun getState(): P3cConfig {
return this
}
override fun loadState(state: P3cConfig) {
XmlSerializerUtil.copyBean(state, this)
}
companion object {
val localeEn = Locale.ENGLISH.language!!
val localeZh = Locale.CHINESE.language!!
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/config/P3cConfigurable.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.config
import com.alibaba.p3c.idea.compatible.inspection.InspectionProfileService
import com.alibaba.p3c.idea.compatible.inspection.Inspections
import com.alibaba.p3c.idea.inspection.AliBaseInspection
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
import com.intellij.openapi.options.Configurable
import com.intellij.openapi.project.Project
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.psi.PsiManager
import java.awt.BorderLayout
import java.awt.GridBagConstraints
import java.awt.GridBagLayout
import java.awt.Insets
import javax.swing.BorderFactory
import javax.swing.JCheckBox
import javax.swing.JComponent
import javax.swing.JLabel
import javax.swing.JPanel
/**
* Settings page for P3C plugin configuration.
* Provides GUI for enabling/disabling plugin without IDE restart.
*
* @author XenoAmess
*/
class P3cConfigurable(private val project: Project) : Configurable {
private var mainPanel: JPanel? = null
private var enablePluginCheckBox: JCheckBox? = null
private var enableRealtimeCheckBox: JCheckBox? = null
override fun getDisplayName(): String = "P3C Code Guidelines"
override fun createComponent(): JComponent? {
mainPanel = JPanel(BorderLayout(10, 10))
mainPanel?.border = BorderFactory.createEmptyBorder(10, 10, 10, 10)
val settingsPanel = JPanel(GridBagLayout())
val gbc = GridBagConstraints().apply {
fill = GridBagConstraints.HORIZONTAL
insets = Insets(5, 5, 5, 5)
weightx = 1.0
gridx = 0
}
// Plugin enable/disable checkbox
enablePluginCheckBox = JCheckBox("Enable P3C Code Guidelines plugin")
enablePluginCheckBox?.toolTipText = "Enable or disable all P3C inspections without IDE restart"
gbc.gridy = 0
gbc.gridwidth = 2
settingsPanel.add(enablePluginCheckBox, gbc)
// Description label
val descLabel = JLabel("<html><body style='width: 400px;'>" +
"When disabled, all P3C inspections will be turned off immediately. " +
"No IDE restart is required for this change to take effect." +
"</body></html>")
descLabel.font = descLabel.font.deriveFont(descLabel.font.size2D - 1)
gbc.gridy = 1
gbc.insets = Insets(0, 25, 15, 5)
settingsPanel.add(descLabel, gbc)
// Real-time inspection checkbox
enableRealtimeCheckBox = JCheckBox("Enable real-time inspection")
enableRealtimeCheckBox?.toolTipText = "Enable or disable real-time code inspection as you type"
gbc.gridy = 2
gbc.insets = Insets(5, 5, 5, 5)
settingsPanel.add(enableRealtimeCheckBox, gbc)
// Real-time description label
val realtimeDescLabel = JLabel("<html><body style='width: 400px;'>" +
"When enabled, P3C inspections run automatically while editing. " +
"Disabling this can improve editor performance on large files." +
"</body></html>")
realtimeDescLabel.font = realtimeDescLabel.font.deriveFont(realtimeDescLabel.font.size2D - 1)
gbc.gridy = 3
gbc.insets = Insets(0, 25, 5, 5)
settingsPanel.add(realtimeDescLabel, gbc)
// Fill remaining space
gbc.gridy = 4
gbc.weighty = 1.0
gbc.fill = GridBagConstraints.BOTH
settingsPanel.add(JPanel(), gbc)
mainPanel?.add(settingsPanel, BorderLayout.NORTH)
reset()
return mainPanel
}
override fun isModified(): Boolean {
val config = project.getService(SmartFoxProjectConfig::class.java)
val pluginEnabled = !config.pluginGloballyDisabled
val realtimeEnabled = config.realtimeInspectionEnabled
return enablePluginCheckBox?.isSelected != pluginEnabled ||
enableRealtimeCheckBox?.isSelected != realtimeEnabled
}
override fun apply() {
val config = project.getService(SmartFoxProjectConfig::class.java)
val wasGloballyDisabled = config.pluginGloballyDisabled
val pluginEnabled = enablePluginCheckBox?.isSelected ?: true
config.pluginGloballyDisabled = !pluginEnabled
val wasRealtimeEnabled = config.realtimeInspectionEnabled
config.realtimeInspectionEnabled = enableRealtimeCheckBox?.isSelected ?: true
// Apply changes immediately if state changed
if (wasGloballyDisabled != config.pluginGloballyDisabled) {
applyPluginState(project, !config.pluginGloballyDisabled)
}
// Refresh all open files to apply changes
if (wasGloballyDisabled != config.pluginGloballyDisabled ||
wasRealtimeEnabled != config.realtimeInspectionEnabled) {
FileEditorManager.getInstance(project).openFiles.forEach { file ->
val psiFile = PsiManager.getInstance(project).findFile(file)
if (psiFile != null) {
DaemonCodeAnalyzer.getInstance(project).restart(psiFile)
}
}
}
}
override fun reset() {
val config = project.getService(SmartFoxProjectConfig::class.java)
enablePluginCheckBox?.isSelected = !config.pluginGloballyDisabled
enableRealtimeCheckBox?.isSelected = config.realtimeInspectionEnabled
}
/**
* Apply plugin enabled/disabled state
*/
private fun applyPluginState(project: Project, enable: Boolean) {
val tools = Inspections.aliInspections(project) {
it.tool is AliBaseInspection
}
InspectionProfileService.toggleInspection(project, tools, !enable)
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/config/SmartFoxProjectConfig.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.config
import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.openapi.components.State
import com.intellij.util.xmlb.XmlSerializerUtil
/**
*
*
* @author caikang
* @date 2017/03/01
*/
@State(name = "SmartFoxProjectConfig", storages = [com.intellij.openapi.components.Storage(file = "smartfox_info.xml")])
class SmartFoxProjectConfig : PersistentStateComponent<SmartFoxProjectConfig> {
var projectInspectionClosed = false
/**
* Global plugin disable state for dynamic plugin support.
* When true, all P3C inspections are completely disabled without IDE restart.
*/
var pluginGloballyDisabled = false
/**
* Individual rule disable list.
* Contains short names of disabled rules.
*/
var disabledRules: MutableSet<String> = mutableSetOf()
/**
* Enable/disable real-time inspection.
*/
var realtimeInspectionEnabled = true
override fun getState(): SmartFoxProjectConfig? {
return this
}
override fun loadState(state: SmartFoxProjectConfig) {
XmlSerializerUtil.copyBean(state, this)
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/ep/InspectionActionExtensionPoint.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.ep
import com.alibaba.smartfox.idea.common.util.PluginVersions
import com.intellij.codeInspection.ex.GlobalInspectionContextImpl
import com.intellij.codeInspection.ui.InspectionResultsView
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.project.Project
/**
*
*
* @author caikang
* @date 2017/06/19
*/
interface InspectionActionExtensionPoint {
fun doOnInspectionFinished(context: GlobalInspectionContextImpl, projectScopeSelected: Boolean) {}
fun doOnClose(noSuspiciousCodeFound: Boolean, project: Project?) {}
fun doOnView(view: InspectionResultsView) {}
companion object {
val extension = ExtensionPointName.create<InspectionActionExtensionPoint>(
"${PluginVersions.pluginId.idString}.inspectionAction")
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/ep/package-info.java
================================================
/**
* extension point
*
* @author caikang
* @date 2017/06/19
*/
package com.alibaba.p3c.idea.ep;
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/i18n/P3cBundle.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.i18n
import com.alibaba.p3c.idea.config.P3cConfig
import com.xenoamess.p3c.pmd.I18nResources
import com.alibaba.smartfox.idea.common.util.getService
import com.intellij.AbstractBundle
import com.intellij.openapi.application.CachedSingletonsRegistry
import java.util.Locale
import java.util.ResourceBundle
import java.util.function.Supplier
/**
*
*
* @author caikang
* @date 2017/06/20
*/
object P3cBundle {
private val p3cConfigSupplier: Supplier<P3cConfig> =
CachedSingletonsRegistry.lazy {
P3cConfig::class.java.getService()
}
private val resourceBundleSupplier =
CachedSingletonsRegistry.lazy {
ResourceBundle.getBundle(
"messages.P3cBundle",
Locale(p3cConfigSupplier.get().locale), I18nResources.XmlControl()
)
}
fun getMessage(key: String): String {
return resourceBundleSupplier.get().getString(key).trim()
}
fun message(key: String, vararg params: Any): String {
return AbstractBundle.message(resourceBundleSupplier.get(), key, *params).trim()
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliAccessToNonThreadSafeStaticFieldFromInstanceInspection.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.siyeh.ig.threading.AccessToNonThreadSafeStaticFieldFromInstanceInspection
/**
* @author caikang
* @date 2016/12/08
*/
class AliAccessToNonThreadSafeStaticFieldFromInstanceInspection
: AccessToNonThreadSafeStaticFieldFromInstanceInspection,
AliBaseInspection {
constructor()
/**
* For Javassist
*/
constructor(any: Any?) : this()
init {
nonThreadSafeClasses.clear()
nonThreadSafeClasses.add("java.text.SimpleDateFormat")
}
override fun ruleName(): String {
return "AvoidCallStaticSimpleDateFormatRule"
}
override fun getDisplayName(): String {
return RuleInspectionUtils.getRuleMessage(ruleName())
}
override fun buildErrorString(vararg infos: Any): String {
return P3cBundle.getMessage("com.alibaba.p3c.idea.inspection.rule.AvoidCallStaticSimpleDateFormatRule.errMsg")
}
override fun getStaticDescription(): String? {
return RuleInspectionUtils.getRuleStaticDescription(ruleName())
}
override fun getDefaultLevel(): HighlightDisplayLevel {
return RuleInspectionUtils.getHighlightDisplayLevel(ruleName())
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliArrayNamingShouldHaveBracketInspection.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.alibaba.p3c.idea.quickfix.DecorateInspectionGadgetsFix
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiField
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiParameter
import com.siyeh.ig.InspectionGadgetsFix
import com.siyeh.ig.style.CStyleArrayDeclarationInspection
import javax.swing.JComponent
/**
*
* Batch QuickFix Supported
* @author caikang
* @date 2017/02/26
*/
class AliArrayNamingShouldHaveBracketInspection : CStyleArrayDeclarationInspection, AliBaseInspection {
constructor()
/**
* ForJavassist
*/
constructor(any: Any?) : this()
override fun ruleName(): String {
return "ArrayNamingShouldHaveBracketRule"
}
override fun getDisplayName(): String {
return RuleInspectionUtils.getRuleMessage(ruleName())
}
override fun getShortName(): String {
return "AliArrayNamingShouldHaveBracket"
}
override fun getStaticDescription(): String? {
return RuleInspectionUtils.getRuleStaticDescription(ruleName())
}
override fun getDefaultLevel(): HighlightDisplayLevel {
return RuleInspectionUtils.getHighlightDisplayLevel(ruleName())
}
override fun createOptionsPanel(): JComponent? {
return null
}
override fun buildErrorString(vararg infos: Any?): String {
val info = infos[0]
if (info is PsiMethod) {
return displayName
}
val choice = if (info is PsiField) 1 else if (info is PsiParameter) 2 else 3
return P3cBundle.message("com.alibaba.p3c.idea.inspection.rule.ArrayNamingShouldHaveBracketRule.errMsg", choice)
}
override fun buildFix(vararg infos: Any): InspectionGadgetsFix? {
val fix = super.buildFix(*infos) ?: return null
return DecorateInspectionGadgetsFix(fix,
P3cBundle.getMessage("com.alibaba.p3c.idea.quickfix.ArrayNamingShouldHaveBracketRule"))
}
override fun manualBuildFix(psiElement: PsiElement, isOnTheFly: Boolean): LocalQuickFix? {
return buildFix(psiElement)
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliBaseInspection.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.intellij.codeInspection.InspectionManager
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
/**
* @author caikang
* @date 2016/12/08
*/
interface AliBaseInspection {
/**
* ruleName
* @return ruleName
*/
fun ruleName(): String
/**
* display info for inspection
* @return display
*/
fun getDisplayName(): String
/**
* group display info for inspection
* @return group display
*/
fun getGroupDisplayName(): String
/**
* inspection enable by default
* @return true -> enable
*/
fun isEnabledByDefault(): Boolean
/**
* default inspection level
* @return level
*/
fun getDefaultLevel(): HighlightDisplayLevel
/**
* inspection short name
* @return short name
*/
fun getShortName(): String
fun manualBuildFix(psiElement: PsiElement, isOnTheFly: Boolean): LocalQuickFix? = null
fun manualParsePsiElement(
psiFile: PsiFile,
manager: InspectionManager,
start: Int,
end: Int
): PsiElement {
return psiFile.findElementAt(start)!!
}
companion object {
const val GROUP_NAME = "Ali-Check"
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliControlFlowStatementWithoutBracesInspection.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.alibaba.p3c.idea.quickfix.DecorateInspectionGadgetsFix
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.psi.PsiElement
import com.siyeh.ig.InspectionGadgetsFix
import com.siyeh.ig.style.ControlFlowStatementWithoutBracesInspection
/**
* Batch QuickFix Supported
* @author caikang
* @date 2016/12/15
*/
class AliControlFlowStatementWithoutBracesInspection
: ControlFlowStatementWithoutBracesInspection,
AliBaseInspection {
constructor()
/**
* For Javassist
*/
constructor(any: Any?) : this()
override fun ruleName(): String {
return "NeedBraceRule"
}
override fun getDisplayName(): String {
return RuleInspectionUtils.getRuleMessage(ruleName())
}
override fun buildErrorString(vararg infos: Any): String {
return P3cBundle.getMessage("com.alibaba.p3c.idea.inspection.rule.NeedBraceRule.errMsg")
}
override fun getStaticDescription(): String? {
return RuleInspectionUtils.getRuleStaticDescription(ruleName())
}
override fun getDefaultLevel(): HighlightDisplayLevel {
return RuleInspectionUtils.getHighlightDisplayLevel(ruleName())
}
override fun buildFix(vararg infos: Any): InspectionGadgetsFix? {
val fix = super.buildFix(*infos) ?: return null
return DecorateInspectionGadgetsFix(fix, P3cBundle.getMessage("com.alibaba.p3c.idea.quickfix.NeedBraceRule"))
}
override fun manualBuildFix(psiElement: PsiElement, isOnTheFly: Boolean): LocalQuickFix? {
return buildFix(psiElement)
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliEqualsAvoidNullInspection.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.alibaba.p3c.idea.quickfix.DecorateInspectionGadgetsFix
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.intellij.codeInspection.InspectionManager
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiField
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiLiteralExpression
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiReferenceExpression
import com.siyeh.HardcodedMethodConstants
import com.siyeh.ig.BaseInspectionVisitor
import com.siyeh.ig.InspectionGadgetsFix
import com.siyeh.ig.psiutils.TypeUtils
import com.siyeh.ig.style.LiteralAsArgToStringEqualsInspection
import org.jetbrains.annotations.NonNls
/**
*
* Batch QuickFix Supported
* @author caikang
* @date 2017/02/27
*/
class AliEqualsAvoidNullInspection : LiteralAsArgToStringEqualsInspection, AliBaseInspection {
constructor()
/**
* For Javassist
*/
constructor(any: Any?) : this()
override fun ruleName(): String {
return "EqualsAvoidNullRule"
}
override fun getDisplayName(): String {
return RuleInspectionUtils.getRuleMessage(ruleName())
}
override fun buildErrorString(vararg infos: Any?): String {
val methodName = infos[0] as String
return String.format(P3cBundle.getMessage("com.alibaba.p3c.idea.inspection.rule.AliEqualsAvoidNull.errMsg"),
methodName)
}
override fun getShortName(): String {
return "AliEqualsAvoidNull"
}
override fun getStaticDescription(): String? {
return RuleInspectionUtils.getRuleStaticDescription(ruleName())
}
override fun getDefaultLevel(): HighlightDisplayLevel {
return RuleInspectionUtils.getHighlightDisplayLevel(ruleName())
}
override fun buildVisitor(): BaseInspectionVisitor {
return LiteralAsArgToEqualsVisitor()
}
private class LiteralAsArgToEqualsVisitor : BaseInspectionVisitor() {
override fun visitMethodCallExpression(
expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
val methodExpression = expression.methodExpression
@NonNls val methodName = methodExpression.referenceName
if (HardcodedMethodConstants.EQUALS != methodName && HardcodedMethodConstants.EQUALS_IGNORE_CASE != methodName) {
return
}
val argList = expression.argumentList
val args = argList.expressions
if (args.size != 1) {
return
}
val argument = args[0]
val argumentType = argument.type ?: return
if (argument !is PsiLiteralExpression && !isConstantField(argument)) {
return
}
if (!TypeUtils.isJavaLangString(argumentType)) {
return
}
val target = methodExpression.qualifierExpression
if (target is PsiLiteralExpression || isConstantField(argument)) {
return
}
registerError(argument, methodName)
}
private fun isConstantField(argument: PsiExpression): Boolean {
if (argument !is PsiReferenceExpression) {
return false
}
val psiField = argument.resolve() as? PsiField ?: return false
val modifierList = psiField.modifierList ?: return false
return modifierList.hasModifierProperty("final") && modifierList.hasModifierProperty("static")
}
}
override fun buildFix(vararg infos: Any): InspectionGadgetsFix? {
val fix = super.buildFix(*infos) ?: return null
return DecorateInspectionGadgetsFix(fix,
P3cBundle.getMessage("com.alibaba.p3c.idea.quickfix.AliEqualsAvoidNull"))
}
override fun manualBuildFix(psiElement: PsiElement, isOnTheFly: Boolean): LocalQuickFix? {
return buildFix(psiElement)
}
override fun manualParsePsiElement(psiFile: PsiFile, manager: InspectionManager, start: Int, end: Int): PsiElement {
return psiFile.findElementAt(start)!!.parent.parent
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliLocalInspectionToolProvider.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.alibaba.p3c.idea.config.P3cConfig
import com.alibaba.p3c.idea.inspection.standalone.AliAccessStaticViaInstanceInspection
import com.alibaba.p3c.idea.inspection.standalone.AliDeprecationInspection
import com.alibaba.p3c.idea.inspection.standalone.AliMissingOverrideAnnotationInspection
import com.alibaba.p3c.idea.inspection.standalone.MapOrSetKeyShouldOverrideHashCodeEqualsInspection
import com.alibaba.smartfox.idea.common.util.getService
import com.beust.jcommander.internal.Lists
import com.beust.jcommander.internal.Maps
import com.intellij.codeInspection.InspectionToolProvider
import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.psi.PsiCompiledFile
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiImportList
import com.intellij.psi.PsiJavaFile
import com.xenoamess.p3c.pmd.I18nResources
import javassist.CannotCompileException
import javassist.ClassClassPath
import javassist.ClassPool
import javassist.CtField
import javassist.NotFoundException
import net.sourceforge.pmd.Rule
import net.sourceforge.pmd.RuleSet
import net.sourceforge.pmd.RuleSetFactory
import net.sourceforge.pmd.RuleSets
import javax.annotation.Generated
/**
* @author caikang
* @date 2016/12/16
*/
class AliLocalInspectionToolProvider : InspectionToolProvider {
override fun getInspectionClasses(): Array<Class<out LocalInspectionTool>> {
return CLASS_LIST.toTypedArray()
}
interface ShouldInspectChecker {
/**
* check inspect whether or not
* @param file file to inspect
* @return true or false
*/
fun shouldInspect(file: PsiFile): Boolean
}
class RuleInfo(var rule: Rule, var shouldInspectChecker: ShouldInspectChecker)
companion object {
val ruleInfoMap: MutableMap<String, RuleInfo> = Maps.newHashMap()
private val LOGGER = Logger.getInstance(AliLocalInspectionToolProvider::class.java)
val ruleNames: MutableList<String> = Lists.newArrayList()!!
private val CLASS_LIST = Lists.newArrayList<Class<LocalInspectionTool>>()
private val nativeInspectionToolClass = arrayListOf<Class<out LocalInspectionTool>>(
AliMissingOverrideAnnotationInspection::class.java,
AliAccessStaticViaInstanceInspection::class.java,
AliDeprecationInspection::class.java,
MapOrSetKeyShouldOverrideHashCodeEqualsInspection::class.java,
AliArrayNamingShouldHaveBracketInspection::class.java,
AliControlFlowStatementWithoutBracesInspection::class.java,
AliEqualsAvoidNullInspection::class.java,
AliLongLiteralsEndingWithLowercaseLInspection::class.java,
AliWrapperTypeEqualityInspection::class.java
)
val javaShouldInspectChecker = object : ShouldInspectChecker {
override fun shouldInspect(file: PsiFile): Boolean {
val basicInspect = file is PsiJavaFile && file !is PsiCompiledFile
if (!basicInspect) {
return false
}
if (!validScope(file)) {
return false
}
val importList = file.children.firstOrNull {
it is PsiImportList
} as? PsiImportList ?: return true
return !importList.allImportStatements.any {
it.text.contains(Generated::class.java.name)
}
}
private fun validScope(file: PsiFile): Boolean {
val virtualFile = file.virtualFile
val index = ProjectRootManager.getInstance(file.project).fileIndex
return index.isInSource(virtualFile)
&& !index.isInTestSourceContent(virtualFile)
&& !index.isInLibraryClasses(virtualFile)
&& !index.isInLibrarySource(virtualFile)
}
}
init {
I18nResources.setLanguageSupplier(
{
P3cConfig::class.java.getService().locale
}
)
Thread.currentThread().contextClassLoader = AliLocalInspectionToolProvider::class.java.classLoader
initPmdInspection()
initNativeInspection()
}
private fun initNativeInspection() {
val pool = ClassPool.getDefault()
pool.insertClassPath(ClassClassPath(DelegateLocalInspectionTool::class.java))
nativeInspectionToolClass.forEach {
pool.insertClassPath(ClassClassPath(it))
val cc = pool.get(DelegateLocalInspectionTool::class.java.name)
cc.name = "Delegate${it.simpleName}"
val ctField = cc.getField("forJavassist")
cc.removeField(ctField)
val itClass = pool.get(it.name)
val toolClass = pool.get(LocalInspectionTool::class.java.name)
val newField = CtField(toolClass, "forJavassist", cc)
cc.addField(newField, CtField.Initializer.byNew(itClass))
CLASS_LIST.add(cc.toClass() as Class<LocalInspectionTool>)
}
}
private fun initPmdInspection() {
for (ri in newRuleInfos()) {
this.ruleNames.add(ri.rule.name)
ruleInfoMap[ri.rule.name] = ri
}
val pool = ClassPool.getDefault()
pool.insertClassPath(ClassClassPath(DelegatePmdInspection::class.java))
try {
for (ruleInfo in ruleInfoMap.values) {
val cc = pool.get(DelegatePmdInspection::class.java.name)
cc.name = ruleInfo.rule.name + "Inspection"
val ctField = cc.getField("ruleName")
cc.removeField(ctField)
val value = "\"" + ruleInfo.rule.name + "\""
val newField = CtField.make("private String ruleName = $value;", cc)
cc.addField(newField, value)
CLASS_LIST.add(cc.toClass() as Class<LocalInspectionTool>)
}
} catch (e: NotFoundException) {
LOGGER.error(e)
} catch (e: CannotCompileException) {
LOGGER.error(e)
}
}
private fun newRuleInfos(): List<RuleInfo> {
val result = Lists.newArrayList<RuleInfo>()
result.addAll(processForRuleSet("java/ali-pmd", javaShouldInspectChecker))
result.addAll(processForRuleSet("vm/ali-other", object : ShouldInspectChecker {
override fun shouldInspect(file: PsiFile): Boolean {
val virtualFile = file.virtualFile ?: return false
val path = virtualFile.canonicalPath
return path != null && path.endsWith(".vm")
}
}))
return result
}
fun getRuleSet(ruleSetName: String): RuleSet {
val factory = RuleSetFactory()
return factory.createRuleSet(ruleSetName.replace("/", "-"))
}
fun getRuleSetList(): List<RuleSet> {
return listOf(getRuleSet("java/ali-pmd"), getRuleSet("vm/ali-other"))
}
fun getRuleSets(): RuleSets {
return RuleSets().also { rs ->
for (ruleSet in getRuleSetList()) {
rs.addRuleSet(ruleSet)
}
}
}
private fun processForRuleSet(ruleSetName: String, shouldInspectChecker: ShouldInspectChecker): List<RuleInfo> {
val result = Lists.newArrayList<RuleInfo>()
try {
val ruleSet = getRuleSet(ruleSetName)
ruleSet.rules.mapTo(result) {
RuleInfo(it, shouldInspectChecker)
}
} catch (e: Exception) {
LOGGER.error(String.format("rule set %s load failed for", ruleSetName))
}
return result
}
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliLongLiteralsEndingWithLowercaseLInspection.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.alibaba.p3c.idea.quickfix.DecorateInspectionGadgetsFix
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.intellij.codeInspection.InspectionManager
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.siyeh.ig.InspectionGadgetsFix
import com.siyeh.ig.numeric.LongLiteralsEndingWithLowercaseLInspection
/**
*
* Batch QuickFix Supported
* @author caikang
* @date 2017/01/20
*/
class AliLongLiteralsEndingWithLowercaseLInspection : LongLiteralsEndingWithLowercaseLInspection, AliBaseInspection {
constructor()
/**
* For Javassist
*/
constructor(any: Any?) : this()
override fun ruleName(): String {
return "UpperEllRule"
}
override fun getDisplayName(): String {
return RuleInspectionUtils.getRuleMessage(ruleName())
}
override fun buildErrorString(vararg infos: Any?): String {
return P3cBundle.getMessage("com.alibaba.p3c.idea.inspection.rule.AliLongLiteralsEndingWithLowercaseL.errMsg")
}
override fun getShortName(): String {
return "AliLongLiteralsEndingWithLowercaseL"
}
override fun getStaticDescription(): String? {
return RuleInspectionUtils.getRuleStaticDescription(ruleName())
}
override fun getDefaultLevel(): HighlightDisplayLevel {
return RuleInspectionUtils.getHighlightDisplayLevel(ruleName())
}
override fun buildFix(vararg infos: Any): InspectionGadgetsFix? {
val fix = super.buildFix(*infos) ?: return null
return DecorateInspectionGadgetsFix(fix,
P3cBundle.getMessage("com.alibaba.p3c.idea.quickfix.AliLongLiteralsEndingWithLowercaseL"))
}
override fun manualBuildFix(psiElement: PsiElement, isOnTheFly: Boolean): LocalQuickFix? {
return buildFix(psiElement)
}
override fun manualParsePsiElement(psiFile: PsiFile, manager: InspectionManager, start: Int, end: Int): PsiElement {
return psiFile.findElementAt(start)!!.parent
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliPmdInspection.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.alibaba.p3c.idea.config.SmartFoxProjectConfig
import com.alibaba.p3c.idea.inspection.AliLocalInspectionToolProvider.ShouldInspectChecker
import com.alibaba.p3c.idea.util.NumberConstants
import com.alibaba.p3c.idea.util.QuickFixes
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.intellij.codeInspection.InspectionManager
import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.components.ServiceManager
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import net.sourceforge.pmd.Rule
import org.jetbrains.annotations.Nls
/**
* @author caikang
* @date 2016/12/16
*/
class AliPmdInspection(private val ruleName: String) : LocalInspectionTool(),
AliBaseInspection,
PmdRuleInspectionIdentify {
override fun manualBuildFix(psiElement: PsiElement, isOnTheFly: Boolean): LocalQuickFix? {
return QuickFixes.getQuickFix(ruleName, isOnTheFly)
}
private val staticDescription: String = RuleInspectionUtils.getRuleStaticDescription(ruleName)
private val displayName: String
private val shouldInspectChecker: ShouldInspectChecker
private val defaultLevel: HighlightDisplayLevel
private val rule: Rule
init {
val ruleInfo = AliLocalInspectionToolProvider.ruleInfoMap[ruleName]!!
shouldInspectChecker = ruleInfo.shouldInspectChecker
rule = ruleInfo.rule
displayName = rule.message
defaultLevel = RuleInspectionUtils.getHighlightDisplayLevel(rule.priority)
}
override fun runForWholeFile(): Boolean {
return true
}
override fun checkFile(
file: PsiFile, manager: InspectionManager,
isOnTheFly: Boolean
): Array<ProblemDescriptor>? {
// Check if plugin is globally disabled (for dynamic plugin support)
val config = ServiceManager.getService(SmartFoxProjectConfig::class.java)
if (config == null) {
return null
}
if (config.pluginGloballyDisabled) {
return null
}
// Check if real-time inspection is disabled (for on-the-fly checks)
if (isOnTheFly && !config.realtimeInspectionEnabled) {
return null
}
// Check individual rule disable list
if (config.disabledRules.contains(getShortName())) {
return null
}
if (!shouldInspectChecker.shouldInspect(file)) {
return null
}
return AliPmdInspectionInvoker.invokeInspection(file, manager, rule, isOnTheFly)
}
override fun getStaticDescription(): String? {
return staticDescription
}
override fun ruleName(): String {
return ruleName
}
@Nls
override fun getDisplayName(): String {
return displayName
}
override fun getDefaultLevel(): HighlightDisplayLevel {
return defaultLevel
}
@Nls
override fun getGroupDisplayName(): String {
return AliBaseInspection.GROUP_NAME
}
override fun isEnabledByDefault(): Boolean {
return true
}
override fun getShortName(): String {
var shortName = "Alibaba$ruleName"
val index = shortName.lastIndexOf("Rule")
if (index > NumberConstants.INDEX_0) {
shortName = shortName.substring(NumberConstants.INDEX_0, index)
}
return shortName
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliPmdInspectionInvoker.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.alibaba.p3c.idea.component.AliProjectComponent
import com.alibaba.p3c.idea.config.P3cConfig
import com.alibaba.p3c.idea.pmd.AliPmdProcessor
import com.alibaba.p3c.idea.util.DocumentUtils.calculateLineStart
import com.alibaba.p3c.idea.util.DocumentUtils.calculateRealOffset
import com.alibaba.p3c.idea.util.ProblemsUtils
import com.xenoamess.p3c.pmd.lang.java.rule.comment.RemoveCommentedCodeRule
import com.beust.jcommander.internal.Lists
import com.google.common.cache.Cache
import com.google.common.cache.CacheBuilder
import com.intellij.codeInspection.InspectionManager
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import net.sourceforge.pmd.Rule
import net.sourceforge.pmd.RuleViolation
import java.util.concurrent.TimeUnit
/**
* @author caikang
* @date 2016/12/13
*/
class AliPmdInspectionInvoker(
private val psiFile: PsiFile,
private val manager: InspectionManager,
private val rule: Rule
) {
private val logger = Logger.getInstance(javaClass)
private var violations: List<RuleViolation> = emptyList()
fun doInvoke(isOnTheFly: Boolean) {
Thread.currentThread().contextClassLoader = javaClass.classLoader
val processor = AliPmdProcessor(rule)
val start = System.currentTimeMillis()
val aliProjectComponent = manager.project.getComponent(AliProjectComponent::class.java)
val fileContext = aliProjectComponent.getFileContext(psiFile.virtualFile)
val ruleViolations = fileContext?.ruleViolations
violations = if (isOnTheFly || ruleViolations == null) {
processor.processFile(psiFile, isOnTheFly)
} else {
ruleViolations[rule.name] ?: emptyList()
}
logger.debug(
"elapsed ${System.currentTimeMillis() - start}ms to" +
" to apply rule ${rule.name} for file ${psiFile.virtualFile.canonicalPath}"
)
}
fun getRuleProblems(isOnTheFly: Boolean): Array<ProblemDescriptor>? {
if (violations.isEmpty()) {
return null
}
val problemDescriptors = Lists.newArrayList<ProblemDescriptor>(violations.size)
for (rv in violations) {
val virtualFile = LocalFileSystem.getInstance().findFileByPath(rv.filename)
?: continue
val psiFile = PsiManager.getInstance(manager.project).findFile(virtualFile)
?: continue
val document = FileDocumentManager.getInstance().getDocument(virtualFile)
?: continue
val offsets = if (rv.rule.name == RemoveCommentedCodeRule::class.java.simpleName) {
Offsets(
calculateLineStart(document, rv.beginLine),
calculateLineStart(document, rv.endLine + 1) - 1
)
} else {
Offsets(
calculateRealOffset(document, rv.beginLine, rv.beginColumn),
calculateRealOffset(document, rv.endLine, rv.endColumn)
)
}
val errorMessage = if (isOnTheFly) {
rv.description
} else {
"${rv.description} (line ${rv.beginLine})"
}
val problemDescriptor = ProblemsUtils.createProblemDescriptorForPmdRule(
psiFile,
manager,
isOnTheFly,
rv.rule.name,
errorMessage,
offsets.start,
offsets.end,
rv.beginLine
) ?: continue
problemDescriptors.add(problemDescriptor)
}
return problemDescriptors.toTypedArray()
}
companion object {
private lateinit var invokers: Cache<FileRule, AliPmdInspectionInvoker>
val smartFoxConfig = ServiceManager.getService(P3cConfig::class.java)!!
init {
reInitInvokers(smartFoxConfig.ruleCacheTime)
}
fun invokeInspection(
psiFile: PsiFile?,
manager: InspectionManager,
rule: Rule,
isOnTheFly: Boolean
): Array<ProblemDescriptor>? {
if (psiFile == null) {
return null
}
val virtualFile = psiFile.virtualFile ?: return null
if (!smartFoxConfig.ruleCacheEnable) {
val invoker = AliPmdInspectionInvoker(psiFile, manager, rule)
invoker.doInvoke(isOnTheFly)
return invoker.getRuleProblems(isOnTheFly)
}
var invoker = invokers.getIfPresent(FileRule(virtualFile.canonicalPath!!, rule.name))
if (invoker == null) {
synchronized(virtualFile) {
invoker = invokers.getIfPresent(virtualFile.canonicalPath!!)
if (invoker == null) {
invoker = AliPmdInspectionInvoker(psiFile, manager, rule)
invoker!!.doInvoke(isOnTheFly)
invokers.put(FileRule(virtualFile.canonicalPath!!, rule.name), invoker!!)
}
}
}
return invoker!!.getRuleProblems(isOnTheFly)
}
private fun doInvokeIfPresent(filePath: String, rule: String, isOnTheFly: Boolean) {
invokers.getIfPresent(FileRule(filePath, rule))?.doInvoke(isOnTheFly)
}
fun refreshFileViolationsCache(file: VirtualFile) {
AliLocalInspectionToolProvider.ruleNames.forEach {
doInvokeIfPresent(file.canonicalPath!!, it, false)
}
}
fun reInitInvokers(expireTime: Long) {
invokers = CacheBuilder.newBuilder().maximumSize(500).expireAfterWrite(
expireTime,
TimeUnit.MILLISECONDS
).build<FileRule, AliPmdInspectionInvoker>()!!
}
/**
* Clear all file violations cache for dynamic plugin unload.
*/
fun clearAllFileViolationsCache() {
if (::invokers.isInitialized) {
invokers.invalidateAll()
}
}
}
}
data class FileRule(val filePath: String, val ruleName: String)
data class Offsets(val start: Int, val end: Int)
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliWrapperTypeEqualityInspection.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.alibaba.p3c.idea.quickfix.DecorateInspectionGadgetsFix
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.CommonClassNames
import com.intellij.psi.JavaTokenType
import com.intellij.psi.PsiArrayType
import com.intellij.psi.PsiBinaryExpression
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiExpression
import com.intellij.util.IncorrectOperationException
import com.siyeh.ig.BaseInspection
import com.siyeh.ig.BaseInspectionVisitor
import com.siyeh.ig.InspectionGadgetsFix
import com.siyeh.ig.PsiReplacementUtil
import com.siyeh.ig.fixes.EqualityToEqualsFix
import com.siyeh.ig.psiutils.ComparisonUtils
import com.siyeh.ig.psiutils.TypeUtils
import org.jetbrains.annotations.NonNls
/**
*
* Batch QuickFix Supported
* @author caikang
* @date 2017/02/27
*/
class AliWrapperTypeEqualityInspection : BaseInspection, AliBaseInspection {
constructor()
/**
* For Javassist
*/
constructor(any: Any?) : this()
fun familyName(): String {
return replaceWith() + " equals"
}
override fun buildErrorString(vararg infos: Any?): String {
return P3cBundle.getMessage("com.alibaba.p3c.idea.inspection.rule.WrapperTypeEqualityRule.errMsg")
}
override fun buildVisitor(): BaseInspectionVisitor {
return ObjectComparisonVisitor()
}
override fun ruleName(): String {
return "WrapperTypeEqualityRule"
}
override fun getDisplayName(): String {
return RuleInspectionUtils.getRuleMessage(ruleName())
}
override fun getShortName(): String {
return "AliWrapperTypeEquality"
}
override fun getStaticDescription(): String? {
return RuleInspectionUtils.getRuleStaticDescription(ruleName())
}
override fun getDefaultLevel(): HighlightDisplayLevel {
return RuleInspectionUtils.getHighlightDisplayLevel(ruleName())
}
public override fun buildFix(vararg infos: Any): InspectionGadgetsFix? {
if (infos.isEmpty()) {
return DecorateInspectionGadgetsFix(EqualityToEqualsFix(), familyName())
}
val type = infos[0] as PsiArrayType
val componentType = type.componentType
val fix = ArrayEqualityFix(componentType is PsiArrayType, familyName())
return DecorateInspectionGadgetsFix(fix, fix.name, familyName())
}
private inner class ObjectComparisonVisitor : BaseInspectionVisitor() {
override fun visitBinaryExpression(expression: PsiBinaryExpression) {
if (!ComparisonUtils.isEqualityComparison(expression)) {
return
}
checkForWrapper(expression)
}
private fun checkForWrapper(expression: PsiBinaryExpression) {
val rhs = expression.rOperand ?: return
val lhs = expression.lOperand
if (!isWrapperType(lhs) || !isWrapperType(rhs)) {
return
}
registerError(expression.operationSign)
}
private fun isWrapperType(expression: PsiExpression): Boolean {
if (hasNumberType(expression)) {
return true
}
return TypeUtils.expressionHasTypeOrSubtype(expression, CommonClassNames.JAVA_LANG_BOOLEAN)
|| TypeUtils.expressionHasTypeOrSubtype(expression, CommonClassNames.JAVA_LANG_CHARACTER)
}
private fun hasNumberType(expression: PsiExpression): Boolean {
return TypeUtils.expressionHasTypeOrSubtype(expression, CommonClassNames.JAVA_LANG_NUMBER)
}
/**
* checkForNumber end
*/
}
private class ArrayEqualityFix(private val deepEquals: Boolean, private val familyName: String) :
InspectionGadgetsFix() {
override fun getName(): String {
return if (deepEquals) {
replaceWith() + " 'Arrays.deepEquals()'"
} else {
replaceWith() + " 'Arrays.equals()'"
}
}
override fun getFamilyName(): String {
return familyName
}
@Throws(IncorrectOperationException::class)
override fun doFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.psiElement
val parent = element.parent as? PsiBinaryExpression ?: return
val tokenType = parent.operationTokenType
@NonNls
val newExpressionText = StringBuilder()
if (JavaTokenType.NE == tokenType) {
newExpressionText.append('!')
} else if (JavaTokenType.EQEQ != tokenType) {
return
}
if (deepEquals) {
newExpressionText.append("java.util.Arrays.deepEquals(")
} else {
newExpressionText.append("java.util.Arrays.equals(")
}
newExpressionText.append(parent.lOperand.text)
newExpressionText.append(',')
val rhs = parent.rOperand ?: return
newExpressionText.append(rhs.text)
newExpressionText.append(')')
PsiReplacementUtil.replaceExpressionAndShorten(
parent,
newExpressionText.toString()
)
}
}
override fun manualBuildFix(psiElement: PsiElement, isOnTheFly: Boolean): LocalQuickFix? {
val expression = psiElement.parent as? PsiBinaryExpression
?: return null
val rhs = expression.rOperand ?: return null
val lhs = expression.lOperand
val lhsType = lhs.type
if (lhsType !is PsiArrayType || rhs.type !is PsiArrayType) {
return buildFix()
}
return buildFix(lhsType)
}
companion object {
@JvmStatic
fun replaceWith(): String {
return P3cBundle.getMessage("com.alibaba.p3c.idea.quickfix.replace.with")
}
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/DelegateLocalInspectionTool.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.intellij.codeInspection.InspectionManager
import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiFile
import org.jetbrains.annotations.Nls
/**
*
* @author caikang
* @date 2017/07/19
*/
class DelegateLocalInspectionTool : LocalInspectionTool(), AliBaseInspection {
private val forJavassist: LocalInspectionTool? = null
private val localInspectionTool: LocalInspectionTool
init {
localInspectionTool = forJavassist ?: throw IllegalStateException()
}
override fun runForWholeFile(): Boolean {
return localInspectionTool.runForWholeFile()
}
override fun checkFile(
file: PsiFile,
manager: InspectionManager,
isOnTheFly: Boolean
): Array<ProblemDescriptor?>? {
return localInspectionTool.checkFile(file, manager, isOnTheFly)
}
override fun getStaticDescription(): String? {
return localInspectionTool.staticDescription
}
override fun ruleName(): String {
return (localInspectionTool as AliBaseInspection).ruleName()
}
@Nls
override fun getDisplayName(): String {
return localInspectionTool.displayName
}
override fun getDefaultLevel(): HighlightDisplayLevel {
return localInspectionTool.defaultLevel
}
@Nls
override fun getGroupDisplayName(): String {
return AliBaseInspection.GROUP_NAME
}
override fun isEnabledByDefault(): Boolean {
return true
}
override fun getShortName(): String {
return localInspectionTool.shortName
}
override fun isSuppressedFor(element: PsiElement): Boolean {
return localInspectionTool.isSuppressedFor(element)
}
override fun buildVisitor(
holder: ProblemsHolder,
isOnTheFly: Boolean,
session: LocalInspectionToolSession
): PsiElementVisitor {
if (!AliLocalInspectionToolProvider.javaShouldInspectChecker.shouldInspect(holder.file)) {
return PsiElementVisitor.EMPTY_VISITOR
}
return localInspectionTool.buildVisitor(holder, isOnTheFly, session)
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/DelegatePmdInspection.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.intellij.codeInspection.InspectionManager
import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import org.jetbrains.annotations.Nls
/**
* @author caikang
* @date 2017/02/28
*/
class DelegatePmdInspection : LocalInspectionTool(), AliBaseInspection, PmdRuleInspectionIdentify {
private val ruleName: String? = null
private val aliPmdInspection: AliPmdInspection
init {
aliPmdInspection = AliPmdInspection(ruleName!!)
}
override fun runForWholeFile(): Boolean {
return aliPmdInspection.runForWholeFile()
}
override fun checkFile(
file: PsiFile,
manager: InspectionManager,
isOnTheFly: Boolean
): Array<ProblemDescriptor>? {
return aliPmdInspection.checkFile(file, manager, isOnTheFly)
}
override fun getStaticDescription(): String? {
return aliPmdInspection.staticDescription
}
override fun ruleName(): String {
return ruleName!!
}
@Nls
override fun getDisplayName(): String {
return aliPmdInspection.displayName
}
override fun getDefaultLevel(): HighlightDisplayLevel {
return aliPmdInspection.defaultLevel
}
@Nls
override fun getGroupDisplayName(): String {
return aliPmdInspection.groupDisplayName
}
override fun isEnabledByDefault(): Boolean {
return aliPmdInspection.isEnabledByDefault
}
override fun getShortName(): String {
return aliPmdInspection.shortName
}
override fun isSuppressedFor(element: PsiElement): Boolean {
return aliPmdInspection.isSuppressedFor(element)
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/PmdRuleInspectionIdentify.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
/**
*
*
* @author caikang
* @date 2017/03/16
6
*/
interface PmdRuleInspectionIdentify
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/RuleInspectionUtils.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection
import com.alibaba.p3c.idea.config.P3cConfig
import com.alibaba.p3c.idea.util.HighlightDisplayLevels
import com.alibaba.p3c.idea.util.NumberConstants
import com.xenoamess.p3c.pmd.I18nResources
import com.alibaba.smartfox.idea.common.util.getService
import com.google.common.base.Joiner
import com.google.common.collect.ImmutableMap
import com.google.common.collect.Lists
import com.google.common.collect.Maps
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.util.io.FileUtil
import com.intellij.util.io.URLUtil
import freemarker.template.Configuration
import freemarker.template.TemplateException
import net.sourceforge.pmd.Rule
import net.sourceforge.pmd.RulePriority
import net.sourceforge.pmd.RuleSetFactory
import net.sourceforge.pmd.RuleSetNotFoundException
import org.apache.commons.lang3.StringUtils
import java.io.File
import java.io.IOException
import java.io.StringWriter
import java.net.URL
import java.net.URLDecoder
import java.nio.charset.StandardCharsets
import java.util.jar.JarFile
import java.util.regex.Pattern
/**
* @author caikang
* @date 2016/12/16
*/
object RuleInspectionUtils {
private val logger = Logger.getInstance(RuleInspectionUtils::class.java)
private val ruleSetFilePattern = Pattern.compile("(java|vm)/ali-.*?\\.xml")
private val staticDescriptionTemplate = run {
val cfg = Configuration(Configuration.VERSION_2_3_25)
cfg.setClassForTemplateLoading(RuleInspectionUtils::class.java, "/tpl")
cfg.defaultEncoding = "UTF-8"
cfg.getTemplate("StaticDescriptionTemplate.ftl")
}
private const val ruleSetsPrefix = "rulesets/"
private val ruleStaticDescriptions: Map<String, String>
private val ruleMessages: Map<String, String>
private val displayLevelMap: Map<String, HighlightDisplayLevel>
init {
I18nResources.setLanguageSupplier(
{
P3cConfig::class.java.getService().locale
}
)
val builder = ImmutableMap.builder<String, String>()
val messageBuilder = ImmutableMap.builder<String, String>()
val displayLevelBuilder = ImmutableMap.builder<String, HighlightDisplayLevel>()
val rules = loadAllAlibabaRule()
for (rule in rules) {
builder.put(rule.name, parseStaticDescription(rule))
messageBuilder.put(rule.name, rule.message)
displayLevelBuilder.put(rule.name, getHighlightDisplayLevel(rule.priority))
}
ruleStaticDescriptions = builder.build()
ruleMessages = messageBuilder.build()
displayLevelMap = displayLevelBuilder.build()
}
fun getRuleStaticDescription(ruleName: String): String {
return ruleStaticDescriptions[ruleName]!!
}
fun getHighlightDisplayLevel(ruleName: String): HighlightDisplayLevel {
val level = displayLevelMap[ruleName]
return level ?: HighlightDisplayLevel.WEAK_WARNING
}
fun getHighlightDisplayLevel(rulePriority: RulePriority): HighlightDisplayLevel {
return when (rulePriority) {
RulePriority.HIGH -> HighlightDisplayLevels.BLOCKER
RulePriority.MEDIUM_HIGH -> HighlightDisplayLevels.CRITICAL
RulePriority.MEDIUM -> HighlightDisplayLevels.MAJOR
RulePriority.MEDIUM_LOW -> HighlightDisplayLevels.WARNING
else -> HighlightDisplayLevels.WEAK_WARNING
}
}
fun getRuleMessage(ruleName: String): String {
return ruleMessages[ruleName]!!
}
private fun parseStaticDescription(rule: Rule): String {
val writer = StringWriter()
try {
val map = Maps.newHashMap<String, Any>()
map["message"] = StringUtils.trimToEmpty(rule.message)
map["description"] = StringUtils.trimToEmpty(rule.description)
val examples = rule.examples.map {
it?.trim { c ->
c == '\n'
}
}
map["examples"] = examples
staticDescriptionTemplate.process(map, writer)
} catch (e: TemplateException) {
logger.error(e)
} catch (e: IOException) {
logger.error(e)
}
return writer.toString()
}
private fun loadAllAlibabaRule(): List<Rule> {
try {
Thread.currentThread().contextClassLoader = RuleInspectionUtils::class.java.classLoader
val ruleSetConfigs = findRuleSetConfigs()
val ruleSetFactory = RuleSetFactory()
val ruleSets = ruleSetFactory.createRuleSets(
Joiner.on(",").join(ruleSetConfigs).replace("/".toRegex(), "-"))
val map = Maps.newHashMap<String, Rule>()
ruleSets.allRuleSets
.asSequence()
.flatMap { it.rules.asSequence() }
.forEach { map[it.name] = it }
return Lists.newArrayList(map.values)
} catch (e: IOException) {
logger.warn("no available alibaba rules")
return emptyList()
} catch (e: RuleSetNotFoundException) {
logger.error("rule sets not found", e)
return emptyList()
}
}
@Throws(IOException::class)
private fun findRuleSetConfigs(): List<String> {
val ruleSets = Lists.newArrayList<String>()
val enumeration = RuleInspectionUtils::class.java.classLoader.getResources(ruleSetsPrefix)
while (enumeration.hasMoreElements()) {
val url = enumeration.nextElement()
if (URLUtil.JAR_PROTOCOL == url.protocol) {
findRuleSetsFromJar(ruleSets, url)
} else if (URLUtil.FILE_PROTOCOL == url.protocol) {
findRuleSetsFromDirectory(ruleSets, url)
}
}
return ruleSets
}
@Throws(IOException::class)
private fun findRuleSetsFromDirectory(ruleSets: MutableList<String>, url: URL) {
val file = File(url.path)
if (file.exists() && file.isDirectory) {
val files = Lists.newArrayList<File>()
FileUtil.collectMatchedFiles(file, ruleSetFilePattern, files)
files.mapTo(ruleSets) { it.canonicalPath.replace(url.path, "").replace(".xml", "") }
}
}
@Throws(IOException::class)
private fun findRuleSetsFromJar(ruleSets: MutableList<String>, url: URL) {
logger.info("start to find rule sets from jar $url")
var path = URLDecoder.decode(url.path, StandardCharsets.UTF_8.name())
val index = path.lastIndexOf(URLUtil.JAR_SEPARATOR)
if (index > NumberConstants.INDEX_0) {
path = path.substring("file:".length, index)
}
val jarFile = JarFile(path)
logger.info("create jarFile for path $path")
val jarEntries = jarFile.entries()
while (jarEntries.hasMoreElements()) {
val jarEntry = jarEntries.nextElement()
val subPath = jarEntry.name.replace(ruleSetsPrefix, "")
if (ruleSetFilePattern.matcher(subPath).find()) {
val resultPath = subPath.replace(".xml", "")
logger.info("get result rule set $resultPath")
ruleSets.add(resultPath)
}
}
logger.info("find rule sets from jar $url finished")
}
}
================================================
FILE: idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/standalone/AliAccessStaticViaInstanceInspection.kt
================================================
/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.p3c.idea.inspection.standalone
import com.alibaba.p3c.idea.config.P3cConfig
import com.alibaba.p3c.idea.i18n.P3cBundle
import com.alibaba.p3c.idea.inspection.AliBaseInspection
import com.alibaba.p3c.idea.util.HighlightDisplayLevels
import com.alibaba.smartfox.idea.common.util.getService
import com.intellij.codeHighlighting.HighlightDisplayLevel
import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil
import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil
import com.intellij.codeInsight.daemon.impl.quickfix.AccessStaticViaInstanceFix
import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.codeInspection.accessStaticViaInstance.AccessStaticViaInstance
import com.intellij.psi.*
/**
* @author caikang
* @date 2016/12/08
*/
class AliAccessStaticViaInstanceInspection : AccessStaticViaInstance, AliBaseInspection {
val messageKey = "com.alibaba.p3c.idea.inspection.standalone.AliAccessStaticViaInstanceInspection"
constructor()
/**
* For Javassist
*/
constructor(any: Any?) : this()
override fun getDisplayName(): String {
return P3cBundle.getMessage("$messageKey.message")
}
override fun getStaticDescription(): String? {
return P3cBundle.getMessage("$messageKey.desc")
}
override fun ruleName(): String {
return "AvoidAccessStaticViaInstanceRule"
}
override fun getShortName(): String {
return "AliAccessStaticViaInstance"
}
override fun createAccessStaticViaInstanceFix(
expr: PsiReferenceExpression,
result: JavaResolveResult
): LocalQuickFix {
val accessStaticViaInstanceFix : AccessStaticViaInstanceFix = object : AccessStaticViaInstanceFix(expr, result) {
val fixKey = "com.alibaba.p3c.idea.quickfix.standalone.AliAccessStaticViaInstanceInspection"
private fun calcText(member: PsiMember, substitutor: PsiSubstitutor): String {
val aClass = member.containingClass ?: return ""
val p3cConfig = P3cConfig::class.java.getService()
return when (p3cConfig.locale) {
P3cConfig.localeZh -> String.format(P3cBundle.getMessage(fixKey),
HighlightUtil.formatClass(aClass, false),
HighlightUtil.formatClass(aClass), HighlightMessageUtil.getSymbolName(member, substitutor))
else -> String.format(P3cBundle.getMessage(fixKey), HighlightUtil.formatClass(aClass),
HighlightMessageUtil.getSymbolName(member, substitutor),
HighlightUtil.formatClass(aClass, false))
}
}
}
return LocalQuickFix.from(accessStaticViaInstanceFix) as LocalQuickFix
}
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
checkAccessStaticMemberViaInstanceReference(expression, holder, isOnTheFly)
}
}
}
override fun getDefaultLevel(): HighlightDisplayLevel {
return HighlightDisplayLevels.BLOCKER
}
private fun checkAccessSt
gitextract_gvecwtd9/ ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── ------.md │ │ ├── bug_report.md │ │ ├── feature_request.md │ │ └── rule-issue-template.md │ ├── dependabot.yml │ └── workflows/ │ ├── auto-merge.yml │ └── build.yml ├── .gitignore ├── .mvn/ │ └── wrapper/ │ ├── MavenWrapperDownloader.java │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── AGENTS.md ├── README.md ├── build.cmd ├── deploy.cmd ├── idea-plugin/ │ ├── .gitignore │ ├── README.md │ ├── README_cn.md │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradle.properties │ ├── gradlew │ ├── gradlew.bat │ ├── p3c-common/ │ │ ├── build.gradle │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── icons/ │ │ │ └── P3cIcons.java │ │ ├── kotlin/ │ │ │ └── com/ │ │ │ └── alibaba/ │ │ │ ├── p3c/ │ │ │ │ └── idea/ │ │ │ │ ├── action/ │ │ │ │ │ ├── AliInspectionAction.kt │ │ │ │ │ ├── PmdGlobalInspectionContextImpl.kt │ │ │ │ │ ├── SwitchLanguageAction.kt │ │ │ │ │ └── ToggleProjectInspectionAction.kt │ │ │ │ ├── activity/ │ │ │ │ │ └── CommonSettingsApplicationStartupActivity.kt │ │ │ │ ├── compatible/ │ │ │ │ │ └── inspection/ │ │ │ │ │ ├── InspectionProfileService.kt │ │ │ │ │ └── Inspections.kt │ │ │ │ ├── component/ │ │ │ │ │ └── AliProjectComponent.kt │ │ │ │ ├── config/ │ │ │ │ │ ├── P3cConfig.kt │ │ │ │ │ ├── P3cConfigurable.kt │ │ │ │ │ └── SmartFoxProjectConfig.kt │ │ │ │ ├── ep/ │ │ │ │ │ ├── InspectionActionExtensionPoint.kt │ │ │ │ │ └── package-info.java │ │ │ │ ├── i18n/ │ │ │ │ │ └── P3cBundle.kt │ │ │ │ ├── inspection/ │ │ │ │ │ ├── AliAccessToNonThreadSafeStaticFieldFromInstanceInspection.kt │ │ │ │ │ ├── AliArrayNamingShouldHaveBracketInspection.kt │ │ │ │ │ ├── AliBaseInspection.kt │ │ │ │ │ ├── AliControlFlowStatementWithoutBracesInspection.kt │ │ │ │ │ ├── AliEqualsAvoidNullInspection.kt │ │ │ │ │ ├── AliLocalInspectionToolProvider.kt │ │ │ │ │ ├── AliLongLiteralsEndingWithLowercaseLInspection.kt │ │ │ │ │ ├── AliPmdInspection.kt │ │ │ │ │ ├── AliPmdInspectionInvoker.kt │ │ │ │ │ ├── AliWrapperTypeEqualityInspection.kt │ │ │ │ │ ├── DelegateLocalInspectionTool.kt │ │ │ │ │ ├── DelegatePmdInspection.kt │ │ │ │ │ ├── PmdRuleInspectionIdentify.kt │ │ │ │ │ ├── RuleInspectionUtils.kt │ │ │ │ │ └── standalone/ │ │ │ │ │ ├── AliAccessStaticViaInstanceInspection.kt │ │ │ │ │ ├── AliDeprecationInspection.kt │ │ │ │ │ ├── AliMissingOverrideAnnotationInspection.kt │ │ │ │ │ └── MapOrSetKeyShouldOverrideHashCodeEqualsInspection.kt │ │ │ │ ├── lifecycle/ │ │ │ │ │ └── P3cPluginLifecycle.kt │ │ │ │ ├── pmd/ │ │ │ │ │ ├── AliPmdProcessor.kt │ │ │ │ │ ├── SourceCodeProcessor.kt │ │ │ │ │ └── index/ │ │ │ │ │ ├── InspectionDataSource.kt │ │ │ │ │ └── InspectionRenderer.kt │ │ │ │ ├── quickfix/ │ │ │ │ │ ├── AliQuickFix.kt │ │ │ │ │ ├── AvoidStartWithDollarAndUnderLineNamingQuickFix.kt │ │ │ │ │ ├── ClassMustHaveAuthorQuickFix.kt │ │ │ │ │ ├── ConstantFieldShouldBeUpperCaseQuickFix.kt │ │ │ │ │ ├── DecorateInspectionFix.kt │ │ │ │ │ ├── LowerCamelCaseVariableNamingQuickFix.kt │ │ │ │ │ └── VmQuietReferenceQuickFix.kt │ │ │ │ ├── util/ │ │ │ │ │ ├── DocumentUtils.kt │ │ │ │ │ ├── HighlightDisplayLevels.kt │ │ │ │ │ ├── HighlightInfoTypes.kt │ │ │ │ │ ├── HighlightSeverities.kt │ │ │ │ │ ├── NumberConstants.kt │ │ │ │ │ ├── ObjectConstants.kt │ │ │ │ │ ├── ProblemsUtils.kt │ │ │ │ │ ├── QuickFixes.kt │ │ │ │ │ └── withLockNotInline.kt │ │ │ │ └── vcs/ │ │ │ │ ├── AliCodeAnalysisCheckinHandler.kt │ │ │ │ └── AliCodeAnalysisCheckinHandlerFactory.kt │ │ │ └── smartfox/ │ │ │ └── idea/ │ │ │ └── common/ │ │ │ ├── activity/ │ │ │ │ └── AliBaseApplicationStartupActivity.kt │ │ │ ├── component/ │ │ │ │ └── AliBaseProjectComponent.kt │ │ │ └── util/ │ │ │ ├── BalloonNotifications.kt │ │ │ ├── CommonExtensions.kt │ │ │ └── PluginVersions.kt │ │ └── resources/ │ │ ├── messages/ │ │ │ ├── P3cBundle.xml │ │ │ └── P3cBundle_en.xml │ │ ├── rulesets/ │ │ │ └── java/ │ │ │ └── ali-pmd.xml │ │ └── tpl/ │ │ └── StaticDescriptionTemplate.ftl │ ├── p3c-idea/ │ │ ├── build.gradle │ │ └── src/ │ │ └── main/ │ │ └── resources/ │ │ └── META-INF/ │ │ ├── plugin.xml │ │ └── pluginWithJava.xml │ └── settings.gradle ├── license.txt ├── mvnw ├── mvnw.cmd ├── p3c-formatter/ │ ├── eclipse-codestyle.xml │ └── eclipse-codetemplate.xml ├── p3c-gitbook/ │ ├── .gitignore │ ├── MySQL数据库/ │ │ ├── ORM映射.md │ │ ├── SQL语句.md │ │ ├── 建表规约.md │ │ └── 索引规约.md │ ├── README.md │ ├── SUMMARY.md │ ├── book.json │ ├── styles/ │ │ └── website.css │ ├── 单元测试.md │ ├── 安全规约.md │ ├── 工程结构/ │ │ ├── 二方库依赖.md │ │ ├── 应用分层.md │ │ └── 服务器.md │ ├── 异常日志/ │ │ ├── 其他.md │ │ ├── 异常处理.md │ │ └── 日志规约.md │ ├── 本手册专有名词.md │ ├── 版本历史.md │ ├── 维护手册.md │ └── 编程规约/ │ ├── OOP规范.md │ ├── 代码格式.md │ ├── 命名风格.md │ ├── 常量定义.md │ ├── 并发处理.md │ ├── 控制语句.md │ ├── 注释规约.md │ └── 集合处理.md ├── p3c-pmd/ │ ├── .gitignore │ ├── .mvn/ │ │ └── wrapper/ │ │ ├── MavenWrapperDownloader.java │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties │ ├── README.md │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── xenoamess/ │ │ │ └── p3c/ │ │ │ └── pmd/ │ │ │ ├── I18nResources.java │ │ │ ├── config/ │ │ │ │ └── P3cConfigDataBean.java │ │ │ ├── fix/ │ │ │ │ └── FixClassTypeResolver.java │ │ │ └── lang/ │ │ │ ├── AbstractAliXpathRule.java │ │ │ ├── java/ │ │ │ │ ├── rule/ │ │ │ │ │ ├── AbstractAliRule.java │ │ │ │ │ ├── AbstractPojoRule.java │ │ │ │ │ ├── comment/ │ │ │ │ │ │ ├── AbstractAliCommentRule.java │ │ │ │ │ │ ├── AbstractMethodOrInterfaceMethodMustUseJavadocRule.java │ │ │ │ │ │ ├── AvoidCommentBehindStatementRule.java │ │ │ │ │ │ ├── ClassMustHaveAuthorRule.java │ │ │ │ │ │ ├── CommentsMustBeJavadocFormatRule.java │ │ │ │ │ │ ├── EnumConstantsMustHaveCommentRule.java │ │ │ │ │ │ └── RemoveCommentedCodeRule.java │ │ │ │ │ ├── concurrent/ │ │ │ │ │ │ ├── AvoidCallStaticSimpleDateFormatRule.java │ │ │ │ │ │ ├── AvoidConcurrentCompetitionRandomRule.java │ │ │ │ │ │ ├── AvoidManuallyCreateThreadRule.java │ │ │ │ │ │ ├── AvoidUseTimerRule.java │ │ │ │ │ │ ├── CountDownShouldInFinallyRule.java │ │ │ │ │ │ ├── ThreadLocalShouldRemoveRule.java │ │ │ │ │ │ ├── ThreadPoolCreationRule.java │ │ │ │ │ │ └── ThreadShouldSetNameRule.java │ │ │ │ │ ├── constant/ │ │ │ │ │ │ ├── UndefineMagicConstantRule.java │ │ │ │ │ │ └── UpperEllRule.java │ │ │ │ │ ├── exception/ │ │ │ │ │ │ ├── AvoidReturnInFinallyRule.java │ │ │ │ │ │ ├── MethodReturnWrapperTypeRule.java │ │ │ │ │ │ └── TransactionMustHaveRollbackRule.java │ │ │ │ │ ├── flowcontrol/ │ │ │ │ │ │ ├── AvoidComplexConditionRule.java │ │ │ │ │ │ ├── AvoidNegationOperatorRule.java │ │ │ │ │ │ ├── NeedBraceRule.java │ │ │ │ │ │ ├── SwitchExpressionRule.java │ │ │ │ │ │ └── SwitchStatementRule.java │ │ │ │ │ ├── naming/ │ │ │ │ │ │ ├── AbstractClassShouldStartWithAbstractNamingRule.java │ │ │ │ │ │ ├── ArrayNamingShouldHaveBracketRule.java │ │ │ │ │ │ ├── AvoidStartWithDollarAndUnderLineNamingRule.java │ │ │ │ │ │ ├── BooleanPropertyShouldNotStartWithIsRule.java │ │ │ │ │ │ ├── ClassNamingShouldBeCamelRule.java │ │ │ │ │ │ ├── ConstantFieldShouldBeUpperCaseRule.java │ │ │ │ │ │ ├── ExceptionClassShouldEndWithExceptionRule.java │ │ │ │ │ │ ├── LowerCamelCaseVariableNamingRule.java │ │ │ │ │ │ ├── PackageNamingRule.java │ │ │ │ │ │ ├── ServiceOrDaoClassShouldEndWithImplRule.java │ │ │ │ │ │ └── TestClassShouldEndWithTestNamingRule.java │ │ │ │ │ ├── oop/ │ │ │ │ │ │ ├── BigDecimalAvoidDoubleConstructorRule.java │ │ │ │ │ │ ├── EqualsAvoidNullRule.java │ │ │ │ │ │ ├── PojoMustOverrideToStringRule.java │ │ │ │ │ │ ├── PojoMustUsePrimitiveFieldRule.java │ │ │ │ │ │ ├── PojoNoDefaultValueRule.java │ │ │ │ │ │ ├── StringConcatRule.java │ │ │ │ │ │ └── WrapperTypeEqualityRule.java │ │ │ │ │ ├── orm/ │ │ │ │ │ │ └── IbatisMethodQueryForListRule.java │ │ │ │ │ ├── other/ │ │ │ │ │ │ ├── AvoidApacheBeanUtilsCopyRule.java │ │ │ │ │ │ ├── AvoidDoubleOrFloatEqualCompareRule.java │ │ │ │ │ │ ├── AvoidMissUseOfMathRandomRule.java │ │ │ │ │ │ ├── AvoidNewDateGetTimeRule.java │ │ │ │ │ │ ├── AvoidPatternCompileInMethodRule.java │ │ │ │ │ │ ├── MethodTooLongRule.java │ │ │ │ │ │ └── UseRightCaseForDateFormatRule.java │ │ │ │ │ ├── set/ │ │ │ │ │ │ ├── ClassCastExceptionWithSubListToArrayListRule.java │ │ │ │ │ │ ├── ClassCastExceptionWithToArrayRule.java │ │ │ │ │ │ ├── CollectionInitShouldAssignCapacityRule.java │ │ │ │ │ │ ├── ConcurrentExceptionWithModifyOriginSubListRule.java │ │ │ │ │ │ ├── DontModifyInForeachCircleRule.java │ │ │ │ │ │ └── UnsupportedExceptionWithModifyAsListRule.java │ │ │ │ │ ├── util/ │ │ │ │ │ │ ├── NodeSortUtils.java │ │ │ │ │ │ └── NodeUtils.java │ │ │ │ │ └── xenoamess/ │ │ │ │ │ ├── additional/ │ │ │ │ │ │ ├── EqualsHashCodeRule.java │ │ │ │ │ │ └── SneakyThrowsWithoutExceptionTypeRule.java │ │ │ │ │ └── deprecated/ │ │ │ │ │ └── VarargsParameterRule.java │ │ │ │ └── util/ │ │ │ │ ├── GeneratedCodeUtils.java │ │ │ │ ├── NumberConstants.java │ │ │ │ ├── PojoUtils.java │ │ │ │ ├── SpiLoader.java │ │ │ │ ├── StringAndCharConstants.java │ │ │ │ ├── VariableUtils.java │ │ │ │ ├── ViolationUtils.java │ │ │ │ └── namelist/ │ │ │ │ ├── NameListConfig.java │ │ │ │ ├── NameListService.java │ │ │ │ └── NameListServiceImpl.java │ │ │ └── vm/ │ │ │ └── rule/ │ │ │ └── other/ │ │ │ └── UseQuietReferenceNotationRule.java │ │ ├── kotlin/ │ │ │ └── com/ │ │ │ └── xenoamess/ │ │ │ └── p3c/ │ │ │ └── pmd/ │ │ │ └── lang/ │ │ │ └── java/ │ │ │ └── rule/ │ │ │ └── concurrent/ │ │ │ └── LockShouldWithTryFinallyRule.kt │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── services/ │ │ │ └── com.xenoamess.p3c.pmd.lang.java.util.namelist.NameListService │ │ ├── messages.xml │ │ ├── messages_en.xml │ │ ├── p3c_config.default.x8l │ │ └── rulesets/ │ │ ├── java/ │ │ │ ├── ali-comment.xml │ │ │ ├── ali-concurrent.xml │ │ │ ├── ali-constant.xml │ │ │ ├── ali-exception.xml │ │ │ ├── ali-flowcontrol.xml │ │ │ ├── ali-naming.xml │ │ │ ├── ali-oop.xml │ │ │ ├── ali-orm.xml │ │ │ ├── ali-other.xml │ │ │ ├── ali-set.xml │ │ │ ├── xenoamess-additional.xml │ │ │ └── xenoamess-deprecated.xml │ │ └── vm/ │ │ └── ali-other.xml │ ├── site/ │ │ └── resources/ │ │ └── checkstyle/ │ │ ├── checkstyle-suppressions.xml │ │ └── checkstyle.xml │ └── test/ │ ├── java/ │ │ └── com/ │ │ └── xenoamess/ │ │ └── p3c/ │ │ └── pmd/ │ │ ├── IfVoidIsPrimitiveTest.java │ │ ├── config/ │ │ │ └── TestConfig.java │ │ ├── lang/ │ │ │ ├── java/ │ │ │ │ └── rule/ │ │ │ │ ├── comment/ │ │ │ │ │ └── CommentRulesTest.java │ │ │ │ ├── concurrent/ │ │ │ │ │ └── ConcurrentRuleTest.java │ │ │ │ ├── constant/ │ │ │ │ │ └── ConstantRulesTest.java │ │ │ │ ├── exception/ │ │ │ │ │ └── ExceptionRulesTest.java │ │ │ │ ├── flowcontrol/ │ │ │ │ │ └── FlowControlRuleTest.java │ │ │ │ ├── naming/ │ │ │ │ │ └── NamingRulesTest.java │ │ │ │ ├── oop/ │ │ │ │ │ └── OopRuleTest.java │ │ │ │ ├── orm/ │ │ │ │ │ └── OrmRulesTest.java │ │ │ │ ├── other/ │ │ │ │ │ ├── OtherRulesTest.java │ │ │ │ │ └── UseRightCaseForDateFormatRuleTest.java │ │ │ │ ├── set/ │ │ │ │ │ └── SetRulesTest.java │ │ │ │ └── xenoamess/ │ │ │ │ ├── additional/ │ │ │ │ │ └── XenoAmessAdditionalTest.java │ │ │ │ └── deprecated/ │ │ │ │ └── XenoAmessDeprecatedTest.java │ │ │ └── vm/ │ │ │ └── rule/ │ │ │ └── other/ │ │ │ └── OtherRulesTest.java │ │ └── testframework/ │ │ ├── ExtendRuleTst.java │ │ └── ExtendSimpleAggregatorTst.java │ └── resources/ │ └── com/ │ └── xenoamess/ │ └── p3c/ │ └── pmd/ │ └── lang/ │ ├── java/ │ │ └── rule/ │ │ ├── comment/ │ │ │ └── xml/ │ │ │ ├── AbstractMethodOrInterfaceMethodMustUseJavadocRule.xml │ │ │ ├── AvoidCommentBehindStatementRule.xml │ │ │ ├── ClassMustHaveAuthorRule.xml │ │ │ ├── CommentsMustBeJavadocFormatRule.xml │ │ │ ├── EnumConstantsMustHaveCommentRule.xml │ │ │ └── RemoveCommentedCodeRule.xml │ │ ├── concurrent/ │ │ │ └── xml/ │ │ │ ├── AvoidCallStaticSimpleDateFormatRule.xml │ │ │ ├── AvoidConcurrentCompetitionRandomRule.xml │ │ │ ├── AvoidManuallyCreateThreadRule.xml │ │ │ ├── AvoidUseTimerRule.xml │ │ │ ├── CountDownShouldInFinallyRule.xml │ │ │ ├── LockShouldWithTryFinallyRule.xml │ │ │ ├── ThreadLocalShouldRemoveRule.xml │ │ │ ├── ThreadPoolCreationRule.xml │ │ │ └── ThreadShouldSetNameRule.xml │ │ ├── constant/ │ │ │ └── xml/ │ │ │ ├── UndefineMagicConstantRule.xml │ │ │ └── UpperEllRule.xml │ │ ├── exception/ │ │ │ └── xml/ │ │ │ ├── AvoidReturnInFinallyRule.xml │ │ │ ├── MethodReturnWrapperTypeRule.xml │ │ │ └── TransactionMustHaveRollbackRule.xml │ │ ├── flowcontrol/ │ │ │ └── xml/ │ │ │ ├── AvoidComplexConditionRule.xml │ │ │ ├── AvoidNegationOperatorRule.xml │ │ │ ├── NeedBraceRule.xml │ │ │ ├── SwitchExpressionRule.xml │ │ │ └── SwitchStatementRule.xml │ │ ├── naming/ │ │ │ └── xml/ │ │ │ ├── AbstractClassShouldStartWithAbstractNamingRule.xml │ │ │ ├── ArrayNamingShouldHaveBracketRule.xml │ │ │ ├── AvoidStartWithDollarAndUnderLineNamingRule.xml │ │ │ ├── BooleanPropertyShouldNotStartWithIsRule.xml │ │ │ ├── ClassNamingShouldBeCamelRule.xml │ │ │ ├── ConstantFieldShouldBeUpperCaseRule.xml │ │ │ ├── ExceptionClassShouldEndWithExceptionRule.xml │ │ │ ├── LowerCamelCaseVariableNamingRule.xml │ │ │ ├── PackageNamingRule.xml │ │ │ ├── ServiceOrDaoClassShouldEndWithImplRule.xml │ │ │ └── TestClassShouldEndWithTestNamingRule.xml │ │ ├── oop/ │ │ │ └── xml/ │ │ │ ├── BigDecimalAvoidDoubleConstructorRule.xml │ │ │ ├── EqualsAvoidNullRule.xml │ │ │ ├── PojoMustOverrideToStringRule.xml │ │ │ ├── PojoMustUsePrimitiveFieldRule.xml │ │ │ ├── PojoNoDefaultValueRule.xml │ │ │ ├── StringConcatRule.xml │ │ │ └── WrapperTypeEqualityRule.xml │ │ ├── orm/ │ │ │ └── xml/ │ │ │ └── IbatisMethodQueryForListRule.xml │ │ ├── other/ │ │ │ ├── java/ │ │ │ │ └── UseRightCaseForDateFormatRuleExam.java │ │ │ └── xml/ │ │ │ ├── AvoidApacheBeanUtilsCopyRule.xml │ │ │ ├── AvoidDoubleOrFloatEqualCompareRule.xml │ │ │ ├── AvoidMissUseOfMathRandomRule.xml │ │ │ ├── AvoidNewDateGetTimeRule.xml │ │ │ ├── AvoidPatternCompileInMethodRule.xml │ │ │ ├── MethodTooLongRule.xml │ │ │ └── UseRightCaseForDateFormatRule.xml │ │ ├── set/ │ │ │ └── xml/ │ │ │ ├── ClassCastExceptionWithSubListToArrayListRule.xml │ │ │ ├── ClassCastExceptionWithToArrayRule.xml │ │ │ ├── CollectionInitShouldAssignCapacityRule.xml │ │ │ ├── ConcurrentExceptionWithModifyOriginSubListRule.xml │ │ │ ├── DontModifyInForeachCircleRule.xml │ │ │ └── UnsupportedExceptionWithModifyAsListRule.xml │ │ └── xenoamess/ │ │ ├── additional/ │ │ │ └── xml/ │ │ │ ├── EqualsHashCodeRule.xml │ │ │ └── SneakyThrowsWithoutExceptionTypeRule.xml │ │ └── deprecated/ │ │ └── xml/ │ │ └── VarargsParameterRule.xml │ └── vm/ │ └── rule/ │ └── other/ │ └── xml/ │ └── UseQuietReferenceNotationRule.xml ├── p3c_config.x8l └── sonar.cmd
SYMBOL INDEX (473 symbols across 101 files)
FILE: .mvn/wrapper/MavenWrapperDownloader.java
class MavenWrapperDownloader (line 21) | public class MavenWrapperDownloader {
method main (line 48) | public static void main(String args[]) {
method downloadFileFromURL (line 97) | private static void downloadFileFromURL(String urlString, File destina...
FILE: idea-plugin/p3c-common/src/main/java/icons/P3cIcons.java
class P3cIcons (line 26) | public final class P3cIcons {
method P3cIcons (line 27) | private P3cIcons() {
FILE: p3c-pmd/.mvn/wrapper/MavenWrapperDownloader.java
class MavenWrapperDownloader (line 21) | public class MavenWrapperDownloader {
method main (line 48) | public static void main(String args[]) {
method downloadFileFromURL (line 97) | private static void downloadFileFromURL(String urlString, File destina...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/I18nResources.java
class I18nResources (line 43) | public class I18nResources {
method getLanguageSupplier (line 59) | @Nullable
method setLanguageSupplier (line 64) | public static void setLanguageSupplier(@Nullable Supplier<String> lang...
method changeLanguage (line 68) | public static ResourceBundle changeLanguage(String language) {
method changeLanguage (line 73) | @NotNull
method getResourceBundle (line 88) | public static ResourceBundle getResourceBundle() {
method getMessage (line 105) | public static String getMessage(String key) {
method getMessage (line 117) | public static String getMessage(String key, Object... params) {
method getMessageWithExceptionHandled (line 125) | public static String getMessageWithExceptionHandled(String key) {
class XmlResourceBundle (line 137) | public static class XmlResourceBundle extends ResourceBundle {
method XmlResourceBundle (line 140) | XmlResourceBundle(InputStream stream) throws IOException {
method handleGetObject (line 145) | @Override
method getKeys (line 155) | @Override
class XmlControl (line 167) | public static class XmlControl extends Control {
method getFormats (line 168) | @Override
method getFallbackLocale (line 176) | @Override
method newBundle (line 181) | @Override
method getInputStream (line 213) | private InputStream getInputStream(ClassLoader loader, String resour...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/config/P3cConfigDataBean.java
class P3cConfigDataBean (line 26) | public class P3cConfigDataBean implements X8lDataBean {
method getContentNodeAsStringSet (line 28) | @SuppressWarnings("unused")
method getRuleClassPairBlackListMap (line 42) | @SuppressWarnings("unused")
method tryPatchP3cConfigDataBean (line 104) | public void tryPatchP3cConfigDataBean(
method getP3cConfigX8lTree (line 126) | public X8lTree getP3cConfigX8lTree() {
method setP3cConfigX8lTree (line 130) | public void setP3cConfigX8lTree(X8lTree p3cConfigX8lTree) {
method getRuleBlackListSet (line 134) | public Set<String> getRuleBlackListSet() {
method setRuleBlackListSet (line 138) | public void setRuleBlackListSet(Set<String> ruleBlackListSet) {
method getClassBlackListSet (line 142) | public Set<String> getClassBlackListSet() {
method setClassBlackListSet (line 146) | public void setClassBlackListSet(Set<String> classBlackListSet) {
method getRuleClassPairBlackListMap (line 150) | public Map<String, Set<String>> getRuleClassPairBlackListMap() {
method setRuleClassPairBlackListMap (line 154) | public void setRuleClassPairBlackListMap(Map<String, Set<String>> rule...
method getPackageBlackListSet (line 158) | public Set<String> getPackageBlackListSet() {
method setPackageBlackListSet (line 162) | public void setPackageBlackListSet(Set<String> packageBlackListSet) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/fix/FixClassTypeResolver.java
class FixClassTypeResolver (line 80) | @Generated("from pmd")
method FixClassTypeResolver (line 148) | public FixClassTypeResolver() {
method FixClassTypeResolver (line 152) | public FixClassTypeResolver(ClassLoader classLoader) {
method visit (line 158) | @Override
method visit (line 182) | @Override
method visit (line 197) | @Override
method visit (line 204) | @Override
method visit (line 211) | @Override
method visit (line 217) | @Override
method visit (line 223) | @Override
method visit (line 229) | @Override
method visit (line 259) | @Override
method visit (line 266) | @Override
method visit (line 273) | @Override
method visit (line 285) | @Override
method visit (line 292) | @Override
method visit (line 299) | @Override
method visit (line 305) | @Override
method visit (line 312) | @Override
method visit (line 324) | @Override
method visit (line 330) | @Override
method visit (line 336) | @Override
method visit (line 343) | @Override
method visit (line 350) | @Override
method visit (line 357) | @Override
method visit (line 363) | @Override
method visit (line 369) | @Override
method visit (line 375) | @Override
method visit (line 383) | @Override
method visit (line 390) | @Override
method visit (line 397) | @Override
method visit (line 404) | @Override
method visit (line 411) | @Override
method visit (line 418) | @Override
method visit (line 429) | @Override
method visit (line 436) | @Override
method visit (line 443) | @Override
method visit (line 455) | @Override
method visit (line 467) | @Override
method visit (line 475) | @Override
method visit (line 481) | @Override
method visit (line 487) | @Override
method visit (line 512) | @Override
method visit (line 525) | @Override
method visit (line 532) | @Override
method visit (line 539) | @Override
method visit (line 546) | @Override
method rollupTypeUnary (line 558) | private void rollupTypeUnary(TypeNode typeNode) {
method rollupTypeUnaryNumericPromotion (line 574) | private void rollupTypeUnaryNumericPromotion(TypeNode typeNode) {
method rollupTypeBinaryNumericPromotion (line 598) | private void rollupTypeBinaryNumericPromotion(TypeNode typeNode) {
method populateType (line 642) | private void populateType(TypeNode node, String className) {
method classNameExists (line 696) | @Override
method loadClass (line 709) | @Override
method processOnDemand (line 718) | private Class<?> processOnDemand(String qualifiedName) {
method getClassName (line 728) | private String getClassName(ASTCompilationUnit node) {
method populateImports (line 747) | private void populateImports(ASTCompilationUnit node) {
method populateClassName (line 765) | private void populateClassName(ASTCompilationUnit node, String classNa...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/AbstractAliXpathRule.java
class AbstractAliXpathRule (line 27) | public abstract class AbstractAliXpathRule extends XPathRule {
method setDescription (line 28) | @Override
method setMessage (line 33) | @Override
method addViolationWithMessage (line 38) | @Override
method addViolationWithMessage (line 46) | @Override
method addViolation (line 59) | @Override
method addViolation (line 71) | @Override
method addViolation (line 83) | @Override
method addViolationWithMessage (line 95) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/AbstractAliRule.java
class AbstractAliRule (line 36) | public abstract class AbstractAliRule extends AbstractJavaRule {
method visit (line 43) | @Override
method setDescription (line 63) | @Override
method setMessage (line 68) | @Override
method addViolationWithMessage (line 73) | @Override
method addViolationWithMessage (line 85) | @Override
method resolveType (line 97) | private void resolveType(ASTCompilationUnit node, Object data) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/AbstractPojoRule.java
class AbstractPojoRule (line 30) | public abstract class AbstractPojoRule extends AbstractAliRule {
method visit (line 40) | @Override
method hasPojoInJavaFile (line 54) | private boolean hasPojoInJavaFile(ASTCompilationUnit node) {
method isPojo (line 65) | protected boolean isPojo(ASTClassOrInterfaceDeclaration node) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/AbstractAliCommentRule.java
class AbstractAliCommentRule (line 27) | public abstract class AbstractAliCommentRule extends AbstractCommentRule {
method setDescription (line 28) | @Override
method setMessage (line 33) | @Override
method addViolationWithMessage (line 38) | @Override
method addViolationWithMessage (line 50) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/AbstractMethodOrInterfaceMethodMustUseJavadocRule.java
class AbstractMethodOrInterfaceMethodMustUseJavadocRule (line 41) | public class AbstractMethodOrInterfaceMethodMustUseJavadocRule extends A...
method visit (line 55) | @Override
method checkMethodCommentFormat (line 98) | public void checkMethodCommentFormat(ASTMethodDeclaration method, Obje...
method visit (line 163) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/AvoidCommentBehindStatementRule.java
class AvoidCommentBehindStatementRule (line 40) | public class AvoidCommentBehindStatementRule extends AbstractAliCommentR...
method visit (line 42) | @Override
method orderedCommentsAndExpressions (line 71) | protected SortedMap<Integer, Node> orderedCommentsAndExpressions(ASTCo...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/ClassMustHaveAuthorRule.java
class ClassMustHaveAuthorRule (line 39) | public class ClassMustHaveAuthorRule extends AbstractAliCommentRule {
method visit (line 54) | @Override
method visit (line 63) | @Override
method visit (line 80) | @Override
method visit (line 86) | @Override
method orderedCommentsAndDeclarations (line 93) | @Override
method addDeclarations (line 113) | private void addDeclarations(SortedMap<Integer, Node> map, List<? exte...
method checkAuthorComment (line 125) | public void checkAuthorComment(AbstractJavaNode decl, Object data) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/CommentsMustBeJavadocFormatRule.java
class CommentsMustBeJavadocFormatRule (line 53) | public class CommentsMustBeJavadocFormatRule extends AbstractAliCommentR...
method visit (line 57) | @Override
method visit (line 64) | @Override
method visit (line 88) | @Override
method visit (line 95) | @Override
method visit (line 102) | @Override
method visit (line 109) | @Override
method checkComment (line 116) | private void checkComment(AbstractJavaAccessNode decl, Object data, Me...
method assignCommentsToDeclarations (line 124) | @Override
method orderedComments (line 155) | protected SortedMap<Integer, Node> orderedComments(ASTCompilationUnit ...
method isCommentOneLineBefore (line 183) | private boolean isCommentOneLineBefore(SortedMap<Integer, Node> items,...
type MessageMaker (line 228) | interface MessageMaker {
method make (line 234) | String make();
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/EnumConstantsMustHaveCommentRule.java
class EnumConstantsMustHaveCommentRule (line 36) | public class EnumConstantsMustHaveCommentRule extends AbstractAliComment...
method visit (line 38) | @Override
method orderedCommentsAndEnumDeclarations (line 65) | private SortedMap<Integer, Node> orderedCommentsAndEnumDeclarations(AS...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/RemoveCommentedCodeRule.java
class RemoveCommentedCodeRule (line 42) | public class RemoveCommentedCodeRule extends AbstractAliCommentRule {
method visit (line 61) | @Override
method checkCommentsBetweenDeclarations (line 68) | protected void checkCommentsBetweenDeclarations(ASTCompilationUnit cUn...
method scanCommentedCode (line 126) | protected CommentPatternEnum scanCommentedCode(String content) {
method orderedCommentsAndDeclarations (line 147) | @Override
method isCommentBefore (line 176) | private boolean isCommentBefore(Comment n1, Node n2) {
type CommentPatternEnum (line 181) | enum CommentPatternEnum {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/AvoidCallStaticSimpleDateFormatRule.java
class AvoidCallStaticSimpleDateFormatRule (line 49) | public class AvoidCallStaticSimpleDateFormatRule extends AbstractAliRule {
method visit (line 52) | @Override
method handleMethod (line 62) | private void handleMethod(ASTMethodDeclaration methodDeclaration, Obje...
method handleFlowNode (line 83) | private void handleFlowNode(Stack<Node> stack, Set<String> localSimple...
method getExpressName (line 132) | private String getExpressName(ASTPrimaryExpression primaryExpression) {
method isStaticSimpleDateFormatCall (line 137) | private boolean isStaticSimpleDateFormatCall(
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/AvoidConcurrentCompetitionRandomRule.java
class AvoidConcurrentCompetitionRandomRule (line 42) | public class AvoidConcurrentCompetitionRandomRule extends AbstractAliRule {
method visit (line 51) | @Override
method checkMathRandom (line 79) | private void checkMathRandom(List<ASTMethodDeclaration> methodDeclarat...
method checkRandom (line 100) | private void checkRandom(ASTFieldDeclaration fieldDeclaration, List<AS...
method hasThread (line 119) | private boolean hasThread(ASTExtendsList extendsList) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/AvoidManuallyCreateThreadRule.java
class AvoidManuallyCreateThreadRule (line 53) | public class AvoidManuallyCreateThreadRule extends AbstractAliRule {
method visit (line 57) | @Override
method isAddShutdownHook (line 95) | private boolean isAddShutdownHook(ASTAllocationExpression node) {
method isInStaticInitializer (line 104) | private boolean isInStaticInitializer(ASTAllocationExpression node) {
method threadFactoryVariable (line 109) | private boolean threadFactoryVariable(ASTAllocationExpression node) {
method isInNewThreadMethod (line 118) | private boolean isInNewThreadMethod(ASTAllocationExpression node) {
method isInPrimaryOrProtectedMethod (line 135) | private boolean isInPrimaryOrProtectedMethod(ASTAllocationExpression n...
method returnThread (line 141) | private boolean returnThread(ASTMethodDeclaration methodDeclaration) {
method addViolationAndReturn (line 147) | private Object addViolationAndReturn(ASTAllocationExpression node, Obj...
method checkForNamingClass (line 152) | private boolean checkForNamingClass(ASTAllocationExpression node) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/AvoidUseTimerRule.java
class AvoidUseTimerRule (line 32) | public class AvoidUseTimerRule extends AbstractAliRule {
method visit (line 33) | @Override
method visit (line 39) | @Override
method checkType (line 49) | private void checkType(AbstractJavaTypeNode node, Object data) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/CountDownShouldInFinallyRule.java
class CountDownShouldInFinallyRule (line 38) | public class CountDownShouldInFinallyRule extends AbstractAliRule {
method visit (line 42) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/ThreadLocalShouldRemoveRule.java
class ThreadLocalShouldRemoveRule (line 41) | public class ThreadLocalShouldRemoveRule extends AbstractAliRule {
method visit (line 49) | @Override
method checkThreadLocalWithInitialValue (line 66) | private boolean checkThreadLocalWithInitialValue(ASTFieldDeclaration f...
method checkThreadLocal (line 82) | private void checkThreadLocal(ASTFieldDeclaration fieldDeclaration, AS...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/ThreadPoolCreationRule.java
class ThreadPoolCreationRule (line 38) | public class ThreadPoolCreationRule extends AbstractAliRule {
method visit (line 49) | @Override
method checkInitStatement (line 78) | private boolean checkInitStatement(Token token, Info info) {
method getFullAssignStatement (line 104) | private String getFullAssignStatement(final Token token) {
class Info (line 117) | static class Info {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/ThreadShouldSetNameRule.java
class ThreadShouldSetNameRule (line 49) | public class ThreadShouldSetNameRule extends AbstractAliRule {
method visit (line 57) | @Override
method visit (line 75) | @Override
method checkThreadPoolExecutor (line 80) | private Object checkThreadPoolExecutor(ASTAllocationExpression node, O...
method checkSchedulePoolExecutor (line 92) | private Object checkSchedulePoolExecutor(ASTAllocationExpression node,...
method checkThreadFactoryArgument (line 104) | @SuppressWarnings("BooleanMethodIsAlwaysInverted")
method isThreadFactoryLambda (line 122) | private boolean isThreadFactoryLambda(ASTLambdaExpression lambdaExpres...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/constant/UndefineMagicConstantRule.java
class UndefineMagicConstantRule (line 38) | public class UndefineMagicConstantRule extends AbstractAliRule {
method getLiteralWhiteList (line 44) | private static List<String> getLiteralWhiteList() {
method visit (line 59) | @Override
method inBlackList (line 90) | private boolean inBlackList(ASTLiteral literal) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/constant/UpperEllRule.java
class UpperEllRule (line 28) | public class UpperEllRule extends AbstractAliRule {
method visit (line 31) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/exception/AvoidReturnInFinallyRule.java
class AvoidReturnInFinallyRule (line 31) | public class AvoidReturnInFinallyRule extends AbstractAliXpathRule {
method AvoidReturnInFinallyRule (line 34) | public AvoidReturnInFinallyRule() {
method addViolation (line 38) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/exception/MethodReturnWrapperTypeRule.java
class MethodReturnWrapperTypeRule (line 40) | public class MethodReturnWrapperTypeRule extends AbstractAliRule {
method getPrimitiveTypeToWrapperType (line 41) | private static Map<String, String> getPrimitiveTypeToWrapperType() {
method visit (line 55) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/exception/TransactionMustHaveRollbackRule.java
class TransactionMustHaveRollbackRule (line 35) | public class TransactionMustHaveRollbackRule extends AbstractAliRule {
method visit (line 50) | @Override
method shouldSkip (line 86) | private boolean shouldSkip(List<ASTMemberValuePair> memberValuePairLis...
method getSiblingForType (line 111) | private <T> T getSiblingForType(ASTAnnotation node, Class<T> clz) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/flowcontrol/AvoidComplexConditionRule.java
class AvoidComplexConditionRule (line 30) | public class AvoidComplexConditionRule extends AbstractAliXpathRule {
method AvoidComplexConditionRule (line 35) | public AvoidComplexConditionRule() {
method addViolation (line 39) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/flowcontrol/AvoidNegationOperatorRule.java
class AvoidNegationOperatorRule (line 30) | public class AvoidNegationOperatorRule extends AbstractAliXpathRule {
method AvoidNegationOperatorRule (line 36) | public AvoidNegationOperatorRule() {
method addViolation (line 40) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/flowcontrol/NeedBraceRule.java
class NeedBraceRule (line 35) | public class NeedBraceRule extends AbstractAliRule {
method visit (line 40) | @Override
method visit (line 58) | @Override
method visit (line 66) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/flowcontrol/SwitchExpressionRule.java
class SwitchExpressionRule (line 29) | public class SwitchExpressionRule extends AbstractAliRule {
method visit (line 32) | @Override
method checkDefault (line 44) | private void checkDefault(ASTSwitchExpression node, Object data) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/flowcontrol/SwitchStatementRule.java
class SwitchStatementRule (line 29) | public class SwitchStatementRule extends AbstractAliRule {
method visit (line 32) | @Override
method checkDefault (line 47) | private void checkDefault(ASTSwitchStatement node, Object data) {
method checkFallThrough (line 66) | private void checkFallThrough(ASTSwitchStatement node, Object data) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/AbstractClassShouldStartWithAbstractNamingRule.java
class AbstractClassShouldStartWithAbstractNamingRule (line 30) | public class AbstractClassShouldStartWithAbstractNamingRule extends Abst...
method AbstractClassShouldStartWithAbstractNamingRule (line 34) | public AbstractClassShouldStartWithAbstractNamingRule() {
method addViolation (line 38) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/ArrayNamingShouldHaveBracketRule.java
class ArrayNamingShouldHaveBracketRule (line 29) | public class ArrayNamingShouldHaveBracketRule extends AbstractAliXpathRu...
method ArrayNamingShouldHaveBracketRule (line 33) | public ArrayNamingShouldHaveBracketRule() {
method addViolation (line 37) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/AvoidStartWithDollarAndUnderLineNamingRule.java
class AvoidStartWithDollarAndUnderLineNamingRule (line 31) | public class AvoidStartWithDollarAndUnderLineNamingRule extends Abstract...
method visit (line 37) | @Override
method visit (line 45) | @Override
method visit (line 53) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/BooleanPropertyShouldNotStartWithIsRule.java
class BooleanPropertyShouldNotStartWithIsRule (line 31) | public class BooleanPropertyShouldNotStartWithIsRule extends AbstractAli...
method BooleanPropertyShouldNotStartWithIsRule (line 37) | public BooleanPropertyShouldNotStartWithIsRule() {
method addViolation (line 41) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/ClassNamingShouldBeCamelRule.java
class ClassNamingShouldBeCamelRule (line 33) | public class ClassNamingShouldBeCamelRule extends AbstractAliRule {
method getClassNamingWhiteList (line 38) | private static List<String> getClassNamingWhiteList() {
method visit (line 45) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/ConstantFieldShouldBeUpperCaseRule.java
class ConstantFieldShouldBeUpperCaseRule (line 36) | public class ConstantFieldShouldBeUpperCaseRule extends AbstractAliRule {
method getLogVariableTypeSet (line 39) | private static Set<String> getLogVariableTypeSet() {
method getWhiteList (line 46) | private static Set<String> getWhiteList() {
method visit (line 53) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/ExceptionClassShouldEndWithExceptionRule.java
class ExceptionClassShouldEndWithExceptionRule (line 33) | public class ExceptionClassShouldEndWithExceptionRule extends AbstractAl...
method visit (line 37) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/LowerCamelCaseVariableNamingRule.java
class LowerCamelCaseVariableNamingRule (line 40) | public class LowerCamelCaseVariableNamingRule extends AbstractAliRule {
method getWhiteList (line 47) | private static List<String> getWhiteList() {
method visit (line 54) | @Override
method visit (line 88) | @Override
method visit (line 119) | @Override
method variableNamingStartOrEndWithDollarAndUnderLine (line 125) | private boolean variableNamingStartOrEndWithDollarAndUnderLine(String ...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/PackageNamingRule.java
class PackageNamingRule (line 30) | public class PackageNamingRule extends AbstractAliXpathRule {
method PackageNamingRule (line 34) | public PackageNamingRule() {
method addViolation (line 38) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/ServiceOrDaoClassShouldEndWithImplRule.java
class ServiceOrDaoClassShouldEndWithImplRule (line 30) | public class ServiceOrDaoClassShouldEndWithImplRule extends AbstractAliX...
method ServiceOrDaoClassShouldEndWithImplRule (line 37) | public ServiceOrDaoClassShouldEndWithImplRule() {
method addViolation (line 41) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/TestClassShouldEndWithTestNamingRule.java
class TestClassShouldEndWithTestNamingRule (line 33) | public class TestClassShouldEndWithTestNamingRule extends AbstractJUnitR...
method visit (line 36) | @Override
method visitInternal (line 55) | private Object visitInternal(ASTClassOrInterfaceDeclaration node, Obje...
method isInInnerClassOrInterface (line 80) | private boolean isInInnerClassOrInterface(ASTMethodDeclaration md) {
method setDescription (line 85) | @Override
method setMessage (line 90) | @Override
method addViolationWithMessage (line 95) | @Override
method addViolationWithMessage (line 103) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/BigDecimalAvoidDoubleConstructorRule.java
class BigDecimalAvoidDoubleConstructorRule (line 36) | public class BigDecimalAvoidDoubleConstructorRule extends AbstractAliRule {
method visit (line 49) | @Override
method addViolation (line 70) | @Override
method isDoubleLiteral (line 76) | private boolean isDoubleLiteral(ASTPrimaryPrefix node) {
method isDoubleVariable (line 81) | private boolean isDoubleVariable(ASTPrimaryPrefix node) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/EqualsAvoidNullRule.java
class EqualsAvoidNullRule (line 42) | public class EqualsAvoidNullRule extends AbstractAliRule {
method visit (line 56) | @Override
method callerIsLiteral (line 106) | private boolean callerIsLiteral(Node equalsInvocation) {
method getInvocationName (line 114) | private String getInvocationName(AbstractJavaNode javaNode) {
method addRuleViolation (line 127) | private void addRuleViolation(Object data, Node invocation) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/PojoMustOverrideToStringRule.java
class PojoMustOverrideToStringRule (line 36) | public class PojoMustOverrideToStringRule extends AbstractPojoRule {
method visit (line 60) | @Override
method checkForExtend (line 82) | private void checkForExtend(ASTClassOrInterfaceDeclaration node, Objec...
method withLombokAnnotation (line 112) | private boolean withLombokAnnotation(ASTClassOrInterfaceDeclaration no...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/PojoMustUsePrimitiveFieldRule.java
class PojoMustUsePrimitiveFieldRule (line 40) | public class PojoMustUsePrimitiveFieldRule extends AbstractPojoRule {
method visit (line 42) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/PojoNoDefaultValueRule.java
class PojoNoDefaultValueRule (line 36) | public class PojoNoDefaultValueRule extends AbstractPojoRule {
method visit (line 38) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/StringConcatRule.java
class StringConcatRule (line 42) | public class StringConcatRule extends AbstractAliRule {
method visit (line 48) | @Override
method visit (line 54) | @Override
method visit (line 60) | @Override
method checkStringConcat (line 73) | private void checkStringConcat(Node node, Object data, Class nodeClass) {
method addViolation (line 132) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/WrapperTypeEqualityRule.java
class WrapperTypeEqualityRule (line 32) | public class WrapperTypeEqualityRule extends AbstractAliRule {
method visit (line 34) | @Override
method isArrayLength (line 65) | private boolean isArrayLength(ASTPrimaryExpression expression) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/orm/IbatisMethodQueryForListRule.java
class IbatisMethodQueryForListRule (line 46) | public class IbatisMethodQueryForListRule extends AbstractAliRule {
method visit (line 57) | @Override
method visitAstClassOrInterfaceDeclaration (line 74) | private void visitAstClassOrInterfaceDeclaration(ASTClassOrInterfaceDe...
method getSqlMapFields (line 91) | private Set<String> getSqlMapFields(List<Node> fieldDeclarations) {
method hasSqlMapClientImport (line 111) | private boolean hasSqlMapClientImport(List<ASTImportDeclaration> impor...
method visitPrimaryExpression (line 133) | private void visitPrimaryExpression(ASTPrimaryExpression node, Object ...
method sqlMapClientField (line 180) | private boolean sqlMapClientField(ASTFieldDeclaration node) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/AvoidApacheBeanUtilsCopyRule.java
class AvoidApacheBeanUtilsCopyRule (line 30) | public class AvoidApacheBeanUtilsCopyRule extends AbstractAliXpathRule {
method AvoidApacheBeanUtilsCopyRule (line 36) | public AvoidApacheBeanUtilsCopyRule() {
method addViolation (line 40) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/AvoidDoubleOrFloatEqualCompareRule.java
class AvoidDoubleOrFloatEqualCompareRule (line 14) | public class AvoidDoubleOrFloatEqualCompareRule extends AbstractAliRule {
method visit (line 20) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/AvoidMissUseOfMathRandomRule.java
class AvoidMissUseOfMathRandomRule (line 30) | public class AvoidMissUseOfMathRandomRule extends AbstractAliXpathRule {
method AvoidMissUseOfMathRandomRule (line 39) | public AvoidMissUseOfMathRandomRule() {
method addViolation (line 43) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/AvoidNewDateGetTimeRule.java
class AvoidNewDateGetTimeRule (line 29) | public class AvoidNewDateGetTimeRule extends AbstractAliXpathRule {
method AvoidNewDateGetTimeRule (line 40) | public AvoidNewDateGetTimeRule() {
method addViolation (line 44) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/AvoidPatternCompileInMethodRule.java
class AvoidPatternCompileInMethodRule (line 32) | public class AvoidPatternCompileInMethodRule extends AbstractAliXpathRule {
method AvoidPatternCompileInMethodRule (line 41) | public AvoidPatternCompileInMethodRule() {
method addViolation (line 45) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/MethodTooLongRule.java
class MethodTooLongRule (line 48) | public class MethodTooLongRule extends AbstractAliRule {
method visit (line 58) | @Override
method visit (line 64) | @Override
method orderedCommentsAndExpressions (line 104) | protected SortedMap<Integer, Node> orderedCommentsAndExpressions(ASTCo...
method getCommentLineCount (line 123) | private int getCommentLineCount(ASTMethodDeclaration methodDecl) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/UseRightCaseForDateFormatRule.java
class UseRightCaseForDateFormatRule (line 28) | public class UseRightCaseForDateFormatRule extends AbstractAliXpathRule {
method UseRightCaseForDateFormatRule (line 37) | public UseRightCaseForDateFormatRule() {
method addViolation (line 41) | @Override
method checkNode (line 52) | private void checkNode(Node argNode, Object data) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/ClassCastExceptionWithSubListToArrayListRule.java
class ClassCastExceptionWithSubListToArrayListRule (line 34) | public class ClassCastExceptionWithSubListToArrayListRule extends Abstra...
method visit (line 40) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/ClassCastExceptionWithToArrayRule.java
class ClassCastExceptionWithToArrayRule (line 35) | public class ClassCastExceptionWithToArrayRule extends AbstractAliRule {
method visit (line 40) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/CollectionInitShouldAssignCapacityRule.java
class CollectionInitShouldAssignCapacityRule (line 34) | public class CollectionInitShouldAssignCapacityRule extends AbstractAliR...
method getCollectionList (line 40) | private static List<String> getCollectionList() {
method visit (line 47) | @Override
method visitByCollections (line 60) | private void visitByCollections(ASTClassOrInterfaceDeclaration node, O...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/ConcurrentExceptionWithModifyOriginSubListRule.java
class ConcurrentExceptionWithModifyOriginSubListRule (line 34) | public class ConcurrentExceptionWithModifyOriginSubListRule extends Abst...
method visit (line 45) | @Override
method getBeforeSubListVal (line 88) | private static String getBeforeSubListVal(String image) {
method checkBlockNodesValid (line 99) | private static boolean checkBlockNodesValid(String variableName, Node ...
method judgeName (line 114) | private static boolean judgeName(String name, String variableName) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/DontModifyInForeachCircleRule.java
class DontModifyInForeachCircleRule (line 34) | public class DontModifyInForeachCircleRule extends AbstractAliRule {
method visit (line 43) | @Override
method judgeName (line 77) | private boolean judgeName(String name, String variableName) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/UnsupportedExceptionWithModifyAsListRule.java
class UnsupportedExceptionWithModifyAsListRule (line 36) | public class UnsupportedExceptionWithModifyAsListRule extends AbstractAl...
method visit (line 47) | @Override
method checkBlockNodesValid (line 101) | private boolean checkBlockNodesValid(String variableName, Node item) {
method judgeName (line 116) | private boolean judgeName(String name, String variableName) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/util/NodeSortUtils.java
class NodeSortUtils (line 29) | public class NodeSortUtils {
method addNodesToSortedMap (line 37) | public static void addNodesToSortedMap(SortedMap<Integer, Node> map, L...
method generateIndex (line 48) | public static int generateIndex(Node node) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/util/NodeUtils.java
class NodeUtils (line 33) | public class NodeUtils {
method isParentOrSelf (line 38) | public static boolean isParentOrSelf(Node descendant, Node ancestor) {
method isWrapperType (line 58) | public static boolean isWrapperType(ASTPrimaryExpression expression) {
method isConstant (line 69) | public static boolean isConstant(ASTFieldDeclaration field) {
method getNodeType (line 73) | public static Class<?> getNodeType(AbstractJavaAccessTypeNode node) {
method isLockStatementExpression (line 77) | public static boolean isLockStatementExpression(ASTStatementExpression...
method isUnLockStatementExpression (line 81) | public static boolean isUnLockStatementExpression(ASTStatementExpressi...
method isLockTypeAndMethod (line 85) | private static boolean isLockTypeAndMethod(ASTStatementExpression stat...
method isLockNode (line 94) | public static boolean isLockNode(Node node) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/xenoamess/additional/EqualsHashCodeRule.java
class EqualsHashCodeRule (line 32) | public class EqualsHashCodeRule extends AbstractAliRule {
method visit (line 34) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/xenoamess/additional/SneakyThrowsWithoutExceptionTypeRule.java
class SneakyThrowsWithoutExceptionTypeRule (line 17) | public class SneakyThrowsWithoutExceptionTypeRule extends AbstractAliRule {
method visit (line 19) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/xenoamess/deprecated/VarargsParameterRule.java
class VarargsParameterRule (line 30) | @Deprecated
method VarargsParameterRule (line 34) | public VarargsParameterRule() {
method addViolation (line 38) | @Override
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/util/GeneratedCodeUtils.java
class GeneratedCodeUtils (line 27) | public class GeneratedCodeUtils {
method isGenerated (line 32) | public static boolean isGenerated(ASTCompilationUnit compilationUnit) {
method isGenerated (line 47) | public static boolean isGenerated(String content) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/util/NumberConstants.java
class NumberConstants (line 22) | public final class NumberConstants {
method NumberConstants (line 23) | private NumberConstants() {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/util/PojoUtils.java
class PojoUtils (line 29) | public class PojoUtils {
method getPojoSuffixSet (line 30) | private static List<String> getPojoSuffixSet() {
method PojoUtils (line 34) | private PojoUtils() {
method isPojo (line 37) | public static boolean isPojo(String klass) {
method isPojo (line 49) | public static boolean isPojo(ASTClassOrInterfaceDeclaration node) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/util/SpiLoader.java
class SpiLoader (line 27) | public class SpiLoader {
method getInstance (line 30) | @SuppressWarnings("unchecked")
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/util/StringAndCharConstants.java
class StringAndCharConstants (line 22) | public final class StringAndCharConstants {
method StringAndCharConstants (line 23) | private StringAndCharConstants() {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/util/VariableUtils.java
class VariableUtils (line 10) | public class VariableUtils {
method getVariableName (line 11) | public static String getVariableName(AbstractJavaAccessNode typeNode) {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/util/ViolationUtils.java
class ViolationUtils (line 35) | public class ViolationUtils {
method addViolationWithPrecisePosition (line 36) | public static void addViolationWithPrecisePosition(AbstractRule rule, ...
method addViolationWithPrecisePosition (line 40) | public static void addViolationWithPrecisePosition(AbstractRule rule, ...
method addViolation (line 59) | private static void addViolation(AbstractRule rule, Node node, Object ...
method shouldIgnoreViolation (line 67) | public static boolean shouldIgnoreViolation(Class ruleClass, Node node) {
method getNodeRoot (line 99) | @Nullable
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/util/namelist/NameListConfig.java
class NameListConfig (line 27) | public class NameListConfig {
method renewNameListService (line 31) | public static synchronized @NotNull
method renewNameListService (line 37) | public static synchronized @NotNull
method createNameListService (line 44) | private static @NotNull
method getNameListService (line 53) | public static synchronized @NotNull
method setNameListService (line 58) | public static synchronized void setNameListService(@NotNull NameListSe...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/util/namelist/NameListService.java
type NameListService (line 29) | public interface NameListService {
method getNameList (line 37) | List<String> getNameList(String className, String name);
method getNameMap (line 45) | Map<String, String> getNameMap(String className, String name);
method loadPatchConfigFile (line 51) | void loadPatchConfigFile(
method ifRuleClassInRuleBlackList (line 60) | boolean ifRuleClassInRuleBlackList(Class ruleClass);
method ifClassNameInClassBlackList (line 67) | boolean ifClassNameInClassBlackList(String className);
method ifPackageNameInPackageBlackList (line 74) | boolean ifPackageNameInPackageBlackList(@Nullable String packageName);
method ifRuleClassNameClassNamePairInPairIgnoreList (line 82) | boolean ifRuleClassNameClassNamePairInPairIgnoreList(Class ruleClass, ...
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/util/namelist/NameListServiceImpl.java
class NameListServiceImpl (line 41) | public class NameListServiceImpl implements NameListService {
method NameListServiceImpl (line 48) | public NameListServiceImpl() {
method NameListServiceImpl (line 52) | public NameListServiceImpl(boolean ifLoadCustomerConfigX8lTree) {
method initP3cConfigDataBean (line 56) | private static P3cConfigDataBean initP3cConfigDataBean(boolean ifLoadC...
method loadPatchConfigFile (line 82) | @Override
method getNameList (line 93) | @Override
method getNameMap (line 98) | @Override
method ifRuleClassInRuleBlackList (line 103) | @Override
method ifStringInRuleBlackList (line 109) | public boolean ifStringInRuleBlackList(String string) {
method ifClassNameInClassBlackList (line 113) | @Override
method ifPackageNameInPackageBlackList (line 118) | @Override
method ifRuleClassNameClassNamePairInPairIgnoreList (line 134) | @Override
method getContentNode (line 144) | public ContentNode getContentNode(String className, String name) {
method getP3cConfigDataBean (line 160) | public P3cConfigDataBean getP3cConfigDataBean() {
FILE: p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/vm/rule/other/UseQuietReferenceNotationRule.java
class UseQuietReferenceNotationRule (line 39) | public class UseQuietReferenceNotationRule extends AbstractAliXpathRule {
method UseQuietReferenceNotationRule (line 54) | public UseQuietReferenceNotationRule() {
method evaluate (line 59) | @Override
method addViolation (line 77) | @Override
method getIdentifyName (line 84) | private String getIdentifyName(AbstractVmNode node) {
method checkMacro (line 102) | private boolean checkMacro(Node node) {
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/IfVoidIsPrimitiveTest.java
class IfVoidIsPrimitiveTest (line 7) | public class IfVoidIsPrimitiveTest {
method test (line 8) | @Test
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/config/TestConfig.java
class TestConfig (line 13) | public class TestConfig {
method testLoadDefaultConfig (line 14) | @Test
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/CommentRulesTest.java
class CommentRulesTest (line 27) | public class CommentRulesTest extends SimpleAggregatorTst {
method setUp (line 31) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/ConcurrentRuleTest.java
class ConcurrentRuleTest (line 27) | public class ConcurrentRuleTest extends SimpleAggregatorTst {
method setUp (line 30) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/constant/ConstantRulesTest.java
class ConstantRulesTest (line 27) | public class ConstantRulesTest extends SimpleAggregatorTst {
method setUp (line 31) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/exception/ExceptionRulesTest.java
class ExceptionRulesTest (line 27) | public class ExceptionRulesTest extends SimpleAggregatorTst {
method setUp (line 30) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/flowcontrol/FlowControlRuleTest.java
class FlowControlRuleTest (line 27) | public class FlowControlRuleTest extends SimpleAggregatorTst {
method setUp (line 31) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/NamingRulesTest.java
class NamingRulesTest (line 27) | public class NamingRulesTest extends SimpleAggregatorTst {
method setUp (line 30) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/OopRuleTest.java
class OopRuleTest (line 27) | public class OopRuleTest extends SimpleAggregatorTst {
method setUp (line 32) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/orm/OrmRulesTest.java
class OrmRulesTest (line 27) | public class OrmRulesTest extends SimpleAggregatorTst {
method setUp (line 30) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/other/OtherRulesTest.java
class OtherRulesTest (line 27) | public class OtherRulesTest extends SimpleAggregatorTst {
method setUp (line 31) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/other/UseRightCaseForDateFormatRuleTest.java
class UseRightCaseForDateFormatRuleTest (line 13) | public class UseRightCaseForDateFormatRuleTest extends ExtendRuleTst {
method testExam1 (line 15) | @Test
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/set/SetRulesTest.java
class SetRulesTest (line 26) | public class SetRulesTest extends SimpleAggregatorTst {
method setUp (line 30) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/xenoamess/additional/XenoAmessAdditionalTest.java
class XenoAmessAdditionalTest (line 26) | public class XenoAmessAdditionalTest extends SimpleAggregatorTst {
method setUp (line 30) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/java/rule/xenoamess/deprecated/XenoAmessDeprecatedTest.java
class XenoAmessDeprecatedTest (line 26) | public class XenoAmessDeprecatedTest extends SimpleAggregatorTst {
method setUp (line 30) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/lang/vm/rule/other/OtherRulesTest.java
class OtherRulesTest (line 27) | public class OtherRulesTest extends SimpleAggregatorTst {
method setUp (line 31) | @Override
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/testframework/ExtendRuleTst.java
class ExtendRuleTst (line 20) | public class ExtendRuleTst extends RuleTst {
method runTest (line 23) | public void runTest(Rule rule, String examFilePath, String expectedVio...
method extractTestsFromJavaFile (line 38) | public TestDescriptor extractTestsFromJavaFile(Rule rule) {
method extractTestsFromJavaFile (line 47) | public TestDescriptor extractTestsFromJavaFile(Rule rule, String javaF...
method extractTestsFromJavaFile (line 51) | public TestDescriptor extractTestsFromJavaFile(Rule rule, String javaF...
method getExpectedLineNumbers (line 83) | public List<Integer> getExpectedLineNumbers(String lineNumbers) {
FILE: p3c-pmd/src/test/java/com/xenoamess/p3c/pmd/testframework/ExtendSimpleAggregatorTst.java
class ExtendSimpleAggregatorTst (line 11) | public class ExtendSimpleAggregatorTst extends SimpleAggregatorTst {
FILE: p3c-pmd/src/test/resources/com/xenoamess/p3c/pmd/lang/java/rule/other/java/UseRightCaseForDateFormatRuleExam.java
class UseRightCaseForDateFormatRuleExam (line 11) | public class UseRightCaseForDateFormatRuleExam {
method exam1 (line 15) | public void exam1() {
method exam2 (line 51) | public void exam2(String formatStr) {
method exam3 (line 57) | public void exam3(){
Condensed preview — 317 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,291K chars).
[
{
"path": ".gitattributes",
"chars": 19,
"preview": "* text=auto eol=lf\n"
},
{
"path": ".github/ISSUE_TEMPLATE/------.md",
"chars": 102,
"preview": "---\nname: 规约问题模板\nabout: 规约问题请使用该模板\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n## 规约原文\n\n## 问题描述\n\n## 修改建议\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 834,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 595,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
},
{
"path": ".github/ISSUE_TEMPLATE/rule-issue-template.md",
"chars": 166,
"preview": "---\nname: Rule issue template\nabout: Rule issue please use this template.\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n## Ru"
},
{
"path": ".github/dependabot.yml",
"chars": 1334,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements. See the NOTICE f"
},
{
"path": ".github/workflows/auto-merge.yml",
"chars": 1336,
"preview": "name: Dependabot auto-merge\n\non:\n pull_request:\n\npermissions:\n pull-requests: write\n contents: write\n\njobs:\n dependa"
},
{
"path": ".github/workflows/build.yml",
"chars": 2421,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one or more\n# contributor license agreements. See the NOTICE f"
},
{
"path": ".gitignore",
"chars": 945,
"preview": "# Gradle\nbuild\n.gradle\n\ntestdata/\n# Java gitignore #\n.class\n.log\n\n# Package Files #\n\n*.war\n*.ear\n\n#hsf files\nconfigurati"
},
{
"path": ".mvn/wrapper/MavenWrapperDownloader.java",
"chars": 4941,
"preview": "/*\n * Copyright 2007-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
},
{
"path": ".mvn/wrapper/maven-wrapper.properties",
"chars": 218,
"preview": "distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip\nwrap"
},
{
"path": "AGENTS.md",
"chars": 8243,
"preview": "# P3C - Alibaba Java Coding Guidelines (XenoAmess TPM)\n\nThis is a Third-Party Maintenance (TPM) fork of the original [al"
},
{
"path": "README.md",
"chars": 5610,
"preview": "# P3C\n\n[](https://www.apache.org/licenses/LICENSE-"
},
{
"path": "build.cmd",
"chars": 298,
"preview": "set JAVA_HOME=C:\\jdk-21\\\n\ncd ./p3c-pmd\ncall ./mvnw clean install -Dmaven.javadoc.skip=false -e -X\ncd ../\ncd ./idea-plugi"
},
{
"path": "deploy.cmd",
"chars": 435,
"preview": "set JAVA_HOME=C:\\jdk-8\\\n\ncd ./p3c-pmd\ncall ./mvnw clean deploy -Dmaven.javadoc.skip=false -e -X -Psonatype-oss-release\nc"
},
{
"path": "idea-plugin/.gitignore",
"chars": 802,
"preview": "# Gradle\nbuild\n.gradle\n\ntestdata/\n# Java gitignore #\n.class\n.log\n\n# Package Files #\n\n*.war\n*.ear\n\n#hsf files\nconfigurati"
},
{
"path": "idea-plugin/README.md",
"chars": 10366,
"preview": "# Idea Plugin \n---\n## <font color=\"green\">Prepare</font>\n- Project JDK: 11\n- Gradle: 7.3(Require JDK17 for gradle)\n\n## <"
},
{
"path": "idea-plugin/README_cn.md",
"chars": 10276,
"preview": "> 首先非常感谢大家对插件的支持与意见,英文版的文档还是略为简单,这里详细介绍一下插件的安装使用。\n\n## 插件安装\n### 通过Jetbrains官方仓库安装\n1. 打开 Settings >> Plugins >> Browse rep"
},
{
"path": "idea-plugin/build.gradle",
"chars": 1822,
"preview": "static boolean shouldIncludeJava(String idea_version_string) {\n if (idea_version_string.contains('-')) {\n idea"
},
{
"path": "idea-plugin/gradle/wrapper/gradle-wrapper.properties",
"chars": 252,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "idea-plugin/gradle.properties",
"chars": 519,
"preview": "# See https://github.com/JetBrains/gradle-intellij-plugin/\n# See https://www.jetbrains.org/intellij/sdk/docs/reference_g"
},
{
"path": "idea-plugin/gradlew",
"chars": 8631,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\")"
},
{
"path": "idea-plugin/gradlew.bat",
"chars": 2846,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "idea-plugin/p3c-common/build.gradle",
"chars": 2087,
"preview": "plugins {\n id 'java'\n id(\"org.jetbrains.intellij.platform\") version \"2.16.0\"\n\n id \"org.sonarqube\" version \"6.3."
},
{
"path": "idea-plugin/p3c-common/src/main/java/icons/P3cIcons.java",
"chars": 1505,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/action/AliInspectionAction.kt",
"chars": 8829,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/action/PmdGlobalInspectionContextImpl.kt",
"chars": 16029,
"preview": "package com.alibaba.p3c.idea.action\n\nimport com.alibaba.p3c.idea.component.AliProjectComponent\nimport com.alibaba.p3c.id"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/action/SwitchLanguageAction.kt",
"chars": 2082,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/action/ToggleProjectInspectionAction.kt",
"chars": 4392,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/activity/CommonSettingsApplicationStartupActivity.kt",
"chars": 2330,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/compatible/inspection/InspectionProfileService.kt",
"chars": 5051,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/compatible/inspection/Inspections.kt",
"chars": 4274,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/component/AliProjectComponent.kt",
"chars": 5790,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/config/P3cConfig.kt",
"chars": 1993,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/config/P3cConfigurable.kt",
"chars": 6261,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/config/SmartFoxProjectConfig.kt",
"chars": 1754,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/ep/InspectionActionExtensionPoint.kt",
"chars": 1432,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/ep/package-info.java",
"chars": 101,
"preview": "/**\n * extension point\n *\n * @author caikang\n * @date 2017/06/19\n */\npackage com.alibaba.p3c.idea.ep;"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/i18n/P3cBundle.kt",
"chars": 1737,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliAccessToNonThreadSafeStaticFieldFromInstanceInspection.kt",
"chars": 1915,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliArrayNamingShouldHaveBracketInspection.kt",
"chars": 2865,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliBaseInspection.kt",
"chars": 2003,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliControlFlowStatementWithoutBracesInspection.kt",
"chars": 2324,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliEqualsAvoidNullInspection.kt",
"chars": 4919,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliLocalInspectionToolProvider.kt",
"chars": 8753,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliLongLiteralsEndingWithLowercaseLInspection.kt",
"chars": 2742,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliPmdInspection.kt",
"chars": 4121,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliPmdInspectionInvoker.kt",
"chars": 7227,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/AliWrapperTypeEqualityInspection.kt",
"chars": 6753,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/DelegateLocalInspectionTool.kt",
"chars": 3090,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/DelegatePmdInspection.kt",
"chars": 2465,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/PmdRuleInspectionIdentify.kt",
"chars": 735,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/RuleInspectionUtils.kt",
"chars": 7984,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/standalone/AliAccessStaticViaInstanceInspection.kt",
"chars": 5519,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/standalone/AliDeprecationInspection.kt",
"chars": 5906,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/standalone/AliMissingOverrideAnnotationInspection.kt",
"chars": 6489,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/inspection/standalone/MapOrSetKeyShouldOverrideHashCodeEqualsInspection.kt",
"chars": 7612,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/lifecycle/P3cPluginLifecycle.kt",
"chars": 2936,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/pmd/AliPmdProcessor.kt",
"chars": 4361,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/pmd/SourceCodeProcessor.kt",
"chars": 11967,
"preview": "/**\n * BSD-style license; for more info see http://pmd.sourceforge.net/license.html\n */\n\npackage com.alibaba.p3c.idea.pm"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/pmd/index/InspectionDataSource.kt",
"chars": 1314,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/pmd/index/InspectionRenderer.kt",
"chars": 1611,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/quickfix/AliQuickFix.kt",
"chars": 4184,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/quickfix/AvoidStartWithDollarAndUnderLineNamingQuickFix.kt",
"chars": 1695,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/quickfix/ClassMustHaveAuthorQuickFix.kt",
"chars": 3004,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/quickfix/ConstantFieldShouldBeUpperCaseQuickFix.kt",
"chars": 2472,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/quickfix/DecorateInspectionFix.kt",
"chars": 1317,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/quickfix/LowerCamelCaseVariableNamingQuickFix.kt",
"chars": 2126,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/quickfix/VmQuietReferenceQuickFix.kt",
"chars": 1450,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/util/DocumentUtils.kt",
"chars": 2057,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/util/HighlightDisplayLevels.kt",
"chars": 1332,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/util/HighlightInfoTypes.kt",
"chars": 1648,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/util/HighlightSeverities.kt",
"chars": 1051,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/util/NumberConstants.kt",
"chars": 895,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/util/ObjectConstants.kt",
"chars": 1001,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/util/ProblemsUtils.kt",
"chars": 6397,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/util/QuickFixes.kt",
"chars": 1943,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/util/withLockNotInline.kt",
"chars": 1037,
"preview": "package com.alibaba.p3c.idea.util\n\nimport com.intellij.openapi.progress.ProcessCanceledException\nimport java.util.concur"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/vcs/AliCodeAnalysisCheckinHandler.kt",
"chars": 9658,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/p3c/idea/vcs/AliCodeAnalysisCheckinHandlerFactory.kt",
"chars": 1167,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/smartfox/idea/common/activity/AliBaseApplicationStartupActivity.kt",
"chars": 822,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/smartfox/idea/common/component/AliBaseProjectComponent.kt",
"chars": 1176,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/smartfox/idea/common/util/BalloonNotifications.kt",
"chars": 5588,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/smartfox/idea/common/util/CommonExtensions.kt",
"chars": 998,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/kotlin/com/alibaba/smartfox/idea/common/util/PluginVersions.kt",
"chars": 1911,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "idea-plugin/p3c-common/src/main/resources/messages/P3cBundle.xml",
"chars": 5513,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.d"
},
{
"path": "idea-plugin/p3c-common/src/main/resources/messages/P3cBundle_en.xml",
"chars": 7282,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.d"
},
{
"path": "idea-plugin/p3c-common/src/main/resources/rulesets/java/ali-pmd.xml",
"chars": 1102,
"preview": "<?xml version=\"1.0\"?>\n\n<ruleset xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" name=\"alibaba-pmd\"\n xmlns="
},
{
"path": "idea-plugin/p3c-common/src/main/resources/tpl/StaticDescriptionTemplate.ftl",
"chars": 243,
"preview": "<#ftl output_format=\"HTML\">\n<html>\n<body>\n<span style=\"color:orange\">\n <pre>${message}<#if description??><br>${descri"
},
{
"path": "idea-plugin/p3c-idea/build.gradle",
"chars": 594,
"preview": "plugins {\n id 'java'\n id(\"org.jetbrains.intellij.platform\") version \"2.16.0\"\n\n id \"com.github.ben-manes.version"
},
{
"path": "idea-plugin/p3c-idea/src/main/resources/META-INF/plugin.xml",
"chars": 13704,
"preview": "<idea-plugin require-restart=\"false\">\n <id>com.alibaba.p3c.xenoamess</id>\n <name>Alibaba Java Coding Guidelines(Xe"
},
{
"path": "idea-plugin/p3c-idea/src/main/resources/META-INF/pluginWithJava.xml",
"chars": 3324,
"preview": "<idea-plugin>\n <project-components>\n <component>\n <implementation-class>com.alibaba.p3c.idea.compon"
},
{
"path": "idea-plugin/settings.gradle",
"chars": 229,
"preview": "plugins {\n id \"com.gradle.develocity\" version \"4.4.1\"\n}\ndevelocity {\n buildScan {\n termsOfUseUrl = \"https:/"
},
{
"path": "license.txt",
"chars": 10896,
"preview": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AN"
},
{
"path": "mvnw",
"chars": 10069,
"preview": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Softwa"
},
{
"path": "mvnw.cmd",
"chars": 6607,
"preview": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software F"
},
{
"path": "p3c-formatter/eclipse-codestyle.xml",
"chars": 46891,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<profiles version=\"12\">\n <profile kind=\"CodeFormatterProfile\" "
},
{
"path": "p3c-formatter/eclipse-codetemplate.xml",
"chars": 4834,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><templates><template autoinsert=\"true\" context=\"gettercomment_cont"
},
{
"path": "p3c-gitbook/.gitignore",
"chars": 352,
"preview": "# Node rules:\n## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n## Dependen"
},
{
"path": "p3c-gitbook/MySQL数据库/ORM映射.md",
"chars": 1432,
"preview": "## (四) ORM映射\n1. 【强制】在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。 \n<br><span style=\"color:orange\">说明</span>:1)增加查询分析器解析成本。2)增减字"
},
{
"path": "p3c-gitbook/MySQL数据库/SQL语句.md",
"chars": 1524,
"preview": "## (三) SQL语句 \n1. 【强制】不要使用count(列名)或count(常量)来替代count(*),count(*)是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。 \n<br><span styl"
},
{
"path": "p3c-gitbook/MySQL数据库/建表规约.md",
"chars": 2216,
"preview": "# 五、MySQL数据库\n## (一) 建表规约\n1. 【强制】表达是与否概念的字段,必须使用is_xxx的方式命名,数据类型是unsigned tinyint( 1表示是,0表示否)。 \n<br><span style=\"color:or"
},
{
"path": "p3c-gitbook/MySQL数据库/索引规约.md",
"chars": 2222,
"preview": "## (二) 索引规约\n1. 【强制】业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。 \n<br><span style=\"color:orange\">说明</span>:不要以为唯一索引影响了insert速度,这个速度"
},
{
"path": "p3c-gitbook/README.md",
"chars": 1010,
"preview": "## <center>前言</center>\n\n 《阿里巴巴Java开发手册》是阿里巴巴集团技术团队的集体智慧结晶和经验总结,经历了多次大规模一线实战的检验及不断的完善,系统化地整理成册,回馈给"
},
{
"path": "p3c-gitbook/SUMMARY.md",
"chars": 680,
"preview": "# Summary\n\n* [前言](README.md)\n* 一、编程规约\n - [(一)命名风格](编程规约/命名风格.md)\n - [(二)常量定义](编程规约/常量定义.md)\n - [(三)代码格式](编程规约/代码格式.md"
},
{
"path": "p3c-gitbook/book.json",
"chars": 278,
"preview": "{\n \"styles\": {\n \"website\": \"styles/website.css\"\n },\n\n \"plugins\": [\n \"book-summary-scroll-position-saver\",\n \""
},
{
"path": "p3c-gitbook/styles/website.css",
"chars": 47,
"preview": ".gitbook-link {\n display: none !important;\n}"
},
{
"path": "p3c-gitbook/单元测试.md",
"chars": 2367,
"preview": "## 三、单元测试 \n1. 【强制】好的单元测试必须遵守AIR原则。 \n<br><span style=\"color:orange\">说明</span>:单元测试在线上运行时,感觉像空气(AIR)一样并不存在,但在测试质量的保障上,却是非常"
},
{
"path": "p3c-gitbook/安全规约.md",
"chars": 1068,
"preview": "## 四、安全规约 \n1. 【强制】隶属于用户个人的页面或者功能必须进行权限控制校验。 \n<br><span style=\"color:orange\">说明</span>:防止没有做水平权限校验就可随意访问、修改、删除别人的数据,比如查看他"
},
{
"path": "p3c-gitbook/工程结构/二方库依赖.md",
"chars": 1996,
"preview": "## (二) 二方库依赖\n\n1. 【强制】定义GAV遵从以下规则: \n1) `G`roupID格式:com.{公司/BU }.业务线.[子业务线],最多4级。 \n<span style=\"color:orange\">说明</span>"
},
{
"path": "p3c-gitbook/工程结构/应用分层.md",
"chars": 1289,
"preview": "# 六、工程结构\n## (一) 应用分层 \n\n1. 【推荐】图中默认上层依赖于下层,箭头关系表示可直接依赖,如:开放接口层可以依赖于Web层,也可以直接依赖于Service层,依此类推:\n  服务器\n1. 【推荐】高并发服务器建议调小TCP协议的`time_wait`超时时间。 说明:操作系统默认240秒后,才会关闭处于`time_wait`状态的连接,在高并发访问下,服务器端会因为处于`time_wait`的连接"
},
{
"path": "p3c-gitbook/异常日志/其他.md",
"chars": 1149,
"preview": "## (三) 其它 \n1. 【强制】在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。 \n<br><span style=\"color:orange\">说明</span>:不要在方法体内定义:Pattern pattern "
},
{
"path": "p3c-gitbook/异常日志/异常处理.md",
"chars": 2752,
"preview": "# 二、异常日志 \n## (一) 异常处理 \n1. 【强制】Java 类库中定义的可以通过预检查方式规避的RuntimeException异常不应该通过catch 的方式来处理,比如:NullPointerException,IndexOu"
},
{
"path": "p3c-gitbook/异常日志/日志规约.md",
"chars": 2035,
"preview": "## (二) 日志规约 \n1. 【强制】应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架SLF4J中的API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。 \n<pre>\nimport"
},
{
"path": "p3c-gitbook/本手册专有名词.md",
"chars": 678,
"preview": "## 附2:本手册专有名词\n1. POJO(Plain Ordinary Java Object): 在本手册中,POJO专指只有setter / getter / toString的简单类,包括DO/DTO/BO/VO等。 \n2. GAV"
},
{
"path": "p3c-gitbook/版本历史.md",
"chars": 880,
"preview": "## 附1:版本历史\n| 版本号 | 更新日期 | 备注 |\n| ------------- |:-------------| :----- |\n| 1.0.0 | 2017.2.9 | 阿里巴巴集团正式对外发布 | \n| 1.0."
},
{
"path": "p3c-gitbook/维护手册.md",
"chars": 799,
"preview": "# markdown维护手册0.2.0\n本手册并非你所阅读的markdown材料的一部分,\n而是旨在更好地维护markdown材料而提出的,\n对于markdown材料维护人员的要求规范。\n\n## 0.及时更新该手册\n该手册发布地址为:\nht"
},
{
"path": "p3c-gitbook/编程规约/OOP规范.md",
"chars": 4359,
"preview": "## (四) OOP规约 \n\n1. 【强制】避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用**类名**来访问即可。 \n2. 【强制】所有的覆写方法,必须加@Override注解。 \n<br><span "
},
{
"path": "p3c-gitbook/编程规约/代码格式.md",
"chars": 2699,
"preview": "## (三)代码格式\n1. 【强制】大括号的使用约定。如果是大括号内为空,则简洁地写成`{}`即可,不需要换行;如果是非空代码块则:\n<br>1) 左大括号前不换行。\n<br>2) 左大括号后换行。\n<br>3) 右大括号前换行。\n<br>"
},
{
"path": "p3c-gitbook/编程规约/命名风格.md",
"chars": 3591,
"preview": "# 一、编程规约\n## (一)命名风格\n\n1. 【强制】代码中的命名均不能以<strong>下划线或美元符号</strong>开始,也不能以<strong>下划线或美元符号</strong>结束。\n <br><span style=\"co"
},
{
"path": "p3c-gitbook/编程规约/常量定义.md",
"chars": 1348,
"preview": "## (二)常量定义\n\n1. 【强制】不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。\n<br><span style=\"color:red\">反例</span>:\n```\nString key = \"Id#taobao_\" + "
},
{
"path": "p3c-gitbook/编程规约/并发处理.md",
"chars": 3546,
"preview": "## (六) 并发处理 \n1. 【强制】获取单例对象需要保证线程安全,其中的方法也要保证线程安全。 \n<br><span style=\"color:orange\">说明</span>:资源驱动类、工具类、单例工厂类都需要注意。 \n2. 【强"
},
{
"path": "p3c-gitbook/编程规约/控制语句.md",
"chars": 2414,
"preview": "## (七) 控制语句 \n1. 【强制】在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程序将继续执行到哪一个case为止;在一个switch块内,都必须包含一个default语句并且放在最后,即使"
},
{
"path": "p3c-gitbook/编程规约/注释规约.md",
"chars": 1615,
"preview": "## (八) 注释规约\n\n1. 【强制】类、类属性、类方法的注释必须使用Javadoc规范,使用/**内容*/格式,不得使用// xxx方式。 \n<br><span style=\"color:orange\">说明</span>:在IDE编辑"
},
{
"path": "p3c-gitbook/编程规约/集合处理.md",
"chars": 4964,
"preview": "## (五) 集合处理 \n1. 【强制】关于`hashCode`和`equals`的处理,遵循如下规则: \n<br>1) 只要重写`equals`,就必须重写`hashCode`。 \n<br>2) 因为Set存储的是不重复的对象,依据`ha"
},
{
"path": "p3c-pmd/.gitignore",
"chars": 834,
"preview": "# reference to https://github.com/github/gitignore\n\ntestdata/\n# Java gitignore #\n.class\n.log\n\n# Package Files #\n\n*.war\n*"
},
{
"path": "p3c-pmd/.mvn/wrapper/MavenWrapperDownloader.java",
"chars": 4941,
"preview": "/*\n * Copyright 2007-present the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \""
},
{
"path": "p3c-pmd/.mvn/wrapper/maven-wrapper.properties",
"chars": 218,
"preview": "distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip\nwrap"
},
{
"path": "p3c-pmd/README.md",
"chars": 19481,
"preview": "# P3C-PMD\n\n## <font color=\"green\">Build requirements</font>\n- JDK 1.7+\n- Maven 3\n\n## <font color=\"green\">Use as dependen"
},
{
"path": "p3c-pmd/mvnw",
"chars": 10069,
"preview": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Softwa"
},
{
"path": "p3c-pmd/mvnw.cmd",
"chars": 6607,
"preview": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software F"
},
{
"path": "p3c-pmd/pom.xml",
"chars": 38854,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n xmlns:xsi=\"http://ww"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/I18nResources.java",
"chars": 7516,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/config/P3cConfigDataBean.java",
"chars": 5193,
"preview": "package com.xenoamess.p3c.pmd.config;\n\nimport com.xenoamess.x8l.ContentNode;\nimport com.xenoamess.x8l.X8lTree;\nimport co"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/fix/FixClassTypeResolver.java",
"chars": 29454,
"preview": "/*\n * BSD-style license; for more info see http://pmd.sourceforge.net/license.html\n */\npackage com.xenoamess.p3c.pmd.fix"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/AbstractAliXpathRule.java",
"chars": 3682,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/AbstractAliRule.java",
"chars": 3710,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/AbstractPojoRule.java",
"chars": 2141,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/AbstractAliCommentRule.java",
"chars": 2137,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/AbstractMethodOrInterfaceMethodMustUseJavadocRule.java",
"chars": 7468,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/AvoidCommentBehindStatementRule.java",
"chars": 3750,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/ClassMustHaveAuthorRule.java",
"chars": 5080,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/CommentsMustBeJavadocFormatRule.java",
"chars": 9473,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/EnumConstantsMustHaveCommentRule.java",
"chars": 3075,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/comment/RemoveCommentedCodeRule.java",
"chars": 7651,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/AvoidCallStaticSimpleDateFormatRule.java",
"chars": 6870,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/AvoidConcurrentCompetitionRandomRule.java",
"chars": 5657,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/AvoidManuallyCreateThreadRule.java",
"chars": 7744,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/AvoidUseTimerRule.java",
"chars": 2020,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/CountDownShouldInFinallyRule.java",
"chars": 2558,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/ThreadLocalShouldRemoveRule.java",
"chars": 4304,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/ThreadPoolCreationRule.java",
"chars": 5053,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/concurrent/ThreadShouldSetNameRule.java",
"chars": 6187,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/constant/UndefineMagicConstantRule.java",
"chars": 4840,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/constant/UpperEllRule.java",
"chars": 1555,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/exception/AvoidReturnInFinallyRule.java",
"chars": 1583,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/exception/MethodReturnWrapperTypeRule.java",
"chars": 5850,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/exception/TransactionMustHaveRollbackRule.java",
"chars": 5048,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/flowcontrol/AvoidComplexConditionRule.java",
"chars": 1732,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/flowcontrol/AvoidNegationOperatorRule.java",
"chars": 1742,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/flowcontrol/NeedBraceRule.java",
"chars": 2878,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/flowcontrol/SwitchExpressionRule.java",
"chars": 2304,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/flowcontrol/SwitchStatementRule.java",
"chars": 3999,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/AbstractClassShouldStartWithAbstractNamingRule.java",
"chars": 1891,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/ArrayNamingShouldHaveBracketRule.java",
"chars": 1624,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/AvoidStartWithDollarAndUnderLineNamingRule.java",
"chars": 2548,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/BooleanPropertyShouldNotStartWithIsRule.java",
"chars": 2260,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/ClassNamingShouldBeCamelRule.java",
"chars": 2295,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/ConstantFieldShouldBeUpperCaseRule.java",
"chars": 3238,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/ExceptionClassShouldEndWithExceptionRule.java",
"chars": 2554,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/LowerCamelCaseVariableNamingRule.java",
"chars": 5436,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/PackageNamingRule.java",
"chars": 1675,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/ServiceOrDaoClassShouldEndWithImplRule.java",
"chars": 1872,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/naming/TestClassShouldEndWithTestNamingRule.java",
"chars": 4034,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/BigDecimalAvoidDoubleConstructorRule.java",
"chars": 3773,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/EqualsAvoidNullRule.java",
"chars": 6535,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/PojoMustOverrideToStringRule.java",
"chars": 5156,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/PojoMustUsePrimitiveFieldRule.java",
"chars": 2861,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/PojoNoDefaultValueRule.java",
"chars": 2616,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/StringConcatRule.java",
"chars": 5871,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/oop/WrapperTypeEqualityRule.java",
"chars": 3106,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/orm/IbatisMethodQueryForListRule.java",
"chars": 9207,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/AvoidApacheBeanUtilsCopyRule.java",
"chars": 1671,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/AvoidDoubleOrFloatEqualCompareRule.java",
"chars": 1560,
"preview": "package com.xenoamess.p3c.pmd.lang.java.rule.other;\n\nimport com.xenoamess.p3c.pmd.lang.java.rule.AbstractAliRule;\nimport"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/AvoidMissUseOfMathRandomRule.java",
"chars": 1867,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/AvoidNewDateGetTimeRule.java",
"chars": 1838,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/AvoidPatternCompileInMethodRule.java",
"chars": 2377,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/MethodTooLongRule.java",
"chars": 6064,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/other/UseRightCaseForDateFormatRule.java",
"chars": 2880,
"preview": "package com.xenoamess.p3c.pmd.lang.java.rule.other;\n\nimport com.xenoamess.p3c.pmd.lang.AbstractAliXpathRule;\nimport net."
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/ClassCastExceptionWithSubListToArrayListRule.java",
"chars": 2207,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/ClassCastExceptionWithToArrayRule.java",
"chars": 3439,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/CollectionInitShouldAssignCapacityRule.java",
"chars": 3212,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/ConcurrentExceptionWithModifyOriginSubListRule.java",
"chars": 4487,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/DontModifyInForeachCircleRule.java",
"chars": 3323,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/set/UnsupportedExceptionWithModifyAsListRule.java",
"chars": 4843,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/util/NodeSortUtils.java",
"chars": 1457,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/util/NodeUtils.java",
"chars": 3892,
"preview": "/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/xenoamess/additional/EqualsHashCodeRule.java",
"chars": 1838,
"preview": "package com.xenoamess.p3c.pmd.lang.java.rule.xenoamess.additional;\n\n/*\n * Copyright 1999-2017 Alibaba Group.\n *\n * Licen"
},
{
"path": "p3c-pmd/src/main/java/com/xenoamess/p3c/pmd/lang/java/rule/xenoamess/additional/SneakyThrowsWithoutExceptionTypeRule.java",
"chars": 1581,
"preview": "package com.xenoamess.p3c.pmd.lang.java.rule.xenoamess.additional;\n\nimport com.xenoamess.p3c.pmd.lang.java.rule.Abstract"
}
]
// ... and 117 more files (download for full content)
About this extraction
This page contains the full source code of the XenoAmess/p3c GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 317 files (1.1 MB), approximately 298.1k tokens, and a symbol index with 473 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.