├── .editorconfig ├── .git-blame-ignore-revs ├── .github ├── dependabot.yml └── workflows │ ├── dependencies.yml │ ├── main.yml │ ├── release.yml │ └── stale.yml ├── .gitignore ├── .idea ├── dictionaries │ └── fried.xml ├── encodings.xml ├── inspectionProfiles │ └── Project_Default.xml └── runConfigurations │ └── runIde.xml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── MAINTAINERSHIP.md ├── README.md ├── build.gradle.kts ├── doc ├── AppCexcerpt.pdf ├── PowerShell 2 0 Language Specification.docx ├── Windows PowerShell Language Specification Version 3.0.docx └── remote-file-editing.gif ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── intellij-updater.json ├── settings.gradle.kts └── src ├── main ├── java │ └── com │ │ └── intellij │ │ └── plugin │ │ └── powershell │ │ ├── ide │ │ ├── injection │ │ │ └── PSPatterns.java │ │ └── run │ │ │ ├── PowerShellRunSettingsEditor.form │ │ │ └── PowerShellRunSettingsEditor.java │ │ └── lang │ │ ├── lsp │ │ └── ide │ │ │ └── settings │ │ │ ├── FormUIUtil.kt │ │ │ ├── PowerShellConfigurable.java │ │ │ ├── PowerShellExecutableChooserPanel.form │ │ │ ├── PowerShellExecutableChooserPanel.java │ │ │ ├── PowerShellJPanelComponent.form │ │ │ └── PowerShellJPanelComponent.java │ │ ├── parser │ │ └── PowerShellGeneratedParserUtil.java │ │ └── util │ │ └── PowerShellStringUtil.java ├── kotlin │ └── com │ │ └── intellij │ │ └── plugin │ │ └── powershell │ │ ├── PowerShellFileType.kt │ │ ├── PowerShellIcons.kt │ │ ├── ide │ │ ├── LoggerEx.kt │ │ ├── MessagesBundle.kt │ │ ├── PluginRootServices.kt │ │ ├── actions │ │ │ ├── NewPowerShellFileAction.kt │ │ │ └── PowerShellConsoleAction.kt │ │ ├── debugger │ │ │ ├── EditorServicesDebuggerHostStarter.kt │ │ │ ├── PowerShellBreakpointHandler.kt │ │ │ ├── PowerShellBreakpointType.kt │ │ │ ├── PowerShellDebugProcess.kt │ │ │ ├── PowerShellDebugSession.kt │ │ │ ├── PowerShellDebuggerEditorsProvider.kt │ │ │ ├── PowerShellDebuggerVariableValue.kt │ │ │ ├── PowerShellExecutionStack.kt │ │ │ ├── PowerShellSourcePosition.kt │ │ │ ├── PowerShellStackFrame.kt │ │ │ ├── PowerShellSuspendContext.kt │ │ │ ├── PowerShellVariableGroup.kt │ │ │ └── PowershellDebuggerEvaluator.kt │ │ ├── editor │ │ │ ├── PowerShellCommenter.kt │ │ │ ├── PowerShellFoldingBuilder.kt │ │ │ ├── completion │ │ │ │ ├── PowerShellCompletionContributor.kt │ │ │ │ └── PowerShellDebuggerCompletionContributor.kt │ │ │ ├── documentation │ │ │ │ └── PowerShellDocumentationProvider.kt │ │ │ ├── formatting │ │ │ │ ├── ChainMethodCallBlockBuilder.kt │ │ │ │ ├── PSFormattingUtils.kt │ │ │ │ ├── PowerShellBlockImpl.kt │ │ │ │ ├── PowerShellCodeBlock.kt │ │ │ │ ├── PowerShellCodeStyleConfigurable.kt │ │ │ │ ├── PowerShellCodeStyleSettings.kt │ │ │ │ ├── PowerShellCodeStyleSettingsProvider.kt │ │ │ │ ├── PowerShellFormattingModelBuilder.kt │ │ │ │ ├── PowerShellLanguageCodeStyleSettingsProvider.kt │ │ │ │ └── SyntheticPowerShellCodeBlock.kt │ │ │ ├── generate │ │ │ │ └── PowerShellScriptContextType.kt │ │ │ └── highlighting │ │ │ │ ├── PowerShellColorSettingsPage.kt │ │ │ │ ├── PowerShellPairedBraceMatcher.kt │ │ │ │ ├── PowerShellSyntaxHighlighter.kt │ │ │ │ └── PowerShellSyntaxHighlighterFactory.kt │ │ ├── injection │ │ │ ├── PSElementPatterns.kt │ │ │ ├── PSPatterUtil.kt │ │ │ ├── PowerShellLanguageInjectionSupport.kt │ │ │ ├── PowerShellLanguageInjector.kt │ │ │ └── PowerShellStringManipulator.kt │ │ ├── refactoring │ │ │ ├── PowerShellElementRefactoringSupportProvider.kt │ │ │ ├── PowerShellElementRenameInputValidator.kt │ │ │ ├── PowerShellNameUtils.kt │ │ │ ├── PowerShellNamesValidator.kt │ │ │ ├── PowerShellRefactoringUtils.kt │ │ │ └── PowerShellRenamePsiElementProcessor.kt │ │ ├── resolve │ │ │ ├── PSFieldScopeProcessor.kt │ │ │ ├── PSMethodScopeProcessor.kt │ │ │ ├── PowerShellClassScopeProcessor.kt │ │ │ ├── PowerShellComponentResolveProcessor.kt │ │ │ ├── PowerShellComponentScopeProcessor.kt │ │ │ ├── PowerShellMemberScopeProcessor.kt │ │ │ ├── PowerShellResolveResult.kt │ │ │ ├── PowerShellResolveUtil.kt │ │ │ ├── PowerShellResolver.kt │ │ │ └── PsNames.kt │ │ ├── run │ │ │ ├── PSExecutionUtil.kt │ │ │ ├── PowerShellConfigurationProducer.kt │ │ │ ├── PowerShellConfigurationType.kt │ │ │ ├── PowerShellProgramDebugRunner.kt │ │ │ ├── PowerShellProgramRunner.kt │ │ │ ├── PowerShellRunConfiguration.kt │ │ │ └── PowerShellScriptCommandLineState.kt │ │ ├── search │ │ │ ├── PowerShellComponentType.kt │ │ │ ├── PowerShellTargetElementEvaluator.kt │ │ │ └── PowerShellUsagesProvider.kt │ │ └── structure │ │ │ ├── PowerShellStructureViewElement.kt │ │ │ ├── PowerShellStructureViewFactory.kt │ │ │ └── PowerShellStructureViewModel.kt │ │ ├── lang │ │ ├── PowerShellAnnotator.kt │ │ ├── PowerShellLanguage.kt │ │ ├── debugger │ │ │ └── PSDebugClient.kt │ │ ├── lexer │ │ │ ├── PowerShellLexerAdapter.kt │ │ │ └── PowerShellTokenType.kt │ │ ├── lsp │ │ │ ├── LanguageServer.kt │ │ │ ├── PowerShellSettings.kt │ │ │ ├── client │ │ │ │ └── PSLanguageClientImpl.kt │ │ │ ├── ide │ │ │ │ ├── EditorEventManager.kt │ │ │ │ ├── LSPRequestManager.kt │ │ │ │ ├── inspection │ │ │ │ │ └── PSESInspection.kt │ │ │ │ └── listeners │ │ │ │ │ ├── DocumentListenerImpl.kt │ │ │ │ │ ├── EditorLSPListener.kt │ │ │ │ │ ├── EditorMouseListenerImpl.kt │ │ │ │ │ ├── EditorMouseMotionListenerImpl.kt │ │ │ │ │ ├── LSPEditorListener.kt │ │ │ │ │ ├── LSPTypedHandler.kt │ │ │ │ │ └── SelectionListenerImpl.kt │ │ │ ├── languagehost │ │ │ │ ├── EditorServicesLanguageHostStarter.kt │ │ │ │ ├── LanguageHostConnectionManager.kt │ │ │ │ ├── LanguageServerEndpoint.kt │ │ │ │ ├── PSESVersion.kt │ │ │ │ ├── PSLanguageHostUtils.kt │ │ │ │ ├── PSVersionInfo.kt │ │ │ │ ├── PowerShellControlFlowException.kt │ │ │ │ ├── PowerShellExtensionError.kt │ │ │ │ ├── PowerShellExtensionNotFound.kt │ │ │ │ ├── PowerShellNotInstalled.kt │ │ │ │ ├── ServerOptions.kt │ │ │ │ ├── TextDocumentServiceQueue.kt │ │ │ │ └── terminal │ │ │ │ │ └── PowerShellConsoleTerminalRunner.kt │ │ │ ├── psi │ │ │ │ ├── LSPInspectionPsiElement.kt │ │ │ │ ├── LSPInspectionPsiElementImpl.kt │ │ │ │ ├── LSPWrapperPsiElement.kt │ │ │ │ └── LSPWrapperPsiElementImpl.kt │ │ │ └── util │ │ │ │ ├── DocumentUtils.kt │ │ │ │ └── FileUtils.kt │ │ ├── parser │ │ │ ├── PowerShellElementType.kt │ │ │ └── PowerShellParserDefinition.kt │ │ └── resolve │ │ │ ├── PowerShellReference.kt │ │ │ ├── PowerShellTypeReference.kt │ │ │ └── PowerShellTypeUtil.kt │ │ └── psi │ │ ├── PowerShellAbstractStringLiteralExpression.kt │ │ ├── PowerShellAttributesHolder.kt │ │ ├── PowerShellCallableDeclaration.kt │ │ ├── PowerShellCallableReference.kt │ │ ├── PowerShellClassDeclaration.kt │ │ ├── PowerShellComponent.kt │ │ ├── PowerShellEnumDeclaration.kt │ │ ├── PowerShellMemberDeclaration.kt │ │ ├── PowerShellPsiElement.kt │ │ ├── PowerShellPsiElementFactory.kt │ │ ├── PowerShellPsiUtil.kt │ │ ├── PowerShellQualifiedReferenceElement.kt │ │ ├── PowerShellReferencePsiElement.kt │ │ ├── PowerShellTokenTypeSets.kt │ │ ├── PowerShellTypeDeclaration.kt │ │ ├── PowerShellVariable.kt │ │ ├── impl │ │ ├── PowerShellAbstractComponent.kt │ │ ├── PowerShellAbstractStringLiteralExpressionImpl.kt │ │ ├── PowerShellCallableDeclarationImpl.kt │ │ ├── PowerShellClassDeclarationImpl.kt │ │ ├── PowerShellCommandCallExpressionImpl.kt │ │ ├── PowerShellEnumDeclarationImpl.kt │ │ ├── PowerShellExpressionImpl.kt │ │ ├── PowerShellFile.kt │ │ ├── PowerShellInvocationExpressionImpl.kt │ │ ├── PowerShellMemberAccessExpressionImpl.kt │ │ ├── PowerShellMemberDeclarationImpl.kt │ │ ├── PowerShellMethodDeclarationImpl.kt │ │ ├── PowerShellPropertyImpl.kt │ │ ├── PowerShellPsiElementImpl.kt │ │ ├── PowerShellPsiImplUtil.kt │ │ ├── PowerShellQualifiedReferenceElementImpl.kt │ │ ├── PowerShellQualifiedReferenceExpression.kt │ │ ├── PowerShellReferencePsiElementImpl.kt │ │ ├── PowerShellTargetVariableImpl.kt │ │ └── mixin │ │ │ ├── PowerShellArrayTypeElementMixin.kt │ │ │ ├── PowerShellCastExpressionMixin.kt │ │ │ ├── PowerShellLabelReferenceExpressionMixin.kt │ │ │ ├── PowerShellParenthesizedExpressionMixin.kt │ │ │ └── PowerShellTypeLiteralExpressionMixin.kt │ │ └── types │ │ ├── PowerShellArrayClassType.kt │ │ ├── PowerShellClassType.kt │ │ ├── PowerShellImmediateClassType.kt │ │ ├── PowerShellReferenceClassType.kt │ │ ├── PowerShellType.kt │ │ ├── PowerShellTypeVisitor.kt │ │ ├── PowerShellTypedElement.kt │ │ └── impl │ │ ├── PowerShellArrayClassTypeImpl.kt │ │ ├── PowerShellImmediateClassTypeImpl.kt │ │ ├── PowerShellObjectType.kt │ │ ├── PowerShellReferenceClassTypeImpl.kt │ │ ├── PowerShellReferenceTypeElementImpl.kt │ │ └── PowerShellTypedElementImpl.kt └── resources │ ├── META-INF │ ├── injection.xml │ ├── plugin.xml │ ├── pluginIcon.svg │ ├── pluginIcon_dark.svg │ └── powerShellConsole.xml │ ├── PowerShell.bnf │ ├── _PowerShellLexer.flex │ ├── fileTemplates │ └── internal │ │ └── PowerShell File.ps1.ft │ ├── icons │ ├── powershell_icon.png │ └── powershell_icon@2x.png │ ├── liveTemplates │ └── PowerShellLiveTemplates.xml │ └── messages │ └── MessagesBundle.properties ├── scripts ├── Get-Distribution.ps1 ├── Publish-Distribution.ps1 ├── Unpack-Distribution.ps1 └── Update-Dependencies.ps1 └── test ├── kotlin └── com │ └── intellij │ └── plugin │ └── powershell │ ├── PowerShellDebuggerTestUtil.kt │ ├── TestEnvironment.kt │ ├── debugger │ ├── BreakpointTest.kt │ ├── EvaluationTest.kt │ ├── StepTest.kt │ └── VariableTest.kt │ ├── ide │ └── run │ │ └── PowerShellRunConfigurationTests.kt │ ├── lang │ ├── PSLanguageHostUtilsTests.kt │ ├── PowerShellCodeInsightTest.kt │ ├── PowerShellCommenterTest.kt │ ├── PowerShellCompletionTests.kt │ ├── PowerShellFormatterTest.kt │ ├── PowerShellLexerTest.kt │ └── PowerShellParserTest.kt │ └── testFramework │ ├── DebuggerTestBase.kt │ ├── EdtInterceptor.kt │ ├── PowerShellCodeInsightTestBase.kt │ ├── PowerShellTestBase.kt │ ├── PowerShellTestSession.kt │ └── PowerShellTestUtils.kt └── resources └── testData ├── codeinsight ├── completion.ps1 └── folding.ps1 ├── debugger ├── secondFileTest.ps1 ├── stepTest.ps1 ├── testBreakpoint.ps1 ├── testBreakpointTwoFiles.ps1 └── variableTest.ps1 ├── format ├── block_parameter_indent.ps1 ├── block_parameter_indent_res.ps1 ├── braces1.ps1 ├── braces1_if_wrapped_res.ps1 ├── compound_identifiers.ps1 ├── compound_identifiers_res.ps1 ├── default1.ps1 ├── default1_res.ps1 ├── indent_brace.ps1 ├── indent_brace_pipeline_wrap_res.ps1 ├── indent_brace_res.ps1 ├── indents.ps1 ├── indents_res.ps1 ├── wrap_binary_expr.ps1 ├── wrap_binary_expr_align.ps1 ├── wrap_binary_expr_always_res.ps1 ├── wrap_binary_expr_as_needed.ps1 ├── wrap_binary_expr_lp_new_line.ps1 ├── wrap_block_parameters.ps1 ├── wrap_block_parameters_default_res.ps1 ├── wrap_block_parameters_res.ps1 ├── wrap_chained_call.ps1 ├── wrap_chained_call_align_res.ps1 ├── wrap_chained_call_always_res.ps1 ├── wrap_chained_call_if_long_first_wrap_res.ps1 └── wrap_chained_call_if_long_res.ps1 └── parser ├── ArrayStatement.ps1 ├── ArrayStatement.txt ├── Attributes.ps1 ├── Attributes.txt ├── CallInvocationOperator.ps1 ├── CallInvocationOperator.txt ├── ClassDeclaration.ps1 ├── ClassDeclaration.txt ├── Closures.ps1 ├── Closures.txt ├── CommandCallExpression.ps1 ├── CommandCallExpression.txt ├── Comment.ps1 ├── Comment.txt ├── DesiredSateConfiguration.ps1 ├── DesiredSateConfiguration.txt ├── EnumDeclaration.ps1 ├── EnumDeclaration.txt ├── ExpandableString.ps1 ├── ExpandableString.txt ├── FunctionMultilineDefinition.ps1 ├── FunctionMultilineDefinition.txt ├── HashTables.ps1 ├── HashTables.txt ├── LabeledStatement.ps1 ├── LabeledStatement.txt ├── MemberElementAccess.ps1 ├── MemberElementAccess.txt ├── Modules.ps1 ├── Modules.txt ├── NullCoalesceOperator.ps1 ├── NullCoalesceOperator.txt ├── Operators.ps1 ├── Operators.txt ├── ParamBlock.ps1 ├── ParamBlock.txt ├── PathExpression.ps1 ├── PathExpression.txt ├── Statements.ps1 ├── Statements.txt ├── StdCmdlets.ps1 ├── StdCmdlets.txt ├── TypeLiteral.ps1 ├── TypeLiteral.txt ├── TypeMemberAccess.ps1 ├── TypeMemberAccess.txt ├── VerbatimCommandArgument.ps1 ├── VerbatimCommandArgument.txt ├── VerbatimString.ps1 └── VerbatimString.txt /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_size = 2 5 | indent_style = space 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # EditorConfig: normalize the indentation to 2 spaces 2 | 7781366a361c3b4bd7d4c78e8fd4d517cb02be39 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#ignore 2 | version: 2 3 | updates: 4 | - package-ecosystem: "gradle" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | ignore: 9 | - dependency-name: "org.jetbrains.kotlin.jvm" 10 | - package-ecosystem: "github-actions" 11 | directory: "/" 12 | schedule: 13 | interval: "daily" 14 | -------------------------------------------------------------------------------- /.github/workflows/dependencies.yml: -------------------------------------------------------------------------------- 1 | name: "Dependency Checker" 2 | on: 3 | schedule: 4 | - cron: '0 0 * * *' # Every day 5 | push: 6 | branches: 7 | - master 8 | pull_request: 9 | branches: 10 | - master 11 | workflow_dispatch: 12 | 13 | jobs: 14 | intellij: 15 | permissions: 16 | contents: write 17 | pull-requests: write 18 | 19 | runs-on: ubuntu-24.04 20 | timeout-minutes: 15 21 | steps: 22 | - name: "Check out the sources" 23 | uses: actions/checkout@v4 24 | 25 | - id: update 26 | uses: ForNeVeR/intellij-updater@v1 27 | name: "Update the dependency versions" 28 | 29 | - if: steps.update.outputs.has-changes == 'true' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') 30 | name: "Create a PR" 31 | uses: peter-evans/create-pull-request@v7 32 | with: 33 | branch: ${{ steps.update.outputs.branch-name }} 34 | author: "intellij-powershell automation " 35 | commit-message: ${{ steps.update.outputs.commit-message }} 36 | title: ${{ steps.update.outputs.pr-title }} 37 | body-path: ${{ steps.update.outputs.pr-body-path }} 38 | 39 | powershell-modules: 40 | permissions: 41 | contents: write 42 | pull-requests: write 43 | 44 | runs-on: ubuntu-24.04 45 | timeout-minutes: 15 46 | steps: 47 | - name: "Check out the sources" 48 | uses: actions/checkout@v4 49 | 50 | - id: update 51 | name: "Update the dependency versions" 52 | shell: pwsh 53 | run: ./src/scripts/Update-Dependencies.ps1 54 | 55 | - if: steps.update.outputs.has-changes == 'true' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') 56 | name: "Create a PR" 57 | uses: peter-evans/create-pull-request@v7 58 | with: 59 | branch: ${{ steps.update.outputs.branch-name }} 60 | author: "intellij-powershell automation " 61 | commit-message: ${{ steps.update.outputs.commit-message }} 62 | title: ${{ steps.update.outputs.pr-title }} 63 | body-path: ${{ steps.update.outputs.pr-body-path }} 64 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Main 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request: 7 | branches: 8 | - master 9 | schedule: 10 | - cron: '0 0 * * 0' # Every Sunday 11 | 12 | jobs: 13 | main: 14 | runs-on: ${{ matrix.image }} 15 | timeout-minutes: 15 16 | strategy: 17 | matrix: 18 | image: [macos-14, ubuntu-24.04, windows-2022] 19 | fail-fast: false 20 | steps: 21 | - if: runner.os == 'Linux' 22 | name: Free disk space 23 | uses: jlumbroso/free-disk-space@v1.3.1 24 | with: 25 | tool-cache: false 26 | large-packages: false 27 | 28 | - name: "Check out the sources" 29 | uses: actions/checkout@v4 30 | 31 | - name: Cache downloaded JDK 32 | uses: actions/cache@v4 33 | with: 34 | path: | 35 | ~/.local/share/gradle-jvm 36 | ~/AppData/Local/gradle-jvm 37 | key: ${{ runner.os }}-${{ hashFiles('gradlew*') }} 38 | 39 | - name: Setup Gradle 40 | uses: gradle/actions/setup-gradle@v4 41 | 42 | - name: Build 43 | run: ./gradlew build 44 | 45 | - name: 'Upload build reports' 46 | uses: actions/upload-artifact@v4 47 | with: 48 | name: ${{ runner.os }}.reports 49 | path: build/reports 50 | if: ${{ always() }} 51 | 52 | - name: 'Upload test logs' 53 | uses: actions/upload-artifact@v4 54 | with: 55 | name: ${{ runner.os }}.test-logs 56 | path: build/idea-sandbox/*/log-test 57 | if: ${{ always() }} 58 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale issues' 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: '0 0 * * *' 7 | 8 | permissions: 9 | issues: write 10 | 11 | jobs: 12 | stale: 13 | runs-on: ubuntu-24.04 14 | steps: 15 | - uses: actions/stale@v9 16 | with: 17 | days-before-stale: -1 18 | stale-issue-label: 'status:waiting-for-info' 19 | remove-stale-when-updated: 'false' 20 | days-before-close: 14 21 | close-issue-message: 'This issue was closed because it has been open for 14 days, but no requested information was received. Please leave a comment if you think this is a mistake.' 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.intellijPlatform/ 2 | /src/main/gen-parser 3 | /src/main/gen-lexer 4 | 5 | # Created by .ignore support plugin (hsz.mobi) 6 | ### JetBrains template 7 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 8 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 9 | 10 | # User-specific stuff 11 | .idea/**/workspace.xml 12 | .idea/**/tasks.xml 13 | .idea/**/usage.statistics.xml 14 | .idea/**/dictionaries 15 | .idea/**/shelf 16 | 17 | # Sensitive or high-churn files 18 | .idea/**/dataSources/ 19 | .idea/**/dataSources.ids 20 | .idea/**/dataSources.local.xml 21 | .idea/**/sqlDataSources.xml 22 | .idea/**/dynamic.xml 23 | .idea/**/uiDesigner.xml 24 | .idea/**/dbnavigator.xml 25 | 26 | # Gradle 27 | .idea/gradle.xml 28 | .idea/libraries 29 | 30 | # Gradle and Maven with auto-import 31 | # When using Gradle or Maven with auto-import, you should exclude module files, 32 | # since they will be recreated, and may cause churn. Uncomment if using 33 | # auto-import. 34 | .idea/modules.xml 35 | .idea/*.iml 36 | .idea/modules 37 | 38 | # IntelliJ 39 | out/ 40 | 41 | # Editor-based Rest Client 42 | .idea/httpRequests 43 | 44 | ### Gradle template 45 | .gradle 46 | /build/ 47 | 48 | # Ignore Gradle GUI config 49 | gradle-app.setting 50 | 51 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 52 | !gradle-wrapper.jar 53 | 54 | # Cache of project 55 | .gradletasknamecache 56 | /distibutives/ 57 | /patches/ 58 | /dumps/ 59 | /.idea/vcs.xml 60 | /.idea/compiler.xml 61 | /Default.xml 62 | /.idea/deployment.xml 63 | /.idea/caches 64 | /.idea/.name 65 | /.idea/jarRepositories.xml 66 | /.idea/kotlinc.xml 67 | /.idea/misc.xml 68 | 69 | # Kotlin compiler's temporary files 70 | /.kotlin/ 71 | -------------------------------------------------------------------------------- /.idea/dictionaries/fried.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bergmeister 5 | dernov 6 | keli 7 | maintainership 8 | nupkg 9 | pses 10 | pwsh 11 | rassokhin 12 | rels 13 | softprops 14 | zheng 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/runConfigurations/runIde.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 17 | 19 | true 20 | true 21 | false 22 | false 23 | 24 | 25 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributor Guide 2 | ================= 3 | 4 | Issue Tracker 5 | ------------- 6 | Looking to contribute? That's great! 7 | 8 | Take a look at the following labels in the issue tracker: 9 | - [good first issue][issues.good-first-issue]: gets assigned to the issues that are assumed to be appropriate for new contributors to get themselves familiar with the code; 10 | - [help wanted][issues.help-wanted]: this is a wider scope, gets assigned to any issues that require help from contributors. 11 | 12 | Keep an eye on the following issue labels: 13 | - [status:waiting-for-info][issues.waiting-for-info]: a bot automatically closes these issues if there's no activity for 2 weeks. The maintainers should remove this label after they've got the info they've requested from the users, to prevent the bot from closing the issue. 14 | 15 | Development Prerequisites 16 | ------------------------- 17 | JDK 17 is required to develop the plugin. 18 | 19 | If you use the default Gradle wrapper (`gradlew` or `gradlew.bat`), it will be auto-downloaded on wrapper start. Otherwise (say, to open the project in an IDE), you should get a JDK17-compatible installation. For example, install [Amazon Corretto 17][downloads.corretto]. 20 | 21 | Build and Test 22 | -------------- 23 | Use the following shell command: 24 | ``` 25 | $ ./gradlew build 26 | ``` 27 | 28 | Lexer and Parser 29 | ---------------- 30 | This project uses lexer generated by JFlex and parser generated by Grammar-Kit, as described in the IntelliJ documentation: 31 | - [Implementing Lexer][docs.lexer] 32 | - [Implementing Parser and PSI][docs.parser] 33 | 34 | They are automatically generated from the `.flex` and `.bnf` files on build. 35 | 36 | [docs.lexer]: https://plugins.jetbrains.com/docs/intellij/implementing-lexer.html 37 | [docs.parser]: https://plugins.jetbrains.com/docs/intellij/implementing-parser-and-psi.html 38 | [downloads.corretto]: https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/downloads-list.html 39 | [issues.good-first-issue]: https://github.com/ant-druha/intellij-powershell/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22 40 | [issues.help-wanted]: https://github.com/ant-druha/intellij-powershell/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22 41 | [issues.waiting-for-info]: https://github.com/ant-druha/intellij-powershell/issues?q=is%3Aissue+is%3Aopen+label%3Astatus%3Awaiting-for-info 42 | [plugins.grammar-kit]: https://plugins.jetbrains.com/plugin/6606-grammar-kit 43 | -------------------------------------------------------------------------------- /MAINTAINERSHIP.md: -------------------------------------------------------------------------------- 1 | intellij-powershell Maintainership 2 | ================================== 3 | 4 | Release 5 | ------- 6 | 7 | To release a new version, follow these steps. 8 | 9 | 1. Update the copyright year in the `README.md` file, if required. 10 | 2. Choose the new version. It should consist of three numbers (i.e. `1.0.0`). 11 | 3. Change the version number in the `gradle.properties` (`pluginVersion=…`). 12 | 4. Make sure there's a properly formed version entry in the `CHANGELOG.md`. 13 | 5. Merge these changes via a PR. 14 | 6. Push a tag named `v` to GitHub. 15 | 16 | The new release will be published automatically. 17 | 18 | Update Token 19 | ------------ 20 | 21 | To update the token used for publishing the plugin, follow these steps. 22 | 23 | 1. Go to [the Marketplace token update section][marketplace.tokens]. 24 | 2. Drop the old token called `github.intellij-powershell`. 25 | 3. Create a new one with the same name. 26 | 4. Go to [the GitHub repository's Secrets page][github.secrets]. 27 | 5. Update the `JETBRAINS_MARKETPLACE_TOKEN` with the new value. 28 | 29 | [github.secrets]: https://github.com/ant-druha/intellij-powershell/settings/secrets/actions 30 | [marketplace.tokens]: https://plugins.jetbrains.com/author/me/tokens 31 | -------------------------------------------------------------------------------- /doc/AppCexcerpt.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ant-druha/intellij-powershell/37d05974e80c1108338200cc6ba43a92f94ec9e9/doc/AppCexcerpt.pdf -------------------------------------------------------------------------------- /doc/PowerShell 2 0 Language Specification.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ant-druha/intellij-powershell/37d05974e80c1108338200cc6ba43a92f94ec9e9/doc/PowerShell 2 0 Language Specification.docx -------------------------------------------------------------------------------- /doc/Windows PowerShell Language Specification Version 3.0.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ant-druha/intellij-powershell/37d05974e80c1108338200cc6ba43a92f94ec9e9/doc/Windows PowerShell Language Specification Version 3.0.docx -------------------------------------------------------------------------------- /doc/remote-file-editing.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ant-druha/intellij-powershell/37d05974e80c1108338200cc6ba43a92f94ec9e9/doc/remote-file-editing.gif -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.stdlib.default.dependency=false 2 | 3 | pluginVersion=2.10.0 4 | 5 | # 30 MiB: 6 | maxUnpackedPluginBytes=31457280 7 | 8 | psScriptAnalyzerVersion=1.24.0 9 | psScriptAnalyzerSha256Hash=E86C97D44BB1BC8A1DE35E753B85EA1D938F6F9F881639A181507E079BCA4556 10 | 11 | psesVersion=4.3.0 12 | psesSha256Hash=CBE2F11F0076B05D44F148F0C7BBD38A3B30EEEAE99C45C6D0C309EDFF50136A 13 | 14 | org.gradle.caching=true 15 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | intellij = "251.23774.318-EAP-SNAPSHOT" 3 | intellijPreview = "251.23774.318-EAP-SNAPSHOT" 4 | junit5 = "5.10.3" 5 | junixsocket = "2.10.1" 6 | lsp4j = "0.24.0" 7 | 8 | [libraries] 9 | junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit5" } 10 | junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit5" } 11 | junit-vintage-engine = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit5" } 12 | junixsocket-common = { module = "com.kohlschutter.junixsocket:junixsocket-common", version.ref = "junixsocket" } 13 | junixsocket-native-common = { module = "com.kohlschutter.junixsocket:junixsocket-native-common", version.ref = "junixsocket" } 14 | lsp4j = {module = "org.eclipse.lsp4j:org.eclipse.lsp4j", version.ref = "lsp4j"} 15 | lsp4jdebug = {module = "org.eclipse.lsp4j:org.eclipse.lsp4j.debug", version.ref = "lsp4j"} 16 | openTest4J = "org.opentest4j:opentest4j:1.3.0" 17 | 18 | [bundles] 19 | junixsocket = ["junixsocket-common", "junixsocket-native-common"] 20 | 21 | [plugins] 22 | changelog = "org.jetbrains.changelog:2.2.1" 23 | gradleJvmWrapper = "me.filippov.gradle.jvm.wrapper:0.14.0" 24 | grammarkit = "org.jetbrains.grammarkit:2022.3.2.2" 25 | intellijPlatform = "org.jetbrains.intellij.platform:2.5.0" 26 | kotlin = { id = "org.jetbrains.kotlin.jvm", version = "2.0.0" } 27 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ant-druha/intellij-powershell/37d05974e80c1108338200cc6ba43a92f94ec9e9/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /intellij-updater.json: -------------------------------------------------------------------------------- 1 | { 2 | "updates": [{ 3 | "file": "gradle/libs.versions.toml", 4 | "field": "intellij", 5 | "kind": "intellij-idea-community", 6 | "versionFlavor": "release", 7 | "versionConstraint": "latestWave", 8 | "order": "oldest" 9 | }, { 10 | "file": "gradle/libs.versions.toml", 11 | "field": "intellijPreview", 12 | "kind": "intellij-idea-community", 13 | "versionFlavor": "eap" 14 | }], 15 | "prBodyPrefix": "## Maintainer Note\n> [!WARNING]\n> This PR will not trigger CI by default. Please **close it and reopen manually** to trigger the CI.\n>\n> Unfortunately, this is a consequence of the current GitHub Action security model (by default, PRs created automatically aren't allowed to trigger other automation)." 16 | } 17 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "PowerShell" 2 | -------------------------------------------------------------------------------- /src/main/java/com/intellij/plugin/powershell/ide/injection/PSPatterns.java: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.injection; 2 | 3 | import com.intellij.patterns.PlatformPatterns; 4 | import com.intellij.plugin.powershell.psi.PowerShellStringLiteralExpression; 5 | 6 | public class PSPatterns extends PlatformPatterns { 7 | public static PSElementPatterns.Capture sqlCapture() { 8 | return PSPatternUtil.INSTANCE.psCapture(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/intellij/plugin/powershell/lang/lsp/ide/settings/PowerShellExecutableChooserPanel.form: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/PowerShellFileType.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell 2 | 3 | import com.intellij.openapi.fileTypes.LanguageFileType 4 | import com.intellij.plugin.powershell.lang.PowerShellLanguage 5 | import javax.swing.Icon 6 | 7 | /** 8 | * Andrey 17/07/17. 9 | */ 10 | class PowerShellFileType : LanguageFileType(PowerShellLanguage.INSTANCE) { 11 | 12 | companion object { 13 | @JvmStatic 14 | val INSTANCE = PowerShellFileType() 15 | } 16 | 17 | override fun getIcon(): Icon { 18 | return PowerShellIcons.FILE 19 | } 20 | 21 | override fun getName(): String { 22 | return "PowerShell" 23 | } 24 | 25 | override fun getDefaultExtension(): String { 26 | return "ps1" 27 | } 28 | 29 | override fun getDescription(): String { 30 | return "PowerShell file" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/PowerShellIcons.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell 2 | 3 | import com.intellij.openapi.util.IconLoader 4 | 5 | 6 | /** 7 | * Andrey 17/07/17. 8 | */ 9 | object PowerShellIcons { 10 | val FILE = IconLoader.getIcon("/icons/powershell_icon.png", PowerShellIcons.javaClass) 11 | } 12 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/LoggerEx.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide 2 | 3 | import com.intellij.openapi.diagnostic.Logger 4 | import kotlin.coroutines.cancellation.CancellationException 5 | 6 | /** 7 | * See [IJPL-171743](https://youtrack.jetbrains.com/issue/IJPL-171743) for details: IntelliJ has a similar function, but 8 | * it's marked as internal. 9 | */ 10 | inline fun Logger.runAndLogException(action: () -> T): T? { 11 | try { 12 | return action() 13 | } catch (t: Throwable) { 14 | if (t is CancellationException) throw t 15 | error(t) 16 | return null 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/MessagesBundle.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide 2 | 3 | import com.intellij.DynamicBundle 4 | import org.jetbrains.annotations.NonNls 5 | import org.jetbrains.annotations.PropertyKey 6 | import java.util.function.Supplier 7 | 8 | 9 | @Suppress("unused") 10 | object MessagesBundle { 11 | @JvmStatic 12 | fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String { 13 | return delegate.getMessage(key, *params) 14 | } 15 | 16 | @JvmStatic 17 | fun messagePointer(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): Supplier { 18 | return delegate.getLazyMessage(key, *params) 19 | } 20 | 21 | @NonNls private const val BUNDLE = "messages.MessagesBundle" 22 | private val delegate = DynamicBundle(MessagesBundle::class.java, BUNDLE) 23 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/PluginRootServices.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide 2 | 3 | import com.intellij.openapi.Disposable 4 | import com.intellij.openapi.components.Service 5 | import com.intellij.openapi.components.service 6 | import com.intellij.openapi.project.Project 7 | import kotlinx.coroutines.CoroutineScope 8 | 9 | /** 10 | * [Project] cannot be used in [com.intellij.openapi.util.Disposer.register], 11 | * so we use this project-level service for that. 12 | */ 13 | @Service(Service.Level.PROJECT) 14 | class PluginProjectRoot(val coroutineScope: CoroutineScope) : Disposable.Default { 15 | 16 | companion object { 17 | fun getInstance(project: Project): PluginProjectRoot { 18 | return project.service() 19 | } 20 | } 21 | } 22 | 23 | @Service 24 | class PluginAppRoot(val coroutineScope: CoroutineScope) { 25 | 26 | companion object { 27 | 28 | fun getInstance(): PluginAppRoot = service() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/actions/NewPowerShellFileAction.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.actions 2 | 3 | import com.intellij.ide.actions.CreateFileFromTemplateAction 4 | import com.intellij.ide.actions.CreateFileFromTemplateDialog 5 | import com.intellij.openapi.project.DumbAware 6 | import com.intellij.openapi.project.Project 7 | import com.intellij.plugin.powershell.PowerShellIcons 8 | import com.intellij.psi.PsiDirectory 9 | 10 | class NewPowerShellFileAction : CreateFileFromTemplateAction("PowerShell script", 11 | "Creates a PowerShell script file from template", 12 | PowerShellIcons.FILE), DumbAware { 13 | override fun getActionName(directory: PsiDirectory?, newName: String, templateName: String?): String = "New PowerShell script$newName" 14 | 15 | override fun buildDialog(project: Project, directory: PsiDirectory, builder: CreateFileFromTemplateDialog.Builder) { 16 | builder.setTitle("New PowerShell file")?.addKind("PowerShell file", PowerShellIcons.FILE, "PowerShell File.ps1") 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/actions/PowerShellConsoleAction.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.actions 2 | 3 | import com.intellij.openapi.actionSystem.AnAction 4 | import com.intellij.openapi.actionSystem.AnActionEvent 5 | import com.intellij.openapi.progress.ProgressIndicator 6 | import com.intellij.openapi.progress.ProgressManager 7 | import com.intellij.openapi.progress.Task 8 | import com.intellij.plugin.powershell.PowerShellIcons 9 | import com.intellij.plugin.powershell.lang.lsp.LanguageServer 10 | 11 | class PowerShellConsoleAction : AnAction(PowerShellIcons.FILE) { 12 | 13 | override fun actionPerformed(e: AnActionEvent) { 14 | val project = e.project ?: return 15 | val server = LanguageServer.getInstance(project).serverWithConsoleProcess.value 16 | ProgressManager.getInstance().run(object : Task.Backgroundable(project, "Starting PowerShell terminal console", false) { 17 | override fun run(indicator: ProgressIndicator) { 18 | indicator.text = "Starting PowerShell terminal console..." 19 | server.start() 20 | } 21 | }) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/debugger/EditorServicesDebuggerHostStarter.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.debugger 2 | 3 | import com.intellij.execution.configurations.PtyCommandLine 4 | import com.intellij.openapi.project.Project 5 | import com.intellij.plugin.powershell.lang.lsp.languagehost.EditorServicesLanguageHostStarter 6 | import com.intellij.util.application 7 | import org.jetbrains.plugins.terminal.TerminalProjectOptionsProvider 8 | 9 | class EditorServicesDebuggerHostStarter(myProject: Project) : EditorServicesLanguageHostStarter(myProject) { 10 | override fun useConsoleRepl(): Boolean = true 11 | override fun createProcess(command: List, environment: Map?): Process { 12 | val workingDirectory = if (application.isUnitTestMode) { 13 | myProject.basePath ?: error("Project has no base path.") 14 | } else TerminalProjectOptionsProvider.getInstance(myProject).startingDirectory 15 | 16 | return PtyCommandLine(command) 17 | .withConsoleMode(false) 18 | .withWorkDirectory(workingDirectory) 19 | .withEnvironment(environment) 20 | .createProcess() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/debugger/PowerShellBreakpointType.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.debugger 2 | 3 | import com.intellij.idea.ActionsBundle 4 | import com.intellij.openapi.actionSystem.AnAction 5 | import com.intellij.openapi.actionSystem.AnActionEvent 6 | import com.intellij.openapi.fileEditor.FileDocumentManager 7 | import com.intellij.openapi.project.Project 8 | import com.intellij.openapi.vfs.VirtualFile 9 | import com.intellij.plugin.powershell.PowerShellFileType 10 | import com.intellij.plugin.powershell.ide.MessagesBundle 11 | import com.intellij.psi.PsiDocumentManager 12 | import com.intellij.ui.components.AnActionLink 13 | import com.intellij.ui.components.JBTextField 14 | import com.intellij.ui.components.Label 15 | import com.intellij.util.ui.JBUI 16 | import com.intellij.xdebugger.XDebuggerManager 17 | import com.intellij.xdebugger.breakpoints.XBreakpointProperties 18 | import com.intellij.xdebugger.breakpoints.XLineBreakpoint 19 | import com.intellij.xdebugger.breakpoints.XLineBreakpointType 20 | import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel 21 | import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider 22 | import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase 23 | import java.awt.BorderLayout 24 | import java.awt.Component 25 | import java.awt.Dimension 26 | import javax.swing.* 27 | 28 | class PowerShellBreakpointType : XLineBreakpointType>("powershell", MessagesBundle.message("powershell.debugger.breakpoints.title")) { 29 | override fun canPutAt(file: VirtualFile, line: Int, project: Project): Boolean { 30 | val document = FileDocumentManager.getInstance().getDocument(file) ?: return false 31 | 32 | val psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document) ?: return false 33 | val fileType = psiFile.fileType 34 | return fileType is PowerShellFileType 35 | } 36 | 37 | override fun createBreakpointProperties(file: VirtualFile, line: Int): XBreakpointProperties<*>? { 38 | return null 39 | } 40 | 41 | override fun getEditorsProvider( 42 | breakpoint: XLineBreakpoint>, 43 | project: Project 44 | ): XDebuggerEditorsProvider { 45 | return PowerShellDebuggerEditorsProvider(XDebuggerManager.getInstance(project).currentSession, "BPTYPE") 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/debugger/PowerShellDebuggerEditorsProvider.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.debugger 2 | 3 | import com.intellij.openapi.editor.Document 4 | import com.intellij.openapi.fileTypes.FileType 5 | import com.intellij.openapi.project.Project 6 | import com.intellij.plugin.powershell.PowerShellFileType 7 | import com.intellij.psi.PsiDocumentManager 8 | import com.intellij.psi.PsiFileFactory 9 | import com.intellij.util.LocalTimeCounter 10 | import com.intellij.xdebugger.XDebugSession 11 | import com.intellij.xdebugger.XDebuggerManager 12 | import com.intellij.xdebugger.XExpression 13 | import com.intellij.xdebugger.XSourcePosition 14 | import com.intellij.xdebugger.evaluation.EvaluationMode 15 | import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider 16 | import java.util.concurrent.atomic.AtomicInteger 17 | 18 | val documentSessionKey = com.intellij.openapi.util.Key.create("DocumentSessionKey") 19 | 20 | class PowerShellDebuggerEditorsProvider(val xDebugSession: XDebugSession? = null, val fileName: String = "pwsh") : 21 | XDebuggerEditorsProvider() { 22 | private var myFileType: PowerShellFileType = PowerShellFileType.INSTANCE 23 | 24 | companion object { 25 | private var documentId = AtomicInteger(0) 26 | } 27 | 28 | override fun getFileType(): FileType { 29 | return myFileType 30 | } 31 | 32 | override fun createDocument( 33 | project: Project, 34 | expression: XExpression, 35 | sourcePosition: XSourcePosition?, 36 | mode: EvaluationMode 37 | ): Document { 38 | val id = documentId.getAndIncrement() 39 | val psiFile = PsiFileFactory.getInstance(project) 40 | .createFileFromText( 41 | "$fileName$id." + myFileType.defaultExtension, myFileType, expression.expression, 42 | LocalTimeCounter.currentTime(), true 43 | ) 44 | val document = checkNotNull(PsiDocumentManager.getInstance(project).getDocument(psiFile)) 45 | val session = xDebugSession ?: XDebuggerManager.getInstance(project).currentSession 46 | document.putUserData(documentSessionKey, session) 47 | return document 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/debugger/PowerShellExecutionStack.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.debugger 2 | 3 | import com.intellij.plugin.powershell.ide.MessagesBundle 4 | import com.intellij.xdebugger.XDebugSession 5 | import com.intellij.xdebugger.frame.XExecutionStack 6 | import com.intellij.xdebugger.frame.XStackFrame 7 | import kotlinx.coroutines.CoroutineScope 8 | import org.eclipse.lsp4j.debug.StackTraceResponse 9 | import org.eclipse.lsp4j.debug.services.IDebugProtocolServer 10 | 11 | class PowerShellExecutionStack(val stackResponse: StackTraceResponse, 12 | val server: IDebugProtocolServer, 13 | val coroutineScope: CoroutineScope, val xDebugSession: XDebugSession 14 | ): XExecutionStack(MessagesBundle.message("powershell.debugger.PowerShellExecutionStackDisplayName")) { 15 | override fun getTopFrame(): XStackFrame? { 16 | return stackResponse.stackFrames.firstOrNull()?.let { 17 | PowerShellStackFrame( 18 | it, 19 | server, 20 | coroutineScope, 21 | xDebugSession 22 | ) 23 | } 24 | } 25 | 26 | override fun computeStackFrames(firstFrameIndex: Int, container: XStackFrameContainer?) { 27 | container?.addStackFrames(stackResponse.stackFrames.drop(firstFrameIndex).map { 28 | PowerShellStackFrame( 29 | it, 30 | server, 31 | coroutineScope, 32 | xDebugSession 33 | ) 34 | }, true) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/debugger/PowerShellSourcePosition.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.debugger 2 | 3 | import com.intellij.xdebugger.XSourcePosition 4 | import com.intellij.xdebugger.XSourcePositionWrapper 5 | 6 | class PowerShellSourcePosition(position: XSourcePosition) : XSourcePositionWrapper(position) 7 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/debugger/PowerShellSuspendContext.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.debugger 2 | 3 | import com.intellij.xdebugger.XDebugSession 4 | import com.intellij.xdebugger.frame.XExecutionStack 5 | import com.intellij.xdebugger.frame.XSuspendContext 6 | import kotlinx.coroutines.CoroutineScope 7 | import org.eclipse.lsp4j.debug.StackTraceResponse 8 | import org.eclipse.lsp4j.debug.Variable 9 | import org.eclipse.lsp4j.debug.services.IDebugProtocolServer 10 | 11 | class PowerShellSuspendContext(val stack: StackTraceResponse, val server: IDebugProtocolServer, 12 | val coroutineScope: CoroutineScope, 13 | val threadId: Int = 0, val xDebugSession: XDebugSession 14 | ): XSuspendContext(){ 15 | 16 | val variablesCache: MutableMap, Variable> = mutableMapOf() 17 | override fun getExecutionStacks(): Array { 18 | return arrayOf(PowerShellExecutionStack(stack, server, coroutineScope, xDebugSession)) 19 | } 20 | 21 | override fun getActiveExecutionStack(): XExecutionStack { 22 | return PowerShellExecutionStack(stack, server, coroutineScope, xDebugSession) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/debugger/PowerShellVariableGroup.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.debugger 2 | 3 | import com.intellij.xdebugger.XDebugSession 4 | import com.intellij.xdebugger.frame.XCompositeNode 5 | import com.intellij.xdebugger.frame.XValueChildrenList 6 | import com.intellij.xdebugger.frame.XValueGroup 7 | import kotlinx.coroutines.CoroutineScope 8 | import org.eclipse.lsp4j.debug.VariablesResponse 9 | import org.eclipse.lsp4j.debug.services.IDebugProtocolServer 10 | 11 | class PowerShellVariableGroup(val groupName: String, val variable: VariablesResponse, val parentReference: Int, 12 | val server: IDebugProtocolServer, 13 | val coroutineScope: CoroutineScope, 14 | val xDebugSession: XDebugSession 15 | ): XValueGroup(groupName){ 16 | override fun computeChildren(node: XCompositeNode) { 17 | val list = XValueChildrenList() 18 | variable.variables.forEach { 19 | list.add(it.name, PowerShellDebuggerVariableValue(it, parentReference, server, coroutineScope, xDebugSession)) 20 | } 21 | node.addChildren(list, true) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/debugger/PowershellDebuggerEvaluator.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.debugger 2 | 3 | import com.intellij.xdebugger.XSourcePosition 4 | import com.intellij.xdebugger.evaluation.XDebuggerEvaluator 5 | import kotlinx.coroutines.CoroutineScope 6 | import kotlinx.coroutines.future.await 7 | import kotlinx.coroutines.launch 8 | import org.eclipse.lsp4j.debug.EvaluateArguments 9 | import org.eclipse.lsp4j.debug.Variable 10 | import org.eclipse.lsp4j.debug.services.IDebugProtocolServer 11 | 12 | class PowershellDebuggerEvaluator(val server: IDebugProtocolServer, 13 | val stackFrame: PowerShellStackFrame, 14 | val coroutineScope: CoroutineScope): XDebuggerEvaluator() { 15 | override fun evaluate(expression: String, callback: XEvaluationCallback, expressionPosition: XSourcePosition?) { 16 | coroutineScope.launch { 17 | val result = server.evaluate(EvaluateArguments().apply { 18 | this.expression = expression 19 | frameId = stackFrame.stack.id 20 | }).await() 21 | val variable: Variable = Variable().apply { 22 | value = result.result 23 | evaluateName = expression 24 | variablesReference = result.variablesReference 25 | type = result.type 26 | presentationHint = result.presentationHint 27 | } 28 | callback.evaluated( 29 | PowerShellDebuggerVariableValue( 30 | variable, 31 | null, 32 | server, 33 | coroutineScope, 34 | stackFrame.xDebugSession 35 | ) 36 | ) 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/editor/PowerShellCommenter.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.editor 2 | 3 | import com.intellij.lang.CodeDocumentationAwareCommenter 4 | import com.intellij.plugin.powershell.psi.PowerShellTypes.COMMENT 5 | import com.intellij.plugin.powershell.psi.PowerShellTypes.DELIMITED_COMMENT 6 | import com.intellij.psi.PsiComment 7 | import com.intellij.psi.tree.IElementType 8 | 9 | class PowerShellCommenter : CodeDocumentationAwareCommenter { 10 | override fun getLineCommentTokenType(): IElementType { 11 | return COMMENT 12 | } 13 | 14 | override fun getBlockCommentTokenType(): IElementType { 15 | return DELIMITED_COMMENT 16 | } 17 | 18 | override fun getDocumentationCommentTokenType(): IElementType? { 19 | return null 20 | } 21 | 22 | override fun getDocumentationCommentPrefix(): String? { 23 | return null 24 | } 25 | 26 | override fun getDocumentationCommentLinePrefix(): String? { 27 | return null 28 | } 29 | 30 | override fun getDocumentationCommentSuffix(): String? { 31 | return null 32 | } 33 | 34 | override fun isDocumentationComment(element: PsiComment): Boolean { 35 | return false 36 | } 37 | 38 | override fun getLineCommentPrefix(): String { 39 | return "#" 40 | } 41 | 42 | override fun getBlockCommentPrefix(): String { 43 | return "<#" 44 | } 45 | 46 | override fun getBlockCommentSuffix(): String { 47 | return "#>" 48 | } 49 | 50 | override fun getCommentedBlockCommentPrefix(): String? { 51 | return null 52 | } 53 | 54 | override fun getCommentedBlockCommentSuffix(): String? { 55 | return null 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/editor/documentation/PowerShellDocumentationProvider.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.editor.documentation 2 | 3 | import com.intellij.lang.documentation.AbstractDocumentationProvider 4 | import com.intellij.plugin.powershell.lang.lsp.psi.LSPWrapperPsiElement 5 | import com.intellij.psi.PsiElement 6 | 7 | class PowerShellDocumentationProvider : AbstractDocumentationProvider() { 8 | override fun generateDoc(element: PsiElement?, originalElement: PsiElement?): String? { 9 | return if (element is LSPWrapperPsiElement) element.getDocumentation() 10 | else super.generateDoc(element, originalElement) 11 | } 12 | 13 | override fun getQuickNavigateInfo(element: PsiElement?, originalElement: PsiElement?): String? { 14 | return if (element is LSPWrapperPsiElement) element.getDocumentation() 15 | else super.getQuickNavigateInfo(element, originalElement) 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/editor/formatting/PowerShellCodeBlock.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.editor.formatting 2 | 3 | import com.intellij.formatting.ASTBlock 4 | import com.intellij.formatting.templateLanguages.BlockWithParent 5 | import com.intellij.lang.ASTNode 6 | 7 | interface PowerShellCodeBlock: ASTBlock, BlockWithParent { 8 | override fun getNode(): ASTNode? 9 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/editor/formatting/PowerShellCodeStyleConfigurable.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.editor.formatting 2 | 3 | import com.intellij.application.options.CodeStyleAbstractConfigurable 4 | import com.intellij.application.options.CodeStyleAbstractPanel 5 | import com.intellij.application.options.TabbedLanguageCodeStylePanel 6 | import com.intellij.plugin.powershell.lang.PowerShellLanguage 7 | import com.intellij.psi.codeStyle.CodeStyleSettings 8 | 9 | /** 10 | * Andrey 09/08/17. 11 | */ 12 | class PowerShellCodeStyleConfigurable(settings: CodeStyleSettings, cloneSettings: CodeStyleSettings) : CodeStyleAbstractConfigurable(settings, cloneSettings, "Power Shell") { 13 | override fun createPanel(settings: CodeStyleSettings): CodeStyleAbstractPanel { 14 | return PowerShellCodeStyleMainPanel(currentSettings, settings) 15 | } 16 | 17 | override fun getHelpTopic(): String? { 18 | return null 19 | } 20 | } 21 | 22 | class PowerShellCodeStyleMainPanel(currentSettings: CodeStyleSettings?, settings: CodeStyleSettings) : 23 | TabbedLanguageCodeStylePanel(PowerShellLanguage.INSTANCE, currentSettings, settings) 24 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/editor/formatting/PowerShellCodeStyleSettings.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.editor.formatting 2 | 3 | import com.intellij.psi.codeStyle.CodeStyleSettings 4 | import com.intellij.psi.codeStyle.CommonCodeStyleSettings 5 | import com.intellij.psi.codeStyle.CustomCodeStyleSettings 6 | 7 | class PowerShellCodeStyleSettings(settings: CodeStyleSettings) : CustomCodeStyleSettings("PowerShellCodeStyleSettings", settings) { 8 | 9 | @JvmField 10 | var CATCH_TYPE_LIST_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP 11 | @JvmField 12 | var ATTRIBUTE_ARGUMENT_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP 13 | @JvmField 14 | var PIPELINE_TAIL_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP 15 | @JvmField 16 | var BLOCK_PARAMETER_CLAUSE_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP 17 | @JvmField 18 | var ALIGN_MULTILINE_CATCH_TYPE_LIST = false 19 | @JvmField 20 | var ALIGN_MULTILINE_ATTRIBUTE_ARGUMENT = false 21 | @JvmField 22 | var ALIGN_MULTILINE_PIPELINE_STATEMENT = false 23 | @JvmField 24 | var ALIGN_MULTILINE_BLOCK_PARAMETERS = false 25 | @JvmField 26 | var KEEP_SIMPLE_HASH_LITERAL_IN_ONE_LINE = true 27 | @JvmField 28 | var BLOCK_PARAMETERS_LPAREN_ON_NEXT_LINE = false 29 | @JvmField 30 | var BLOCK_PARAMETERS_RPAREN_ON_NEXT_LINE = true 31 | @JvmField 32 | var SPACE_WITHIN_SUB_EXPRESSION_PARENTHESES = true 33 | @JvmField 34 | var SPACE_BEFORE_DATA_LBRACE = true 35 | @JvmField 36 | var SPACE_BEFORE_TRAP_LBRACE = true 37 | @JvmField 38 | var SPACE_BEFORE_COLON = false 39 | @JvmField 40 | var SPACE_AFTER_COLON = true 41 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/editor/formatting/PowerShellCodeStyleSettingsProvider.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.editor.formatting 2 | 3 | import com.intellij.lang.Language 4 | import com.intellij.plugin.powershell.lang.PowerShellLanguage 5 | import com.intellij.psi.codeStyle.CodeStyleConfigurable 6 | import com.intellij.psi.codeStyle.CodeStyleSettings 7 | import com.intellij.psi.codeStyle.CodeStyleSettingsProvider 8 | import com.intellij.psi.codeStyle.CustomCodeStyleSettings 9 | 10 | /** 11 | * Andrey 09/08/17. 12 | */ 13 | class PowerShellCodeStyleSettingsProvider : CodeStyleSettingsProvider() { 14 | 15 | override fun getLanguage(): Language = PowerShellLanguage.INSTANCE 16 | 17 | override fun createConfigurable(settings: CodeStyleSettings, modelSettings: CodeStyleSettings): CodeStyleConfigurable { 18 | return PowerShellCodeStyleConfigurable(settings, modelSettings) 19 | } 20 | 21 | override fun createCustomSettings(settings: CodeStyleSettings): CustomCodeStyleSettings { 22 | return PowerShellCodeStyleSettings(settings) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/editor/formatting/PowerShellFormattingModelBuilder.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.editor.formatting 2 | 3 | import com.intellij.formatting.Block 4 | import com.intellij.formatting.FormattingContext 5 | import com.intellij.formatting.FormattingModel 6 | import com.intellij.formatting.FormattingModelBuilder 7 | import com.intellij.lang.ASTNode 8 | import com.intellij.openapi.util.TextRange 9 | import com.intellij.psi.PsiFile 10 | import com.intellij.psi.TokenType 11 | import com.intellij.psi.formatter.FormatterUtil 12 | import com.intellij.psi.formatter.FormattingDocumentModelImpl 13 | import com.intellij.psi.formatter.PsiBasedFormattingModel 14 | import com.intellij.psi.impl.source.tree.TreeUtil 15 | 16 | /** 17 | * Andrey 08/08/17. 18 | */ 19 | class PowerShellFormattingModelBuilder : FormattingModelBuilder { 20 | override fun getRangeAffectingIndent(file: PsiFile?, offset: Int, elementAtOffset: ASTNode?): TextRange? { 21 | return elementAtOffset?.textRange 22 | } 23 | 24 | override fun createModel(formattingContext: FormattingContext): FormattingModel { 25 | val containingFile = formattingContext.containingFile 26 | val settings = formattingContext.codeStyleSettings 27 | val rootBlock = PowerShellBlockImpl(containingFile, settings) 28 | return PowerShellFormattingModel(containingFile, rootBlock, FormattingDocumentModelImpl.createOn(containingFile)) 29 | } 30 | 31 | private class PowerShellFormattingModel(file: PsiFile, rootBlock: Block, documentModel: FormattingDocumentModelImpl) 32 | : PsiBasedFormattingModel(file, rootBlock, documentModel) { 33 | 34 | 35 | override fun replaceWithPsiInLeaf(textRange: TextRange?, whiteSpace: String?, leafElement: ASTNode?): String? { 36 | if (!myCanModifyAllWhiteSpaces) { 37 | if (leafElement != null && isWhiteSpaceOrNls(leafElement)) return null 38 | } 39 | 40 | var elementTypeToUse = TokenType.WHITE_SPACE 41 | val prevNode = TreeUtil.prevLeaf(leafElement) 42 | if (prevNode != null && isWhiteSpaceOrNls(prevNode)) { 43 | elementTypeToUse = prevNode.elementType 44 | } 45 | 46 | FormatterUtil.replaceWhiteSpace(whiteSpace, leafElement, elementTypeToUse, textRange) 47 | return whiteSpace 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/editor/highlighting/PowerShellPairedBraceMatcher.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.editor.highlighting 2 | 3 | import com.intellij.codeInsight.highlighting.PairedBraceMatcherAdapter 4 | import com.intellij.lang.BracePair 5 | import com.intellij.lang.PairedBraceMatcher 6 | import com.intellij.plugin.powershell.lang.PowerShellLanguage 7 | import com.intellij.plugin.powershell.psi.PowerShellTypes.* 8 | import com.intellij.psi.PsiFile 9 | import com.intellij.psi.tree.IElementType 10 | 11 | class PowerShellPairedBraceMatcher : PairedBraceMatcherAdapter(MyPairedBraceMatcher(), PowerShellLanguage.INSTANCE) { 12 | 13 | private class MyPairedBraceMatcher : PairedBraceMatcher { 14 | private val PAIRS = arrayOf( 15 | BracePair(LCURLY, RCURLY, true), 16 | BracePair(BRACED_VAR_START, RCURLY, false), 17 | BracePair(LP, RP, false), 18 | BracePair(SQBR_L, SQBR_R, false) 19 | ) 20 | 21 | override fun getPairs(): Array { 22 | return PAIRS 23 | } 24 | 25 | override fun isPairedBracesAllowedBeforeType(lbraceType: IElementType, contextType: IElementType?): Boolean { 26 | return true 27 | } 28 | 29 | override fun getCodeConstructStart(file: PsiFile, openingBraceOffset: Int): Int { 30 | return openingBraceOffset 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/editor/highlighting/PowerShellSyntaxHighlighterFactory.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.editor.highlighting 2 | 3 | import com.intellij.openapi.fileTypes.SyntaxHighlighter 4 | import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory 5 | import com.intellij.openapi.project.Project 6 | import com.intellij.openapi.vfs.VirtualFile 7 | 8 | /** 9 | * Andrey 17/07/17. 10 | */ 11 | class PowerShellSyntaxHighlighterFactory : SyntaxHighlighterFactory() { 12 | override fun getSyntaxHighlighter(project: Project?, virtualFile: VirtualFile?): SyntaxHighlighter { 13 | return PowerShellSyntaxHighlighter() 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/injection/PSElementPatterns.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.injection 2 | 3 | import com.intellij.patterns.InitialPatternCondition 4 | import com.intellij.patterns.PsiElementPattern 5 | import com.intellij.plugin.powershell.psi.PowerShellStringLiteralExpression 6 | 7 | open class PSElementPatterns>(condition: InitialPatternCondition) : PsiElementPattern(condition) { 8 | 9 | class Capture(condition: InitialPatternCondition) : PSElementPatterns>(condition) 10 | 11 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/injection/PSPatterUtil.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.injection 2 | 3 | import com.intellij.patterns.InitialPatternCondition 4 | import com.intellij.plugin.powershell.psi.PowerShellStringLiteralExpression 5 | import com.intellij.util.ProcessingContext 6 | 7 | object PSPatternUtil { 8 | 9 | fun psCapture(): PSElementPatterns.Capture { 10 | val initPatternCond: InitialPatternCondition = object : InitialPatternCondition(PowerShellStringLiteralExpression::class.java) { 11 | override fun accepts(obj: Any?, context: ProcessingContext): Boolean { 12 | if (obj !is PowerShellStringLiteralExpression) return false 13 | return obj.text.contains(Regex("script type=\"text/javascript\"")) 14 | } 15 | } 16 | return PSElementPatterns.Capture(initPatternCond) 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/injection/PowerShellLanguageInjectionSupport.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.injection 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellStringLiteralExpression 4 | import com.intellij.psi.PsiLanguageInjectionHost 5 | import org.intellij.plugins.intelliLang.inject.AbstractLanguageInjectionSupport 6 | import org.intellij.plugins.intelliLang.inject.TemporaryPlacesRegistry 7 | import org.jetbrains.annotations.NonNls 8 | 9 | 10 | @NonNls 11 | val POWERSHELL_SUPPORT_ID = "PowerShell" 12 | 13 | class PowerShellLanguageInjectionSupport : AbstractLanguageInjectionSupport() { 14 | override fun getId(): String = POWERSHELL_SUPPORT_ID 15 | override fun useDefaultInjector(host: PsiLanguageInjectionHost?): Boolean = false 16 | 17 | override fun removeInjectionInPlace(psiElement: PsiLanguageInjectionHost?): Boolean { 18 | if (psiElement !is PowerShellStringLiteralExpression) return false 19 | val project = psiElement.project 20 | TemporaryPlacesRegistry.getInstance(project).removeHostWithUndo(project, psiElement) 21 | return true 22 | } 23 | 24 | override fun getPatternClasses() = arrayOf(PSPatterns::class.java) //arrayOf() 25 | 26 | 27 | override fun isApplicableTo(host: PsiLanguageInjectionHost?): Boolean = host is PowerShellStringLiteralExpression 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/refactoring/PowerShellElementRefactoringSupportProvider.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.refactoring 2 | 3 | import com.intellij.lang.refactoring.RefactoringSupportProvider 4 | import com.intellij.plugin.powershell.psi.PowerShellComponent 5 | import com.intellij.psi.PsiElement 6 | 7 | class PowerShellElementRefactoringSupportProvider : RefactoringSupportProvider() { 8 | 9 | override fun isSafeDeleteAvailable(element: PsiElement): Boolean = element is PowerShellComponent 10 | 11 | override fun isInplaceRenameAvailable(element: PsiElement, context: PsiElement?): Boolean = false 12 | 13 | override fun isMemberInplaceRenameAvailable(element: PsiElement, context: PsiElement?): Boolean = 14 | isAvailable(element) && !isBracedVariable(element) && !isVariableWithNamespace(element) 15 | 16 | override fun isAvailable(context: PsiElement): Boolean = context is PowerShellComponent 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/refactoring/PowerShellElementRenameInputValidator.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.refactoring 2 | 3 | import com.intellij.patterns.ElementPattern 4 | import com.intellij.patterns.PlatformPatterns.psiElement 5 | import com.intellij.patterns.StandardPatterns.or 6 | import com.intellij.plugin.powershell.psi.PowerShellFunctionStatement 7 | import com.intellij.plugin.powershell.psi.PowerShellMemberDeclaration 8 | import com.intellij.plugin.powershell.psi.PowerShellTargetVariableExpression 9 | import com.intellij.psi.PsiElement 10 | import com.intellij.refactoring.rename.RenameInputValidator 11 | import com.intellij.util.ProcessingContext 12 | 13 | class PowerShellElementRenameInputValidator : RenameInputValidator { 14 | override fun isInputValid(newName: String, element: PsiElement, context: ProcessingContext): Boolean = 15 | PowerShellNameUtils.isValidName(newName, element) 16 | 17 | override fun getPattern(): ElementPattern = 18 | or( 19 | psiElement(PowerShellTargetVariableExpression::class.java), 20 | psiElement(PowerShellFunctionStatement::class.java), 21 | psiElement(PowerShellMemberDeclaration::class.java) 22 | ) 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/refactoring/PowerShellNamesValidator.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.refactoring 2 | 3 | import com.intellij.lang.refactoring.NamesValidator 4 | import com.intellij.openapi.project.Project 5 | import com.intellij.plugin.powershell.lang.lexer.PowerShellLexerAdapter 6 | import com.intellij.plugin.powershell.psi.PowerShellTokenTypeSets 7 | import com.intellij.psi.tree.IElementType 8 | 9 | class PowerShellNamesValidator : NamesValidator { 10 | override fun isKeyword(name: String, project: Project?): Boolean = isKeyword(name) 11 | 12 | override fun isIdentifier(name: String, project: Project?): Boolean = PowerShellNameUtils.isValidName(name, project) 13 | 14 | private fun isKeyword(name: String): Boolean = PowerShellTokenTypeSets.KEYWORDS.contains(getTokenType(name)) 15 | 16 | private fun getTokenType(name: String): IElementType? { 17 | val lexer = PowerShellLexerAdapter() 18 | lexer.start(name) 19 | val tt = lexer.tokenType 20 | lexer.advance() 21 | return if (lexer.tokenType == null) tt else null 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/refactoring/PowerShellRefactoringUtils.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.refactoring 2 | 3 | import com.intellij.openapi.util.text.StringUtil 4 | import com.intellij.plugin.powershell.psi.* 5 | import com.intellij.psi.PsiElement 6 | 7 | 8 | internal fun isBracedVariable(element: PsiElement?): Boolean = isVariable(element) 9 | && element!!.firstChild?.node?.elementType === PowerShellTypes.BRACED_VAR_START 10 | 11 | internal fun isSimpleVariable(element: PsiElement?): Boolean = isVariable(element) 12 | && element!!.firstChild?.node?.elementType !== PowerShellTypes.BRACED_VAR_START 13 | 14 | private fun isVariable(element: PsiElement?) = element is PowerShellTargetVariableExpression 15 | 16 | internal fun isFunctionStatement(element: PsiElement?) = element is PowerShellFunctionStatement 17 | 18 | internal fun isMember(element: PsiElement?): Boolean { 19 | return element is PowerShellClassDeclarationStatement 20 | || element is PowerShellPropertyDeclarationStatement 21 | || element is PowerShellMethodDeclarationStatement 22 | || element is PowerShellConstructorDeclarationStatement 23 | || element is PowerShellEnumDeclarationStatement 24 | || element is PowerShellEnumLabelDeclaration 25 | } 26 | 27 | internal fun isComponent(element: PsiElement): Boolean = element is PowerShellComponent 28 | 29 | internal fun isVariableWithNamespace(element: PsiElement): Boolean = 30 | element is PowerShellVariable && StringUtil.isNotEmpty(element.getScopeName()) 31 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/refactoring/PowerShellRenamePsiElementProcessor.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.refactoring 2 | 3 | import com.intellij.find.FindManager 4 | import com.intellij.find.impl.FindManagerImpl 5 | import com.intellij.openapi.editor.Editor 6 | import com.intellij.openapi.project.Project 7 | import com.intellij.plugin.powershell.ide.refactoring.PowerShellNameUtils.nameHasSubExpression 8 | import com.intellij.plugin.powershell.psi.PowerShellComponent 9 | import com.intellij.psi.PsiElement 10 | import com.intellij.psi.PsiReference 11 | import com.intellij.psi.search.LocalSearchScope 12 | import com.intellij.psi.search.SearchScope 13 | import com.intellij.refactoring.rename.RenameDialog 14 | import com.intellij.refactoring.rename.RenamePsiElementProcessor 15 | 16 | class PowerShellRenamePsiElementProcessor : RenamePsiElementProcessor() { 17 | override fun canProcessElement(element: PsiElement): Boolean = element is PowerShellComponent 18 | override fun findReferences(element: PsiElement, searchScope: SearchScope, searchInCommentsAndStrings: Boolean): MutableCollection { 19 | if (element is PowerShellComponent && nameHasSubExpression(element)) {//TODO[#192]: it's workaround to resort to findUsage handler because default index does not contain needed tokens 20 | val findManager = FindManager.getInstance(element.getProject()) as? FindManagerImpl 21 | ?: return super.findReferences(element, searchScope, searchInCommentsAndStrings) 22 | val findUsagesManager = findManager.findUsagesManager 23 | val findUsagesHandler = findUsagesManager.getFindUsagesHandler(element, true) 24 | ?: return super.findReferences(element, searchScope, searchInCommentsAndStrings) 25 | val scope = LocalSearchScope(element.containingFile) 26 | return findUsagesHandler.findReferencesToHighlight(element, scope) 27 | } else return super.findReferences(element, searchScope, searchInCommentsAndStrings) 28 | } 29 | 30 | override fun createRenameDialog(project: Project, element: PsiElement, nameSuggestionContext: PsiElement?, editor: Editor?): RenameDialog { 31 | return object : RenameDialog(project, element, nameSuggestionContext, editor) { 32 | override fun getNewName(): String = nameSuggestionsField.enteredName 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/resolve/PSFieldScopeProcessor.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.resolve 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellEnumLabelDeclaration 4 | import com.intellij.plugin.powershell.psi.PowerShellMemberDeclaration 5 | import com.intellij.plugin.powershell.psi.PowerShellMethodDeclarationStatement 6 | import com.intellij.plugin.powershell.psi.PowerShellPropertyDeclarationStatement 7 | import com.intellij.psi.ResolveState 8 | 9 | /** 10 | * Andrey 19/12/17. 11 | */ 12 | class PSFieldScopeProcessor(private val myName: String) : PowerShellMemberScopeProcessor() { 13 | 14 | override fun doExecute(psMember: PowerShellMemberDeclaration, state: ResolveState): Boolean { 15 | if (psMember is PowerShellPropertyDeclarationStatement || psMember is PowerShellEnumLabelDeclaration 16 | || psMember is PowerShellMethodDeclarationStatement) { 17 | 18 | if (myName.equals(psMember.name, true)) { 19 | myResult.add(PowerShellResolveResult(psMember)) 20 | } 21 | } 22 | return true 23 | } 24 | 25 | 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/resolve/PSMethodScopeProcessor.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.resolve 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellConstructorDeclarationStatement 4 | import com.intellij.plugin.powershell.psi.PowerShellMemberDeclaration 5 | import com.intellij.plugin.powershell.psi.PowerShellMethodDeclarationStatement 6 | import com.intellij.psi.ResolveState 7 | 8 | /** 9 | * Andrey 19/12/17. 10 | */ 11 | class PSMethodScopeProcessor(private val myName: String) : PowerShellMemberScopeProcessor() { 12 | 13 | override fun doExecute(psMember: PowerShellMemberDeclaration, state: ResolveState): Boolean { 14 | if (psMember is PowerShellMethodDeclarationStatement) { 15 | if (myName.equals((psMember as PowerShellMemberDeclaration).name, true)) { 16 | myResult.add(PowerShellResolveResult(psMember)) 17 | return false 18 | } 19 | } 20 | if (PsNames.CONSTRUCTOR_CALL.equals(myName, true)) { 21 | val memberName = psMember.name 22 | val clazz = psMember.getContainingClass() 23 | if (memberName != null && memberName.equals(clazz?.name, true)) { 24 | assert(psMember is PowerShellConstructorDeclarationStatement) 25 | myResult.add(PowerShellResolveResult(psMember)) 26 | return false 27 | } 28 | } 29 | return true 30 | } 31 | 32 | 33 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/resolve/PowerShellClassScopeProcessor.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.resolve 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellTypeDeclaration 4 | import com.intellij.psi.PsiElement 5 | import com.intellij.psi.ResolveState 6 | import com.intellij.psi.scope.PsiScopeProcessor 7 | 8 | /** 9 | * Andrey 24/12/17. 10 | */ 11 | open class PowerShellClassScopeProcessor : PsiScopeProcessor { 12 | private val myResult: ArrayList = ArrayList() 13 | 14 | override fun execute(element: PsiElement, state: ResolveState): Boolean { 15 | if (element is PowerShellTypeDeclaration) { 16 | return doExecute(element, state) 17 | } 18 | return true 19 | } 20 | 21 | open fun doExecute(pstype: PowerShellTypeDeclaration, state: ResolveState): Boolean { 22 | myResult.add(PowerShellResolveResult(pstype)) 23 | return true 24 | } 25 | 26 | fun getResult(): List { 27 | return myResult 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/resolve/PowerShellComponentResolveProcessor.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.resolve 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellReferencePsiElement 4 | import com.intellij.psi.PsiElement 5 | import com.intellij.psi.ResolveState 6 | import com.intellij.psi.impl.source.resolve.ResolveCache 7 | import com.intellij.psi.util.PsiTreeUtil 8 | 9 | class PowerShellComponentResolveProcessor : ResolveCache.AbstractResolver> { 10 | 11 | companion object { 12 | val INSTANCE = PowerShellComponentResolveProcessor() 13 | } 14 | 15 | override fun resolve(ref: PowerShellReferencePsiElement, incompleteCode: Boolean): List { 16 | 17 | // local 18 | val resolveProcessor = PowerShellComponentScopeProcessor() 19 | PsiTreeUtil.treeWalkUp(resolveProcessor, ref.element, null, ResolveState.initial()) 20 | val results = resolveProcessor.getResult() 21 | return results.toList() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/resolve/PowerShellComponentScopeProcessor.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.resolve 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellComponent 4 | import com.intellij.plugin.powershell.psi.PowerShellTargetVariableExpression 5 | import com.intellij.psi.PsiElement 6 | import com.intellij.psi.ResolveState 7 | import com.intellij.psi.scope.PsiScopeProcessor 8 | import java.util.HashMap 9 | import kotlin.collections.ArrayList 10 | 11 | /** 12 | * Andrey 18/08/17. 13 | */ 14 | class PowerShellComponentScopeProcessor : PsiScopeProcessor { 15 | private val myResult: ArrayList = ArrayList() 16 | private val myCollectedVariables = HashMap() 17 | 18 | override fun execute(element: PsiElement, state: ResolveState): Boolean { 19 | if (element is PowerShellTargetVariableExpression) { 20 | val name = element.getQualifiedName() 21 | val oldVar = myCollectedVariables[name] 22 | if (oldVar == null || oldVar.textOffset > element.textOffset) { 23 | myCollectedVariables[name] = element 24 | } else if (element.containingFile !== oldVar.containingFile) { 25 | myCollectedVariables[name] = element//should not happen if the file is the same 26 | // if there already variable with the same name defined it should be located in the same local context 27 | throw AssertionError("Elements are defined in different files") 28 | } 29 | } else if (element is PowerShellComponent) { 30 | myResult.add(element) 31 | } 32 | return true 33 | } 34 | 35 | fun getResult(): List { 36 | myResult.addAll(myCollectedVariables.values) 37 | return myResult 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/resolve/PowerShellMemberScopeProcessor.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.resolve 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellMemberDeclaration 4 | import com.intellij.psi.PsiElement 5 | import com.intellij.psi.ResolveState 6 | import com.intellij.psi.scope.PsiScopeProcessor 7 | 8 | /** 9 | * Andrey 19/12/17. 10 | */ 11 | open class PowerShellMemberScopeProcessor : PsiScopeProcessor { 12 | protected val myResult: ArrayList = ArrayList() 13 | 14 | override fun execute(element: PsiElement, state: ResolveState): Boolean { 15 | if (element is PowerShellMemberDeclaration) { 16 | return doExecute(element, state) 17 | } 18 | return true 19 | } 20 | 21 | open fun doExecute(psMember: PowerShellMemberDeclaration, state: ResolveState): Boolean { 22 | myResult.add(PowerShellResolveResult(psMember)) 23 | return true 24 | } 25 | 26 | fun getResult(): List { 27 | return myResult 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/resolve/PowerShellResolveResult.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.resolve 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellComponent 4 | import com.intellij.psi.ResolveResult 5 | 6 | /** 7 | * Andrey 19/08/17. 8 | */ 9 | class PowerShellResolveResult(private val myElement: PowerShellComponent) : ResolveResult { 10 | 11 | override fun getElement(): PowerShellComponent { 12 | return myElement 13 | } 14 | 15 | private val myIsValid: Boolean = true 16 | 17 | override fun isValidResult(): Boolean { 18 | return myIsValid 19 | } 20 | 21 | companion object { 22 | val EMPTY_ARRAY = arrayOf() 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/resolve/PsNames.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.resolve 2 | 3 | object PsNames { 4 | 5 | const val CONSTRUCTOR_CALL = "new" 6 | const val INSTANCE_THIS = "this" 7 | const val UNNAMED = "" 8 | const val NAMESPACE_FUNCTION = "function" 9 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/run/PSExecutionUtil.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.run 2 | 3 | import com.intellij.openapi.util.SystemInfo 4 | import com.intellij.openapi.util.io.FileUtil 5 | import com.intellij.plugin.powershell.lang.lsp.languagehost.PowerShellExtensionError 6 | import com.intellij.plugin.powershell.lang.lsp.languagehost.PowerShellNotInstalled 7 | import com.intellij.util.EnvironmentUtil 8 | import com.intellij.util.text.nullize 9 | import java.nio.file.Path 10 | import kotlin.io.path.Path 11 | 12 | @Throws(PowerShellNotInstalled::class) 13 | fun findPsExecutable(): String { 14 | val osPath = EnvironmentUtil.getValue("PATH") ?: throw PowerShellNotInstalled("Can not get OS PATH") 15 | val paths = osPath.split(if (SystemInfo.isWindows) ";" else ":") 16 | val suf = if (SystemInfo.isWindows) ".exe" else "" 17 | val exec = arrayListOf("pwsh$suf", "powershell$suf") 18 | exec.forEach { e -> 19 | paths.forEach { p -> 20 | val answer = join(p, e) 21 | if (checkExists(answer)) return answer 22 | } 23 | } 24 | throw PowerShellNotInstalled("Can not find PowerShell executable in PATH") 25 | } 26 | 27 | @Throws(PowerShellExtensionError::class) 28 | fun getModuleVersion(moduleBase: String, moduleName: String): String { 29 | val moduleFile = join(moduleBase, "$moduleName/$moduleName.psd1") 30 | if (!checkExists(moduleFile)) throw PowerShellExtensionError("Module manifest file not found: $moduleFile") 31 | val lines = FileUtil.loadLines(moduleFile) 32 | for (l in lines) { 33 | if (l.contains("ModuleVersion", true)) { 34 | //TODO[#196]: can be not in one line 35 | return l.trimStart { c -> c != '=' }.substringAfter('=').trim().trim { c -> c == '\'' } 36 | } 37 | } 38 | throw PowerShellExtensionError("ModuleVersion info not found in: $moduleFile") 39 | } 40 | 41 | fun escapePath(path: String) = "&(\"$path\")" 42 | 43 | fun checkExists(path: String?): Boolean { 44 | return FileUtil.exists(path) 45 | } 46 | 47 | fun join(vararg pathPart: String): String { 48 | return FileUtil.toCanonicalPath(FileUtil.join(*pathPart)) 49 | } 50 | 51 | fun getDefaultWorkingDirectory(scriptPath: Path?): Path { 52 | val workingDir = scriptPath?.parent 53 | if (workingDir != null) return workingDir 54 | 55 | val directory = (System.getProperty("user.home") ?: System.getProperty("user.dir")) 56 | .nullize(nullizeSpaces = true) ?: "." 57 | return Path(directory) 58 | } 59 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/run/PowerShellConfigurationProducer.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.run 2 | 3 | import com.intellij.execution.actions.ConfigurationContext 4 | import com.intellij.execution.actions.LazyRunConfigurationProducer 5 | import com.intellij.execution.configurations.ConfigurationFactory 6 | import com.intellij.openapi.util.Ref 7 | import com.intellij.plugin.powershell.psi.impl.PowerShellFile 8 | import com.intellij.psi.PsiElement 9 | 10 | class PowerShellConfigurationProducer : LazyRunConfigurationProducer() { 11 | 12 | override fun setupConfigurationFromContext(configuration: PowerShellRunConfiguration, context: ConfigurationContext, sourceElement: Ref): Boolean { 13 | val elem = context.psiLocation 14 | val file = (elem?.containingFile ?: return false) as? PowerShellFile ?: return false 15 | val vFile = file.virtualFile 16 | val scriptPath = if (vFile != null) file.virtualFile.path else null 17 | if (scriptPath != null) { 18 | configuration.scriptPath = scriptPath 19 | val parts = scriptPath.split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() 20 | if (parts.isNotEmpty()) { 21 | configuration.name = parts[parts.size - 1] 22 | } 23 | } 24 | return true 25 | } 26 | 27 | 28 | override fun isConfigurationFromContext(configuration: PowerShellRunConfiguration, context: ConfigurationContext): Boolean { 29 | val file = context.psiLocation?.containingFile ?: return false 30 | val currentFile = file.virtualFile 31 | return currentFile != null && currentFile.path == configuration.scriptPath 32 | } 33 | 34 | override fun getConfigurationFactory(): ConfigurationFactory { 35 | return PowerShellConfigurationType().configurationFactories[0] 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/run/PowerShellConfigurationType.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.run 2 | 3 | import com.intellij.execution.configurations.ConfigurationFactory 4 | import com.intellij.execution.configurations.ConfigurationTypeBase 5 | import com.intellij.execution.configurations.RunConfiguration 6 | import com.intellij.execution.configurations.RunConfigurationSingletonPolicy 7 | import com.intellij.openapi.project.Project 8 | import com.intellij.plugin.powershell.PowerShellIcons 9 | 10 | class PowerShellConfigurationType : ConfigurationTypeBase("PowerShellRunType", "PowerShell", "Run Configuration for PowerShell", PowerShellIcons.FILE) { 11 | init { 12 | addFactory(object : ConfigurationFactory(this) { 13 | override fun getId() = "PowerShell" 14 | override fun getSingletonPolicy(): RunConfigurationSingletonPolicy = RunConfigurationSingletonPolicy.SINGLE_INSTANCE_ONLY 15 | override fun createTemplateConfiguration(project: Project): RunConfiguration = PowerShellRunConfiguration(project, this, "Template config") 16 | }) 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/run/PowerShellProgramRunner.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.run 2 | 3 | import com.intellij.execution.configurations.RunProfile 4 | import com.intellij.execution.configurations.RunProfileState 5 | import com.intellij.execution.configurations.RunnerSettings 6 | import com.intellij.execution.executors.DefaultRunExecutor 7 | import com.intellij.execution.runners.AsyncProgramRunner 8 | import com.intellij.execution.runners.ExecutionEnvironment 9 | import com.intellij.execution.runners.showRunContent 10 | import com.intellij.execution.ui.RunContentDescriptor 11 | import com.intellij.openapi.application.EDT 12 | import com.intellij.openapi.fileEditor.FileDocumentManager 13 | import com.intellij.openapi.rd.util.toPromise 14 | import com.intellij.plugin.powershell.ide.PluginProjectRoot 15 | import kotlinx.coroutines.Dispatchers 16 | import kotlinx.coroutines.ExperimentalCoroutinesApi 17 | import kotlinx.coroutines.async 18 | import kotlinx.coroutines.withContext 19 | import org.jetbrains.concurrency.Promise 20 | 21 | /** 22 | * The main purpose of this runner is to call [RunProfileState.execute] on a background thread instead of a foreground 23 | * one, as our [RunProfileState] implementation requires FS access that's only possible from the background. 24 | */ 25 | class PowerShellProgramRunner : AsyncProgramRunner() { 26 | 27 | override fun getRunnerId() = "com.intellij.plugin.powershell.ide.run.PowerShellProgramRunner" 28 | 29 | override fun canRun(executorId: String, profile: RunProfile) = 30 | executorId == DefaultRunExecutor.EXECUTOR_ID && profile is PowerShellRunConfiguration 31 | 32 | @OptIn(ExperimentalCoroutinesApi::class) 33 | override fun execute(environment: ExecutionEnvironment, state: RunProfileState): Promise = 34 | PluginProjectRoot.getInstance(environment.project).coroutineScope.async(Dispatchers.Default) { 35 | state as PowerShellScriptCommandLineState 36 | withContext(Dispatchers.EDT) { 37 | FileDocumentManager.getInstance().saveAllDocuments() 38 | } 39 | state.prepareExecution() 40 | val executionResult = state.execute(environment.executor, this@PowerShellProgramRunner) 41 | val descriptor = withContext(Dispatchers.EDT) { showRunContent(executionResult, environment) } 42 | descriptor 43 | }.toPromise() 44 | } 45 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/search/PowerShellTargetElementEvaluator.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.search 2 | 3 | import com.intellij.codeInsight.TargetElementEvaluatorEx 4 | import com.intellij.plugin.powershell.psi.PowerShellTokenTypeSets 5 | import com.intellij.psi.PsiElement 6 | import com.intellij.psi.PsiFile 7 | import com.intellij.psi.PsiReference 8 | 9 | class PowerShellTargetElementEvaluator : TargetElementEvaluatorEx { 10 | 11 | override fun getElementByReference(ref: PsiReference, flags: Int): PsiElement? = ref.resolve() 12 | 13 | override fun includeSelfInGotoImplementation(element: PsiElement): Boolean = true 14 | 15 | override fun isIdentifierPart(file: PsiFile, text: CharSequence, offset: Int): Boolean { 16 | val elementAt = file.findElementAt(offset) 17 | return PowerShellTokenTypeSets.IDENTIFIERS.contains(elementAt?.node?.elementType) 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/search/PowerShellUsagesProvider.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.search 2 | 3 | import com.intellij.lang.cacheBuilder.DefaultWordsScanner 4 | import com.intellij.lang.cacheBuilder.WordsScanner 5 | import com.intellij.lang.findUsages.FindUsagesProvider 6 | import com.intellij.openapi.util.text.StringUtil 7 | import com.intellij.plugin.powershell.lang.lexer.PowerShellLexerAdapter 8 | import com.intellij.plugin.powershell.psi.PowerShellComponent 9 | import com.intellij.plugin.powershell.psi.PowerShellReferencePsiElement 10 | import com.intellij.plugin.powershell.psi.PowerShellTokenTypeSets 11 | import com.intellij.psi.PsiElement 12 | import com.intellij.psi.PsiNamedElement 13 | import com.intellij.psi.PsiReference 14 | import com.intellij.psi.tree.TokenSet 15 | 16 | /** 17 | * Andrey 15/08/17. 18 | */ 19 | class PowerShellUsagesProvider : FindUsagesProvider { 20 | 21 | override fun getWordsScanner(): WordsScanner { 22 | return DefaultWordsScanner(PowerShellLexerAdapter(), 23 | PowerShellTokenTypeSets.IDENTIFIERS, 24 | PowerShellTokenTypeSets.COMMENTS, 25 | PowerShellTokenTypeSets.STRINGS, 26 | TokenSet.EMPTY, 27 | PowerShellTokenTypeSets.PROCESS_AS_WORD_TOKENS 28 | ) 29 | } 30 | 31 | override fun canFindUsagesFor(psiElement: PsiElement): Boolean { 32 | return psiElement is PowerShellReferencePsiElement || psiElement is PowerShellComponent 33 | } 34 | 35 | override fun getHelpId(psiElement: PsiElement): String? { 36 | return null 37 | } 38 | 39 | override fun getType(element: PsiElement): String { 40 | val componentType = PowerShellComponentType.typeOf(element) 41 | return componentType?.toString()?.lowercase() ?: "reference" 42 | } 43 | 44 | override fun getDescriptiveName(element: PsiElement): String { 45 | return when (element) { 46 | is PsiNamedElement -> 47 | PowerShellComponentType.typeOf(element)?.toString()?.lowercase() + " " + StringUtil.notNullize(element.name) 48 | is PsiReference -> element.canonicalText 49 | else -> element.text 50 | } 51 | } 52 | 53 | override fun getNodeText(element: PsiElement, useFullName: Boolean): String { 54 | val name = (element as? PsiNamedElement)?.name 55 | return name ?: element.text 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/structure/PowerShellStructureViewFactory.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.structure 2 | 3 | import com.intellij.ide.structureView.StructureViewBuilder 4 | import com.intellij.ide.structureView.StructureViewModel 5 | import com.intellij.ide.structureView.TreeBasedStructureViewBuilder 6 | import com.intellij.lang.PsiStructureViewFactory 7 | import com.intellij.openapi.editor.Editor 8 | import com.intellij.plugin.powershell.psi.impl.PowerShellFile 9 | import com.intellij.psi.PsiFile 10 | 11 | class PowerShellStructureViewFactory : PsiStructureViewFactory { 12 | override fun getStructureViewBuilder(psiFile: PsiFile): StructureViewBuilder? { 13 | if (psiFile !is PowerShellFile) return null 14 | 15 | return object : TreeBasedStructureViewBuilder() { 16 | override fun createStructureViewModel(editor: Editor?): StructureViewModel { 17 | return PowerShellStructureViewModel(psiFile, editor) 18 | } 19 | 20 | override fun isRootNodeShown() = true 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/ide/structure/PowerShellStructureViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.ide.structure 2 | 3 | import com.intellij.ide.structureView.StructureViewModel 4 | import com.intellij.ide.structureView.StructureViewModelBase 5 | import com.intellij.ide.structureView.StructureViewTreeElement 6 | import com.intellij.ide.util.treeView.smartTree.Sorter 7 | import com.intellij.openapi.editor.Editor 8 | import com.intellij.plugin.powershell.psi.* 9 | import com.intellij.plugin.powershell.psi.impl.PowerShellFile 10 | import com.intellij.psi.PsiElement 11 | 12 | class PowerShellStructureViewModel(file: PowerShellFile, editor: Editor?) : 13 | StructureViewModelBase(file, editor, PowerShellStructureViewElement(file)), StructureViewModel.ElementInfoProvider { 14 | 15 | init { 16 | withSuitableClasses(*PowerShellStructureViewModel.getSuitableClasses()) 17 | withSorters(Sorter.ALPHA_SORTER) 18 | } 19 | 20 | companion object { 21 | fun getSuitableClasses(): Array> { 22 | return arrayOf(PowerShellFile::class.java, 23 | PowerShellClassDeclarationStatement::class.java, 24 | PowerShellEnumDeclarationStatement::class.java, 25 | PowerShellMethodDeclarationStatement::class.java, 26 | PowerShellConstructorDeclarationStatement::class.java, 27 | PowerShellPropertyDeclarationStatement::class.java, 28 | PowerShellTargetVariableExpression::class.java, 29 | PowerShellFunctionStatement::class.java, 30 | PowerShellEnumLabelDeclaration::class.java, 31 | PowerShellConfigurationBlock::class.java 32 | ) 33 | } 34 | } 35 | 36 | override fun shouldEnterElement(element: Any?): Boolean { 37 | return element is PowerShellClassDeclarationStatement 38 | } 39 | 40 | override fun isAlwaysShowsPlus(element: StructureViewTreeElement?): Boolean { 41 | return false 42 | } 43 | 44 | override fun isAlwaysLeaf(element: StructureViewTreeElement?): Boolean { 45 | return false 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/PowerShellLanguage.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang 2 | 3 | import com.intellij.lang.Language 4 | 5 | class PowerShellLanguage : Language("PowerShell") { 6 | 7 | companion object { 8 | @JvmStatic 9 | val INSTANCE = PowerShellLanguage() 10 | 11 | /** 12 | * Language id for PowerShell LSP. 13 | */ 14 | const val LSP_ID = "powershell" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lexer/PowerShellLexerAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lexer 2 | 3 | import com.intellij.lexer.FlexAdapter 4 | import com.intellij.plugin.powershell.lang._PowerShellLexer 5 | 6 | /** 7 | * Andrey 17/07/17. 8 | */ 9 | class PowerShellLexerAdapter : FlexAdapter(_PowerShellLexer()) -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lexer/PowerShellTokenType.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lexer 2 | 3 | import com.intellij.plugin.powershell.lang.PowerShellLanguage 4 | import com.intellij.psi.tree.IElementType 5 | 6 | /** 7 | * Andrey 26/06/17. 8 | */ 9 | class PowerShellTokenType(debugName: String) : IElementType(debugName, PowerShellLanguage.INSTANCE) -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/PowerShellSettings.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * adopted from https://github.com/gtache/intellij-lsp 3 | */ 4 | package com.intellij.plugin.powershell.lang.lsp 5 | 6 | import com.intellij.openapi.components.* 7 | import com.intellij.plugin.powershell.ide.run.findPsExecutable 8 | 9 | @Service 10 | @State(name = "PowerShellSettings", storages = [Storage(value = "powerShellSettings.xml", roamingType = RoamingType.DISABLED)]) 11 | class PowerShellSettings : PersistentStateComponent { 12 | 13 | companion object { 14 | @JvmStatic 15 | fun getInstance(): PowerShellSettings = service() 16 | } 17 | 18 | data class PowerShellInfo( 19 | var editorServicesStartupScript: String = "", 20 | var powerShellExePath: String? = null, 21 | var powerShellVersion: String? = null, 22 | var powerShellExtensionPath: String? = null, 23 | var editorServicesModuleVersion: String? = null, 24 | var isUseLanguageServer: Boolean = true 25 | ) 26 | 27 | fun getPowerShellExecutable(): String { 28 | val psExecutable = myPowerShellInfo.powerShellExePath ?: findPsExecutable() 29 | myPowerShellInfo.powerShellExePath = psExecutable 30 | return psExecutable 31 | } 32 | 33 | private var myPowerShellInfo: PowerShellInfo = PowerShellInfo() 34 | 35 | override fun loadState(powerShellInfo: PowerShellInfo) { 36 | myPowerShellInfo = powerShellInfo 37 | } 38 | 39 | override fun getState(): PowerShellInfo { 40 | return myPowerShellInfo 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/ide/listeners/DocumentListenerImpl.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * adopted from https://github.com/gtache/intellij-lsp 3 | */ 4 | package com.intellij.plugin.powershell.lang.lsp.ide.listeners 5 | 6 | import com.intellij.openapi.editor.event.DocumentEvent 7 | import com.intellij.openapi.editor.event.DocumentListener 8 | import kotlinx.coroutines.CoroutineScope 9 | import kotlinx.coroutines.CoroutineStart 10 | import kotlinx.coroutines.launch 11 | 12 | class DocumentListenerImpl(private val coroutineScope: CoroutineScope) : LSPEditorListener(), DocumentListener { 13 | /** 14 | * Called before the text of the document is changed. 15 | * 16 | * @param event the event containing the information about the change. 17 | */ 18 | override fun beforeDocumentChange(event: DocumentEvent) {} 19 | 20 | /** 21 | * Called after the text of the document has been changed. 22 | * 23 | * @param event the event containing the information about the change. 24 | */ 25 | override fun documentChanged(event: DocumentEvent) { 26 | if (checkManager()) { 27 | coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) { editorManager?.documentChanged(event) } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/ide/listeners/EditorLSPListener.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * adopted from https://github.com/gtache/intellij-lsp 3 | */ 4 | package com.intellij.plugin.powershell.lang.lsp.ide.listeners 5 | 6 | import com.intellij.openapi.editor.event.EditorFactoryEvent 7 | import com.intellij.openapi.editor.event.EditorFactoryListener 8 | import com.intellij.plugin.powershell.lang.lsp.LanguageServer 9 | 10 | class EditorLSPListener : EditorFactoryListener { 11 | 12 | override fun editorReleased(event: EditorFactoryEvent) { 13 | LanguageServer.editorClosed(event.editor) 14 | } 15 | 16 | override fun editorCreated(event: EditorFactoryEvent) { 17 | LanguageServer.editorOpened(event.editor) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/ide/listeners/EditorMouseListenerImpl.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * adopted from https://github.com/gtache/intellij-lsp 3 | */ 4 | 5 | package com.intellij.plugin.powershell.lang.lsp.ide.listeners 6 | 7 | import com.intellij.openapi.editor.event.EditorMouseListener 8 | 9 | class EditorMouseListenerImpl : LSPEditorListener(), EditorMouseListener -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/ide/listeners/EditorMouseMotionListenerImpl.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * adopted from https://github.com/gtache/intellij-lsp 3 | */ 4 | 5 | package com.intellij.plugin.powershell.lang.lsp.ide.listeners 6 | 7 | import com.intellij.openapi.editor.event.EditorMouseMotionListener 8 | 9 | class EditorMouseMotionListenerImpl : LSPEditorListener(), EditorMouseMotionListener -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/ide/listeners/LSPEditorListener.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * adopted from https://github.com/gtache/intellij-lsp 3 | */ 4 | package com.intellij.plugin.powershell.lang.lsp.ide.listeners 5 | 6 | import com.intellij.openapi.diagnostic.Logger 7 | import com.intellij.plugin.powershell.lang.lsp.ide.EditorEventManager 8 | 9 | open class LSPEditorListener { 10 | protected var editorManager: EditorEventManager? = null 11 | private val LOG: Logger = Logger.getInstance(javaClass) 12 | 13 | fun setManager(manager: EditorEventManager) { 14 | this.editorManager = manager 15 | } 16 | 17 | protected fun checkManager(): Boolean { 18 | return if (editorManager == null) { 19 | LOG.error("Manager is null") 20 | false 21 | } else true 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/ide/listeners/LSPTypedHandler.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * adopted from https://github.com/gtache/intellij-lsp 3 | */ 4 | package com.intellij.plugin.powershell.lang.lsp.ide.listeners 5 | 6 | import com.intellij.codeInsight.editorActions.TypedHandlerDelegate 7 | import com.intellij.openapi.editor.Editor 8 | import com.intellij.openapi.project.Project 9 | import com.intellij.psi.PsiFile 10 | 11 | class LSPTypedHandler : TypedHandlerDelegate() { 12 | 13 | override fun charTyped(c: Char, project: Project, editor: Editor, file: PsiFile): Result { 14 | return Result.CONTINUE 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/ide/listeners/SelectionListenerImpl.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * adopted from https://github.com/gtache/intellij-lsp 3 | */ 4 | package com.intellij.plugin.powershell.lang.lsp.ide.listeners 5 | 6 | import com.intellij.openapi.editor.event.SelectionListener 7 | 8 | class SelectionListenerImpl : LSPEditorListener(), SelectionListener -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/LanguageHostConnectionManager.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lsp.languagehost 2 | 3 | import java.io.InputStream 4 | import java.io.OutputStream 5 | 6 | interface LanguageHostConnectionManager { 7 | suspend fun establishConnection(): Pair? 8 | suspend fun establishDebuggerConnection(): Pair? 9 | fun closeConnection() 10 | fun isConnected(): Boolean 11 | fun getProcess(): Process? 12 | fun createProcess(command: List, environment: Map?): Process 13 | fun connectServer(server: LanguageServerEndpoint) {} 14 | fun useConsoleRepl(): Boolean = false 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/PSESVersion.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lsp.languagehost 2 | 3 | import java.lang.NumberFormatException 4 | 5 | class PSESVersion(private val major: Int, private val minor: Int, private val bugFix: Int) : Comparable { 6 | 7 | override fun compareTo(other: PSESVersion): Int { 8 | if (major > other.major) return 1 9 | if (major < other.major) return -1 10 | 11 | if (minor > other.minor) return 1 12 | if (minor < other.minor) return -1 13 | 14 | if (bugFix > other.bugFix) return 1 15 | if (bugFix < other.bugFix) return -1 16 | 17 | return 0 18 | } 19 | 20 | fun isGreaterOrEqual(other: PSESVersion): Boolean = compareTo(other) >= 0 21 | fun isLessOrEqual(other: PSESVersion): Boolean = compareTo(other) <= 0 22 | 23 | override fun toString(): String { 24 | return "$major.$minor.$bugFix" 25 | } 26 | 27 | companion object { 28 | 29 | val v1_7_0 = PSESVersion(1, 7, 0) 30 | val v1_8_0 = PSESVersion(1, 8, 0) 31 | 32 | @Throws(NumberFormatException::class) 33 | fun create(string: String): PSESVersion? { 34 | val versions = string.split('.') 35 | val major = if (versions.isNotEmpty()) versions[0].toInt() else return null 36 | val minor = if (versions.size > 1) versions[1].toInt() else 0 37 | val bugFix = if (versions.size > 2) versions[2].toInt() else 0 38 | return PSESVersion(major, minor, bugFix) 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/PSVersionInfo.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lsp.languagehost 2 | 3 | enum class PowerShellEdition { 4 | 5 | /** 6 | * PowerShell 5.x mostly. 7 | */ 8 | Desktop, 9 | 10 | /** 11 | * PowerShell Core (6+). 12 | */ 13 | Core, 14 | 15 | Unknown; 16 | 17 | companion object { 18 | 19 | fun parse(name: String) = when(name) { 20 | "Desktop" -> Desktop 21 | "Core" -> Core 22 | else -> Unknown 23 | } 24 | } 25 | } 26 | 27 | 28 | data class PSVersionInfo(val versionString: String, val edition: PowerShellEdition?) { 29 | 30 | override fun toString(): String { 31 | if (edition == null) return versionString 32 | return "$versionString $edition" 33 | } 34 | 35 | companion object { 36 | 37 | val empty = PSVersionInfo("", null) 38 | 39 | fun parse(fullString: String): PSVersionInfo { 40 | val components = fullString.split(" ".toRegex(), 2) 41 | return when (components.size) { 42 | 0 -> empty 43 | 1 -> PSVersionInfo(components[0], null) 44 | 2 -> PSVersionInfo(components[0], PowerShellEdition.parse(components[1])) 45 | else -> error("Impossible") 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/PowerShellControlFlowException.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lsp.languagehost 2 | 3 | import com.intellij.openapi.diagnostic.ControlFlowException 4 | 5 | class PowerShellControlFlowException(message: String?, throwable: Throwable?) : Throwable(message, throwable), ControlFlowException -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/PowerShellExtensionError.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lsp.languagehost 2 | 3 | class PowerShellExtensionError(msg: String) : Exception(msg) -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/PowerShellExtensionNotFound.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lsp.languagehost 2 | 3 | class PowerShellExtensionNotFound(msg: String) : Exception(msg) -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/PowerShellNotInstalled.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lsp.languagehost 2 | 3 | class PowerShellNotInstalled(msg: String) : Exception(msg) -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/languagehost/ServerOptions.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * adopted from https://github.com/gtache/intellij-lsp 3 | */ 4 | package com.intellij.plugin.powershell.lang.lsp.languagehost 5 | 6 | import org.eclipse.lsp4j.* 7 | 8 | class ServerOptions(internal val syncKind: TextDocumentSyncKind?, internal val completionProvider: CompletionOptions?, 9 | internal val signatureHelpProvider: SignatureHelpOptions, internal val codeLensProvider: CodeLensOptions?, 10 | internal val documentOnTypeFormattingProvider: DocumentOnTypeFormattingOptions?, 11 | internal val documentLinkProvider: DocumentLinkOptions?, internal val executeCommandProvider: ExecuteCommandOptions?) -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/psi/LSPInspectionPsiElement.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lsp.psi 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellPsiElement 4 | 5 | interface LSPInspectionPsiElement: PowerShellPsiElement -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/psi/LSPInspectionPsiElementImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lsp.psi 2 | 3 | import com.intellij.lang.Language 4 | import com.intellij.navigation.ItemPresentation 5 | import com.intellij.openapi.util.TextRange 6 | import com.intellij.plugin.powershell.lang.PowerShellLanguage 7 | import com.intellij.psi.PsiElement 8 | import com.intellij.psi.PsiFile 9 | import com.intellij.psi.impl.FakePsiElement 10 | 11 | class LSPInspectionPsiElementImpl(private val myContainingFile: PsiFile, private val myRange: TextRange) : FakePsiElement(), LSPInspectionPsiElement { 12 | 13 | constructor(parent: PsiFile, range: TextRange, name: String) : this(parent, range) { 14 | myName = name 15 | } 16 | 17 | override fun getContainingFile(): PsiFile { 18 | return myContainingFile 19 | } 20 | override fun getLanguage(): Language= PowerShellLanguage.INSTANCE 21 | 22 | override fun getTextRange(): TextRange = myRange 23 | 24 | override fun isPhysical(): Boolean = true 25 | 26 | private var myName: String? = null 27 | 28 | override fun toString(): String { 29 | return "Inspection LSP element. Text: $text; File: ${myContainingFile.name}" 30 | } 31 | 32 | override fun getPresentation(): ItemPresentation { 33 | return this 34 | } 35 | 36 | override fun getName(): String? { 37 | return myName ?: super.getName() 38 | } 39 | 40 | override fun getParent(): PsiElement = myContainingFile 41 | } 42 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/psi/LSPWrapperPsiElement.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lsp.psi 2 | 3 | import com.intellij.plugin.powershell.ide.search.PowerShellComponentType 4 | import com.intellij.plugin.powershell.psi.PowerShellComponent 5 | import com.intellij.psi.PsiElement 6 | import org.eclipse.lsp4j.CompletionItem 7 | import org.eclipse.lsp4j.CompletionItemKind 8 | 9 | interface LSPWrapperPsiElement : PowerShellComponent { 10 | 11 | fun getCompletionKind(): CompletionItemKind 12 | fun getCompletionItem(): CompletionItem? 13 | fun getDocumentation(): String? 14 | override fun getName(): String? 15 | override fun getParent(): PsiElement? 16 | fun setType(type: PowerShellComponentType) 17 | fun getType(): PowerShellComponentType 18 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/lsp/util/FileUtils.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.lsp.util 2 | 3 | import com.intellij.openapi.editor.Editor 4 | import com.intellij.openapi.fileEditor.FileDocumentManager 5 | import com.intellij.openapi.fileEditor.FileEditorManager 6 | import com.intellij.openapi.fileEditor.TextEditor 7 | import com.intellij.openapi.project.Project 8 | import com.intellij.openapi.util.io.toNioPathOrNull 9 | import com.intellij.openapi.vfs.VirtualFile 10 | import com.intellij.plugin.powershell.ide.run.join 11 | 12 | fun editorToURIString(editor: Editor): String? { 13 | val file = FileDocumentManager.getInstance().getFile(editor.document)?: return null 14 | return file.path.toNioPathOrNull()?.toUri()?.toString() 15 | } 16 | 17 | fun getTextEditor(file: VirtualFile, project: Project): Editor? { 18 | return FileEditorManager.getInstance(project).getAllEditors(file).filterIsInstance().map { e -> e.editor }.firstOrNull() 19 | } 20 | 21 | fun isRemotePath(docPath: String?) = docPath != null && docPath.contains(REMOTE_FILES_DIR_PREFIX) 22 | 23 | private val REMOTE_FILES_DIR_PREFIX = join(System.getProperty("java.io.tmpdir"), "PSES-") 24 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/parser/PowerShellElementType.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.parser 2 | 3 | import com.intellij.plugin.powershell.lang.PowerShellLanguage 4 | import com.intellij.psi.tree.IElementType 5 | 6 | /** 7 | * Andrey 26/06/17. 8 | */ 9 | class PowerShellElementType(debugName: String) : IElementType(debugName, PowerShellLanguage.INSTANCE) 10 | 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/parser/PowerShellParserDefinition.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.parser 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.lang.ParserDefinition 5 | import com.intellij.lang.PsiParser 6 | import com.intellij.lexer.Lexer 7 | import com.intellij.openapi.project.Project 8 | import com.intellij.plugin.powershell.lang.PowerShellLanguage 9 | import com.intellij.plugin.powershell.lang.lexer.PowerShellLexerAdapter 10 | import com.intellij.plugin.powershell.psi.PowerShellTypes 11 | import com.intellij.plugin.powershell.psi.impl.PowerShellFile 12 | import com.intellij.psi.FileViewProvider 13 | import com.intellij.psi.PsiElement 14 | import com.intellij.psi.PsiFile 15 | import com.intellij.psi.TokenType 16 | import com.intellij.psi.tree.IFileElementType 17 | import com.intellij.psi.tree.TokenSet 18 | 19 | /** 20 | * Andrey 17/07/17. 21 | */ 22 | class PowerShellParserDefinition : ParserDefinition { 23 | 24 | private val FILE = IFileElementType(PowerShellLanguage.INSTANCE) 25 | 26 | override fun createFile(viewProvider: FileViewProvider): PsiFile { 27 | return PowerShellFile(viewProvider) 28 | } 29 | 30 | override fun spaceExistenceTypeBetweenTokens(left: ASTNode?, right: ASTNode?): ParserDefinition.SpaceRequirements { 31 | return ParserDefinition.SpaceRequirements.MAY 32 | } 33 | 34 | override fun getStringLiteralElements(): TokenSet { 35 | return TokenSet.create(PowerShellTypes.STRING_LITERAL_EXPRESSION) 36 | } 37 | 38 | override fun getFileNodeType(): IFileElementType { 39 | return FILE 40 | } 41 | 42 | override fun getWhitespaceTokens(): TokenSet { 43 | return TokenSet.create(TokenType.WHITE_SPACE) 44 | } 45 | 46 | override fun createLexer(project: Project?): Lexer { 47 | return PowerShellLexerAdapter() 48 | } 49 | 50 | override fun createElement(node: ASTNode?): PsiElement { 51 | return PowerShellTypes.Factory.createElement(node) 52 | } 53 | 54 | override fun getCommentTokens(): TokenSet { 55 | return TokenSet.create(PowerShellTypes.COMMENT) 56 | } 57 | 58 | override fun createParser(project: Project?): PsiParser { 59 | return PowerShellParser() 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/resolve/PowerShellReference.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.resolve 2 | 3 | interface PowerShellReference -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/resolve/PowerShellTypeReference.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.resolve 2 | 3 | class PowerShellTypeReference : PowerShellReference -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/lang/resolve/PowerShellTypeUtil.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang.resolve 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellExpression 4 | import com.intellij.plugin.powershell.psi.PowerShellReferenceTypeElement 5 | import com.intellij.plugin.powershell.psi.PowerShellTargetVariableExpression 6 | import com.intellij.plugin.powershell.psi.PowerShellTypeLiteralExpression 7 | import com.intellij.plugin.powershell.psi.types.PowerShellType 8 | 9 | object PowerShellTypeUtil { 10 | 11 | // fun createType(expression: PowerShellExpression): PowerShellType { 12 | // if (expression is PowerShellTypeLiteralExpression) { 13 | // val typeElement = expression.typeElement 14 | // if (typeElement is PowerShellReferenceTypeElement) { 15 | // return PowerShellReferenceClassTypeImpl(typeElement) 16 | // 17 | // } 18 | // } 19 | // return PowerShellType.UNNAMED 20 | // } 21 | 22 | fun inferExpressionType(e: PowerShellExpression): PowerShellType { 23 | when (e) { 24 | is PowerShellTypeLiteralExpression -> { 25 | // return e.typeElement.getType() //SOE could happen if not reference 26 | val typE = e.typeElement //SOE could happen if not reference 27 | if (typE is PowerShellReferenceTypeElement) return typE.getType() 28 | } 29 | is PowerShellTargetVariableExpression -> { 30 | val resolved = e.resolve() 31 | if (resolved is PowerShellTargetVariableExpression) { 32 | return resolved.getType() // 33 | } 34 | } 35 | } 36 | return PowerShellType.UNKNOWN 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellAbstractStringLiteralExpression.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | import com.intellij.openapi.util.TextRange 4 | import com.intellij.psi.PsiLanguageInjectionHost 5 | 6 | interface PowerShellAbstractStringLiteralExpression : PowerShellExpression, PsiLanguageInjectionHost { 7 | fun hasSubstitutions(): Boolean 8 | fun isHereString(): Boolean 9 | fun isExpandable(): Boolean 10 | fun getQuoteEscapeChar(): Char 11 | fun getQuoteChar(): Char 12 | fun getContentRange(): TextRange 13 | fun getStringContent(): String 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellAttributesHolder.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | interface PowerShellAttributesHolder { 4 | fun getAttributeList(): List 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellCallableDeclaration.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | import com.intellij.plugin.powershell.psi.types.PowerShellType 4 | 5 | interface PowerShellCallableDeclaration : PowerShellComponent { 6 | fun getReturnType(): PowerShellType? 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellCallableReference.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | /** 4 | * Andrey 24/08/17. 5 | */ 6 | interface PowerShellCallableReference : PowerShellReferencePsiElement -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellClassDeclaration.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | interface PowerShellClassDeclaration : PowerShellTypeDeclaration -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellComponent.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | import com.intellij.psi.PsiNameIdentifierOwner 4 | import com.intellij.psi.PsiNamedElement 5 | 6 | /** 7 | * Andrey 15/08/17. 8 | */ 9 | interface PowerShellComponent : PowerShellPsiElement, PsiNamedElement, PsiNameIdentifierOwner { 10 | override fun getName(): String? 11 | override fun getNameIdentifier(): PowerShellIdentifier? 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellEnumDeclaration.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | interface PowerShellEnumDeclaration : PowerShellTypeDeclaration -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellMemberDeclaration.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | interface PowerShellMemberDeclaration : PowerShellComponent { 4 | fun getContainingClass(): PowerShellTypeDeclaration? 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellPsiElement.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | import com.intellij.navigation.ItemPresentation 4 | import com.intellij.psi.NavigatablePsiElement 5 | 6 | /** 7 | * Andrey 26/06/17. 8 | */ 9 | interface PowerShellPsiElement : NavigatablePsiElement { 10 | override fun getPresentation(): ItemPresentation 11 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellPsiElementFactory.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | import com.intellij.openapi.project.Project 4 | import com.intellij.plugin.powershell.PowerShellFileType 5 | import com.intellij.plugin.powershell.psi.impl.PowerShellFile 6 | import com.intellij.plugin.powershell.psi.impl.rhsElement 7 | import com.intellij.psi.PsiFileFactory 8 | import com.intellij.psi.util.PsiTreeUtil 9 | 10 | /** 11 | * Andrey 16/08/17. 12 | */ 13 | object PowerShellPsiElementFactory { 14 | fun createIdentifierFromText(project: Project, text: String, functionId: Boolean = false): PowerShellIdentifier? { 15 | val fileText = if (functionId) { 16 | "function $text {}" 17 | } else { 18 | "class $text {}" 19 | } 20 | val file = createFile(project, fileText) 21 | val component = PsiTreeUtil.findChildOfAnyType(file, PowerShellComponent::class.java) 22 | return component?.nameIdentifier 23 | } 24 | 25 | fun createCommandName(project: Project, text: String): PowerShellCommandName? { 26 | val file = createFile(project, text) 27 | val component = PsiTreeUtil.findChildOfAnyType(file, PowerShellCommandCallExpression::class.java) 28 | return component?.commandName 29 | } 30 | 31 | fun createVariableFromText(project: Project, text: String, bracedVariable: Boolean = false): PowerShellVariable? { 32 | val varText = if (bracedVariable) "\${$text}" else "$$text" 33 | val file = createFile(project, varText) 34 | return PsiTreeUtil.findChildOfAnyType(file, PowerShellTargetVariableExpression::class.java) 35 | } 36 | 37 | private fun createFile(project: Project, text: String): PowerShellFile { 38 | val name = "dummy_file" + PowerShellFileType.INSTANCE.defaultExtension 39 | val stamp = System.currentTimeMillis() 40 | val factory = PsiFileFactory.getInstance(project) 41 | return factory.createFileFromText(name, PowerShellFileType.INSTANCE, text, stamp, false) as PowerShellFile 42 | } 43 | 44 | fun createExpression(project: Project, text: String): PowerShellExpression { 45 | val file = createFile(project, "\$foo = $text") 46 | val assignment = PsiTreeUtil.findChildOfType(file, PowerShellAssignmentExpression::class.java) ?: error("text='$text'") 47 | return assignment.rhsElement as? PowerShellExpression ?: error("text='$text'") 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellPsiUtil.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellTypes.* 5 | import com.intellij.psi.TokenType 6 | import com.intellij.psi.tree.IElementType 7 | 8 | 9 | fun isLabelContext(node: ASTNode): Boolean = node.treeParent?.elementType === LABEL 10 | 11 | internal fun findSiblingSkipping(node: ASTNode, toSkip: Array, forward: Boolean = true): ASTNode? { 12 | var result = if (forward) node.treeNext else node.treePrev 13 | if (toSkip.isEmpty()) return result 14 | while (result != null && toSkip.contains(result.elementType)) result = if (forward) result.treeNext else result.treePrev 15 | return result 16 | } 17 | 18 | internal fun findSiblingSkippingWS(node: ASTNode, forward: Boolean = true): ASTNode? { 19 | return findSiblingSkipping(node, arrayOf(NLS, TokenType.WHITE_SPACE), forward) 20 | } 21 | 22 | fun isTargetVariableContext(node: ASTNode): Boolean { 23 | return node.treeParent.elementType == TARGET_VARIABLE_EXPRESSION 24 | } 25 | 26 | fun isFunctionDeclarationContext(node: ASTNode): Boolean { 27 | return node.treeParent.elementType == FUNCTION_STATEMENT 28 | } 29 | 30 | fun isPathExpressionContext(node: ASTNode): Boolean { 31 | return node.treeParent.elementType == PATH_EXPRESSION 32 | } 33 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellQualifiedReferenceElement.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | import com.intellij.psi.PsiQualifiedReference 4 | 5 | /** 6 | * Andrey 18/08/17. 7 | */ 8 | interface PowerShellQualifiedReferenceElement : PowerShellReferencePsiElement, PsiQualifiedReference { 9 | override fun getQualifier(): Q? 10 | override fun getReferenceName(): String? 11 | fun isTypeMemberAccess(): Boolean 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellReferencePsiElement.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | import com.intellij.psi.PsiElement 4 | import com.intellij.psi.PsiReference 5 | 6 | /** 7 | * Andrey 18/08/17. 8 | */ 9 | interface PowerShellReferencePsiElement : PowerShellPsiElement, PsiReference { 10 | override fun resolve(): PowerShellComponent? 11 | fun getNameElement(): PsiElement? 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellTokenTypeSets.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellTypes.* 4 | import com.intellij.psi.tree.TokenSet 5 | 6 | /** 7 | * Andrey 17/07/17. 8 | */ 9 | object PowerShellTokenTypeSets { 10 | 11 | val KEYWORDS = TokenSet.create(BEGIN, BREAK, CATCH, CLASS, CONTINUE, DATA, DEFINE, DO, DYNAMICPARAM, ELSE, ELSEIF, END, EXIT, FILTER, FINALLY, FOR, 12 | FOREACH, FROM, FUNCTION, IF, IN, INLINESCRIPT, PARALLEL, PARAM, PROCESS, RETURN, SWITCH, THROW, TRAP, TRY, UNTIL, USING, VAR, WHILE, WORKFLOW, 13 | CONFIGURATION, THIS, HIDDEN, STATIC, ENUM) 14 | val COMMENTS = TokenSet.create(COMMENT, REQUIRES_COMMENT_START) 15 | val STRINGS = TokenSet.create(EXPANDABLE_STRING_PART, DQ_OPEN, DQ_CLOSE, VERBATIM_STRING, EXPANDABLE_HERE_STRING_START, EXPANDABLE_HERE_STRING_END, EXPANDABLE_HERE_STRING_PART, VERBATIM_HERE_STRING) 16 | val NUMBERS = TokenSet.create(DEC_INTEGER, HEX_INTEGER, REAL_NUM) 17 | val IDENTIFIERS = TokenSet.create(SIMPLE_ID, BRACED_ID, VAR_ID, GENERIC_ID_PART, DS, QMARK, HAT) 18 | private val IDENTIFIERS_ALLOWED_AS_KEYWORD = TokenSet.create(PARAM, UNTIL, WORKFLOW, END, DEFINE, FINALLY, PARALLEL, CONTINUE, BEGIN, DYNAMICPARAM, IN, 19 | PROCESS, BREAK, ELSE, INLINESCRIPT, CATCH, THIS, HIDDEN, FOREACH, STATIC) 20 | val MEMBER_IDENTIFIERS = TokenSet.orSet(TokenSet.create(SIMPLE_ID), IDENTIFIERS_ALLOWED_AS_KEYWORD) 21 | val BRACED_VARIABLE_IDENTIFIERS = TokenSet.create(BRACED_ID) 22 | val SIMPLE_VARIABLE_IDENTIFIERS = TokenSet.create(SIMPLE_ID, VAR_ID, THIS, QMARK, HAT, DS) 23 | val FUNCTION_IDENTIFIERS = TokenSet.orSet(TokenSet.create(SIMPLE_ID, GENERIC_ID_PART, THIS, QMARK, HAT, DS, DOT), IDENTIFIERS_ALLOWED_AS_KEYWORD) 24 | val OPERATORS = TokenSet.create(OP_C, OP_AND, OP_OR, OP_XOR, OP_BAND, OP_BOR, OP_BXOR, PLUS, DASH, STAR, DIV, PERS) 25 | val PROCESS_AS_WORD_TOKENS = TokenSet.create(QMARK, DS, HAT, LP, RP, DOT) 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellTypeDeclaration.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | interface PowerShellTypeDeclaration : PowerShellComponent { 4 | fun getMembers(): List 5 | fun getBaseClass(): PowerShellReferenceTypeElement? 6 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/PowerShellVariable.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi 2 | 3 | import com.intellij.plugin.powershell.psi.types.PowerShellTypedElement 4 | import com.intellij.psi.PsiElement 5 | 6 | /** 7 | * Andrey 18/08/17. 8 | */ 9 | interface PowerShellVariable : PowerShellComponent, PowerShellReferencePsiElement, PowerShellTypedElement { 10 | override fun getReference(): PowerShellReferencePsiElement? 11 | fun getScopeName(): String? 12 | fun getScope(): PsiElement? 13 | fun getPrefix(): String 14 | fun getSuffix(): String? 15 | fun isBracedVariable(): Boolean 16 | /** 17 | * returns full name of the element, including namespace 18 | */ 19 | fun getQualifiedName(): String 20 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellAbstractComponent.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.navigation.ItemPresentation 5 | import com.intellij.plugin.powershell.ide.search.PowerShellComponentType 6 | import com.intellij.plugin.powershell.psi.PowerShellComponent 7 | import com.intellij.plugin.powershell.psi.PowerShellFunctionStatement 8 | import com.intellij.plugin.powershell.psi.PowerShellIdentifier 9 | import com.intellij.plugin.powershell.psi.PowerShellPsiElementFactory 10 | import com.intellij.psi.PsiElement 11 | import javax.swing.Icon 12 | 13 | 14 | /** 15 | * Andrey 15/08/17. 16 | */ 17 | abstract class PowerShellAbstractComponent(node: ASTNode) : PowerShellPsiElementImpl(node), PowerShellComponent { 18 | 19 | override fun getPresentation(): ItemPresentation { 20 | return object : ItemPresentation { 21 | override fun getLocationString(): String? = null 22 | override fun getIcon(unused: Boolean): Icon? = getIcon(0) 23 | override fun getPresentableText(): String? = name 24 | } 25 | } 26 | 27 | override fun getName(): String? = nameIdentifier?.text 28 | 29 | override fun getTextOffset(): Int = nameIdentifier?.textOffset ?: super.getTextOffset() 30 | 31 | override fun getNameIdentifier(): PowerShellIdentifier? = findChildByClass(PowerShellIdentifier::class.java) 32 | 33 | override fun setName(name: String): PsiElement { 34 | val identifier = nameIdentifier 35 | val identifierNew = PowerShellPsiElementFactory.createIdentifierFromText(project, name, this is PowerShellFunctionStatement) 36 | if (identifierNew != null && identifier != null) { 37 | node.replaceChild(identifier.node, identifierNew.node) 38 | } 39 | return this 40 | } 41 | 42 | override fun getIcon(flags: Int): Icon? = PowerShellComponentType.typeOf(this)?.getIcon() 43 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellCallableDeclarationImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellCallableDeclaration 5 | import com.intellij.plugin.powershell.psi.types.PowerShellType 6 | import com.intellij.plugin.powershell.psi.types.impl.PowerShellObjectType 7 | 8 | open class PowerShellCallableDeclarationImpl(node: ASTNode) : PowerShellAbstractComponent(node), PowerShellCallableDeclaration { 9 | override fun getReturnType(): PowerShellType? { 10 | return PowerShellObjectType()//stub 11 | } 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellClassDeclarationImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellBlockBody 5 | import com.intellij.plugin.powershell.psi.PowerShellClassDeclaration 6 | import com.intellij.plugin.powershell.psi.PowerShellMemberDeclaration 7 | import com.intellij.plugin.powershell.psi.PowerShellReferenceTypeElement 8 | import com.intellij.psi.util.PsiTreeUtil 9 | 10 | open class PowerShellClassDeclarationImpl(node: ASTNode) : PowerShellAbstractComponent(node), PowerShellClassDeclaration { 11 | override fun getBaseClass(): PowerShellReferenceTypeElement? { 12 | return findChildByClass(PowerShellReferenceTypeElement::class.java) 13 | } 14 | 15 | override fun getMembers(): List { 16 | val result = mutableListOf() 17 | val classBody = findChildByClass(PowerShellBlockBody::class.java) 18 | result.addAll(PsiTreeUtil.findChildrenOfType(classBody, PowerShellMemberDeclaration::class.java)) 19 | return result 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellCommandCallExpressionImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.openapi.util.TextRange 5 | import com.intellij.plugin.powershell.lang.resolve.PowerShellTypeUtil 6 | import com.intellij.plugin.powershell.psi.PowerShellCallableReference 7 | import com.intellij.plugin.powershell.psi.PowerShellCommandName 8 | import com.intellij.plugin.powershell.psi.PowerShellExpression 9 | import com.intellij.plugin.powershell.psi.types.PowerShellType 10 | import com.intellij.psi.PsiElement 11 | 12 | /** 13 | * Andrey 24/08/17. 14 | */ 15 | open class PowerShellCommandCallExpressionImpl(node: ASTNode) : PowerShellReferencePsiElementImpl(node), PowerShellCallableReference, PowerShellExpression { 16 | override fun getType(): PowerShellType { 17 | return PowerShellTypeUtil.inferExpressionType(this) 18 | } 19 | 20 | override fun getRangeInElement(): TextRange { 21 | val refRange = getNameElement()?.textRange ?: this.textRange 22 | return TextRange(refRange.startOffset - textRange.startOffset, refRange.endOffset - textRange.startOffset) 23 | } 24 | 25 | override fun getNameElement(): PsiElement? = findChildByClass(PowerShellCommandName::class.java)?.identifier 26 | 27 | override fun getCanonicalText(): String = getNameElement()?.text ?: super.getCanonicalText() 28 | } 29 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellEnumDeclarationImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellBlockBody 5 | import com.intellij.plugin.powershell.psi.PowerShellEnumDeclaration 6 | import com.intellij.plugin.powershell.psi.PowerShellMemberDeclaration 7 | import com.intellij.plugin.powershell.psi.PowerShellReferenceTypeElement 8 | import com.intellij.psi.util.PsiTreeUtil 9 | 10 | open class PowerShellEnumDeclarationImpl(node: ASTNode) : PowerShellAbstractComponent(node), PowerShellEnumDeclaration { 11 | override fun getBaseClass(): PowerShellReferenceTypeElement? { 12 | return findChildByClass(PowerShellReferenceTypeElement::class.java) 13 | } 14 | 15 | override fun getMembers(): List { 16 | val result = mutableListOf() 17 | val classBody = findChildByClass(PowerShellBlockBody::class.java) 18 | result.addAll(PsiTreeUtil.findChildrenOfType(classBody, PowerShellMemberDeclaration::class.java)) 19 | return result 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellExpressionImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.lang.resolve.PowerShellTypeUtil 5 | import com.intellij.plugin.powershell.psi.PowerShellExpression 6 | import com.intellij.plugin.powershell.psi.types.PowerShellType 7 | import com.intellij.plugin.powershell.psi.types.PowerShellTypedElement 8 | 9 | open class PowerShellExpressionImpl(node: ASTNode) : PowerShellPsiElementImpl(node), PowerShellExpression, PowerShellTypedElement { 10 | override fun getType(): PowerShellType { 11 | 12 | return PowerShellTypeUtil.inferExpressionType(this) 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellFile.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.extapi.psi.PsiFileBase 4 | import com.intellij.navigation.ItemPresentation 5 | import com.intellij.openapi.fileTypes.FileType 6 | import com.intellij.plugin.powershell.PowerShellIcons 7 | import com.intellij.plugin.powershell.ide.resolve.PowerShellResolveUtil 8 | import com.intellij.plugin.powershell.lang.PowerShellLanguage 9 | import com.intellij.plugin.powershell.psi.PowerShellComponent 10 | import com.intellij.plugin.powershell.psi.PowerShellPsiElement 11 | import com.intellij.psi.FileViewProvider 12 | import com.intellij.psi.PsiElement 13 | import com.intellij.psi.ResolveState 14 | import com.intellij.psi.scope.PsiScopeProcessor 15 | import javax.swing.Icon 16 | 17 | /** 18 | * Andrey 17/07/17. 19 | */ 20 | class PowerShellFile(viewProvider: FileViewProvider) : PsiFileBase(viewProvider, PowerShellLanguage.INSTANCE), PowerShellPsiElement { 21 | override fun getFileType(): FileType { 22 | return viewProvider.fileType 23 | } 24 | 25 | override fun getPresentation(): ItemPresentation { 26 | return object : ItemPresentation { 27 | override fun getLocationString(): String { 28 | return viewProvider.virtualFile.path 29 | } 30 | 31 | override fun getIcon(unused: Boolean): Icon { 32 | return PowerShellIcons.FILE 33 | } 34 | 35 | override fun getPresentableText(): String { 36 | return name 37 | } 38 | } 39 | } 40 | 41 | override fun processDeclarations(processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement): Boolean { 42 | return processDeclarationsImpl(processor, state, lastParent, place) 43 | } 44 | 45 | private fun processDeclarationsImpl(processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement): Boolean { 46 | val result = HashSet() 47 | PowerShellResolveUtil.collectChildrenDeclarations(this, result, processor, state, lastParent) 48 | return result.none { place.textOffset > it.textOffset && processor.execute(it, state).not() } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellInvocationExpressionImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.ide.resolve.PSMethodScopeProcessor 5 | import com.intellij.plugin.powershell.ide.resolve.PowerShellResolveResult 6 | import com.intellij.plugin.powershell.ide.resolve.PowerShellResolveUtil 7 | import com.intellij.plugin.powershell.ide.resolve.PsNames 8 | import com.intellij.plugin.powershell.psi.PowerShellExpression 9 | import com.intellij.plugin.powershell.psi.PowerShellQualifiedReferenceElement 10 | import com.intellij.plugin.powershell.psi.PowerShellTypeDeclaration 11 | import com.intellij.plugin.powershell.psi.types.PowerShellClassType 12 | import com.intellij.plugin.powershell.psi.types.PowerShellType 13 | import com.intellij.plugin.powershell.psi.types.PowerShellTypedElement 14 | 15 | open class PowerShellInvocationExpressionImpl(node: ASTNode) : PowerShellQualifiedReferenceExpression(node), PowerShellQualifiedReferenceElement, PowerShellTypedElement { 16 | 17 | override fun getType(): PowerShellType { 18 | if (isConstructorCall()) { 19 | //this means that this is a call 'new' -> can infer from qualifier 20 | val qType = getQualifierType() 21 | if (qType != null) return qType 22 | } 23 | return super.getType() 24 | } 25 | 26 | override fun multiResolve(incompleteCode: Boolean): Array { 27 | if (isConstructorCall()) { 28 | //TODO[#195] where is the best place to implement resolve to a default constructor? 29 | val qType = getQualifierType() 30 | if (qType is PowerShellClassType) { 31 | val qClass = qType.resolve() 32 | if (qClass is PowerShellTypeDeclaration && PowerShellResolveUtil.hasDefaultConstructor(qClass)) { 33 | val res = PowerShellResolveResult(qClass) 34 | return Array(1) { res } 35 | } 36 | } else if (qType != null && qType != PowerShellType.UNKNOWN) { 37 | val refName = referenceName 38 | if (refName != null) { 39 | val resolveProcessor = PSMethodScopeProcessor(refName) 40 | if (PowerShellResolveUtil.processMembersForType(qType, resolveProcessor)) return extractResults(resolveProcessor) 41 | } 42 | } 43 | } 44 | return super.multiResolve(incompleteCode) 45 | } 46 | 47 | private fun isConstructorCall() = PsNames.CONSTRUCTOR_CALL.equals(referenceName, true) 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellMemberAccessExpressionImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellEnumLabelDeclaration 5 | import com.intellij.plugin.powershell.psi.PowerShellExpression 6 | import com.intellij.plugin.powershell.psi.PowerShellQualifiedReferenceElement 7 | import com.intellij.plugin.powershell.psi.types.PowerShellType 8 | import com.intellij.plugin.powershell.psi.types.PowerShellTypedElement 9 | 10 | open class PowerShellMemberAccessExpressionImpl(node: ASTNode) : PowerShellQualifiedReferenceExpression(node), PowerShellQualifiedReferenceElement, PowerShellTypedElement { 11 | override fun getType(): PowerShellType { 12 | val resolved = resolve() 13 | if (resolved is PowerShellEnumLabelDeclaration) { 14 | //for enum label references the type is the same as qualifier 15 | val qType = qualifier?.getType() 16 | if (qType != null) return qType 17 | } else if (resolved != null) { 18 | return inferTypeFromResolved(resolved) 19 | } 20 | return PowerShellType.UNKNOWN 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellMemberDeclarationImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellBlockBody 5 | import com.intellij.plugin.powershell.psi.PowerShellMemberDeclaration 6 | import com.intellij.plugin.powershell.psi.PowerShellTypeDeclaration 7 | 8 | abstract class PowerShellMemberDeclarationImpl(node: ASTNode) : PowerShellAbstractComponent(node), PowerShellMemberDeclaration { 9 | override fun getContainingClass(): PowerShellTypeDeclaration? = (context as? PowerShellBlockBody)?.context as? PowerShellTypeDeclaration 10 | 11 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellMethodDeclarationImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellBlockBody 5 | import com.intellij.plugin.powershell.psi.PowerShellCallableDeclaration 6 | import com.intellij.plugin.powershell.psi.PowerShellMemberDeclaration 7 | import com.intellij.plugin.powershell.psi.PowerShellTypeDeclaration 8 | import com.intellij.plugin.powershell.psi.types.PowerShellType 9 | import com.intellij.plugin.powershell.psi.types.impl.PowerShellObjectType 10 | 11 | open class PowerShellMethodDeclarationImpl(node: ASTNode) : PowerShellCallableDeclarationImpl(node), PowerShellCallableDeclaration, PowerShellMemberDeclaration { 12 | override fun getContainingClass(): PowerShellTypeDeclaration? { 13 | return (context as? PowerShellBlockBody)?.context as? PowerShellTypeDeclaration 14 | } 15 | 16 | override fun getReturnType(): PowerShellType? { 17 | return PowerShellObjectType()//stub 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellPropertyImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.openapi.util.TextRange 5 | import com.intellij.openapi.util.UnfairTextRange 6 | import com.intellij.plugin.powershell.ide.search.PowerShellComponentType 7 | import com.intellij.plugin.powershell.psi.* 8 | import com.intellij.plugin.powershell.psi.types.PowerShellType 9 | import javax.swing.Icon 10 | 11 | abstract class PowerShellPropertyImpl(node: ASTNode) : PowerShellTargetVariableImpl(node), PowerShellMemberDeclaration, PowerShellAttributesHolder { 12 | 13 | override fun getType(): PowerShellType { 14 | getAttributeList().mapNotNull { it.typeLiteralExpression }.forEach { return it.typeElement.getType() } 15 | return super.getType() 16 | } 17 | 18 | override fun getContainingClass(): PowerShellTypeDeclaration? = (context as? PowerShellBlockBody)?.context as? PowerShellTypeDeclaration 19 | 20 | override fun getRangeInElement(): TextRange { 21 | val myVar = getVariable() 22 | if (myVar != null) return myVar.rangeInElement 23 | val namId = nameIdentifier 24 | if (namId != null) { 25 | val range = namId.node.textRange 26 | return range.shiftRight(-node.startOffset) 27 | } 28 | return UnfairTextRange(0, this.textRange.endOffset - this.textRange.startOffset) 29 | } 30 | 31 | override fun getNameIdentifier(): PowerShellIdentifier? { 32 | val variable = getVariable() 33 | return variable?.nameIdentifier 34 | } 35 | 36 | private fun findFirstAssignmentTarget(): PowerShellVariable? { 37 | val assignmentVariables = findChildByClass(PowerShellAssignmentExpression::class.java)?.targetVariables 38 | return if (assignmentVariables != null && assignmentVariables.size > 0) assignmentVariables[0] else null 39 | } 40 | 41 | private fun getVariable(): PowerShellVariable? = findChildByClass(PowerShellTargetVariableExpression::class.java) ?: findFirstAssignmentTarget() 42 | 43 | override fun getPrefix(): String = getVariable()?.getPrefix() ?: "" 44 | 45 | override fun getSuffix(): String? = getVariable()?.getSuffix() 46 | 47 | override fun getScopeName(): String? = getVariable()?.getScopeName() 48 | 49 | override fun getIcon(flags: Int): Icon? = PowerShellComponentType.PROPERTY.getIcon() 50 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellPsiElementImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.extapi.psi.ASTWrapperPsiElement 4 | import com.intellij.lang.ASTNode 5 | import com.intellij.navigation.ItemPresentation 6 | import com.intellij.plugin.powershell.psi.PowerShellAssignmentExpression 7 | import com.intellij.plugin.powershell.psi.PowerShellComponent 8 | import com.intellij.plugin.powershell.psi.PowerShellPsiElement 9 | import com.intellij.psi.PsiElement 10 | import com.intellij.psi.ResolveState 11 | import com.intellij.psi.impl.source.tree.LeafPsiElement 12 | import com.intellij.psi.scope.PsiScopeProcessor 13 | import javax.swing.Icon 14 | 15 | /** 16 | * Andrey 26/06/17. 17 | */ 18 | open class PowerShellPsiElementImpl(node: ASTNode) : ASTWrapperPsiElement(node), PowerShellPsiElement { 19 | override fun processDeclarations(processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement): Boolean { 20 | return processDeclarationsImpl(processor, state, lastParent, place) 21 | } 22 | 23 | override fun getPresentation(): ItemPresentation { 24 | return object : ItemPresentation { 25 | override fun getLocationString(): String? { 26 | return null 27 | } 28 | 29 | override fun getIcon(unused: Boolean): Icon? { 30 | return null 31 | } 32 | 33 | override fun getPresentableText(): String? { 34 | return text 35 | } 36 | } 37 | } 38 | 39 | private fun processDeclarationsImpl(processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement): Boolean { 40 | val result = HashSet() 41 | // PowerShellResolveUtil.collectChildrenDeclarations(this, result, processor, state, lastParent) 42 | children.forEach { child -> 43 | if (child === lastParent) return@forEach 44 | when (child) { 45 | is PowerShellComponent -> result.add(child) 46 | is PowerShellAssignmentExpression -> result += child.targetVariables 47 | !is LeafPsiElement -> { 48 | if (!child.processDeclarations(processor, state, lastParent, place)) return false 49 | } 50 | } 51 | } 52 | 53 | return result.none { place.textOffset > it.textOffset && processor.execute(it, state).not() } 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellPsiImplUtil.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.* 5 | import com.intellij.plugin.powershell.psi.types.PowerShellType 6 | import com.intellij.psi.PsiElement 7 | import com.intellij.psi.TokenType 8 | import com.intellij.psi.impl.source.tree.TreeUtil 9 | import com.intellij.psi.util.PsiTreeUtil 10 | import org.jetbrains.annotations.Contract 11 | 12 | private fun isWhiteSpace(node: ASTNode): Boolean { 13 | return node.elementType === TokenType.WHITE_SPACE 14 | } 15 | 16 | fun ASTNode.isWhiteSpaceOrNls(): Boolean { 17 | return isWhiteSpace(this) || elementType === PowerShellTypes.NLS || elementType === PowerShellTypes.LF 18 | } 19 | 20 | val PowerShellAssignmentExpression.targetVariables: List 21 | get() { 22 | val result: MutableList = ArrayList() 23 | val targets = PsiTreeUtil.findChildrenOfAnyType( 24 | this, 25 | PowerShellTargetVariableExpression::class.java 26 | ) 27 | if (!targets.isEmpty()) result.addAll(targets) 28 | return result 29 | } 30 | 31 | val PowerShellAssignmentExpression.rhsElement: PowerShellPsiElement? 32 | get() { 33 | val child = this.firstChild ?: return null 34 | val rhsNode = TreeUtil.findSibling(child.node, PowerShellTypes.EQ) 35 | if (rhsNode != null) { 36 | return PsiTreeUtil.getNextSiblingOfType( 37 | rhsNode.psi, 38 | PowerShellPsiElement::class.java 39 | ) 40 | } 41 | return null 42 | } 43 | 44 | val PowerShellMemberAccessExpression.identifier: PsiElement? 45 | get() { 46 | return this.referenceIdentifier 47 | } 48 | 49 | val PowerShellInvocationExpression.identifier: PsiElement? 50 | get() { 51 | return referenceIdentifier 52 | } 53 | 54 | val PowerShellCastExpression.castType: PowerShellType 55 | get() { 56 | val typeLiteral = checkNotNull( 57 | PsiTreeUtil.getChildOfType( 58 | this, 59 | PowerShellTypeLiteralExpression::class.java 60 | ) 61 | ) 62 | return typeLiteral.typeElement.getType() 63 | } 64 | 65 | @Contract(pure = true) 66 | fun PsiElement.isTypeDeclarationContext(): Boolean { 67 | val context = context 68 | return context is PowerShellClassDeclarationStatement || context is PowerShellEnumDeclarationStatement 69 | } 70 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/PowerShellQualifiedReferenceElementImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.openapi.util.TextRange 5 | import com.intellij.plugin.powershell.psi.PowerShellPsiElement 6 | import com.intellij.plugin.powershell.psi.PowerShellQualifiedReferenceElement 7 | import com.intellij.plugin.powershell.psi.PowerShellReferenceIdentifier 8 | import com.intellij.plugin.powershell.psi.PowerShellTypes 9 | import com.intellij.psi.PsiElement 10 | 11 | abstract class PowerShellQualifiedReferenceElementImpl(node: ASTNode) : PowerShellReferencePsiElementImpl(node), PowerShellQualifiedReferenceElement { 12 | 13 | override fun isTypeMemberAccess(): Boolean { 14 | return findChildByType(PowerShellTypes.COLON2) != null 15 | } 16 | 17 | override fun getNavigationElement(): PsiElement { 18 | return getNameElement() ?: super.getNavigationElement() 19 | } 20 | 21 | override fun getReferenceName(): String? { 22 | return getNameElement()?.text 23 | } 24 | 25 | override fun getNameElement(): PsiElement? { 26 | return findChildByClass(PowerShellReferenceIdentifier::class.java) 27 | } 28 | 29 | override fun getRangeInElement(): TextRange { 30 | val nameRange = getNameElement()?.textRange ?: textRange 31 | return TextRange(nameRange.startOffset - textRange.startOffset, nameRange.endOffset - textRange.startOffset) 32 | } 33 | 34 | override fun getTextOffset(): Int { 35 | return getNameElement()?.textOffset ?: super.getTextOffset() 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/mixin/PowerShellArrayTypeElementMixin.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl.mixin 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellArrayTypeElement 5 | import com.intellij.plugin.powershell.psi.impl.PowerShellTypeElementImplGen 6 | import com.intellij.plugin.powershell.psi.types.PowerShellType 7 | import com.intellij.plugin.powershell.psi.types.impl.PowerShellArrayClassTypeImpl 8 | 9 | abstract class PowerShellArrayTypeElementMixin( 10 | node: ASTNode? 11 | ) : PowerShellTypeElementImplGen(node), PowerShellArrayTypeElement { 12 | 13 | override fun getType(): PowerShellType { 14 | return PowerShellArrayClassTypeImpl(this) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/mixin/PowerShellCastExpressionMixin.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl.mixin 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellCastExpression 5 | import com.intellij.plugin.powershell.psi.impl.PowerShellExpressionImplGen 6 | import com.intellij.plugin.powershell.psi.impl.castType 7 | import com.intellij.plugin.powershell.psi.types.PowerShellType 8 | 9 | abstract class PowerShellCastExpressionMixin(node: ASTNode?) : PowerShellExpressionImplGen(node), PowerShellCastExpression { 10 | 11 | override fun getType(): PowerShellType { 12 | return castType 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/mixin/PowerShellLabelReferenceExpressionMixin.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl.mixin 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellLabelReferenceExpression 5 | import com.intellij.plugin.powershell.psi.impl.PowerShellReferencePsiElementImpl 6 | import com.intellij.plugin.powershell.psi.types.PowerShellType 7 | 8 | abstract class PowerShellLabelReferenceExpressionMixin( 9 | node: ASTNode 10 | ) : PowerShellReferencePsiElementImpl(node), PowerShellLabelReferenceExpression { 11 | 12 | override fun getType(): PowerShellType { 13 | return PowerShellType.UNKNOWN 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/mixin/PowerShellParenthesizedExpressionMixin.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl.mixin 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellExpression 5 | import com.intellij.plugin.powershell.psi.PowerShellParenthesizedExpression 6 | import com.intellij.plugin.powershell.psi.impl.PowerShellExpressionImplGen 7 | import com.intellij.plugin.powershell.psi.types.PowerShellType 8 | import com.intellij.psi.util.PsiTreeUtil 9 | 10 | abstract class PowerShellParenthesizedExpressionMixin( 11 | node: ASTNode? 12 | ) : PowerShellExpressionImplGen(node), PowerShellParenthesizedExpression { 13 | 14 | override fun getType(): PowerShellType { 15 | val exprInParenthesis = PsiTreeUtil.getChildOfType( 16 | this, 17 | PowerShellExpression::class.java 18 | ) 19 | return exprInParenthesis?.getType() ?: PowerShellType.UNKNOWN 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/impl/mixin/PowerShellTypeLiteralExpressionMixin.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.impl.mixin 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellTypeLiteralExpression 5 | import com.intellij.plugin.powershell.psi.impl.PowerShellExpressionImplGen 6 | import com.intellij.plugin.powershell.psi.types.PowerShellType 7 | 8 | abstract class PowerShellTypeLiteralExpressionMixin( 9 | node: ASTNode? 10 | ) : PowerShellExpressionImplGen(node), PowerShellTypeLiteralExpression { 11 | 12 | override fun getType(): PowerShellType { 13 | return typeElement.getType() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/PowerShellArrayClassType.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types 2 | 3 | interface PowerShellArrayClassType : PowerShellReferenceClassType { 4 | fun getComponentType(): PowerShellType 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/PowerShellClassType.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellComponent 4 | 5 | interface PowerShellClassType: PowerShellType { 6 | fun resolve(): PowerShellComponent? 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/PowerShellImmediateClassType.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types 2 | 3 | interface PowerShellImmediateClassType : PowerShellClassType -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/PowerShellReferenceClassType.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types 2 | 3 | interface PowerShellReferenceClassType : PowerShellClassType { 4 | fun getReferenceName(): String? 5 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/PowerShellType.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types 2 | 3 | interface PowerShellType { 4 | 5 | companion object { 6 | val UNKNOWN = object : PowerShellType { 7 | override fun accept(visitor: PowerShellTypeVisitor): T? { 8 | return visitor.visitType(this) 9 | } 10 | 11 | override fun getName(): String { 12 | return "" 13 | } 14 | } 15 | } 16 | 17 | fun accept(visitor: PowerShellTypeVisitor): T? 18 | 19 | 20 | fun getName(): String 21 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/PowerShellTypeVisitor.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types 2 | 3 | abstract class PowerShellTypeVisitor { 4 | open fun visitClassType(o: PowerShellClassType): T? { 5 | return visitType(o) 6 | } 7 | 8 | open fun visitArrayClassType(o: PowerShellArrayClassType): T? { 9 | return visitType(o.getComponentType()) 10 | } 11 | 12 | open fun visitType(o: PowerShellType): T? { 13 | return null 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/PowerShellTypedElement.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellPsiElement 4 | 5 | interface PowerShellTypedElement : PowerShellPsiElement { 6 | fun getType(): PowerShellType 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/impl/PowerShellArrayClassTypeImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types.impl 2 | 3 | import com.intellij.plugin.powershell.ide.resolve.PsNames 4 | import com.intellij.plugin.powershell.psi.PowerShellArrayTypeElement 5 | import com.intellij.plugin.powershell.psi.PowerShellComponent 6 | import com.intellij.plugin.powershell.psi.types.PowerShellArrayClassType 7 | import com.intellij.plugin.powershell.psi.types.PowerShellClassType 8 | import com.intellij.plugin.powershell.psi.types.PowerShellType 9 | import com.intellij.plugin.powershell.psi.types.PowerShellTypeVisitor 10 | 11 | class PowerShellArrayClassTypeImpl(private val psiElement: PowerShellArrayTypeElement) : PowerShellArrayClassType { 12 | 13 | override fun getComponentType(): PowerShellType { 14 | return psiElement.referenceTypeElement.getType() 15 | } 16 | 17 | override fun getReferenceName(): String { 18 | return "[" + getName() + "]" 19 | } 20 | 21 | override fun resolve(): PowerShellComponent? {//TODO[#194] resolve to the actual array class 22 | val componentType = getComponentType() 23 | return (componentType as? PowerShellClassType)?.resolve() 24 | } 25 | 26 | override fun accept(visitor: PowerShellTypeVisitor): T? { 27 | return visitor.visitArrayClassType(this) 28 | } 29 | 30 | override fun getName(): String { 31 | return psiElement.referenceTypeElement.referenceName ?: PsNames.UNNAMED 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/impl/PowerShellImmediateClassTypeImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types.impl 2 | 3 | import com.intellij.plugin.powershell.psi.PowerShellComponent 4 | import com.intellij.plugin.powershell.psi.PowerShellTypeDeclaration 5 | import com.intellij.plugin.powershell.psi.types.PowerShellImmediateClassType 6 | import com.intellij.plugin.powershell.psi.types.PowerShellTypeVisitor 7 | 8 | class PowerShellImmediateClassTypeImpl(private val myClass: PowerShellTypeDeclaration) : PowerShellImmediateClassType { 9 | override fun accept(visitor: PowerShellTypeVisitor): T? { 10 | return visitor.visitClassType(this) 11 | } 12 | 13 | override fun resolve(): PowerShellComponent { 14 | return myClass 15 | } 16 | 17 | override fun getName(): String { 18 | return myClass.name ?: "" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/impl/PowerShellObjectType.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types.impl 2 | 3 | import com.intellij.plugin.powershell.psi.types.PowerShellType 4 | import com.intellij.plugin.powershell.psi.types.PowerShellTypeVisitor 5 | 6 | class PowerShellObjectType: PowerShellType { 7 | override fun accept(visitor: PowerShellTypeVisitor): T? { 8 | return visitor.visitType(this) 9 | } 10 | 11 | override fun getName(): String = "Object" 12 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/impl/PowerShellReferenceClassTypeImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types.impl 2 | 3 | import com.intellij.plugin.powershell.ide.resolve.PsNames 4 | import com.intellij.plugin.powershell.psi.PowerShellComponent 5 | import com.intellij.plugin.powershell.psi.PowerShellReferenceTypeElement 6 | import com.intellij.plugin.powershell.psi.types.PowerShellReferenceClassType 7 | import com.intellij.plugin.powershell.psi.types.PowerShellTypeVisitor 8 | 9 | class PowerShellReferenceClassTypeImpl(private val myReference: PowerShellReferenceTypeElement) : PowerShellReferenceClassType { 10 | override fun accept(visitor: PowerShellTypeVisitor): T? { 11 | return visitor.visitClassType(this) 12 | } 13 | 14 | override fun resolve(): PowerShellComponent? { 15 | return myReference.resolve() 16 | } 17 | 18 | override fun getReferenceName(): String? { 19 | return myReference.referenceName 20 | } 21 | 22 | override fun getName(): String { 23 | return getReferenceName() ?: PsNames.UNNAMED 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/impl/PowerShellReferenceTypeElementImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.PowerShellQualifiedReferenceElement 5 | import com.intellij.plugin.powershell.psi.PowerShellReferenceTypeElement 6 | import com.intellij.plugin.powershell.psi.PowerShellTypes 7 | import com.intellij.plugin.powershell.psi.impl.PowerShellReferencePsiElementImpl 8 | import com.intellij.plugin.powershell.psi.types.PowerShellType 9 | import com.intellij.psi.PsiElement 10 | 11 | open class PowerShellReferenceTypeElementImpl(node: ASTNode) : PowerShellReferencePsiElementImpl(node), PowerShellReferenceTypeElement, 12 | PowerShellQualifiedReferenceElement { 13 | override fun isTypeMemberAccess(): Boolean = false 14 | 15 | override fun getReferenceName(): String? { 16 | return getNameElement()?.text 17 | } 18 | 19 | override fun getQualifier(): PowerShellReferenceTypeElement? = findChildByClass(PowerShellReferenceTypeElement::class.java) 20 | 21 | 22 | override fun getType(): PowerShellType { 23 | return PowerShellReferenceClassTypeImpl(this) 24 | } 25 | 26 | 27 | override fun getNameElement(): PsiElement? = findLastChildByType(PowerShellTypes.SIMPLE_ID) ?: lastChild 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/com/intellij/plugin/powershell/psi/types/impl/PowerShellTypedElementImpl.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.psi.types.impl 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.plugin.powershell.psi.impl.PowerShellPsiElementImpl 5 | import com.intellij.plugin.powershell.psi.types.PowerShellType 6 | import com.intellij.plugin.powershell.psi.types.PowerShellTypedElement 7 | 8 | open class PowerShellTypedElementImpl(node: ASTNode) : PowerShellPsiElementImpl(node), PowerShellTypedElement { 9 | 10 | override fun getType(): PowerShellType = PowerShellObjectType() 11 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/injection.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/powerShellConsole.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/internal/PowerShell File.ps1.ft: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ant-druha/intellij-powershell/37d05974e80c1108338200cc6ba43a92f94ec9e9/src/main/resources/fileTemplates/internal/PowerShell File.ps1.ft -------------------------------------------------------------------------------- /src/main/resources/icons/powershell_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ant-druha/intellij-powershell/37d05974e80c1108338200cc6ba43a92f94ec9e9/src/main/resources/icons/powershell_icon.png -------------------------------------------------------------------------------- /src/main/resources/icons/powershell_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ant-druha/intellij-powershell/37d05974e80c1108338200cc6ba43a92f94ec9e9/src/main/resources/icons/powershell_icon@2x.png -------------------------------------------------------------------------------- /src/main/resources/messages/MessagesBundle.properties: -------------------------------------------------------------------------------- 1 | code.style.align.multiline=Align when multiline 2 | 3 | editor.services.inspection=PSScriptAnalyzer 4 | 5 | powershell-console.launching=Launching PowerShell Terminal Console 6 | 7 | powershell.download.link=https://github.com/powershell/powershell#get-powershell 8 | powershell.editor.services.download.link=https://github.com/PowerShell/PowerShellEditorServices/releases 9 | powershell.extension.path.form.description=Here you can specify the path to PowerShellEditorServices package. 10 | powershell.extension.path.form.label=PowerShell Editor Services: 11 | powershell.not.installed.install.action=Download 12 | powershell.not.installed.message=PowerShell executable not found in PATH 13 | powershell.not.installed.title=PowerShell is not installed 14 | powershell.vs.code.extension.configure.action=Configure 15 | powershell.vs.code.extension.install.action=Install 16 | powershell.vs.code.extension.install.link=https://github.com/PowerShell/vscode-powershell#installing-the-extension 17 | powershell.vs.code.extension.not.installed.message=Would you like to install PowerShell VSCode extension to get more rich PowerShell Editor assistance? \nIf extension is already installed, you can specify the path manually in Settings. 18 | powershell.vs.code.extension.not.installed.title=PowerShell extension is not installed 19 | 20 | ps.editor.services.detected.version.label=Version: 21 | 22 | settings.errors.executable-not-found=PowerShell executable "{0}" could not be found. 23 | settings.powershell.lsp.is.enabled.box.text=Integrate Editor with PowerShell EditorServices host 24 | settings.powershell=PowerShell 25 | 26 | wrapping.attribute.argument=Attribute arguments 27 | wrapping.block.parameters=Block parameters 28 | wrapping.catch,type.list=Catch type list 29 | wrapping.pipeline=Pipeline 30 | 31 | powershell.debugger.breakpoints.title=Breakpoints 32 | powershell.debugger.breakpoints.invalidBreakPoint=Invalid Breakpoint 33 | powershell.debugger.PowerShellExecutionStackDisplayName="PowerShell Debug Execution Stack" 34 | powershell.debugger.cantRunException=Cannot establish debugger agent connection 35 | -------------------------------------------------------------------------------- /src/scripts/Get-Distribution.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This script gets the distribution file available in the path passed to it. 4 | .PARAMETER DistributionsPath 5 | Path to the directory containing compressed plugin distribution. 6 | #> 7 | param ( 8 | [Parameter(Mandatory = $true)] 9 | [string] $DistributionsPath 10 | ) 11 | 12 | Set-StrictMode -Version Latest 13 | $ErrorActionPreference = 'Stop' 14 | 15 | $file = Get-Item $DistributionsPath/*.zip 16 | if (!$file) { 17 | throw "File not found in $DistributionsPath" 18 | } 19 | if (@($file).Count -gt 1) { 20 | throw "Found more files than expected in ${DistributionsPath}: $($file.Count)" 21 | } 22 | 23 | return $file 24 | -------------------------------------------------------------------------------- /src/scripts/Publish-Distribution.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This script publishes the plugin distribution from the $DistributionsLocation to the JetBrains Marketplace. 4 | .PARAMETER SourceRootPath 5 | Path to the project source root. 6 | .PARAMETER DistributionsPath 7 | Path to the directory containing compressed plugin distribution. 8 | .PARAMETER PluginXmlId 9 | Plugin identifier. 10 | .PARAMETER Channel 11 | Channel name to publish the plugin. 12 | .PARAMETER AuthToken 13 | Token to authenticate to the Marketplace. 14 | #> 15 | param ( 16 | [string] $SourceRootPath = "$PSScriptRoot/../..", 17 | [string] $DistributionsPath = "$SourceRootPath/build/distributions", 18 | [string] $PluginXmlId = 'com.intellij.plugin.adernov.powershell', 19 | [Parameter(Mandatory = $true)] 20 | [string] $AuthToken 21 | ) 22 | 23 | Set-StrictMode -Version Latest 24 | $ErrorActionPreference = 'Stop' 25 | 26 | $file = & "$PSScriptRoot/Get-Distribution.ps1" -DistributionsPath $DistributionsPath 27 | curl -i ` 28 | --fail-with-body ` 29 | --header "Authorization: Bearer $AuthToken" ` 30 | -F xmlId=$PluginXmlId ` 31 | -F file=@$file ` 32 | https://plugins.jetbrains.com/plugin/uploadPlugin 33 | 34 | if (!$?) { 35 | throw "Curl failed with exit code $LASTEXITCODE" 36 | } 37 | -------------------------------------------------------------------------------- /src/scripts/Unpack-Distribution.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | The purpose of this script is to unpack the compressed plugin artifact. 4 | 5 | It is used during CI builds to generate the layout for uploading. 6 | .PARAMETER SourceRootPath 7 | Path to the project source root. 8 | .PARAMETER DistributionsPath 9 | Path to the directory containing compressed plugin distribution. 10 | #> 11 | param ( 12 | [string] $SourceRootPath = "$PSScriptRoot/../..", 13 | [string] $DistributionsPath = "$SourceRootPath/build/distributions" 14 | ) 15 | 16 | Set-StrictMode -Version Latest 17 | $ErrorActionPreference = 'Stop' 18 | 19 | $file = & "$PSScriptRoot/Get-Distribution.ps1" -DistributionsPath $DistributionsPath 20 | 21 | Expand-Archive -Path $file -DestinationPath $DistributionsPath/unpacked 22 | -------------------------------------------------------------------------------- /src/test/kotlin/com/intellij/plugin/powershell/PowerShellDebuggerTestUtil.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell 2 | 3 | import com.intellij.plugin.powershell.ide.debugger.PowerShellSuspendContext 4 | import com.intellij.xdebugger.XDebuggerTestUtil 5 | import com.intellij.xdebugger.XTestCompositeNode 6 | import com.intellij.xdebugger.frame.XValue 7 | 8 | class PowerShellDebuggerTestUtil { 9 | companion object { 10 | fun getVariable(suspendContext: PowerShellSuspendContext, variableName: String): XValue { 11 | val topFrame = suspendContext.activeExecutionStack.topFrame!! 12 | val children = XTestCompositeNode(topFrame).collectChildren() 13 | return XDebuggerTestUtil.findVar(children, variableName) 14 | } 15 | 16 | fun getChildren(suspendContext: PowerShellSuspendContext, variableName: String): MutableList { 17 | val topFrame = suspendContext.activeExecutionStack.topFrame!! 18 | return XTestCompositeNode(topFrame).collectChildren() 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/kotlin/com/intellij/plugin/powershell/TestEnvironment.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell 2 | 3 | val isOnCiServer = 4 | System.getenv("CI").equals("true", ignoreCase = true) 5 | -------------------------------------------------------------------------------- /src/test/kotlin/com/intellij/plugin/powershell/debugger/EvaluationTest.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.debugger 2 | 3 | import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx 4 | import com.intellij.plugin.powershell.testFramework.DebuggerTestBase 5 | import com.intellij.plugin.powershell.testFramework.PowerShellTestSession 6 | import com.intellij.plugin.powershell.testFramework.runInEdt 7 | import com.intellij.testFramework.junit5.TestApplication 8 | import com.intellij.xdebugger.XDebuggerTestUtil 9 | import com.jetbrains.rd.util.lifetime.Lifetime 10 | import org.junit.jupiter.api.Assertions 11 | import org.junit.jupiter.api.Test 12 | 13 | @TestApplication 14 | class EvaluationTest: DebuggerTestBase() { 15 | 16 | @Test 17 | fun testEvaluation() { 18 | runInEdt { 19 | val psiFile = copyAndOpenFile("debugger/testBreakpoint.ps1") 20 | val file = psiFile.virtualFile 21 | 22 | val fileLine = 1 // line in file, starting from 1 23 | val line = fileLine - 1 // breakpoint line, starting from 0 24 | val expression = "1 + 2" 25 | val expectedResult = "3" 26 | 27 | val testSession = PowerShellTestSession(project, file.toNioPath()) 28 | XDebuggerTestUtil.toggleBreakpoint(project, file, line) 29 | Lifetime.using { lt -> 30 | val debugSession = testSession.startDebugSession(lt) 31 | Assertions.assertTrue(XDebuggerTestUtil.waitFor( 32 | testSession.sessionListener.pausedSemaphore, 33 | testSession.waitForBackgroundTimeout.toMillis() 34 | ), "Pause should be triggered in ${testSession.waitForBackgroundTimeout}") 35 | val variableValue = 36 | XDebuggerTestUtil.evaluate(debugSession, expression, testSession.waitForBackgroundTimeout.toMillis()).first 37 | val variableValueNode = XDebuggerTestUtil.computePresentation(variableValue) 38 | Assertions.assertEquals(expectedResult, variableValueNode.myValue) 39 | } 40 | } 41 | } 42 | 43 | override fun tearDownInEdt() { 44 | FileEditorManagerEx.getInstanceEx(project).closeAllFiles() 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/kotlin/com/intellij/plugin/powershell/lang/PowerShellCommenterTest.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang 2 | 3 | import com.intellij.openapi.actionSystem.IdeActions 4 | import com.intellij.plugin.powershell.testFramework.PowerShellCodeInsightTestBase 5 | import com.intellij.testFramework.junit5.TestApplication 6 | import org.junit.jupiter.api.Test 7 | 8 | @TestApplication 9 | class PowerShellCommenterTest : PowerShellCodeInsightTestBase() { 10 | 11 | @Test 12 | fun testCommentExtension() { 13 | codeInsightTestFixture.configureByText( 14 | "file.ps1", """ 15 | <# 16 | #> 17 | """.trimIndent() 18 | ) 19 | waitForEditorManagerCreated(codeInsightTestFixture.file.virtualFile.toNioPath()) 20 | codeInsightTestFixture.performEditorAction(IdeActions.ACTION_EDITOR_ENTER) 21 | waitForEditorManagerCreated(codeInsightTestFixture.file.virtualFile.toNioPath()) 22 | codeInsightTestFixture.checkResult( 23 | """ 24 | <# 25 | 26 | #> 27 | """.trimIndent() 28 | ) 29 | waitForEditorManagerCreated(codeInsightTestFixture.file.virtualFile.toNioPath()) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/kotlin/com/intellij/plugin/powershell/lang/PowerShellCompletionTests.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang 2 | 3 | import com.intellij.codeInsight.completion.CompletionType 4 | import com.intellij.plugin.powershell.testFramework.PowerShellCodeInsightTestBase 5 | import com.intellij.testFramework.junit5.TestApplication 6 | import org.junit.jupiter.api.Assertions 7 | import org.junit.jupiter.api.Test 8 | 9 | @TestApplication 10 | class PowerShellCompletionTests : PowerShellCodeInsightTestBase() { 11 | 12 | override fun getTestDataPath() = "src/test/resources/testData" 13 | 14 | @Test 15 | fun testCompletion() { 16 | val psiFile = codeInsightTestFixture.configureByFile("codeinsight/completion.ps1") 17 | 18 | waitForEditorConnects(psiFile.virtualFile.toNioPath()) 19 | codeInsightTestFixture.complete(CompletionType.BASIC) 20 | val lookupElementStrings = codeInsightTestFixture.lookupElementStrings 21 | Assertions.assertNotNull(lookupElementStrings) 22 | Assertions.assertTrue { lookupElementStrings!!.contains("Get-Alias") } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/kotlin/com/intellij/plugin/powershell/lang/PowerShellParserTest.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.lang 2 | 3 | import com.intellij.lang.LanguageBraceMatching 4 | import com.intellij.plugin.powershell.ide.editor.highlighting.PowerShellPairedBraceMatcher 5 | import com.intellij.plugin.powershell.lang.parser.PowerShellParserDefinition 6 | import com.intellij.testFramework.ParsingTestCase 7 | 8 | class PowerShellParserTest : ParsingTestCase("parser", "ps1", PowerShellParserDefinition()) { 9 | 10 | override fun setUp() { 11 | super.setUp() 12 | addExplicitExtension(LanguageBraceMatching.INSTANCE, PowerShellLanguage.INSTANCE, PowerShellPairedBraceMatcher()) 13 | } 14 | 15 | override fun getTestDataPath() = "src/test/resources/testData" 16 | override fun includeRanges() = true 17 | 18 | fun testCallInvocationOperator() { doTest(true) } 19 | fun testVerbatimCommandArgument() { doTest(true) } 20 | fun testPathExpression() { doTest(true) } 21 | fun testCommandCallExpression() { doTest(true) } 22 | fun testStdCmdlets() { doTest(true) } 23 | fun testMemberElementAccess() { doTest(true) } 24 | fun testTypeMemberAccess() { doTest(true) } 25 | fun testOperators() { doTest(true) } 26 | fun testNullCoalesceOperator() { doTest(true) } 27 | fun testLabeledStatement() { doTest(true) } 28 | fun testStatements() { doTest(true) } 29 | fun testFunctionMultilineDefinition() { doTest(true) } 30 | fun testDesiredSateConfiguration() { doTest(true) } 31 | fun testArrayStatement() { doTest(true) } 32 | fun testAttributes() { doTest(true) } 33 | fun testClosures() { doTest(true) } 34 | fun testModules() { doTest(true) } 35 | fun testHashTables() { doTest(true) } 36 | fun testExpandableString() { doTest(true) } 37 | fun testVerbatimString() { doTest(true) } 38 | fun testTypeLiteral() { doTest(true) } 39 | fun testClassDeclaration() { doTest(true) } 40 | fun testEnumDeclaration() { doTest(true) } 41 | fun testParamBlock() { doTest(true) } 42 | fun testComment() { doTest(true) } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/kotlin/com/intellij/plugin/powershell/testFramework/DebuggerTestBase.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.testFramework 2 | 3 | import com.intellij.openapi.command.WriteCommandAction 4 | import com.intellij.openapi.util.ThrowableComputable 5 | import com.intellij.openapi.vfs.VfsUtil 6 | import com.intellij.psi.PsiFile 7 | import com.intellij.psi.PsiManager 8 | import kotlin.io.path.Path 9 | import kotlin.io.path.createDirectories 10 | 11 | abstract class DebuggerTestBase: PowerShellTestBase() { 12 | 13 | private val testData = "testData" 14 | 15 | protected fun copyAndOpenFile(nameRelativeToTestData: String): PsiFile { 16 | val fullName = "$testData/$nameRelativeToTestData" 17 | val original = DebuggerTestBase::class.java.classLoader.getResource(fullName) 18 | ?: error("Cannot find the original file \"$fullName\".") 19 | val originalVirtual = VfsUtil.findFileByURL(original) 20 | ?: error("Cannot find the original file \"$original\" on disk.") 21 | val basePath = Path(project.basePath ?: error("No base path defined for project $project.")) 22 | basePath.createDirectories() 23 | 24 | val baseDir = VfsUtil.findFile(basePath, /* refreshIfNeeded = */ true) 25 | ?: error("Cannot find the base directory for project $project.") 26 | 27 | val result = WriteCommandAction.writeCommandAction(/* project = */ null).compute(ThrowableComputable { 28 | originalVirtual.copy(originalVirtual, baseDir, originalVirtual.name) 29 | }) 30 | 31 | return PsiManager.getInstance(project).findFile(result) ?: error("Cannot find the PSI file for \"$result\".") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/kotlin/com/intellij/plugin/powershell/testFramework/EdtInterceptor.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.testFramework 2 | 3 | import org.junit.jupiter.api.extension.ExtensionContext 4 | import org.junit.jupiter.api.extension.InvocationInterceptor 5 | import org.junit.jupiter.api.extension.ReflectiveInvocationContext 6 | import java.lang.reflect.Method 7 | 8 | class EdtInterceptor: InvocationInterceptor { 9 | override fun interceptTestMethod( 10 | invocation: InvocationInterceptor.Invocation, 11 | invocationContext: ReflectiveInvocationContext, 12 | extensionContext: ExtensionContext 13 | ) { 14 | if(invocationContext.executable?.getAnnotation(RunInEdt::class.java) != null || invocationContext.targetClass?.getAnnotation(RunInEdt::class.java) != null) 15 | runInEdt { invocation.proceed() } 16 | else invocation.proceed() 17 | } 18 | } 19 | 20 | @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) 21 | annotation class RunInEdt 22 | -------------------------------------------------------------------------------- /src/test/kotlin/com/intellij/plugin/powershell/testFramework/PowerShellTestBase.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.testFramework 2 | 3 | import com.intellij.openapi.project.Project 4 | import com.intellij.testFramework.junit5.fixture.projectFixture 5 | import org.junit.jupiter.api.AfterEach 6 | import org.junit.jupiter.api.BeforeEach 7 | import java.nio.file.Path 8 | import kotlin.io.path.Path 9 | 10 | abstract class PowerShellTestBase { 11 | protected val projectFixture = projectFixture() 12 | 13 | lateinit var project: Project 14 | 15 | val projectPath: Path 16 | get() = Path(project.basePath!!) 17 | 18 | @BeforeEach 19 | open fun setUp() { 20 | project = projectFixture.get() 21 | } 22 | 23 | @AfterEach 24 | open fun tearDown() { 25 | } 26 | 27 | @AfterEach 28 | fun tearDownEdt() { 29 | runInEdt { 30 | tearDownInEdt() 31 | } 32 | } 33 | 34 | protected open fun tearDownInEdt() {} 35 | } 36 | -------------------------------------------------------------------------------- /src/test/kotlin/com/intellij/plugin/powershell/testFramework/PowerShellTestUtils.kt: -------------------------------------------------------------------------------- 1 | package com.intellij.plugin.powershell.testFramework 2 | 3 | import com.intellij.openapi.application.EDT 4 | import kotlinx.coroutines.Dispatchers 5 | import kotlinx.coroutines.runBlocking 6 | import kotlinx.coroutines.withContext 7 | 8 | fun runInEdt(test: suspend () -> Unit) { 9 | runBlocking { 10 | withContext(Dispatchers.EDT) { 11 | test() 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/resources/testData/codeinsight/completion.ps1: -------------------------------------------------------------------------------- 1 | Get- 2 | -------------------------------------------------------------------------------- /src/test/resources/testData/codeinsight/folding.ps1: -------------------------------------------------------------------------------- 1 | $fruit = @("Apples", "Oranges", 2 | "Bananas") 3 | 4 | $( for ($i = 1; $i -le 10; ++$i) { 5 | "$i $( $i*$i ) " 6 | } ) 7 | 8 | function foo() { 9 | $i = 1 10 | while ($i -le 10) { 11 | $str = "Output $i" 12 | Write-Output $str 13 | $i = $i + 1 14 | Start-Sleep -Milliseconds $DelayMilliseconds 15 | } 16 | } -------------------------------------------------------------------------------- /src/test/resources/testData/debugger/secondFileTest.ps1: -------------------------------------------------------------------------------- 1 | $temp = 69 2 | 3 | function GetVal{ 4 | return $temp 5 | } 6 | -------------------------------------------------------------------------------- /src/test/resources/testData/debugger/stepTest.ps1: -------------------------------------------------------------------------------- 1 | function Add-Numbers { 2 | param( 3 | [double]$num1, 4 | [double]$num2 5 | ) 6 | 7 | $result = $num1 + $num2 8 | return $result 9 | } 10 | Write-Output "Starting the script..." 11 | $result = Add-Numbers -num1 10 -num2 5 12 | Write-Output "The result is: $result" 13 | Write-Output "End of the script." 14 | -------------------------------------------------------------------------------- /src/test/resources/testData/debugger/testBreakpoint.ps1: -------------------------------------------------------------------------------- 1 | $val = 0 2 | $result = Get-Variable 3 | while($val -ne 3) 4 | { 5 | $val++ 6 | Write-Host $val 7 | } 8 | -------------------------------------------------------------------------------- /src/test/resources/testData/debugger/testBreakpointTwoFiles.ps1: -------------------------------------------------------------------------------- 1 | $val = 0 2 | $result = Get-Variable 3 | 4 | .".\secondFileTest.ps1" 5 | Write-Host (GetVal) 6 | 7 | while($val -ne 3) 8 | { 9 | $val++ 10 | Write-Host $val 11 | } 12 | -------------------------------------------------------------------------------- /src/test/resources/testData/debugger/variableTest.ps1: -------------------------------------------------------------------------------- 1 | $myPrimitiveVar = 69 2 | $myComplexVar = [PSCustomObject]@{ 3 | NestedField = 123 4 | } 5 | Write-Host "Variable Test" 6 | -------------------------------------------------------------------------------- /src/test/resources/testData/format/block_parameter_indent.ps1: -------------------------------------------------------------------------------- 1 | [CmdLetBinding()] 2 | param ( 3 | [PSParameter(Mandatory = $true)] $foo 4 | ) 5 | $bar = $baz 6 | 7 | function foo 8 | { 9 | [CmdLetBinding()] 10 | param ( 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/resources/testData/format/block_parameter_indent_res.ps1: -------------------------------------------------------------------------------- 1 | [CmdLetBinding()] 2 | param ( 3 | [PSParameter(Mandatory = $true)] $foo 4 | ) 5 | $bar = $baz 6 | 7 | function foo 8 | { 9 | [CmdLetBinding()] 10 | param ( 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/test/resources/testData/format/braces1.ps1: -------------------------------------------------------------------------------- 1 | function test { 2 | foreach ($i in get-childitem | 3 | sort-object length) { 4 | $i #highlight 5 | # comment here 6 | Write-Object (($j -gt 5) -and ($i -lt 15)) 7 | } 8 | } -------------------------------------------------------------------------------- /src/test/resources/testData/format/braces1_if_wrapped_res.ps1: -------------------------------------------------------------------------------- 1 | function test { 2 | foreach ($i in get-childitem | 3 | sort-object length) 4 | { 5 | $i #highlight 6 | # comment here 7 | Write-Object (($j -gt 5) -and ($i -lt 15)) 8 | } 9 | } -------------------------------------------------------------------------------- /src/test/resources/testData/format/compound_identifiers.ps1: -------------------------------------------------------------------------------- 1 | $tsFiles = (Get-ChildItem -Path $Path -Filter *.ts) 2 | 3 | $d = new-object System.Data.Datatable -------------------------------------------------------------------------------- /src/test/resources/testData/format/compound_identifiers_res.ps1: -------------------------------------------------------------------------------- 1 | $tsFiles = (Get-ChildItem -Path $Path -Filter *.ts) 2 | 3 | $d = new-object System.Data.Datatable -------------------------------------------------------------------------------- /src/test/resources/testData/format/indent_brace.ps1: -------------------------------------------------------------------------------- 1 | function test 2 | { 3 | foreach ($i in get-childitem | sort-object length) 4 | { 5 | $i #highlight 6 | # comment here 7 | Write-Object (($j -gt 5) -and ($i -lt 15)) 8 | } 9 | } -------------------------------------------------------------------------------- /src/test/resources/testData/format/indent_brace_pipeline_wrap_res.ps1: -------------------------------------------------------------------------------- 1 | function test 2 | { 3 | foreach ($i in get-childitem | 4 | sort-object length) 5 | { 6 | $i #highlight 7 | # comment here 8 | Write-Object (($j -gt 5) -and ($i -lt 15)) 9 | } 10 | } -------------------------------------------------------------------------------- /src/test/resources/testData/format/indent_brace_res.ps1: -------------------------------------------------------------------------------- 1 | function test 2 | { 3 | foreach ($i in get-childitem | sort-object length) 4 | { 5 | $i #highlight 6 | # comment here 7 | Write-Object (($j -gt 5) -and ($i -lt 15)) 8 | } 9 | } -------------------------------------------------------------------------------- /src/test/resources/testData/format/indents.ps1: -------------------------------------------------------------------------------- 1 | function test 2 | { 3 | foreach ($i in get-childitem | sort-object length) 4 | { 5 | $i #highlight 6 | # comment here 7 | Write-Object (($j -gt 5) -and ($i -lt 15)) 8 | } 9 | } 10 | function a() 11 | { 12 | @" 13 | Date is: $( get-date ) 14 | "@ 15 | Write-Object 16 | } 17 | 18 | function b() 19 | { 20 | @" 21 | Date is: $( get-date ) 22 | "@ 23 | Write-Object 24 | } 25 | function c() 26 | { 27 | @' 28 | Date is: $( get-date ) 29 | '@ 30 | Write-Object 31 | } 32 | function d() 33 | { 34 | $arr = @( 35 | 1 36 | "2" 37 | "3=$(3)" 38 | 4, 5 39 | 6 40 | ) 41 | } -------------------------------------------------------------------------------- /src/test/resources/testData/format/indents_res.ps1: -------------------------------------------------------------------------------- 1 | function test 2 | { 3 | foreach ($i in get-childitem | sort-object length) 4 | { 5 | $i #highlight 6 | # comment here 7 | Write-Object (($j -gt 5) -and ($i -lt 15)) 8 | } 9 | } 10 | function a() 11 | { 12 | @" 13 | Date is: $( get-date ) 14 | "@ 15 | Write-Object 16 | } 17 | 18 | function b() 19 | { 20 | @" 21 | Date is: $( get-date ) 22 | "@ 23 | Write-Object 24 | } 25 | function c() 26 | { 27 | @' 28 | Date is: $( get-date ) 29 | '@ 30 | Write-Object 31 | } 32 | function d() 33 | { 34 | $arr = @( 35 | 1 36 | "2" 37 | "3=$( 3 )" 38 | 4, 5 39 | 6 40 | ) 41 | } -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_binary_expr.ps1: -------------------------------------------------------------------------------- 1 | function foo 2 | { 3 | Write-Object (($j -gt 5) -and ($i -lt 15)) 4 | 5 | ($Error -eq $Null) -or ($Error -ne $Null) 6 | 7 | ($a -and $b) -eq !(!$a -or !$b) 8 | 9 | ($a -gt $b) -and (($a -lt 20) -or ($b -lt 20)) 10 | 11 | (1 -eq 1) -and -not(2 -gt 2) 12 | 13 | !($Null) 14 | 15 | $a -and $b 16 | 17 | $a -or $b 18 | 19 | $a -xor $b 20 | 21 | $a -band $b 22 | 23 | -not($a) 24 | !($a) 25 | 26 | "abcdef" -like "abc*" 27 | } 28 | -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_binary_expr_align.ps1: -------------------------------------------------------------------------------- 1 | function foo 2 | { 3 | Write-Object (($j -gt 4 | 5) -and 5 | ($i -lt 6 | 15)) 7 | 8 | ($Error -eq 9 | $Null) -or 10 | ($Error -ne 11 | $Null) 12 | 13 | ($a -and 14 | $b) -eq 15 | !(!$a -or 16 | !$b) 17 | 18 | ($a -gt 19 | $b) -and 20 | (($a -lt 21 | 20) -or 22 | ($b -lt 23 | 20)) 24 | 25 | (1 -eq 26 | 1) -and 27 | -not (2 -gt 28 | 2) 29 | 30 | !($Null) 31 | 32 | $a -and 33 | $b 34 | 35 | $a -or 36 | $b 37 | 38 | $a -xor 39 | $b 40 | 41 | $a -band 42 | $b 43 | 44 | -not ($a) 45 | !($a) 46 | 47 | "abcdef" -like 48 | "abc*" 49 | } 50 | -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_binary_expr_always_res.ps1: -------------------------------------------------------------------------------- 1 | function foo 2 | { 3 | Write-Object (($j -gt 4 | 5) -and 5 | ($i -lt 6 | 15)) 7 | 8 | ($Error -eq 9 | $Null) -or 10 | ($Error -ne 11 | $Null) 12 | 13 | ($a -and 14 | $b) -eq 15 | !(!$a -or 16 | !$b) 17 | 18 | ($a -gt 19 | $b) -and 20 | (($a -lt 21 | 20) -or 22 | ($b -lt 23 | 20)) 24 | 25 | (1 -eq 26 | 1) -and 27 | -not (2 -gt 28 | 2) 29 | 30 | !($Null) 31 | 32 | $a -and 33 | $b 34 | 35 | $a -or 36 | $b 37 | 38 | $a -xor 39 | $b 40 | 41 | $a -band 42 | $b 43 | 44 | -not ($a) 45 | !($a) 46 | 47 | "abcdef" -like 48 | "abc*" 49 | } 50 | -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_binary_expr_as_needed.ps1: -------------------------------------------------------------------------------- 1 | function foo 2 | { 3 | Write-Object (($j -gt 4 | 5) -and 5 | ($i -lt 15)) 6 | 7 | ($Error -eq $Null) -or 8 | ($Error -ne $Null) 9 | 10 | ($a -and $b) -eq 11 | !(!$a -or !$b) 12 | 13 | ($a -gt $b) -and 14 | (($a -lt 20) -or 15 | ($b -lt 20)) 16 | 17 | (1 -eq 1) -and 18 | -not (2 -gt 2) 19 | 20 | !($Null) 21 | 22 | $a -and $b 23 | 24 | $a -or $b 25 | 26 | $a -xor $b 27 | 28 | $a -band $b 29 | 30 | -not ($a) 31 | !($a) 32 | 33 | "abcdef" -like "abc*" 34 | } 35 | -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_binary_expr_lp_new_line.ps1: -------------------------------------------------------------------------------- 1 | function foo 2 | { 3 | Write-Object 4 | ( 5 | ($j -gt 5) -and 6 | ($i -lt 15)) 7 | 8 | ($Error -eq $Null) -or 9 | ($Error -ne $Null) 10 | 11 | ($a -and $b) -eq ! 12 | (!$a -or !$b) 13 | 14 | ($a -gt $b) -and 15 | ( 16 | ($a -lt 20) -or 17 | ($b -lt 18 | 20)) 19 | 20 | (1 -eq 1) -and -not 21 | (2 -gt 2) 22 | 23 | !($Null) 24 | 25 | $a -and $b 26 | 27 | $a -or $b 28 | 29 | $a -xor $b 30 | 31 | $a -band $b 32 | 33 | -not ($a) 34 | !($a) 35 | 36 | "abcdef" -like "abc*" 37 | } 38 | -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_block_parameters.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$false)][string]$Currency , 3 | [Parameter(Mandatory=$false)][string]$Locale , [Parameter(Mandatory=$false)][string]$RegionInfo , 4 | [Parameter(Mandatory=$false)][string]$OfferDurableId , 5 | [Parameter(Mandatory=$false)][bool]$propagatetags=$true, 6 | [Parameter(Mandatory=$false)][string]$syncInterval , 7 | [Parameter(Mandatory=$false)] [bool] $clearLocks=$false 8 | ) 9 | #region Login to Azure account and select the subscription. 10 | #Authenticate to Azure with SPN section 11 | Write-Verbose "Logging in to Azure..." 12 | $Conn = Get-AutomationConnection -Name AzureRunAsConnection -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_block_parameters_default_res.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory = $false)][string]$Currency, 3 | [Parameter(Mandatory = $false)][string]$Locale, [Parameter(Mandatory = $false)][string]$RegionInfo, 4 | [Parameter(Mandatory = $false)][string]$OfferDurableId, 5 | [Parameter(Mandatory = $false)][bool]$propagatetags = $true, 6 | [Parameter(Mandatory = $false)][string]$syncInterval, 7 | [Parameter(Mandatory = $false)] [bool] $clearLocks = $false 8 | ) 9 | #region Login to Azure account and select the subscription. 10 | #Authenticate to Azure with SPN section 11 | Write-Verbose "Logging in to Azure..." 12 | $Conn = Get-AutomationConnection -Name AzureRunAsConnection -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_block_parameters_res.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory = $false)][string]$Currency, 3 | [Parameter(Mandatory = $false)][string]$Locale, 4 | [Parameter(Mandatory = $false)][string]$RegionInfo, 5 | [Parameter(Mandatory = $false)][string]$OfferDurableId, 6 | [Parameter(Mandatory = $false)][bool]$propagatetags = $true, 7 | [Parameter(Mandatory = $false)][string]$syncInterval, 8 | [Parameter(Mandatory = $false)] [bool] $clearLocks = $false 9 | ) 10 | #region Login to Azure account and select the subscription. 11 | #Authenticate to Azure with SPN section 12 | Write-Verbose "Logging in to Azure..." 13 | $Conn = Get-AutomationConnection -Name AzureRunAsConnection -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_chained_call.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue() 2 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue().booo() 3 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue().booooo().dooooooooo 4 | $VerbosePreference = $PSCmdlet.alue().foooooooooooo.fooooooooo().fooooooooo() 5 | $VerbosePreference = $PSCmdlet.alue().fooooooooooo.foooooooooo().sdsdsdsdsd 6 | $VerbosePreference = $PSCmdlet.alue().fooooooooooo.foooooooooo().sdsdsdsdsd() 7 | $VerbosePreference = $PSCmdlet.alues.fooooooooooooooooooooooooo().fooooooooo().saj() 8 | $VerbosePreference = $PSCmdlet.alues().foooooooooooooooooooooooo().fooooooooo().saj() 9 | $VerbosePreference = $PSCmdlet.alues.fooooooooooooooooooooooooo().fooooooooo() -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_chained_call_align_res.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue() 2 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue(). 3 | booo() 4 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue(). 5 | booooo().dooooooooo 6 | $VerbosePreference = $PSCmdlet.alue().foooooooooooo.fooooooooo(). 7 | fooooooooo() 8 | $VerbosePreference = $PSCmdlet.alue().fooooooooooo.foooooooooo().sdsdsdsdsd 9 | $VerbosePreference = $PSCmdlet.alue().fooooooooooo.foooooooooo(). 10 | sdsdsdsdsd() 11 | $VerbosePreference = $PSCmdlet.alues.fooooooooooooooooooooooooo(). 12 | fooooooooo().saj() 13 | $VerbosePreference = $PSCmdlet.alues(). 14 | foooooooooooooooooooooooo(). 15 | fooooooooo().saj() 16 | $VerbosePreference = $PSCmdlet.alues.fooooooooooooooooooooooooo(). 17 | fooooooooo() -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_chained_call_always_res.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue() 2 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue(). 3 | booo() 4 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue(). 5 | booooo().dooooooooo 6 | $VerbosePreference = $PSCmdlet.alue().foooooooooooo.fooooooooo(). 7 | fooooooooo() 8 | $VerbosePreference = $PSCmdlet.alue().fooooooooooo.foooooooooo().sdsdsdsdsd 9 | $VerbosePreference = $PSCmdlet.alue().fooooooooooo.foooooooooo(). 10 | sdsdsdsdsd() 11 | $VerbosePreference = $PSCmdlet.alues.fooooooooooooooooooooooooo(). 12 | fooooooooo(). 13 | saj() 14 | $VerbosePreference = $PSCmdlet.alues(). 15 | foooooooooooooooooooooooo(). 16 | fooooooooo(). 17 | saj() 18 | $VerbosePreference = $PSCmdlet.alues.fooooooooooooooooooooooooo(). 19 | fooooooooo() -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_chained_call_if_long_first_wrap_res.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue() 2 | $VerbosePreference = $PSCmdlet. 3 | GetFooooooooooooooooVariableValue().booo() 4 | $VerbosePreference = $PSCmdlet. 5 | GetFooooooooooooooooVariableValue(). 6 | booooo().dooooooooo 7 | $VerbosePreference = $PSCmdlet.alue().foooooooooooo. 8 | fooooooooo().fooooooooo() 9 | $VerbosePreference = $PSCmdlet.alue().fooooooooooo.foooooooooo().sdsdsdsdsd 10 | $VerbosePreference = $PSCmdlet.alue().fooooooooooo. 11 | foooooooooo().sdsdsdsdsd() 12 | $VerbosePreference = $PSCmdlet.alues. 13 | fooooooooooooooooooooooooo().fooooooooo().saj() 14 | $VerbosePreference = $PSCmdlet.alues(). 15 | foooooooooooooooooooooooo().fooooooooo().saj() 16 | $VerbosePreference = $PSCmdlet.alues. 17 | fooooooooooooooooooooooooo().fooooooooo() -------------------------------------------------------------------------------- /src/test/resources/testData/format/wrap_chained_call_if_long_res.ps1: -------------------------------------------------------------------------------- 1 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue() 2 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue(). 3 | booo() 4 | $VerbosePreference = $PSCmdlet.GetFooooooooooooooooVariableValue(). 5 | booooo().dooooooooo 6 | $VerbosePreference = $PSCmdlet.alue().foooooooooooo.fooooooooo(). 7 | fooooooooo() 8 | $VerbosePreference = $PSCmdlet.alue().fooooooooooo.foooooooooo().sdsdsdsdsd 9 | $VerbosePreference = $PSCmdlet.alue().fooooooooooo.foooooooooo(). 10 | sdsdsdsdsd() 11 | $VerbosePreference = $PSCmdlet.alues.fooooooooooooooooooooooooo(). 12 | fooooooooo().saj() 13 | $VerbosePreference = $PSCmdlet.alues(). 14 | foooooooooooooooooooooooo().fooooooooo().saj() 15 | $VerbosePreference = $PSCmdlet.alues.fooooooooooooooooooooooooo(). 16 | fooooooooo() -------------------------------------------------------------------------------- /src/test/resources/testData/parser/CallInvocationOperator.ps1: -------------------------------------------------------------------------------- 1 | & "Script1.ps1" 2 | & $myVar 3 | &{ 4 | $i = 1 5 | } 6 | & { 7 | $i = 1 8 | } 9 | 10 | #dot notation 11 | . "Script2.ps1" 12 | . { 13 | $i = 1 14 | } 15 | . FunctionA 16 | 17 | & mycmd.exe 18 | 19 | &{} {} {} {} -------------------------------------------------------------------------------- /src/test/resources/testData/parser/Closures.ps1: -------------------------------------------------------------------------------- 1 | function Get-NextID ([int]$startValue = 1) 2 | { 3 | $nextID = $startValue 4 | { 5 | ($script:nextID++) 6 | }.GetNewClosure() 7 | } 8 | $v1 = Get-NextID # get a scriptblock with $startValue of 0 9 | &$v1 # invoke Get-NextID getting back 1 10 | &$v1 # invoke Get-NextID getting back 1 11 | $v2 = Get-NextID 100 # get a scriptblock with $startValue of 100 12 | &$v2 # invoke Get-NextID getting back 100 13 | &$v2 # invoke Get-NextID getting back 101 14 | 15 | $v3 = &{ # get a scriptblock with $startValue of 200 16 | param ([int]$startValue = 1) 17 | $nextID = $startValue 18 | { 19 | ($script:nextID++) 20 | }.GetNewClosure() 21 | } 200 22 | &$v3 # invoke script getting back 200 23 | &$v3 # invoke script getting back 201 -------------------------------------------------------------------------------- /src/test/resources/testData/parser/CommandCallExpression.ps1: -------------------------------------------------------------------------------- 1 | mycmd.exe "./plink.exe" $escapeparser $Hostname -l $Username -pw $Password $Command 2 | 3 | Get-ChildItem e:\ProgramdFiles\*.txt | Sort-Object -CaseSensitive | Process-File > results.txt 4 | 5 | $fullCommand = '& "other.exe" --% ' + $commandArgs 6 | Invoke-Expression $fullCommand 7 | 8 | #switch parameter 9 | Set-MyProcess -Strict 10 | Set-MyProcess -Strict: $true #the same as above 11 | 12 | 13 | #parameter with argument 14 | Get-Power -base 5 -exponent 3 15 | Get-Power -exponent 3 -base 5 16 | 17 | #Positional argument 18 | Get-Power 5 3 19 | 20 | $a = New-Object 'double[,]' 3, 2 21 | 22 | #Performs an operation against each of a set of input objects. (alias %, foreach) 23 | 5,20,-3 | ForEach-Object -Process {$_ * 2} 24 | 5,20,-3 | % -Begin { "Setup" } -Process {$_ * $_} -End { "Cleanup" } 25 | 26 | #Creates a filter to determine which input objects are be passed along a command pipeline. 27 | Get-ChildItem "E:\Files\*.*" | Where-Object { $_.Length -le 1000 } 28 | Get-ChildItem "E:\Files\*.*" | Where-Object Length –eq 0 29 | Get-ChildItem "E:\Files\*.*" | Where-Object Length –xor 0 30 | Get-ChildItem "E:\Files\*.*" | Where-Object Length –and 0 31 | 32 | cmdkey /list 33 | 34 | msbuild CmderLauncher.vcxproj /p:configuration=Release 35 | 36 | & $7zipexe x -o"C:\Install" $apprendazip 37 | 38 | my.exe 01/01/2012 39 | 40 | #some-cmd.exe 'Count101', -p 'Count102', 'Count104' 210 41 | 42 | msbuild CmderLauncher.vcxproj /property:WarningLevel`;OutputDirbinDebug #command argument is not parsed 43 | 44 | $reponse=Invoke-WebRequest -Uri http://localhost:50342/oauth2/token -Method POST -Body $postBody -UseBasicParsing -Headers $headers 45 | 46 | (Get-WmiObject Win32_PhysicalMemory | measure-object Capacity -sum).sum/1mb 47 | (measure-object Capacity -sum).sum+1mb 48 | (measure-object Capacity -sum).sum%1mb 49 | (measure-object Capacity -sum).sum*1mb 50 | (measure-object Capacity -sum).sum-1mb 51 | 52 | Switch-SqlAvailabilityGroup -Path $Path -AllowDataLoss -force 53 | 54 | process-me 55 | process-1 56 | process1 57 | 58 | my.exe 11 2 4 59 | my.exe *11 *2 4 3 *3* -------------------------------------------------------------------------------- /src/test/resources/testData/parser/Comment.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .DESCRIPTION 3 | This will create a Public IP address for the failed over VM - only in test failover. 4 | 5 | Pre-requisites 6 | 1. when you create a new Automation Account, make sure you have chosen to create a run-as account with it. 7 | 2. If you create a run as account on your own, give the Connection Name in the variable - $connectionName 8 | 9 | What all you need to change in this script? 10 | 1. Give the name of the Automation account in the variable - $AutomationAccountName 11 | 2. Give the Resource Group name of the Automation Account in $AutomationAccountRg 12 | 13 | Do you want to add a NSG to the failed over VM? If yes, follow the below steps - you can skip this step if you dont want to add an NSG. 14 | 1. Create the NSG that you want to apply 15 | 2. Create a new Azure automation string variable -NSG (example testrp-NSG). Save it with the value of the NSG you want to use. 16 | 3. Create a new Azure automation string variable -NSGRG (example testrp-NSGRG). Save it with the value of the NSG's Resource group you want to use. 17 | 18 | How to add the script? 19 | Add this script as a post action in boot up group for which you need a public IP. All the VMs in the group will get a public IP assigned. 20 | If the NSG parameters are specified, all the VM's NICs will get the same NSG attached. 21 | 22 | Clean up test failover behavior 23 | Clean up test failover will not delete the IP address. You will need to delete the IP address manually 24 | 25 | 26 | .NOTES 27 | AUTHOR: RuturajD@microsoft.com 28 | LASTEDIT: 27 January, 2017 29 | #> 30 | 31 | #comment 32 | command#notcomment 33 | command #comment -------------------------------------------------------------------------------- /src/test/resources/testData/parser/EnumDeclaration.ps1: -------------------------------------------------------------------------------- 1 | [Flags()] enum FileAttributes { 2 | Archive = 1 3 | Compressed = 2 4 | Device = 4 5 | Directory = 8 6 | Encrypted = 16 7 | Hidden = 32 8 | } 9 | 10 | [FileAttributes]$file1 = [FileAttributes]::Archive + [FileAttributes]::Compressed + [FileAttributes]::Device 11 | "file1 attributes are: $file1" 12 | 13 | [FileAttributes]$file2 = [FileAttributes]28 ## => 16 + 8 + 4 14 | "file2 attributes are: $file2" 15 | 16 | enum MediaTypes { 17 | unknown 18 | music = 10 19 | mp3 20 | aac 21 | ogg = 15 22 | oga = 15 23 | mogg = 15 24 | picture = 20 25 | jpg 26 | jpeg = 21 27 | png 28 | video = 40 29 | mpg 30 | mpeg = 41 31 | avi 32 | m4v 33 | } 34 | $dsd[1]=1 35 | $dsd[$s] -------------------------------------------------------------------------------- /src/test/resources/testData/parser/ExpandableString.ps1: -------------------------------------------------------------------------------- 1 | ">$a.Length<" #results in >100 200.Length< 2 | ">$($a.Length)<" #results in >2< 3 | 4 | $count = 10 5 | "The value of `$count is $count" #The value of $count is 10. 6 | 7 | $a = "red","blue" 8 | # second [0] is taken literally 9 | "`$a[0] is $a[0], `$a[0] is $($a[0])" #result: $a[0] is red blue[0], $a[0] is red 10 | 11 | $count = 10 12 | "$count + 5 is $($count + 5)" 13 | "$count + 5 is `$($count + 5)" 14 | "$count + 5 is `$(`$count + 5)" 15 | 16 | $i = 5; $j = 10; $k = 15 17 | "`$i, `$j, and `$k have the values $( $i; $j; $k )" #$i, $j, and $k have the values 5 10 15 18 | "`$i, `$j, and `$k have the values $(($i = 5); ($j = 10); ($k = 15))" 19 | "First 10 squares: $(for ($i = 1; $i -le 10; ++$i) { "$i $($i*$i) " })" 20 | 21 | $a = 10 22 | $s1 = "`$a = $($a; ++$a)" 23 | "`$s1 = >$s1<" 24 | $s2 = "`$a = $($a; ++$a)" 25 | "`$s2 = >$s2<" 26 | $s2 = $s1 27 | "`$s2 = >$s2<" 28 | 29 | "lonely dollar $ is here$" 30 | 31 | "$sss::log" 32 | 33 | $lit = @" 34 | That's it! 35 | 2 * 3 = $(2*3) 36 | $a = $(2*3) 37 | "@ 38 | @" 39 | "@ -------------------------------------------------------------------------------- /src/test/resources/testData/parser/FunctionMultilineDefinition.ps1: -------------------------------------------------------------------------------- 1 | function 2 | Multi-Line-Definition 3 | { 4 | Write-Output "TEST" 5 | } -------------------------------------------------------------------------------- /src/test/resources/testData/parser/FunctionMultilineDefinition.txt: -------------------------------------------------------------------------------- 1 | FILE(0,58) 2 | PowerShellFunctionStatementImplGen(FUNCTION_STATEMENT)(0,58) 3 | PsiElement(function)('function')(0,8) 4 | PsiElement(NLS)('\n')(8,9) 5 | PowerShellIdentifierImplGen(IDENTIFIER)(9,30) 6 | PsiElement(GENERIC_ID_PART)('Multi-Line-Definition')(9,30) 7 | PsiElement(NLS)('\n')(30,31) 8 | PsiElement({)('{')(31,32) 9 | PowerShellBlockBodyImplGen(BLOCK_BODY)(32,57) 10 | PsiElement(NLS)('\n ')(32,37) 11 | PowerShellCommandCallExpressionImplGen(COMMAND_CALL_EXPRESSION)(37,56) 12 | PowerShellCommandNameImplGen(COMMAND_NAME)(37,49) 13 | PowerShellIdentifierImplGen(IDENTIFIER)(37,49) 14 | PsiElement(GENERIC_ID_PART)('Write-Output')(37,49) 15 | PsiWhiteSpace(' ')(49,50) 16 | PowerShellCommandArgumentImplGen(COMMAND_ARGUMENT)(50,56) 17 | PowerShellStringLiteralExpressionImplGen(STRING_LITERAL_EXPRESSION)(50,56) 18 | PsiElement(DQ_OPEN)('"')(50,51) 19 | PsiElement(EXPANDABLE_STRING_PART)('TEST')(51,55) 20 | PsiElement(DQ_CLOSE)('"')(55,56) 21 | PsiElement(NLS)('\n')(56,57) 22 | PsiElement(})('}')(57,58) -------------------------------------------------------------------------------- /src/test/resources/testData/parser/HashTables.ps1: -------------------------------------------------------------------------------- 1 | $h1 = @{FirstName = "James"; LastName = "Anderson"; IDNum = 123} 2 | $h2 = $h1 3 | $h1.FirstName = "John" # change key's value in $h1 4 | $h2.FirstName # change is reflected in $h2 5 | 6 | #removal 7 | $h1 = @{FirstName = "James"; LastName = "Anderson"; IDNum = 123} 8 | $h1.Dept = "Finance" # adds element Finance 9 | $h1["Salaried"] = $false # adds element Salaried 10 | $h1.Remove("Salaried") # removes element Salaried 11 | 12 | #enumerating 13 | $h1 = @{ FirstName = "James"; LastName = "Anderson"; IDNum = 123 } 14 | foreach ($e in $h1.Keys) 15 | { 16 | "Key is " + $e + ", Value is " + $h1[$e] 17 | } 18 | 19 | $getTargetResourceResult = @{ 20 | Name = $Website.Name; 21 | Ensure = $ensureResult; 22 | PhysicalPath = $Website.physicalPath; 23 | State = $Website.state; 24 | ID = $Website.id; 25 | ApplicationPool = $Website.applicationPool; 26 | Protocol = $Website.bindings.Collection.protocol; 27 | Binding = $Website.bindings.Collection.bindingInformation; 28 | } -------------------------------------------------------------------------------- /src/test/resources/testData/parser/LabeledStatement.ps1: -------------------------------------------------------------------------------- 1 | #labeled statement 2 | :go_here while ($j -le 100) 3 | { 4 | # … 5 | } 6 | :labelA 7 | for ($i = 1; $i -le 5; ++$i) 8 | { 9 | :labelB 10 | for ($j = 1; $j -le 3; ++$j) 11 | { 12 | :labelC 13 | for ($k = 1; $k -le 2; ++$k) 14 | { 15 | # … 16 | } 17 | } 18 | } 19 | 20 | : with_space while ($i -le 100) {} -------------------------------------------------------------------------------- /src/test/resources/testData/parser/MemberElementAccess.ps1: -------------------------------------------------------------------------------- 1 | #member access: 2 | $a = 10, 20, 30 3 | $a.Length # get instance property 4 | (10, 20, 30).Length 5 | $property = "Length" 6 | $a.$property # property name is a variable 7 | $h1 = @{FirstName = "James"; LastName = "Anderson"; IDNum = 123} 8 | $h1.FirstName # designates the key FirstName 9 | $h1.Keys # gets the collection of keys 10 | [int]::MinValue # get static property 11 | [double]::PositiveInfinity # get static property 12 | $property = "MinValue" 13 | [long]::$property # property name is a variable 14 | foreach ($t in [byte], [int], [long]) 15 | { 16 | $t::MaxValue # get static property 17 | } 18 | $a = @{ID=1}, @{ID=2}, @{ID=3} 19 | $a.ID # get ID from each element in the array 20 | 21 | #element access: 22 | $a = [int[]](10, 20, 30) # [int[]], Length 3 23 | $a[1] # returns int 20 24 | $a[20] # no such position, returns $null 25 | $a[-1] # returns int 30, i.e., $a[$a.Length-1] 26 | $a[2] = 5 # changes int 30 to int 5 27 | $a[20] = 5 # implementation-defined behavior 28 | $a = New-Object 'double[,]' 3, 2 29 | $a[0, 0] = 10.5 # changes 0.0 to 10.5 30 | $a[0, 0]++ # changes 10.5 to 10.6 31 | $list = ("red", $true, 10), 20, (1.2, "yes") 32 | $list[2][1] # returns string "yes" 33 | $a = @{A = 10}, @{B = $true}, @{C = 123.45} 34 | $a[1]["B"] # $a[1] is a Hashtable, where B is a key 35 | $a = "red", "green" 36 | $a[1][4] # returns string "n" from string in $a[1] 37 | 38 | $a[1,3,5] # slice has Length 3, value 40,60,80 39 | ++$a[1,3,5][1] # preincrement 60 in array 40,60,80 40 | $a[,5] # slice with Length 1 41 | $a[@()] # slice with Length 0 42 | $a[-1..-3] # slice with Length 0, value 90,80,70 43 | 44 | (0..15).ForEach ({ 45 | $ComputeServer = [ComputeServer]::new() 46 | $ComputeServer.Brand = "Fabrikam, Inc." 47 | $ComputeServer.Model = "Fbk5040" 48 | $ComputeServer.Status = "Installed" 49 | $ComputeServer.ProcessorIdentifier = "x64" 50 | $ComputeServer.Hostname = ("r1s" + $_.ToString("000")) 51 | $FirstRack.AddDevice($ComputeServer, $_) 52 | }) 53 | 54 | TR (-join $Properties.Foreach{ TD ($row.$_) } ) 55 | 56 | {1,2,3}.foreach{ echo "$_" } -------------------------------------------------------------------------------- /src/test/resources/testData/parser/NullCoalesceOperator.ps1: -------------------------------------------------------------------------------- 1 | # Null-coalescing operator: 2 | $Variable1 = $env:ENV_VAR_1 ?? "defaultValue" 3 | -------------------------------------------------------------------------------- /src/test/resources/testData/parser/NullCoalesceOperator.txt: -------------------------------------------------------------------------------- 1 | FILE(0,73) 2 | PsiComment(COMMENT)('# Null-coalescing operator:')(0,27) 3 | PsiElement(NLS)('\n')(27,28) 4 | PowerShellAssignmentExpressionImplGen(ASSIGNMENT_EXPRESSION)(28,73) 5 | PowerShellTargetVariableExpressionImplGen(TARGET_VARIABLE_EXPRESSION)(28,38) 6 | PsiElement($)('$')(28,29) 7 | PowerShellIdentifierImplGen(IDENTIFIER)(29,38) 8 | PsiElement(SIMPLE_ID)('Variable1')(29,38) 9 | PsiWhiteSpace(' ')(38,39) 10 | PsiElement(=)('=')(39,40) 11 | PsiWhiteSpace(' ')(40,41) 12 | PowerShellNullCoalesceExpressionImplGen(NULL_COALESCE_EXPRESSION)(41,73) 13 | PowerShellTargetVariableExpressionImplGen(TARGET_VARIABLE_EXPRESSION)(41,55) 14 | PsiElement($)('$')(41,42) 15 | PsiElement(SIMPLE_ID)('env')(42,45) 16 | PsiElement(:)(':')(45,46) 17 | PowerShellIdentifierImplGen(IDENTIFIER)(46,55) 18 | PsiElement(SIMPLE_ID)('ENV_VAR_1')(46,55) 19 | PsiWhiteSpace(' ')(55,56) 20 | PsiElement(DOUBLE_QUESTION_MARK)('??')(56,58) 21 | PsiWhiteSpace(' ')(58,59) 22 | PowerShellStringLiteralExpressionImplGen(STRING_LITERAL_EXPRESSION)(59,73) 23 | PsiElement(DQ_OPEN)('"')(59,60) 24 | PsiElement(EXPANDABLE_STRING_PART)('defaultValue')(60,72) 25 | PsiElement(DQ_CLOSE)('"')(72,73) -------------------------------------------------------------------------------- /src/test/resources/testData/parser/ParamBlock.ps1: -------------------------------------------------------------------------------- 1 | function Test-SympaMailingListMember 2 | { 3 | 4 | <# 5 | .Synopsis 6 | This function returns True or False against a member of a list in relation to their function/role within that list (subscriber/owner/editor). 7 | .EXAMPLE 8 | Test-SympaMailingListMember -Sympa $Sympa -MailingList queens-it -Member jim.bob@queens.ox.ac.uk -Function subscriber 9 | #> 10 | 11 | param( 12 | 13 |     [Parameter(Mandatory=$true,HelpMessage="Pass in the result of the 'Get-SympaLogin' function")] 14 |     $Sympa, 15 | 16 |     [Parameter(Mandatory=$true,HelpMessage="Enter the name of the Mailing list(s) you want to query the member against")] 17 |     [Array]$MailingList, 18 | 19 |     [Parameter(Mandatory=$true,HelpMessage="Enter the address of the member(s) you want to test")] 20 |     [Array]$Member, 21 | 22 | [Parameter()] 23 | [int] 24 | $Properties = 111+ 2, 25 | [Parameter()] 26 | [string] 27 | $Property = "Hello", 28 | 29 |     [Parameter(Mandatory=$true,HelpMessage="Set the ")] 30 |     [ValidateSet("subscriber", "owner", "editor")] 31 |     [String]$Function 32 | 33 |     ) 34 | 35 | [bool]$Results = $Sympa.amI("$MailingList","$Function","$Member") 36 | 37 | #Return the result 38 | Return [bool]$Results 39 | } -------------------------------------------------------------------------------- /src/test/resources/testData/parser/PathExpression.ps1: -------------------------------------------------------------------------------- 1 | C:\MyPath\To\Command.exe 3 2 | Get-ChildItem e:\d-.txt 3 | Get-ChildItem e:\*.txt 4 | Get-ChildItem e:\ProgramFiles\sample.txt 5 | Get-ChildItem .. 6 | Get-ChildItem \ 7 | Get-ChildItem . 8 | Get-ChildItem e:\ 9 | Get-ChildItem $PSScriptRoot\ 10 | Import-Module $PSScriptRoot\..\SampleModule.psd1 11 | Import-Module $PSScriptRoot\..\$var_module 12 | Import-Module ModuleName\::C:\ProgramFiles\sample.txt 13 | Import-Module ModuleName1\::ModuleName2\::C:\ProgramFiles\sample.txt 14 | New-File -Path ..\Examples\READMENew.md 15 | New-File -Path ..\Examples\README.md, XYZZY.ps1 #Processes multiple relative path via -Path param 16 | . .\Stop-Process2.ps1 # vs . ./Stop-Process2.ps1 17 | #Converts a path (§3.4) from a PowerShell path to a PowerShell provider path. 18 | Convert-Path -Path E:. 19 | Convert-Path -Path E:.,G:\Temp\.. 20 | 21 | Not-Path-Arg $PSScriptRoot 22 | Not-Path-Arg 42d 23 | 24 | #in older releases of Windows PowerShell, you can run the following command to get the value of the Application Base property 25 | #of the PowerShellEngine registry key: 26 | (Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine -Name ApplicationBase).ApplicationBase 27 | #Starting in Windows PowerShell 5.0, you can run 28 | Get-ItemPropertyValue -Path HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine -Name ApplicationBase 29 | 30 | cd (Get-Location)\pip #command with 2 arguments: (Get-Location) and \pip TODO[#200]: check it is really works 31 | cd (Get-Location)\pip\(Get-Location)\ 32 | cd \pip 33 | cd \pip\wwe 34 | 35 | #drive name in unc path 36 | $acl = Get-Acl \$(hostname)\e$\"some folder" 37 | 38 | foreach ($srv in (Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services\ts*).Name) {} 39 | -------------------------------------------------------------------------------- /src/test/resources/testData/parser/TypeLiteral.ps1: -------------------------------------------------------------------------------- 1 | [switch]$trace 2 | [System.switch.MySampleType]$i 3 | [int[]]$my_array 4 | [string]$str, [int]$start_pos = 0 -------------------------------------------------------------------------------- /src/test/resources/testData/parser/TypeMemberAccess.ps1: -------------------------------------------------------------------------------- 1 | [System.Environment]::Exit(0) 2 | [System.Environment]::ExitCode = 0 3 | $null = Register-ObjectEvent -InputObject $process -EventName 'Exited' -Action { [System.Environment]::Exit(0) } 4 | -------------------------------------------------------------------------------- /src/test/resources/testData/parser/VerbatimCommandArgument.ps1: -------------------------------------------------------------------------------- 1 | myCommand --% action /mode %UserMode% /path:"location with spaces" /fancyparam { /dothis /dothat:"%userArgs%" } /verbose -------------------------------------------------------------------------------- /src/test/resources/testData/parser/VerbatimCommandArgument.txt: -------------------------------------------------------------------------------- 1 | FILE(0,120) 2 | PowerShellCommandCallExpressionImplGen(COMMAND_CALL_EXPRESSION)(0,120) 3 | PowerShellCommandNameImplGen(COMMAND_NAME)(0,9) 4 | PowerShellIdentifierImplGen(IDENTIFIER)(0,9) 5 | PsiElement(SIMPLE_ID)('myCommand')(0,9) 6 | PsiWhiteSpace(' ')(9,10) 7 | PowerShellCommandArgumentImplGen(COMMAND_ARGUMENT)(10,120) 8 | PsiElement(--%)('--%')(10,13) 9 | PsiElement(VERBATIM_ARG_INPUT)(' action /mode %UserMode% /path:"location with spaces" /fancyparam { /dothis /dothat:"%userArgs%" } /verbose')(13,120) -------------------------------------------------------------------------------- /src/test/resources/testData/parser/VerbatimString.ps1: -------------------------------------------------------------------------------- 1 | # make a jQuery call 2 | ExecJavaScript $ie @' 3 | // this is JS code, remember to use semicolons 4 | var content = $('#home-content'); 5 | return content.text(); 6 | '@ 7 | @' 8 | '@ 9 | @' 10 | '@ 11 | @' 12 | test text 13 | '@ 14 | @' wrong 15 | ss 16 | '@ -------------------------------------------------------------------------------- /src/test/resources/testData/parser/VerbatimString.txt: -------------------------------------------------------------------------------- 1 | FILE(0,204) 2 | PsiComment(COMMENT)('# make a jQuery call')(0,20) 3 | PsiElement(NLS)('\n')(20,21) 4 | PowerShellCommandCallExpressionImplGen(COMMAND_CALL_EXPRESSION)(21,161) 5 | PowerShellCommandNameImplGen(COMMAND_NAME)(21,35) 6 | PowerShellIdentifierImplGen(IDENTIFIER)(21,35) 7 | PsiElement(SIMPLE_ID)('ExecJavaScript')(21,35) 8 | PsiWhiteSpace(' ')(35,36) 9 | PowerShellCommandArgumentImplGen(COMMAND_ARGUMENT)(36,39) 10 | PowerShellTargetVariableExpressionImplGen(TARGET_VARIABLE_EXPRESSION)(36,39) 11 | PsiElement($)('$')(36,37) 12 | PowerShellIdentifierImplGen(IDENTIFIER)(37,39) 13 | PsiElement(SIMPLE_ID)('ie')(37,39) 14 | PsiWhiteSpace(' ')(39,40) 15 | PowerShellCommandArgumentImplGen(COMMAND_ARGUMENT)(40,161) 16 | PowerShellStringLiteralExpressionImplGen(STRING_LITERAL_EXPRESSION)(40,161) 17 | PsiElement(VERBATIM_HERE_STRING)('@'\n // this is JS code, remember to use semicolons\n var content = $('#home-content');\n return content.text();\n'@')(40,161) 18 | PsiElement(NLS)('\n')(161,162) 19 | PowerShellStringLiteralExpressionImplGen(STRING_LITERAL_EXPRESSION)(162,173) 20 | PsiElement(VERBATIM_HERE_STRING)('@'\n'@\n@'\n'@')(162,173) 21 | PsiElement(NLS)('\n')(173,174) 22 | PowerShellStringLiteralExpressionImplGen(STRING_LITERAL_EXPRESSION)(174,189) 23 | PsiElement(VERBATIM_HERE_STRING)('@'\ntest text\n'@')(174,189) 24 | PsiElement(NLS)('\n')(189,190) 25 | PsiElement(@)('@')(190,191) 26 | PsiElement(VERBATIM_STRING)('' wrong\nss\n'')(191,203) 27 | PsiElement(@)('@')(203,204) 28 | PsiErrorElement:';', , LF or NLS expected(204,204) 29 | --------------------------------------------------------------------------------