├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradlew ├── gradlew.bat ├── grammar ├── GlslGrammar.bnf ├── GlslHighlightLexer.flex └── GlslLexer.flex ├── plugin-info ├── description.html └── example.glsl ├── settings.gradle └── src ├── main ├── kotlin │ └── glsl │ │ ├── data │ │ ├── GlslBuiltinFuncDocs.kt │ │ ├── GlslDefinitions.kt │ │ └── GlslTokenSets.kt │ │ └── plugin │ │ ├── completion │ │ ├── GlslCompletionContributor.kt │ │ └── GlslCompletionProvider.kt │ │ ├── editor │ │ ├── GlslBraceMatcher.kt │ │ ├── GlslCommenter.kt │ │ ├── GlslDocumentationProvider.kt │ │ ├── GlslMultiHostInjector.kt │ │ ├── GlslNewShaderFile.kt │ │ ├── GlslQuoteHandler.kt │ │ ├── GlslStructureView.kt │ │ ├── formatter │ │ │ ├── GlslBlock.kt │ │ │ └── GlslFormattingModelBuilder.kt │ │ ├── highlighting │ │ │ ├── GlslColorSettings.kt │ │ │ ├── GlslHighlightingAnnotator.kt │ │ │ └── GlslSyntaxHighlighter.kt │ │ └── style │ │ │ ├── GlslCodeStyleProvider.kt │ │ │ └── GlslCodeStyleSettings.kt │ │ ├── inspections │ │ ├── GlslErrorMessages.kt │ │ ├── GlslInspection.kt │ │ ├── GlslInspectionConstructorNoArguments.kt │ │ ├── GlslInspectionCyclicImports.kt │ │ ├── GlslInspectionIncompatibleType.kt │ │ ├── GlslInspectionMissingReturn.kt │ │ ├── GlslInspectionNoMatchingFunction.kt │ │ ├── GlslInspectionOperatorDoesNotOperate.kt │ │ ├── GlslInspectionTooFewArguments.kt │ │ └── GlslInspectionTooManyArguments.kt │ │ ├── language │ │ ├── GlslFile.kt │ │ ├── GlslIFileElementType.kt │ │ ├── GlslLanguage.kt │ │ ├── GlslLexer.kt │ │ ├── GlslParserAdapter.kt │ │ └── GlslParserDefinition.kt │ │ ├── psi │ │ ├── GlslExprType.kt │ │ ├── GlslIdentifier.kt │ │ ├── GlslPsiBuilder.kt │ │ ├── GlslPsiUtils.kt │ │ ├── GlslType.kt │ │ ├── GlslVariable.kt │ │ └── named │ │ │ ├── GlslNamedElement.kt │ │ │ ├── GlslNamedType.kt │ │ │ ├── GlslNamedVariable.kt │ │ │ ├── types │ │ │ ├── builtins │ │ │ │ ├── GlslBuiltinRest.kt │ │ │ │ ├── GlslBuiltinType.kt │ │ │ │ ├── GlslMatrix.kt │ │ │ │ ├── GlslScalar.kt │ │ │ │ └── GlslVector.kt │ │ │ └── user │ │ │ │ ├── GlslNamedBlockStructure.kt │ │ │ │ └── GlslNamedStructSpecifier.kt │ │ │ └── variables │ │ │ ├── GlslNamedBlockStructureWrapper.kt │ │ │ ├── GlslNamedDeclarationIdentifierWrapper.kt │ │ │ ├── GlslNamedFunctionDeclarator.kt │ │ │ ├── GlslNamedInitDeclaratorVariable.kt │ │ │ ├── GlslNamedParameterDeclarator.kt │ │ │ ├── GlslNamedPpDefineFunction.kt │ │ │ ├── GlslNamedPpDefineObject.kt │ │ │ ├── GlslNamedSingleDeclaration.kt │ │ │ └── GlslNamedStructDeclarator.kt │ │ ├── reference │ │ ├── GlslFindUsageProvider.kt │ │ ├── GlslRefactoring.kt │ │ ├── GlslReference.kt │ │ ├── GlslReferenceContributor.kt │ │ ├── GlslTypeReference.kt │ │ └── GlslVariableReference.kt │ │ └── utils │ │ ├── GlslBuiltinUtils.kt │ │ └── GlslUtils.kt └── resources │ ├── META-INF │ ├── plugin.xml │ └── pluginIcon.svg │ ├── builtin-objects │ ├── builtin-funcs-docs.html │ ├── glsl-builtin-constants.glsl │ ├── glsl-builtin-functions.glsl │ ├── glsl-shader-variables.glsl │ └── glsl-vector-structs.glsl │ ├── colors │ ├── GlslColorsConfiguration.xml │ └── color-demo-text.txt │ ├── fileTemplates │ └── internal │ │ ├── cs-template.comp.ft │ │ ├── fs-template.frag.ft │ │ ├── gs-template.geom.ft │ │ ├── shader-template.glsl.ft │ │ ├── tc-template.tesc.ft │ │ ├── te-template.tese.ft │ │ └── vs-template.vert.ft │ ├── formatter │ └── sample-code.txt │ ├── icons │ └── file-icon.svg │ ├── inspectionDescriptions │ ├── GlslInspectionConstructorNoArguments.html │ ├── GlslInspectionIncompatibleType.html │ ├── GlslInspectionMissingReturn.html │ ├── GlslInspectionNoMatchingFunction.html │ ├── GlslInspectionOperatorDoesNotOperate.html │ ├── GlslInspectionTooFewArguments.html │ └── GlslInspectionTooManyArguments.html │ └── live-templates │ └── glsl-live-template.xml └── test ├── java └── VectorStructGen.java ├── kotlin ├── GlslCompletionTest.kt ├── GlslDocumentationTest.kt ├── GlslDummyTest.kt ├── GlslFormatterTest.kt ├── GlslIncludeTest.kt ├── GlslInspectionsTest.kt ├── GlslLanguageInjectionTest.kt ├── GlslParserTest.kt ├── GlslReferenceTest.kt └── GlslRenamingTest.kt └── testData ├── completion ├── CompletionFile1.glsl ├── CompletionFile10.glsl ├── CompletionFile11.glsl ├── CompletionFile12.glsl ├── CompletionFile13.glsl ├── CompletionFile14.glsl ├── CompletionFile15.glsl ├── CompletionFile16.glsl ├── CompletionFile17.glsl ├── CompletionFile18.glsl ├── CompletionFile19.comp ├── CompletionFile2.glsl ├── CompletionFile20.comp ├── CompletionFile21.glsl ├── CompletionFile22.glsl ├── CompletionFile23.glsl ├── CompletionFile24a.glsl ├── CompletionFile3.geom ├── CompletionFile4.glsl ├── CompletionFile5.glsl ├── CompletionFile6.glsl ├── CompletionFile7.glsl ├── CompletionFile8.glsl ├── CompletionFile9.glsl └── include-test │ ├── include-test2 │ └── CompletionFile24b.glsl │ └── include-test3 │ └── CompletionFile24c.glsl ├── documentation ├── DocumentationFile1.glsl └── DocumentationFile2.glsl ├── dummy └── dummy.glsl ├── formatter ├── formatterFile.glsl └── formatterFileExpected.glsl ├── include ├── IncludeFile1.glsl ├── IncludeFile2.glsl ├── IncludeFile3.glsl ├── IncludeFile4.glsl ├── IncludeFile5.glsl ├── IncludeFile6.glsl ├── IncludeFile7.glsl ├── IncludeFile8.glsl └── shaders │ ├── IncludeFile10.glsl │ ├── IncludeFile7.glsl │ ├── IncludeFile8.glsl │ ├── IncludeFile9.glsl │ └── shaders2 │ └── IncludeFile7.glsl ├── inspections ├── InspectionPrimitiveConstructorNoArguments.glsl ├── InspectionsNoMatchingFunction.glsl ├── InspectionsNoMatchingFunction2.glsl ├── InspectionsTestDoesNotOperate.glsl ├── InspectionsTestIncompatibleTypes.glsl └── InspectionsTestMissingReturn.glsl ├── languageInjection └── LanguageInjectionHtml.html ├── parser ├── ParserFile.test └── ParserFile.txt ├── reference ├── FindUsageFile1.glsl ├── FindUsageFile2.glsl ├── FindUsageFile3.glsl ├── ReferenceFile1.glsl ├── ReferenceFile10.glsl ├── ReferenceFile11.glsl ├── ReferenceFile12.glsl ├── ReferenceFile13.glsl ├── ReferenceFile14.glsl ├── ReferenceFile15.glsl ├── ReferenceFile16.glsl ├── ReferenceFile17.comp ├── ReferenceFile18.comp ├── ReferenceFile19.frag ├── ReferenceFile2.glsl ├── ReferenceFile20.frag ├── ReferenceFile21.glsl ├── ReferenceFile22.glsl ├── ReferenceFile23.glsl ├── ReferenceFile24.glsl ├── ReferenceFile25.glsl ├── ReferenceFile26.glsl ├── ReferenceFile27.glsl ├── ReferenceFile28.glsl ├── ReferenceFile29.glsl ├── ReferenceFile3.glsl ├── ReferenceFile30.glsl ├── ReferenceFile31.glsl ├── ReferenceFile32.glsl ├── ReferenceFile33.glsl ├── ReferenceFile34.glsl ├── ReferenceFile35.glsl ├── ReferenceFile36.glsl ├── ReferenceFile37.glsl ├── ReferenceFile4.glsl ├── ReferenceFile5.glsl ├── ReferenceFile6.glsl ├── ReferenceFile7.glsl ├── ReferenceFile8.glsl └── ReferenceFile9.glsl └── renaming ├── RenamingIdentifierFile1.glsl ├── RenamingIdentifierFile1Expected.glsl ├── RenamingIdentifierFile2.glsl ├── RenamingIdentifierFile2Expected.glsl ├── RenamingIdentifierFile3.glsl ├── RenamingIdentifierFile3Expected.glsl ├── RenamingIdentifierFile4.glsl ├── RenamingIdentifierFile4Expected.glsl ├── RenamingIdentifierFile5.glsl ├── RenamingIdentifierFile5Expected.glsl ├── RenamingIdentifierFile6.glsl ├── RenamingIdentifierFile6Expected.glsl ├── RenamingIdentifierFile7.glsl ├── RenamingIdentifierFile7Expected.glsl ├── RenamingIdentifierFile8.html ├── RenamingIdentifierFile8Expected.html ├── RenamingIdentifierFile9.glsl └── RenamingIdentifierFile9Expected.glsl /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .DS_Store 3 | /dependencies/repo 4 | /android.tests.dependencies 5 | /dependencies/android.tests.dependencies 6 | /dist 7 | /local 8 | /ideaSDK 9 | /clionSDK 10 | /android-studio/sdk 11 | out/ 12 | /tmp 13 | /intellij 14 | workspace.xml 15 | *.versionsBackup 16 | /idea/testData/debugger/tinyApp/classes* 17 | build/ 18 | !**/src/**/build 19 | !**/test/**/build 20 | *.iml 21 | !**/testData/**/*.iml 22 | /.idea/ 23 | .rpt2_cache/ 24 | libraries/tools/kotlin-test-js-runner/lib/ 25 | local.properties 26 | buildSrcTmp/ 27 | distTmp/ 28 | outTmp/ 29 | /test.output 30 | /kotlin-native/dist 31 | kotlin-ide/ 32 | /archive/ 33 | /src/main/gen/ 34 | /glsl-spec/ 35 | .intellijPlatform -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Downloads](https://img.shields.io/jetbrains/plugin/d/18470-glsl)](https://plugins.jetbrains.com/plugin/18470-glsl/reviews) 2 | [![Rating](https://img.shields.io/jetbrains/plugin/r/stars/18470-glsl)](https://plugins.jetbrains.com/plugin/18470-glsl/reviews) 3 | ### [Donation with PayPal](https://www.paypal.com/donate/?hosted_button_id=FVDM2Z3ESPC5Y) 4 | 5 | # GLSL Plugin 6 | GLSL plugin support for JetBrains IDE's. 7 | Feel free to report any issue, problem, bug or add any request. 8 | 9 | [Plugin Page](https://plugins.jetbrains.com/plugin/18470-glsl) 10 | 11 | 12 | ## Build & Run 13 | ``` shell 14 | git clone https://github.com/walt-grace/glsl-plugin-idea.git 15 | ``` 16 | Assuming you're developing with Intellij (and you want to develop with Intellij): 17 | 1. **Generate grammar**. Execute the `generateGrammarClean` task from _gradle.build_ file or under _Tasks/other_ if you use the Gradle tab. 18 | 2. **Run**. Execute the `runIde` task (Intellij will build the project and then run the instance). 19 | 20 | \* If you're only interested in building the project without running it you can use task `buildPlugin` after step 1. 21 | 22 | ## Test 23 | Just execute the `test` task from the Gradle tab or run specific classes or tests from within the ide. 24 | 25 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | import org.jetbrains.intellij.platform.gradle.TestFrameworkType 2 | 3 | plugins { 4 | id 'org.jetbrains.kotlin.jvm' version "2.1.0" 5 | id 'org.jetbrains.intellij.platform' version '2.6.0' 6 | id "org.jetbrains.grammarkit" version "2022.3.2.2" 7 | id 'org.jetbrains.changelog' version "2.2.1" 8 | id 'java' 9 | } 10 | 11 | group 'glsl.plugin' 12 | version pluginVersion 13 | 14 | repositories { 15 | mavenCentral() 16 | intellijPlatform { 17 | defaultRepositories() 18 | } 19 | } 20 | 21 | dependencies { 22 | intellijPlatform { 23 | intellijIdeaCommunity '2025.1' 24 | testFramework TestFrameworkType.Platform.INSTANCE 25 | instrumentationTools() 26 | } 27 | testImplementation 'junit:junit:4.13.2' 28 | testImplementation 'org.opentest4j:opentest4j:1.3.0' 29 | } 30 | 31 | compileJava { 32 | sourceCompatibility = JavaVersion.VERSION_21 33 | targetCompatibility = JavaVersion.VERSION_21 34 | } 35 | 36 | runIde { 37 | maxHeapSize = "6g" 38 | } 39 | 40 | 41 | generateParser { 42 | doFirst { 43 | delete 'src/main/gen/psi' 44 | } 45 | sourceFile = file('grammar/GlslGrammar.bnf') 46 | targetRootOutputDir = file('src/main/gen') 47 | pathToParser = '_GlslParser.java' 48 | pathToPsiRoot = 'psi' 49 | } 50 | 51 | def generateLexer(String fileName) { 52 | return generateLexer { 53 | source = 'grammar/' + fileName 54 | targetDir = 'src/main/gen/glsl' 55 | targetOutputDir = file('src/main/gen') 56 | sourceFile = file('grammar/' + fileName) 57 | } 58 | } 59 | 60 | tasks.register('generateGrammarClean') { 61 | doFirst { 62 | delete 'src/main/gen' 63 | } 64 | doLast { 65 | generateParser.exec() 66 | generateLexer("GlslHighlightLexer.flex").exec() 67 | generateLexer("GlslLexer.flex").exec() 68 | } 69 | } 70 | 71 | patchPluginXml { 72 | def descriptionHtml = file('plugin-info/description.html').text 73 | changeNotes = changelog.get(version.toString()).toHTML() 74 | pluginDescription = descriptionHtml 75 | sinceBuild = '223' 76 | } 77 | 78 | changelog { 79 | version = pluginVersion 80 | } 81 | 82 | publishPlugin { 83 | token = System.getenv('PUBLISH_TOKEN') 84 | } 85 | 86 | sourceSets { 87 | main { 88 | java.srcDirs 'src/main/gen' 89 | } 90 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | pluginVersion=1.1.6 2 | kotlin.code.style=official 3 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /plugin-info/description.html: -------------------------------------------------------------------------------- 1 |

Donation

2 |

Plugin support for GLSL.

3 |

Features:

4 | 15 |
16 |

Supported file extensions:

17 | -------------------------------------------------------------------------------- /plugin-info/example.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | #define PI 3.14 3 | #define f(a, b) if (a > b) { int num = 2; } 4 | #include "different/file.glsl" 5 | 6 | precision mediump float; 7 | layout (location = 0) in vec3 aPos; 8 | layout (location = 1) in vec2 aTexCoord; 9 | 10 | out vec2 TexCoord; 11 | 12 | uniform mat4 model; 13 | uniform mat4 view; 14 | uniform mat4 projection; 15 | 16 | /** 17 | * 18 | */ 19 | int add(int a, int b) { 20 | f(1, 2) 21 | float v = normalize(a * PI); 22 | return a + b; 23 | } 24 | 25 | void main() { 26 | gl_Position = projection * view * model * vec4(abs(aPos), 1.0f); 27 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 28 | } 29 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'glsl-plugin-idea' -------------------------------------------------------------------------------- /src/main/kotlin/glsl/data/GlslDefinitions.kt: -------------------------------------------------------------------------------- 1 | package glsl.data 2 | 3 | import glsl.GlslTypes.* 4 | 5 | 6 | /** 7 | * 8 | */ 9 | enum class ShaderType { 10 | GLSL, VERT, TESC, TESE, GEOM, FRAG, COMP 11 | } 12 | 13 | object GlslDefinitions { 14 | 15 | /** 16 | * 17 | */ 18 | const val BACKSLASH = "\\" 19 | 20 | /** 21 | * 22 | */ 23 | val VERSIONS = arrayOf( 24 | "110", "120", "130", "140", "150", "330", "340", "350", "360", "370", "380", "390", "400", "410", "420", 25 | "430", "440", "450", "460" 26 | ) 27 | 28 | /** 29 | * 30 | */ 31 | val VEC_MAT_CONSTRUCTORS = listOf( 32 | "bvec2", "bvec3", "bvec4", "vec2", "vec3", "vec4", "ivec2", "ivec3", "ivec4", "uvec2", "uvec3", "uvec4", "dvec2", "dvec3", 33 | "dvec4", "mat2", "mat3", "mat4", "mat2x2", "mat2x3", "mat2x4", "mat3x2", "mat3x3", "mat3x4", "mat4x2", "mat4x3", "mat4x4", 34 | "dmat2", "dmat3", "dmat4", "dmat2x2", "dmat2x3", "dmat2x4", "dmat3x2", "dmat3x3", "dmat3x4", "dmat4x2", "dmat4x3", "dmat4x4", 35 | ) 36 | 37 | /** 38 | * 39 | */ 40 | val SCALARS = mapOf( 41 | INT to listOf(INT, UINT, FLOAT, DOUBLE), 42 | UINT to listOf(UINT, FLOAT, DOUBLE), 43 | FLOAT to listOf(FLOAT, DOUBLE), 44 | DOUBLE to listOf(DOUBLE), 45 | BOOL to null, 46 | ) 47 | 48 | /** 49 | * 50 | */ 51 | val VECTORS = mapOf( 52 | VEC2 to listOf(VEC2, DVEC2), 53 | IVEC2 to listOf(IVEC2, VEC2, DVEC2), 54 | UVEC2 to listOf(UVEC2, VEC2, DVEC2), 55 | VEC3 to listOf(VEC3, DVEC3), 56 | IVEC3 to listOf(IVEC3, VEC3, DVEC3), 57 | UVEC3 to listOf(UVEC3, VEC3, DVEC3), 58 | VEC4 to listOf(VEC4, DVEC4), 59 | IVEC4 to listOf(IVEC4, VEC4, DVEC4), 60 | UVEC4 to listOf(UVEC4, VEC4, DVEC4), 61 | BVEC2 to null, BVEC3 to null, BVEC4 to null, DVEC2 to null, DVEC3 to null, DVEC4 to null, 62 | I64VEC2 to null, I64VEC3 to null, I64VEC4 to null, U64VEC2 to null, U64VEC3 to null, 63 | U64VEC4 to null, I8VEC2 to null, I8VEC3 to null, I8VEC4 to null, U8VEC2 to null, 64 | U8VEC3 to null, U8VEC4 to null, I16VEC2 to null, I16VEC3 to null, I16VEC4 to null, 65 | U16VEC2 to null, U16VEC3 to null, U16VEC4 to null, I32VEC2 to null, I32VEC3 to null, 66 | I32VEC4 to null, U32VEC2 to null, U32VEC3 to null, U32VEC4 to null, F16VEC2 to null, 67 | F16VEC3 to null, F16VEC4 to null, F32VEC2 to null, F32VEC3 to null, F32VEC4 to null, 68 | F64VEC2 to null, F64VEC3 to null, F64VEC4 to null, 69 | ) 70 | 71 | /** 72 | * 73 | */ 74 | val MATRICES = mapOf( 75 | MAT2 to listOf(DMAT2), 76 | MAT3 to listOf(DMAT3), 77 | MAT4 to listOf(DMAT4), 78 | MAT2X3 to listOf(DMAT2X3), 79 | MAT2X4 to listOf(DMAT2X4), 80 | MAT3X2 to listOf(DMAT3X2), 81 | MAT3X4 to listOf(DMAT3X4), 82 | MAT4X2 to listOf(DMAT4X2), 83 | MAT4X3 to listOf(DMAT4X3), 84 | DMAT2 to null, DMAT3 to null, DMAT4 to null, DMAT2X2 to null, DMAT2X3 to null, DMAT2X4 to null, 85 | DMAT3X2 to null, DMAT3X3 to null, DMAT3X4 to null, DMAT4X2 to null, DMAT4X3 to null, DMAT4X4 to null, 86 | F16MAT2 to null, F16MAT3 to null, F16MAT4 to null, F16MAT2X2 to null, F16MAT2X3 to null, 87 | F16MAT2X4 to null, F16MAT3X2 to null, F16MAT3X3 to null, F16MAT3X4 to null, F16MAT4X2 to null, 88 | F16MAT4X3 to null, F16MAT4X4 to null, F32MAT2 to null, F32MAT3 to null, F32MAT4 to null, 89 | F32MAT2X2 to null, F32MAT2X3 to null, F32MAT2X4 to null, F32MAT3X2 to null, F32MAT3X3 to null, 90 | F32MAT3X4 to null, F32MAT4X2 to null, F32MAT4X3 to null, F32MAT4X4 to null, F64MAT2 to null, 91 | F64MAT3 to null, F64MAT4 to null, F64MAT2X2 to null, F64MAT2X3 to null, F64MAT2X4 to null, 92 | F64MAT3X2 to null, F64MAT3X3 to null, F64MAT3X4 to null, F64MAT4X2 to null, F64MAT4X3 to null, 93 | F64MAT4X4 to null, 94 | ) 95 | } 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/completion/GlslCompletionContributor.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.completion 2 | 3 | import com.intellij.codeInsight.completion.CompletionContributor 4 | import com.intellij.codeInsight.completion.CompletionType 5 | import com.intellij.patterns.PlatformPatterns.psiElement 6 | import com.intellij.patterns.StandardPatterns.or 7 | import glsl.GlslTypes.* 8 | import glsl.data.GlslDefinitions 9 | import glsl.data.GlslTokenSets 10 | import glsl.plugin.utils.GlslUtils 11 | import glsl.psi.interfaces.* 12 | 13 | 14 | /** 15 | * 16 | */ 17 | class GlslCompletionContributor : CompletionContributor() { 18 | // Keywords sets 19 | private val selectionKeywords = GlslUtils.getTokenSetAsStrings(GlslTokenSets.SELECTION) 20 | private val iterationKeywords = GlslUtils.getTokenSetAsStrings(GlslTokenSets.ITERATION) 21 | private val funcJumpsKeywords = GlslUtils.getTokenSetAsStrings(GlslTokenSets.FUNC_JUMPS) 22 | private val iterationJumpsKeywords = GlslUtils.getTokenSetAsStrings(GlslTokenSets.ITERATION_JUMPS) 23 | private val typeQualifiers = GlslUtils.getTokenSetAsStrings(GlslTokenSets.TYPE_QUALIFIERS) 24 | 25 | // Patterns 26 | private val numeric = or( 27 | psiElement(INTCONSTANT), 28 | psiElement(UINTCONSTANT), 29 | psiElement(FLOATCONSTANT), 30 | psiElement(DOUBLECONSTANT), 31 | ) 32 | 33 | private val afterDot = psiElement().afterLeaf(".") 34 | private val afterPpLiteral = psiElement().afterLeaf("#") 35 | private val insidePpStatement = psiElement().inside(GlslPpStatement::class.java) 36 | private val afterVersion = psiElement().afterLeaf(psiElement(INTCONSTANT).afterLeaf(psiElement(PP_VERSION))) 37 | 38 | private val insideIteration = psiElement() 39 | .inside(psiElement(GlslCompoundStatementNoNewScope::class.java).withParent(GlslIterationStatement::class.java)) 40 | .andNot(psiElement().afterLeaf(numeric)) 41 | .andNot(afterDot) 42 | 43 | private val insideTypeSpecifier = psiElement(IDENTIFIER) 44 | .withParent(GlslTypeName::class.java) 45 | .andNot(psiElement().afterLeaf(numeric)) 46 | .inside(GlslTypeSpecifier::class.java) 47 | 48 | private val insideExpression = psiElement(IDENTIFIER) 49 | .andNot(psiElement().afterLeaf(numeric)) 50 | .andNot(afterDot) 51 | .inside(GlslExpr::class.java) 52 | 53 | private val statementBeginning = psiElement() 54 | .andNot(psiElement().afterLeaf(numeric)) 55 | .atStartOf(psiElement(GlslStatement::class.java)) 56 | .andNot(afterDot) 57 | .andNot(insidePpStatement) 58 | 59 | private val externalDeclarationBeginning = psiElement(IDENTIFIER) 60 | .andNot(psiElement().afterLeaf(numeric)) 61 | .atStartOf(psiElement(GlslExternalDeclaration::class.java)) 62 | .andNot(afterDot) 63 | .andNot(insidePpStatement) 64 | 65 | private val paramBeginning = psiElement() 66 | .andNot(psiElement().afterLeaf(numeric)) 67 | .inside(psiElement(GlslFuncHeaderWithParams::class.java)) 68 | .afterLeaf("(", ",") 69 | 70 | private val typeQualifiersPattern = or( 71 | statementBeginning, 72 | externalDeclarationBeginning, 73 | paramBeginning 74 | ) 75 | 76 | private val insideInclude = psiElement(STRING_LITERAL) 77 | .inside(GlslPpIncludeDeclaration::class.java) 78 | 79 | init { 80 | extend(CompletionType.BASIC, typeQualifiersPattern, GlslGenericCompletion(*typeQualifiers)) 81 | extend(CompletionType.BASIC, statementBeginning, GlslGenericCompletion(*selectionKeywords, *iterationKeywords, *funcJumpsKeywords)) 82 | extend(CompletionType.BASIC, insideIteration, GlslGenericCompletion(*iterationJumpsKeywords)) 83 | extend(CompletionType.BASIC, afterPpLiteral, GlslPpCompletion()) 84 | extend(CompletionType.BASIC, afterVersion, GlslGenericCompletion(*GlslDefinitions.VERSIONS)) 85 | extend(CompletionType.BASIC, insideInclude, GlslIncludeStatementCompletion()) 86 | // Builtin objects 87 | extend(CompletionType.BASIC, insideTypeSpecifier, GlslBuiltinTypesCompletion()) 88 | extend(CompletionType.BASIC, insideExpression, GlslBuiltinFuncCompletion()) 89 | } 90 | } 91 | 92 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/completion/GlslCompletionProvider.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.completion 2 | 3 | import com.intellij.codeInsight.completion.CompletionParameters 4 | import com.intellij.codeInsight.completion.CompletionProvider 5 | import com.intellij.codeInsight.completion.CompletionResultSet 6 | import com.intellij.codeInsight.completion.InsertHandler 7 | import com.intellij.codeInsight.lookup.LookupElement 8 | import com.intellij.icons.AllIcons 9 | import com.intellij.util.ProcessingContext 10 | import glsl.data.GlslDefinitions 11 | import glsl.data.GlslTokenSets 12 | import glsl.plugin.language.GlslIcon 13 | import glsl.plugin.utils.GlslBuiltinUtils 14 | import glsl.plugin.utils.GlslUtils 15 | import glsl.plugin.utils.GlslUtils.createLookupElement 16 | import glsl.plugin.utils.GlslUtils.createLookupElements 17 | import glsl.plugin.utils.GlslUtils.getVectorInsertHandler 18 | import javax.swing.Icon 19 | 20 | 21 | /** 22 | * 23 | */ 24 | abstract class GlslCompletionProvider : CompletionProvider() 25 | 26 | /** 27 | * 28 | */ 29 | class GlslGenericCompletion(private vararg var keywords: String, private val icon: Icon? = null) : GlslCompletionProvider() { 30 | 31 | /** 32 | * 33 | */ 34 | override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, resultSet: CompletionResultSet) { 35 | resultSet.addAllElements(keywords.map { createLookupElement(it, psiElement = parameters.position, icon = icon) }) 36 | } 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | class GlslPpCompletion : GlslCompletionProvider() { 43 | 44 | private val preprocessors = GlslUtils.getTokenSetAsStrings(GlslTokenSets.PREPROCESSORS) 45 | .map { it.lowercase().replace("pp_", "") } 46 | .toTypedArray() 47 | 48 | private val insertHandler = InsertHandler { context, lookupElement -> 49 | context.document.replaceString(context.startOffset, context.selectionEndOffset, "${lookupElement.lookupString} ") 50 | } 51 | 52 | /** 53 | * 54 | */ 55 | override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, resultSet: CompletionResultSet) { 56 | resultSet.addAllElements(preprocessors.map { 57 | createLookupElement(it.drop(1), insertHandler, psiElement = parameters.position) 58 | }) 59 | } 60 | } 61 | 62 | 63 | /** 64 | * 65 | */ 66 | class GlslBuiltinFuncCompletion : GlslCompletionProvider() { 67 | private val builtinFuncMap = GlslBuiltinUtils.getBuiltinFuncs() 68 | 69 | /** 70 | * 71 | */ 72 | override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, resultSet: CompletionResultSet) { 73 | for ((funcName, funcOverloads) in builtinFuncMap) { 74 | val prefix = resultSet.prefixMatcher.prefix.lowercase() 75 | if (!funcName.lowercase().contains(prefix)) continue 76 | for (funcVariant in funcOverloads) { 77 | resultSet.addElement(GlslUtils.getFunctionLookupElement(funcVariant, GlslIcon.PLUGIN_FILE_ICON)) 78 | } 79 | } 80 | val elements = GlslDefinitions.VEC_MAT_CONSTRUCTORS.map { createLookupElement(it, getVectorInsertHandler(), AllIcons.Nodes.Type) } 81 | resultSet.addAllElements(elements) 82 | } 83 | } 84 | 85 | /** 86 | * 87 | */ 88 | class GlslBuiltinTypesCompletion : GlslCompletionProvider() { 89 | private val tokens = GlslTokenSets.BUILTIN_TYPES.map { it.toString() } 90 | 91 | /** 92 | * 93 | */ 94 | override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, resultSet: CompletionResultSet) { 95 | val builtinTypes = createLookupElements(tokens.toList()) 96 | resultSet.addAllElements(builtinTypes) 97 | } 98 | } 99 | 100 | /** 101 | * 102 | */ 103 | class GlslIncludeStatementCompletion : GlslCompletionProvider() { 104 | private val insertHandler = InsertHandler { context, lookupElement -> 105 | val s = lookupElement.lookupString 106 | context.document.replaceString(context.startOffset, context.selectionEndOffset, s) 107 | context.editor.caretModel.moveToOffset(context.startOffset + s.length) 108 | } 109 | 110 | /** 111 | * 112 | */ 113 | override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, resultSet: CompletionResultSet) { 114 | val virtualFile = parameters.originalFile.virtualFile 115 | val parentDir = virtualFile.parent ?: return 116 | val lookupElements = mutableListOf() 117 | for (siblingFile in parentDir.children) { 118 | val siblingFileName = siblingFile.name 119 | if (siblingFileName == virtualFile.name) continue 120 | if (siblingFile.isDirectory) { 121 | lookupElements.add(createLookupElement("$siblingFileName/", insertHandler)) 122 | } else { 123 | lookupElements.add(createLookupElement(siblingFileName)) 124 | } 125 | } 126 | resultSet.addAllElements(lookupElements) 127 | } 128 | } 129 | 130 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/GlslBraceMatcher.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor 2 | 3 | import com.intellij.codeInsight.highlighting.PairedBraceMatcherAdapter 4 | import com.intellij.lang.BracePair 5 | import com.intellij.lang.PairedBraceMatcher 6 | import com.intellij.psi.PsiFile 7 | import com.intellij.psi.TokenType 8 | import com.intellij.psi.tree.IElementType 9 | import com.intellij.psi.tree.TokenSet 10 | import glsl.GlslTypes 11 | import glsl.plugin.language.GlslLanguage 12 | 13 | /** 14 | * 15 | */ 16 | class GlslBraceMatcher : PairedBraceMatcherAdapter(GlslBraceMatcherBase(), GlslLanguage.INSTANCE) 17 | 18 | /** 19 | * 20 | */ 21 | private class GlslBraceMatcherBase : PairedBraceMatcher { 22 | /** 23 | * 24 | */ 25 | override fun getPairs(): Array { 26 | return arrayOf( 27 | BracePair(GlslTypes.LEFT_BRACE, GlslTypes.RIGHT_BRACE, true), 28 | BracePair(GlslTypes.LEFT_PAREN, GlslTypes.RIGHT_PAREN, false), 29 | BracePair(GlslTypes.LEFT_BRACKET, GlslTypes.RIGHT_BRACKET, false), 30 | ) 31 | } 32 | 33 | /** 34 | * 35 | */ 36 | override fun isPairedBracesAllowedBeforeType(lbraceType: IElementType, contextType: IElementType?): Boolean { 37 | return contextType in TokenSet.orSet( 38 | TokenSet.create(GlslTypes.LINE_COMMENT), 39 | TokenSet.create( 40 | TokenType.WHITE_SPACE, 41 | GlslTypes.SEMICOLON, 42 | GlslTypes.COMMA, 43 | GlslTypes.RIGHT_PAREN, 44 | GlslTypes.RIGHT_BRACKET, 45 | GlslTypes.RIGHT_BRACE, 46 | GlslTypes.LEFT_BRACE 47 | ) 48 | ) 49 | } 50 | 51 | /** 52 | * 53 | */ 54 | override fun getCodeConstructStart(file: PsiFile?, openingBraceOffset: Int): Int { 55 | return openingBraceOffset 56 | } 57 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/GlslCommenter.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor 2 | 3 | import com.intellij.lang.Commenter 4 | 5 | class GlslCommenter : Commenter { 6 | /** 7 | * 8 | */ 9 | override fun getLineCommentPrefix(): String? { 10 | return "//" 11 | } 12 | 13 | /** 14 | * 15 | */ 16 | override fun getBlockCommentPrefix(): String? { 17 | return "/**" 18 | } 19 | 20 | /** 21 | * 22 | */ 23 | override fun getBlockCommentSuffix(): String? { 24 | return "*/" 25 | } 26 | 27 | /** 28 | * 29 | */ 30 | override fun getCommentedBlockCommentPrefix(): String? { 31 | return null 32 | } 33 | 34 | /** 35 | * 36 | */ 37 | override fun getCommentedBlockCommentSuffix(): String? { 38 | return null 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/GlslDocumentationProvider.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor 2 | 3 | import com.intellij.lang.documentation.DocumentationProvider 4 | import com.intellij.openapi.editor.Editor 5 | import com.intellij.psi.PsiElement 6 | import com.intellij.psi.PsiFile 7 | import glsl.plugin.utils.GlslBuiltinUtils.isBuiltinFunction 8 | import glsl.plugin.utils.GlslUtils 9 | import org.jsoup.Jsoup 10 | import org.jsoup.nodes.Document 11 | 12 | /** 13 | * 14 | */ 15 | class GlslDocumentationProvider : DocumentationProvider { 16 | private var document: Document? = null 17 | 18 | init { 19 | val fileText = GlslUtils.getResourceFileAsString("builtin-objects/builtin-funcs-docs.html") 20 | if (fileText != null) { 21 | document = Jsoup.parse(fileText) 22 | } 23 | } 24 | 25 | /** 26 | * 27 | */ 28 | override fun getCustomDocumentationElement( 29 | editor: Editor, 30 | file: PsiFile, 31 | contextElement: PsiElement?, 32 | targetOffset: Int 33 | ): PsiElement? { 34 | if (isBuiltinFunction(contextElement?.text)) { 35 | return contextElement 36 | } 37 | return null 38 | } 39 | 40 | /** 41 | * 42 | */ 43 | override fun generateDoc(element: PsiElement?, originalElement: PsiElement?): String? { 44 | val elementText = element?.text 45 | if (isBuiltinFunction(elementText)) { 46 | return document?.getElementById(elementText!!).toString() 47 | } 48 | return null 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/GlslMultiHostInjector.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor 2 | 3 | import com.intellij.codeInsight.template.TemplateActionContext 4 | import com.intellij.codeInsight.template.TemplateContextType 5 | import com.intellij.lang.injection.MultiHostInjector 6 | import com.intellij.lang.injection.MultiHostRegistrar 7 | import com.intellij.psi.PsiElement 8 | import com.intellij.psi.PsiLanguageInjectionHost 9 | import com.intellij.psi.html.HtmlTag 10 | import com.intellij.psi.util.childrenOfType 11 | import com.intellij.psi.xml.XmlTag 12 | import com.intellij.psi.xml.XmlText 13 | import glsl.plugin.language.GlslFile 14 | import glsl.plugin.language.GlslLanguage 15 | 16 | class GlslTemplateContext : TemplateContextType( "GLSL") { 17 | override fun isInContext(templateActionContext: TemplateActionContext): Boolean { 18 | return templateActionContext.file is GlslFile 19 | } 20 | } 21 | 22 | class GlslMultiHostInjector : MultiHostInjector { 23 | /** 24 | * 25 | */ 26 | override fun getLanguagesToInject(registrar: MultiHostRegistrar, context: PsiElement) { 27 | when (context) { 28 | is HtmlTag -> { 29 | val typeText = context.getAttribute("type")?.value ?: return 30 | if (!typeText.contains("x-shader")) return 31 | val xmlText = context.childrenOfType().firstOrNull() ?: return 32 | val textRangeInParent = xmlText.firstChild.textRangeInParent 33 | registrar.startInjecting(GlslLanguage.INSTANCE) 34 | .addPlace(null, null, xmlText as PsiLanguageInjectionHost, textRangeInParent) 35 | .doneInjecting() 36 | } 37 | } 38 | } 39 | 40 | /** 41 | * 42 | */ 43 | override fun elementsToInjectIn(): MutableList> { 44 | return mutableListOf(XmlTag::class.java) 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/GlslNewShaderFile.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor 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.psi.PsiDirectory 8 | import glsl.plugin.language.GlslIcon 9 | 10 | private const val NEW_SHADER_DIALOG_TEXT = "Shader File" 11 | 12 | class GlslNewShaderFile 13 | : CreateFileFromTemplateAction(NEW_SHADER_DIALOG_TEXT, "", GlslIcon.PLUGIN_FILE_ICON), DumbAware { 14 | 15 | /** 16 | * 17 | */ 18 | override fun buildDialog(project: Project, directory: PsiDirectory, builder: CreateFileFromTemplateDialog.Builder) { 19 | builder.setTitle(NEW_SHADER_DIALOG_TEXT) 20 | .addKind("Shader (.glsl)", GlslIcon.PLUGIN_FILE_ICON, "shader-template") 21 | .addKind("Vertex (.vert)", GlslIcon.PLUGIN_FILE_ICON, "vs-template") 22 | .addKind("Fragment (.frag)", GlslIcon.PLUGIN_FILE_ICON, "fs-template") 23 | .addKind("Geometry (.geom)", GlslIcon.PLUGIN_FILE_ICON, "gs-template") 24 | .addKind("Tessellation-Evaluation (.tese)", GlslIcon.PLUGIN_FILE_ICON, "te-template") 25 | .addKind("Tessellation-Control (.tesc)", GlslIcon.PLUGIN_FILE_ICON, "tc-template") 26 | .addKind("Compute (.comp)", GlslIcon.PLUGIN_FILE_ICON, "cs-template") 27 | } 28 | 29 | /** 30 | * 31 | */ 32 | override fun getActionName(directory: PsiDirectory?, newName: String, templateName: String?): String { 33 | return NEW_SHADER_DIALOG_TEXT 34 | } 35 | 36 | /** 37 | * 38 | */ 39 | override fun hashCode(): Int { 40 | return 0 41 | } 42 | 43 | /** 44 | * 45 | */ 46 | override fun equals(other: Any?): Boolean { 47 | return other is GlslNewShaderFile 48 | } 49 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/GlslQuoteHandler.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor 2 | 3 | import com.intellij.codeInsight.editorActions.SimpleTokenSetQuoteHandler 4 | import com.intellij.psi.TokenType 5 | import glsl.GlslTypes 6 | 7 | class GlslQuoteHandler: SimpleTokenSetQuoteHandler(GlslTypes.STRING_LITERAL, TokenType.BAD_CHARACTER) -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/GlslStructureView.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.ide.projectView.PresentationData 5 | import com.intellij.ide.structureView.* 6 | import com.intellij.ide.util.treeView.smartTree.SortableTreeElement 7 | import com.intellij.ide.util.treeView.smartTree.Sorter 8 | import com.intellij.ide.util.treeView.smartTree.TreeElement 9 | import com.intellij.lang.PsiStructureViewFactory 10 | import com.intellij.navigation.ItemPresentation 11 | import com.intellij.openapi.editor.Editor 12 | import com.intellij.openapi.editor.HighlighterColors 13 | import com.intellij.psi.NavigatablePsiElement 14 | import com.intellij.psi.PsiFile 15 | import com.intellij.psi.util.PsiTreeUtil 16 | import glsl.plugin.language.GlslFile 17 | import glsl.psi.impl.GlslFunctionDefinitionImpl 18 | import glsl.psi.interfaces.GlslExternalDeclaration 19 | import glsl.psi.interfaces.GlslFunctionDefinition 20 | 21 | 22 | class GlslStructureViewFactory : PsiStructureViewFactory { 23 | override fun getStructureViewBuilder(psiFile: PsiFile): StructureViewBuilder { 24 | return object : TreeBasedStructureViewBuilder() { 25 | override fun createStructureViewModel(editor: Editor?): StructureViewModel { 26 | return GlslStructureViewModel(editor, psiFile) 27 | } 28 | } 29 | } 30 | } 31 | 32 | class GlslStructureViewModel(editor: Editor?, psiFile: PsiFile) : 33 | StructureViewModelBase(psiFile, editor, GlslStructureViewElement(psiFile)), StructureViewModel.ElementInfoProvider { 34 | 35 | override fun getSorters(): Array { 36 | return arrayOf(Sorter.ALPHA_SORTER) 37 | } 38 | 39 | override fun getSuitableClasses(): Array> { 40 | return arrayOf(GlslExternalDeclaration::class.java) 41 | } 42 | 43 | override fun isAlwaysShowsPlus(element: StructureViewTreeElement?): Boolean { 44 | return false 45 | } 46 | 47 | override fun isAlwaysLeaf(element: StructureViewTreeElement?): Boolean { 48 | return element?.value is GlslExternalDeclaration 49 | } 50 | } 51 | 52 | 53 | class GlslStructureViewElement(private val element: NavigatablePsiElement) : StructureViewTreeElement, SortableTreeElement { 54 | 55 | override fun getValue(): Any { 56 | return element 57 | } 58 | 59 | override fun getPresentation(): ItemPresentation { 60 | if (element is GlslFunctionDefinition) { 61 | return PresentationData(element.functionDeclarator.text + ")", "", AllIcons.Nodes.Function, HighlighterColors.NO_HIGHLIGHTING) 62 | } else if (element is GlslFile) { 63 | return element.presentation ?: PresentationData() 64 | } 65 | return PresentationData() 66 | } 67 | 68 | override fun getChildren(): Array { 69 | if (element !is GlslFile) return emptyArray() 70 | val externalDeclarations = PsiTreeUtil.getChildrenOfType(element, GlslExternalDeclaration::class.java) ?: return emptyArray() 71 | val funcs = mutableListOf() 72 | for (externalDeclaration in externalDeclarations) { 73 | if (externalDeclaration.functionDefinition == null) continue 74 | funcs.add(GlslStructureViewElement(externalDeclaration.functionDefinition!! as GlslFunctionDefinitionImpl)) 75 | } 76 | return funcs.toTypedArray() 77 | } 78 | 79 | override fun getAlphaSortKey(): String { 80 | return element.name ?: "" 81 | } 82 | 83 | override fun navigate(requestFocus: Boolean) { 84 | element.navigate(requestFocus) 85 | } 86 | 87 | override fun canNavigate(): Boolean { 88 | return element.canNavigate() 89 | } 90 | override fun canNavigateToSource(): Boolean { 91 | return element.canNavigateToSource() 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/formatter/GlslFormattingModelBuilder.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor.formatter 2 | 3 | import com.intellij.formatting.* 4 | import com.intellij.formatting.FormattingModelProvider.createFormattingModelForPsiFile 5 | import com.intellij.psi.codeStyle.CodeStyleSettings 6 | import com.intellij.psi.tree.TokenSet 7 | import glsl.GlslTypes.* 8 | import glsl.data.GlslTokenSets.ADD_OPERATORS 9 | import glsl.data.GlslTokenSets.BITWISE_OPERATORS 10 | import glsl.data.GlslTokenSets.EQUALITY_OPERATORS 11 | import glsl.data.GlslTokenSets.KEYWORDS 12 | import glsl.data.GlslTokenSets.LOGICAL_OPERATORS 13 | import glsl.data.GlslTokenSets.MUL_OPERATORS 14 | import glsl.data.GlslTokenSets.NUMBER_SET 15 | import glsl.data.GlslTokenSets.RELATIONAL_OPERATORS 16 | import glsl.data.GlslTokenSets.SHIFT_OPERATORS 17 | import glsl.data.GlslTokenSets.UNARY_OPERATORS 18 | import glsl.plugin.language.GlslLanguage 19 | 20 | 21 | class GlslFormattingModelBuilder : FormattingModelBuilder { 22 | 23 | 24 | /** 25 | * 26 | */ 27 | override fun createModel(formattingContext: FormattingContext): FormattingModel { 28 | val codeStyleSettings = formattingContext.codeStyleSettings 29 | val glslBlock = GlslBlock( 30 | formattingContext.node, 31 | Wrap.createWrap(WrapType.NONE, false), 32 | null, 33 | createSpaceBuilder(codeStyleSettings), 34 | Indent.getNoneIndent() 35 | ) 36 | return createFormattingModelForPsiFile(formattingContext.containingFile, glslBlock, codeStyleSettings) 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | private fun createSpaceBuilder(settings: CodeStyleSettings): SpacingBuilder { 43 | val commonSettings = settings.getCommonSettings(GlslLanguage.INSTANCE.id) 44 | commonSettings.SPACE_BEFORE_COLON = false 45 | return SpacingBuilder(settings, GlslLanguage.INSTANCE) 46 | .after(SEMICOLON).spaceIf(commonSettings.SPACE_AFTER_SEMICOLON) 47 | .before(SEMICOLON).spaceIf(commonSettings.SPACE_BEFORE_SEMICOLON) 48 | .before(LEFT_BRACKET).none() 49 | .before(ARRAY_SPECIFIER).none() 50 | .after(LEFT_PAREN_MACRO_CALL).none() 51 | .before(RIGHT_PAREN_MACRO).none() 52 | .before(RIGHT_PAREN_MACRO_CALL).none() 53 | .between(PP_VERSION, INTCONSTANT).spaces(1) 54 | .afterInside(LEFT_ANGLE, PP_INCLUDE_DECLARATION).none() 55 | .beforeInside(RIGHT_ANGLE, PP_INCLUDE_DECLARATION).none() 56 | .around(TYPE_QUALIFIER).spaces(1) 57 | .between(RIGHT_PAREN, TYPE_QUALIFIER).spaces(1) 58 | .between(RIGHT_PAREN, TYPE_QUALIFIER).spaces(1) 59 | .between(TYPE_QUALIFIER, TYPE_SPECIFIER).spaces(1) 60 | .between(TYPE_SPECIFIER, STRUCT_DECLARATOR).spaces(1) 61 | .between(TYPE_SPECIFIER, VARIABLE_IDENTIFIER).spaces(1) 62 | .between(BLOCK_STRUCTURE, VARIABLE_IDENTIFIER).spaces(1) 63 | .between(STRUCT_SPECIFIER, VARIABLE_IDENTIFIER).spaces(1) 64 | .after(COMMA).spaceIf(commonSettings.SPACE_AFTER_COMMA) 65 | .before(COMMA).spaceIf(commonSettings.SPACE_BEFORE_COMMA) 66 | .aroundInside(TokenSet.create(QUESTION, COLON), CONDITIONAL_EXPR).spaces(1) 67 | .after(COLON).spaceIf(commonSettings.SPACE_AFTER_COLON) 68 | .before(COLON).spaceIf(commonSettings.SPACE_BEFORE_COLON) 69 | .after(QUESTION).spaceIf(commonSettings.SPACE_AFTER_QUEST) 70 | .before(QUESTION).spaceIf(commonSettings.SPACE_BEFORE_QUEST) 71 | .between(LAYOUT, LEFT_PAREN).spaces(1) 72 | .between(TYPE_SPECIFIER, LEFT_PAREN).none() 73 | .between(RIGHT_PAREN, LEFT_BRACE).spaces(1) 74 | .between(RIGHT_PAREN, COMPOUND_STATEMENT).spaces(1) 75 | .between(RIGHT_PAREN, COMPOUND_STATEMENT_NO_NEW_SCOPE).spaces(1) 76 | .between(FUNCTION_DECLARATOR, COMPOUND_STATEMENT_NO_NEW_SCOPE).spaces(1) 77 | .between(VARIABLE_IDENTIFIER, LEFT_PAREN).none() 78 | .withinPair(LEFT_PAREN, RIGHT_PAREN).spaceIf(commonSettings.SPACE_WITHIN_PARENTHESES) 79 | .withinPair(LEFT_BRACKET, RIGHT_BRACKET).spaceIf(commonSettings.SPACE_WITHIN_BRACKETS) 80 | .withinPairInside(LEFT_BRACE, RIGHT_BRACE, SINGLE_DECLARATION).spaces(1) 81 | .between(TYPE_NAME, LEFT_BRACE).spaces(1) 82 | .between(VARIABLE_IDENTIFIER, FUNC_HEADER_WITH_PARAMS).none() 83 | .betweenInside(TokenSet.create(DASH), NUMBER_SET, ADD_EXPR).spaces(1) 84 | .between(DASH, PRIMARY_EXPR).none() 85 | .between(DASH, FUNCTION_CALL).none() 86 | .between(DASH, POSTFIX_INC).none() 87 | .between(DASH, POSTFIX_ARRAY_INDEX).none() 88 | .between(DASH, POSTFIX_FIELD_SELECTION).none() 89 | .around(KEYWORDS).spaces(1) 90 | .between(KEYWORDS, SEMICOLON).none() 91 | .around(EQUAL).spaces(1) 92 | .around(ASSIGNMENT_OPERATOR).spaceIf(commonSettings.SPACE_AROUND_ASSIGNMENT_OPERATORS) 93 | .around(UNARY_OPERATORS).spaceIf(commonSettings.SPACE_AROUND_UNARY_OPERATOR) 94 | .around(ADD_OPERATORS).spaceIf(commonSettings.SPACE_AROUND_ADDITIVE_OPERATORS) 95 | .around(MUL_OPERATORS).spaceIf(commonSettings.SPACE_AROUND_MULTIPLICATIVE_OPERATORS) 96 | .around(EQUALITY_OPERATORS).spaceIf(commonSettings.SPACE_AROUND_EQUALITY_OPERATORS) 97 | .around(RELATIONAL_OPERATORS).spaceIf(commonSettings.SPACE_AROUND_RELATIONAL_OPERATORS) 98 | .around(LOGICAL_OPERATORS).spaceIf(commonSettings.SPACE_AROUND_LOGICAL_OPERATORS) 99 | .around(BITWISE_OPERATORS).spaceIf(commonSettings.SPACE_AROUND_BITWISE_OPERATORS) 100 | .around(SHIFT_OPERATORS).spaceIf(commonSettings.SPACE_AROUND_SHIFT_OPERATORS) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/highlighting/GlslColorSettings.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor.highlighting 2 | 3 | import com.intellij.openapi.editor.colors.TextAttributesKey 4 | import com.intellij.openapi.fileTypes.SyntaxHighlighter 5 | import com.intellij.openapi.options.colors.AttributesDescriptor 6 | import com.intellij.openapi.options.colors.ColorDescriptor 7 | import com.intellij.openapi.options.colors.ColorSettingsPage 8 | import glsl.plugin.language.GlslIcon 9 | import glsl.plugin.utils.GlslUtils 10 | import javax.swing.Icon 11 | 12 | private val DESCRIPTORS = arrayOf( 13 | AttributesDescriptor("Comment // Multi-line", GlslTextAttributes.MULTILINE_COMMENT_TEXT_ATTR), 14 | AttributesDescriptor("Comment // One-line", GlslTextAttributes.LINE_COMMENT_TEXT_ATTR), 15 | AttributesDescriptor("Identifier // User defined identifier", GlslTextAttributes.VARIABLE_TEXT_ATTR), 16 | AttributesDescriptor("Identifier // Builtin identifier", GlslTextAttributes.BUILTIN_NAME_TEXT_ATTR), 17 | AttributesDescriptor("Identifier // Builtin global constant", GlslTextAttributes.BUILTIN_GLOBAL_CONSTANTS), 18 | AttributesDescriptor("String", GlslTextAttributes.STRING_TEXT_ATTR), 19 | AttributesDescriptor("Number", GlslTextAttributes.NUMBERS_TEXT_ATTR), 20 | AttributesDescriptor("Keyword", GlslTextAttributes.KEYWORD_TEXT_ATTR), 21 | AttributesDescriptor("User-defined type", GlslTextAttributes.USER_DEFINED_TYPE_TEXT_ATTR), 22 | AttributesDescriptor("Function // Function call and declaration", GlslTextAttributes.FUNC_TEXT_ATTR), 23 | AttributesDescriptor("Function // Function parameter", GlslTextAttributes.FUNC_PARAM_TEXT_ATTR), 24 | AttributesDescriptor("Builtin type", GlslTextAttributes.BUILTIN_TYPE_TEXT_ATTR), 25 | AttributesDescriptor("Preprocessor directive", GlslTextAttributes.PREPROCESSOR_TEXT_ATTR), 26 | AttributesDescriptor("Macro // Object name", GlslTextAttributes.MACRO_OBJECT_NAME_ATTR), 27 | AttributesDescriptor("Macro // Function name", GlslTextAttributes.MACRO_FUNC_NAME_ATTR), 28 | AttributesDescriptor("Operators", GlslTextAttributes.OPERATORS_TEXT_ATTR), 29 | AttributesDescriptor("Bad character", GlslTextAttributes.BAD_CHARACTER_TEXT_ATTR), 30 | ) 31 | 32 | private val ADDITIONAL_DESCRIPTORS = mutableMapOf( 33 | "fn" to GlslTextAttributes.FUNC_TEXT_ATTR, 34 | "fp" to GlslTextAttributes.FUNC_PARAM_TEXT_ATTR, 35 | "bi" to GlslTextAttributes.BUILTIN_NAME_TEXT_ATTR, 36 | "gc" to GlslTextAttributes.BUILTIN_GLOBAL_CONSTANTS, 37 | "v" to GlslTextAttributes.VARIABLE_TEXT_ATTR, 38 | "si" to GlslTextAttributes.STRUCT_TYPE_TEXT_ATTR, 39 | "udt" to GlslTextAttributes.USER_DEFINED_TYPE_TEXT_ATTR, 40 | "pp" to GlslTextAttributes.PREPROCESSOR_TEXT_ATTR, 41 | "mo" to GlslTextAttributes.MACRO_OBJECT_NAME_ATTR, 42 | "mf" to GlslTextAttributes.MACRO_FUNC_NAME_ATTR, 43 | ) 44 | 45 | 46 | /** 47 | * 48 | */ 49 | class GlslColorSettings : ColorSettingsPage { 50 | 51 | /** 52 | * 53 | */ 54 | override fun getAttributeDescriptors(): Array { 55 | return DESCRIPTORS 56 | } 57 | 58 | /** 59 | * 60 | */ 61 | override fun getColorDescriptors(): Array { 62 | return ColorDescriptor.EMPTY_ARRAY 63 | } 64 | 65 | /** 66 | * 67 | */ 68 | override fun getDisplayName(): String { 69 | return "GLSL" 70 | } 71 | 72 | /** 73 | * 74 | */ 75 | override fun getIcon(): Icon { 76 | return GlslIcon.PLUGIN_FILE_ICON 77 | } 78 | 79 | /** 80 | * 81 | */ 82 | override fun getHighlighter(): SyntaxHighlighter { 83 | return GlslSyntaxHighlighter() 84 | } 85 | 86 | /** 87 | * 88 | */ 89 | override fun getDemoText(): String { 90 | return GlslUtils.getResourceFileAsString("colors/color-demo-text.txt") ?: "" 91 | } 92 | /** 93 | * 94 | */ 95 | override fun getAdditionalHighlightingTagToDescriptorMap(): MutableMap { 96 | return ADDITIONAL_DESCRIPTORS 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/highlighting/GlslHighlightingAnnotator.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor.highlighting 2 | 3 | import com.intellij.lang.annotation.AnnotationHolder 4 | import com.intellij.lang.annotation.Annotator 5 | import com.intellij.lang.annotation.HighlightSeverity 6 | import com.intellij.openapi.editor.colors.TextAttributesKey 7 | import com.intellij.psi.PsiElement 8 | import glsl.plugin.psi.GlslIdentifier 9 | import glsl.plugin.psi.named.GlslNamedElement 10 | import glsl.plugin.psi.named.types.builtins.GlslBuiltinType 11 | import glsl.plugin.utils.GlslBuiltinUtils.isBuiltinConstant 12 | import glsl.plugin.utils.GlslBuiltinUtils.isBuiltinFunction 13 | import glsl.plugin.utils.GlslBuiltinUtils.isBuiltinShaderVariable 14 | import glsl.psi.interfaces.GlslLayoutQualifierId 15 | 16 | 17 | /** 18 | * 19 | */ 20 | class GlslHighlightingAnnotator : Annotator { 21 | 22 | /** 23 | * 24 | */ 25 | override fun annotate(element: PsiElement, holder: AnnotationHolder) { 26 | if (element !is GlslIdentifier || element is GlslBuiltinType) return 27 | val extension = holder.currentAnnotationSession.file.virtualFile.extension 28 | val elementName = element.getName() 29 | if (isBuiltinFunction(elementName) || isBuiltinShaderVariable(elementName, extension)) { 30 | createAnnotation(holder, GlslTextAttributes.BUILTIN_NAME_TEXT_ATTR) 31 | } else if (isBuiltinConstant(elementName)) { 32 | createAnnotation(holder, GlslTextAttributes.BUILTIN_GLOBAL_CONSTANTS) 33 | } else { 34 | val reference = element.resolveReference() 35 | if (reference != null) { 36 | setReferenceHighlighting(reference, holder) 37 | } else { 38 | setDeclarationHighlighting(element, holder) 39 | } 40 | } 41 | 42 | } 43 | 44 | /** 45 | * 46 | */ 47 | private fun setReferenceHighlighting(element: GlslNamedElement, holder: AnnotationHolder) { 48 | val textAttr = element.getHighlightTextAttr() 49 | holder.newSilentAnnotation(HighlightSeverity.INFORMATION) 50 | .textAttributes(textAttr) 51 | .create() 52 | } 53 | 54 | /** 55 | * 56 | */ 57 | private fun setDeclarationHighlighting(element: GlslIdentifier, holder: AnnotationHolder) { 58 | if (element.parent is GlslLayoutQualifierId) { 59 | createAnnotation(holder, GlslTextAttributes.VARIABLE_TEXT_ATTR) 60 | return 61 | } 62 | val declaration = element.getDeclaration() ?: return 63 | createAnnotation(holder, declaration.getHighlightTextAttr()) 64 | } 65 | 66 | /** 67 | * 68 | */ 69 | private fun createAnnotation(holder: AnnotationHolder, textAttr: TextAttributesKey?) { 70 | if (textAttr == null) return 71 | holder.newSilentAnnotation(HighlightSeverity.INFORMATION) 72 | .textAttributes(textAttr) 73 | .create() 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/highlighting/GlslSyntaxHighlighter.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor.highlighting 2 | 3 | import com.intellij.lexer.FlexAdapter 4 | import com.intellij.lexer.Lexer 5 | import com.intellij.openapi.editor.DefaultLanguageHighlighterColors.* 6 | import com.intellij.openapi.editor.HighlighterColors 7 | import com.intellij.openapi.editor.colors.TextAttributesKey 8 | import com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey 9 | import com.intellij.openapi.fileTypes.SyntaxHighlighter 10 | import com.intellij.openapi.fileTypes.SyntaxHighlighterBase 11 | import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory 12 | import com.intellij.openapi.project.Project 13 | import com.intellij.openapi.vfs.VirtualFile 14 | import com.intellij.psi.TokenType 15 | import com.intellij.psi.tree.IElementType 16 | import glsl.GlslTypes 17 | import glsl._GlslHighlightLexer 18 | import glsl.data.GlslTokenSets 19 | import glsl.plugin.editor.highlighting.GlslTextAttributes.BAD_CHARACTER_TEXT_ATTR 20 | import glsl.plugin.editor.highlighting.GlslTextAttributes.BOOLEAN_TEXT_ATTR 21 | import glsl.plugin.editor.highlighting.GlslTextAttributes.BUILTIN_TYPE_TEXT_ATTR 22 | import glsl.plugin.editor.highlighting.GlslTextAttributes.FUNC_PARAM_TEXT_ATTR 23 | import glsl.plugin.editor.highlighting.GlslTextAttributes.KEYWORD_TEXT_ATTR 24 | import glsl.plugin.editor.highlighting.GlslTextAttributes.LINE_COMMENT_TEXT_ATTR 25 | import glsl.plugin.editor.highlighting.GlslTextAttributes.MACRO_FUNC_NAME_ATTR 26 | import glsl.plugin.editor.highlighting.GlslTextAttributes.MACRO_OBJECT_NAME_ATTR 27 | import glsl.plugin.editor.highlighting.GlslTextAttributes.MULTILINE_COMMENT_TEXT_ATTR 28 | import glsl.plugin.editor.highlighting.GlslTextAttributes.NUMBERS_TEXT_ATTR 29 | import glsl.plugin.editor.highlighting.GlslTextAttributes.OPERATORS_TEXT_ATTR 30 | import glsl.plugin.editor.highlighting.GlslTextAttributes.PREPROCESSOR_TEXT_ATTR 31 | import glsl.plugin.editor.highlighting.GlslTextAttributes.STRING_TEXT_ATTR 32 | 33 | /** 34 | * 35 | */ 36 | class GlslSyntaxHighlighter : SyntaxHighlighterBase() { 37 | 38 | /** 39 | * 40 | */ 41 | override fun getHighlightingLexer(): Lexer { 42 | return FlexAdapter(_GlslHighlightLexer(null)) 43 | } 44 | 45 | /** 46 | * 47 | */ 48 | override fun getTokenHighlights(tokenType: IElementType): Array { 49 | return pack(mapTokenToTextAttr(tokenType)) 50 | } 51 | 52 | /** 53 | * 54 | */ 55 | private fun mapTokenToTextAttr(tokenType: IElementType): TextAttributesKey? { 56 | return when (tokenType) { 57 | GlslTypes.LINE_COMMENT -> LINE_COMMENT_TEXT_ATTR 58 | GlslTypes.MULTILINE_COMMENT -> MULTILINE_COMMENT_TEXT_ATTR 59 | GlslTypes.STRING_LITERAL -> STRING_TEXT_ATTR 60 | GlslTypes.BOOLCONSTANT -> BOOLEAN_TEXT_ATTR 61 | GlslTypes.MACRO_OBJECT -> MACRO_OBJECT_NAME_ATTR 62 | GlslTypes.MACRO_FUNCTION -> MACRO_FUNC_NAME_ATTR 63 | GlslTypes.MACRO_FUNC_PARAM -> FUNC_PARAM_TEXT_ATTR 64 | in GlslTokenSets.ALL_OPERATORS -> OPERATORS_TEXT_ATTR 65 | in GlslTokenSets.PREPROCESSORS -> PREPROCESSOR_TEXT_ATTR 66 | in GlslTokenSets.NUMBER_SET -> NUMBERS_TEXT_ATTR 67 | in GlslTokenSets.KEYWORDS -> KEYWORD_TEXT_ATTR 68 | in GlslTokenSets.BUILTIN_TYPES -> BUILTIN_TYPE_TEXT_ATTR 69 | TokenType.BAD_CHARACTER -> BAD_CHARACTER_TEXT_ATTR 70 | else -> null 71 | } 72 | } 73 | } 74 | 75 | /** 76 | * 77 | */ 78 | object GlslTextAttributes { 79 | val VARIABLE_TEXT_ATTR = createTextAttributesKey("GLSL_VARIABLE", IDENTIFIER) 80 | val USER_DEFINED_TYPE_TEXT_ATTR = createTextAttributesKey("GLSL_USER_DEFINED_TYPE", CLASS_REFERENCE) 81 | val BUILTIN_NAME_TEXT_ATTR = createTextAttributesKey("GLSL_BUILTIN_NAME_TEXT_ATTR", IDENTIFIER) 82 | val BUILTIN_GLOBAL_CONSTANTS = createTextAttributesKey("GLSL_BUILTIN_GLOBAL_CONSTANTS", CONSTANT) 83 | val STRING_TEXT_ATTR = createTextAttributesKey("GLSL_STRING", STRING) 84 | val BOOLEAN_TEXT_ATTR = createTextAttributesKey("GLSL_BOOLEAN", KEYWORD) 85 | val OPERATORS_TEXT_ATTR = createTextAttributesKey("GLSL_OPERATORS", OPERATION_SIGN) 86 | val PREPROCESSOR_TEXT_ATTR = createTextAttributesKey("GLSL_PREPROCESSOR", KEYWORD) 87 | val MACRO_OBJECT_NAME_ATTR = createTextAttributesKey("GLSL_MACRO_OBJECT_NAME", IDENTIFIER) 88 | val MACRO_FUNC_NAME_ATTR = createTextAttributesKey("GLSL_MACRO_FUNC_NAME", FUNCTION_CALL) 89 | val STRUCT_TYPE_TEXT_ATTR = createTextAttributesKey("GLSL_STRUCT_IDENTIFIER", CLASS_REFERENCE) 90 | val NUMBERS_TEXT_ATTR = createTextAttributesKey("GLSL_NUMBER", NUMBER) 91 | val KEYWORD_TEXT_ATTR = createTextAttributesKey("GLSL_KEYWORD", KEYWORD) 92 | val FUNC_TEXT_ATTR = createTextAttributesKey("GLSL_FUNCTION", FUNCTION_CALL) 93 | val FUNC_PARAM_TEXT_ATTR = createTextAttributesKey("GLSL_FUNCTION_PARAM", PARAMETER) 94 | val BUILTIN_TYPE_TEXT_ATTR = createTextAttributesKey("GLSL_BUILTIN_TYPE", CLASS_REFERENCE) 95 | val LINE_COMMENT_TEXT_ATTR = createTextAttributesKey("GLSL_LINE_COMMENT", LINE_COMMENT) 96 | val MULTILINE_COMMENT_TEXT_ATTR = createTextAttributesKey("GLSL_MULTILINE_COMMENT", LINE_COMMENT) 97 | val BAD_CHARACTER_TEXT_ATTR = createTextAttributesKey("GLSL_BAD_CHARACTER", HighlighterColors.BAD_CHARACTER) 98 | } 99 | 100 | /** 101 | * 102 | */ 103 | class GlslSyntaxHighlightingFactory : SyntaxHighlighterFactory() { 104 | /** 105 | * 106 | */ 107 | override fun getSyntaxHighlighter(project: Project?, virtualFile: VirtualFile?): SyntaxHighlighter { 108 | return GlslSyntaxHighlighter() 109 | } 110 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/style/GlslCodeStyleProvider.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor.style 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.psi.codeStyle.CodeStyleConfigurable 7 | import com.intellij.psi.codeStyle.CodeStyleSettings 8 | import com.intellij.psi.codeStyle.CodeStyleSettingsProvider 9 | import com.intellij.psi.codeStyle.CustomCodeStyleSettings 10 | import glsl.plugin.language.GlslLanguage 11 | 12 | /** 13 | * 14 | */ 15 | class GlslCodeStyleProvider : CodeStyleSettingsProvider() { 16 | 17 | /** 18 | * 19 | */ 20 | override fun getConfigurableDisplayName(): String { 21 | return "GLSL" 22 | } 23 | 24 | /** 25 | * 26 | */ 27 | override fun createConfigurable(settings: CodeStyleSettings, modelSettings: CodeStyleSettings): CodeStyleConfigurable { 28 | return GlslCodeStyleConfigurable(settings, modelSettings, configurableDisplayName) 29 | } 30 | 31 | /** 32 | * 33 | */ 34 | override fun createCustomSettings(settings: CodeStyleSettings): CustomCodeStyleSettings { 35 | return GlslCodeStyleSettings(settings) 36 | } 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | class GlslCodeStyleConfigurable(settings: CodeStyleSettings, modelSettings: CodeStyleSettings, displayName: String) 43 | : CodeStyleAbstractConfigurable(settings, modelSettings, displayName) { 44 | 45 | /** 46 | * 47 | */ 48 | override fun createPanel(settings: CodeStyleSettings): CodeStyleAbstractPanel { 49 | return GlslCodeStylePanel(currentSettings, settings) 50 | } 51 | 52 | /** 53 | * 54 | */ 55 | inner class GlslCodeStylePanel(currentSettings: CodeStyleSettings, settings: CodeStyleSettings) : TabbedLanguageCodeStylePanel(GlslLanguage.INSTANCE, currentSettings, settings) 56 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/editor/style/GlslCodeStyleSettings.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.editor.style 2 | 3 | import com.intellij.application.options.IndentOptionsEditor 4 | import com.intellij.application.options.SmartIndentOptionsEditor 5 | import com.intellij.lang.Language 6 | import com.intellij.psi.codeStyle.CodeStyleSettings 7 | import com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable 8 | import com.intellij.psi.codeStyle.CustomCodeStyleSettings 9 | import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider 10 | import glsl.plugin.language.GlslLanguage 11 | import glsl.plugin.utils.GlslUtils 12 | 13 | class GlslCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvider() { 14 | /** 15 | * 16 | */ 17 | override fun getLanguage(): Language { 18 | return GlslLanguage.INSTANCE 19 | } 20 | 21 | /** 22 | * 23 | */ 24 | override fun getCodeSample(settingsType: SettingsType): String? { 25 | return GlslUtils.getResourceFileAsString("formatter/sample-code.txt") 26 | } 27 | 28 | /** 29 | * 30 | */ 31 | override fun getIndentOptionsEditor(): IndentOptionsEditor { 32 | return SmartIndentOptionsEditor() 33 | } 34 | 35 | /** 36 | * 37 | */ 38 | override fun customizeSettings(consumer: CodeStyleSettingsCustomizable, settingsType: SettingsType) { 39 | consumer.showStandardOptions( 40 | "SPACE_BEFORE_SEMICOLON", 41 | "SPACE_BEFORE_SEMICOLON", 42 | "SPACE_AFTER_SEMICOLON", 43 | "SPACE_BEFORE_QUEST", 44 | "SPACE_AFTER_QUEST", 45 | "SPACE_BEFORE_COLON", 46 | "SPACE_AFTER_COLON", 47 | "SPACE_BEFORE_COMMA", 48 | "SPACE_AFTER_COMMA", 49 | "SPACE_AROUND_ASSIGNMENT_OPERATORS", 50 | "SPACE_AROUND_ADDITIVE_OPERATORS", 51 | "SPACE_AROUND_MULTIPLICATIVE_OPERATORS", 52 | "SPACE_AROUND_EQUALITY_OPERATORS", 53 | "SPACE_AROUND_RELATIONAL_OPERATORS", 54 | "SPACE_AROUND_LOGICAL_OPERATORS", 55 | "SPACE_AROUND_BITWISE_OPERATORS", 56 | "SPACE_AROUND_SHIFT_OPERATORS", 57 | "SPACE_WITHIN_PARENTHESES", 58 | "SPACE_WITHIN_BRACKETS", 59 | ) 60 | 61 | consumer.renameStandardOption("SPACE_WITHIN_PARENTHESES", "Parentheses") 62 | } 63 | } 64 | 65 | /** 66 | * 67 | */ 68 | class GlslCodeStyleSettings(settings: CodeStyleSettings) : CustomCodeStyleSettings("GlslCodeStyleSetting", settings) -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/inspections/GlslErrorMessages.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.inspections 2 | 3 | data class GlslError( 4 | val errorCode: GlslErrorCode, 5 | val formattedMessage: String 6 | ) 7 | 8 | enum class GlslErrorCode(val message: String) { 9 | INCOMPATIBLE_TYPES_IN_INIT("Incompatible types in initialization (and no available implicit conversion)."), 10 | MISSING_RETURN_FUNCTION("Missing return for function '%s'."), 11 | NO_MATCHING_FUNCTION_CALL("No matching function for call to %s(%s)."), 12 | DOES_NOT_OPERATE_ON("'%s' does not operate on '%s' and '%s'."), 13 | TOO_FEW_ARGUMENTS_CONSTRUCTOR("Too few arguments to constructor of '%s'."), 14 | TOO_MANY_ARGUMENTS_CONSTRUCTOR("Too many arguments to constructor of '%s'."), 15 | PRIMITIVE_CONSTRUCTOR_ZERO_ARGUMENTS("Constructor of primitive type must have at least one argument."), 16 | REDECLARED_IDENTIFIER("Regular non-array variable '%s' may not be redeclared."), 17 | MAIN_MUST_RETURN_VOID("main() must return void."), 18 | INCOMPATIBLE_TYPES_IN_ASSIGNMENT("Incompatible types (%s and %s) in assignment (and no available implicit conversion)."), 19 | CANT_ACCESS_ARRAY_OF_TYPE("Can't access array element of type '%s'."), 20 | TYPES_CONDITIONAL_EXPR_NO_MATCH("Types '%s' and '%s' in conditional operator do not match (and no applicable implicit type conversion)."), 21 | CONDITION_MUST_BE_BOOL("Condition must be of type bool."), 22 | INVALID_TYPES_ARGUMENT_CONSTRUCTOR("Invalid type '%s' as argument %s of constructor of '%s'."), 23 | CANT_ACCESS_ARRAY_ELEMENT("Can't access array element of type '%s'."), 24 | INVALID_CALL_OF("Invalid call of '%s' (not a function or subroutine uniform)."), 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/inspections/GlslInspection.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.inspections 2 | 3 | import com.intellij.codeInspection.LocalInspectionTool 4 | 5 | /** 6 | * 7 | */ 8 | abstract class GlslInspection: LocalInspectionTool() { 9 | abstract val errorMessageCode: GlslErrorCode? 10 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/inspections/GlslInspectionConstructorNoArguments.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.inspections 2 | 3 | import com.intellij.codeInspection.ProblemHighlightType.GENERIC_ERROR 4 | import com.intellij.codeInspection.ProblemsHolder 5 | import com.intellij.psi.PsiElementVisitor 6 | import glsl.plugin.utils.GlslUtils.getType 7 | import glsl.psi.interfaces.GlslConstructorCall 8 | import glsl.psi.interfaces.GlslVisitor 9 | 10 | /** 11 | * 12 | */ 13 | class GlslInspectionConstructorNoArguments : GlslInspection() { 14 | override val errorMessageCode = GlslErrorCode.PRIMITIVE_CONSTRUCTOR_ZERO_ARGUMENTS 15 | 16 | /** 17 | * 18 | */ 19 | override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { 20 | return object : GlslVisitor() { 21 | override fun visitConstructorCall(constructorCall: GlslConstructorCall) { 22 | val type = getType(constructorCall.typeSpecifier) ?: return 23 | val args = constructorCall.exprNoAssignmentList 24 | if (type.isPrimitive && args.isEmpty()) { 25 | holder.registerProblem(constructorCall, errorMessageCode.message, GENERIC_ERROR) 26 | } 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/inspections/GlslInspectionCyclicImports.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.inspections 2 | 3 | import com.intellij.codeInspection.ProblemsHolder 4 | import com.intellij.psi.PsiElementVisitor 5 | import glsl.psi.interfaces.GlslPpIncludeDeclaration 6 | import glsl.psi.interfaces.GlslVisitor 7 | 8 | /** 9 | * 10 | */ 11 | class GlslInspectionCyclicImports : GlslInspection() { 12 | override val errorMessageCode = GlslErrorCode.PRIMITIVE_CONSTRUCTOR_ZERO_ARGUMENTS 13 | 14 | /** 15 | * 16 | */ 17 | override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { 18 | return object : GlslVisitor() { 19 | override fun visitPpIncludeDeclaration(o: GlslPpIncludeDeclaration) { 20 | super.visitPpIncludeDeclaration(o) 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/inspections/GlslInspectionIncompatibleType.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.inspections 2 | 3 | import com.intellij.codeInspection.ProblemHighlightType.GENERIC_ERROR 4 | import com.intellij.codeInspection.ProblemsHolder 5 | import com.intellij.psi.PsiElementVisitor 6 | import glsl.psi.interfaces.GlslDeclaration 7 | import glsl.psi.interfaces.GlslSingleDeclaration 8 | import glsl.psi.interfaces.GlslVisitor 9 | 10 | /** 11 | * 12 | */ 13 | class GlslInspectionIncompatibleType : GlslInspection() { 14 | override val errorMessageCode = GlslErrorCode.INCOMPATIBLE_TYPES_IN_INIT 15 | 16 | /** 17 | * 18 | */ 19 | override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { 20 | return object : GlslVisitor() { 21 | override fun visitSingleDeclaration(singleDeclaration: GlslSingleDeclaration) { 22 | var expr = singleDeclaration.exprNoAssignmentList.firstOrNull() 23 | if (expr == null) { 24 | expr = (singleDeclaration.parent as GlslDeclaration).exprNoAssignmentList.firstOrNull() ?: return 25 | } 26 | val declarationType = singleDeclaration.getAssociatedType() ?: return 27 | val exprType = expr.getExprType() ?: return 28 | if (declarationType.isEqual(exprType)) return 29 | holder.registerProblem(expr, GlslErrorCode.INCOMPATIBLE_TYPES_IN_INIT.message, GENERIC_ERROR) 30 | } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/inspections/GlslInspectionMissingReturn.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.inspections 2 | 3 | import com.intellij.codeInspection.ProblemHighlightType 4 | import com.intellij.codeInspection.ProblemsHolder 5 | import com.intellij.openapi.util.TextRange 6 | import com.intellij.psi.PsiElementVisitor 7 | import com.intellij.psi.util.PsiTreeUtil 8 | import com.intellij.psi.util.elementType 9 | import glsl.GlslTypes 10 | import glsl.psi.interfaces.GlslFunctionDefinition 11 | import glsl.psi.interfaces.GlslVisitor 12 | 13 | /** 14 | * 15 | */ 16 | class GlslInspectionMissingReturn : GlslInspection() { 17 | override val errorMessageCode = GlslErrorCode.MISSING_RETURN_FUNCTION 18 | 19 | /** 20 | * 21 | */ 22 | override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { 23 | return object: GlslVisitor() { 24 | override fun visitFunctionDefinition(functionDefinition: GlslFunctionDefinition) { 25 | val functionDeclarator = functionDefinition.functionDeclarator 26 | if (functionDeclarator.typeSpecifier.textMatches("void")) return 27 | val returnExists = PsiTreeUtil 28 | .collectElements(functionDefinition) { e -> e.elementType == GlslTypes.RETURN } 29 | .isNotEmpty() 30 | if (returnExists) return 31 | val endOffset = functionDefinition.textRangeInParent.endOffset 32 | val textRange = TextRange(endOffset - 1, endOffset) 33 | val funcName = functionDeclarator.name 34 | val msg = errorMessageCode.message.format(funcName) 35 | holder.registerProblem(functionDefinition, msg, ProblemHighlightType.GENERIC_ERROR, textRange) 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/inspections/GlslInspectionNoMatchingFunction.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.inspections 2 | 3 | //import com.intellij.codeInspection.ProblemHighlightType 4 | //import com.intellij.codeInspection.ProblemsHolder 5 | //import com.intellij.psi.PsiElementVisitor 6 | //import glsl.psi.impl.GlslFunctionDeclaratorImpl 7 | //import glsl.psi.interfaces.GlslFunctionCall 8 | //import glsl.psi.interfaces.GlslVisitor 9 | // 10 | ///** 11 | // * 12 | // */ 13 | //class GlslInspectionNoMatchingFunction : GlslInspection() { 14 | // override val errorMessageCode = GlslErrorCode.NO_MATCHING_FUNCTION_CALL 15 | // 16 | // /** 17 | // * 18 | // */ 19 | // override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { 20 | // return object : GlslVisitor() { 21 | // override fun visitFunctionCall(functionCall: GlslFunctionCall) { 22 | // val funcIdentifier = functionCall.variableIdentifier ?: return 23 | // val functionDeclarator = funcIdentifier.resolveReference() as? GlslFunctionDeclaratorImpl ?: return 24 | // val exprTypes = functionCall.exprNoAssignmentList.map { it.getExprType() } 25 | // val actualTypesString = exprTypes.mapNotNull { it?.name }.joinToString(", ") 26 | // val msg = errorMessageCode.message.format(funcIdentifier.getName(), actualTypesString) 27 | // holder.registerProblem(functionCall, msg, ProblemHighlightType.GENERIC_ERROR) 28 | // } 29 | // } 30 | // } 31 | //} -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/inspections/GlslInspectionOperatorDoesNotOperate.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.inspections 2 | 3 | import com.intellij.codeInspection.ProblemHighlightType 4 | import com.intellij.codeInspection.ProblemsHolder 5 | import com.intellij.psi.PsiElementVisitor 6 | import glsl.psi.interfaces.GlslSingleDeclaration 7 | import glsl.psi.interfaces.GlslVisitor 8 | 9 | 10 | /** 11 | * 12 | */ 13 | class GlslInspectionOperatorDoesNotOperate : GlslInspection() { 14 | override val errorMessageCode = GlslErrorCode.DOES_NOT_OPERATE_ON 15 | 16 | /** 17 | * 18 | */ 19 | override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { 20 | return object : GlslVisitor() { 21 | override fun visitSingleDeclaration(singleDeclaration: GlslSingleDeclaration) { 22 | val expr = singleDeclaration.exprNoAssignmentList.firstOrNull() ?: return 23 | val exprType = expr.getExprType() 24 | val error = exprType?.glslError ?: return 25 | if (error.errorCode != errorMessageCode) return 26 | holder.registerProblem(expr, error.formattedMessage, ProblemHighlightType.GENERIC_ERROR) 27 | } 28 | } 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/inspections/GlslInspectionTooFewArguments.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.inspections 2 | 3 | import com.intellij.codeInspection.ProblemHighlightType.GENERIC_ERROR 4 | import com.intellij.codeInspection.ProblemsHolder 5 | import com.intellij.openapi.util.TextRange 6 | import com.intellij.psi.PsiElementVisitor 7 | import glsl.plugin.utils.GlslUtils.getType 8 | import glsl.psi.interfaces.GlslConstructorCall 9 | import glsl.psi.interfaces.GlslVisitor 10 | 11 | /** 12 | * 13 | */ 14 | class GlslInspectionTooFewArguments : GlslInspection() { 15 | override val errorMessageCode = GlslErrorCode.TOO_FEW_ARGUMENTS_CONSTRUCTOR 16 | 17 | /** 18 | * 19 | */ 20 | override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { 21 | return object : GlslVisitor() { 22 | override fun visitConstructorCall(constructorCall: GlslConstructorCall) { 23 | val constructorType = getType(constructorCall.typeSpecifier) ?: return 24 | if (constructorType.isPrimitive) return 25 | val actualParamsCount = constructorCall.exprNoAssignmentList.size 26 | val expectedParamCount = constructorType.getStructMembers().size 27 | if (expectedParamCount <= actualParamsCount) return 28 | val msg = errorMessageCode.message.format(constructorType.name) 29 | val startOffset = constructorCall.leftParen.textRangeInParent.startOffset 30 | val endOffset = constructorCall.rightParen.textRangeInParent.endOffset 31 | holder.registerProblem(constructorCall, msg, GENERIC_ERROR, TextRange(startOffset, endOffset)) 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/inspections/GlslInspectionTooManyArguments.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.inspections 2 | 3 | import com.intellij.codeInspection.ProblemHighlightType.GENERIC_ERROR 4 | import com.intellij.codeInspection.ProblemsHolder 5 | import com.intellij.openapi.util.TextRange 6 | import com.intellij.psi.PsiElementVisitor 7 | import glsl.plugin.utils.GlslUtils.getType 8 | import glsl.psi.interfaces.GlslConstructorCall 9 | import glsl.psi.interfaces.GlslVisitor 10 | 11 | /** 12 | * 13 | */ 14 | class GlslInspectionTooManyArguments : GlslInspection() { 15 | override val errorMessageCode = GlslErrorCode.TOO_MANY_ARGUMENTS_CONSTRUCTOR 16 | 17 | /** 18 | * 19 | */ 20 | override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { 21 | return object : GlslVisitor() { 22 | override fun visitConstructorCall(constructorCall: GlslConstructorCall) { 23 | val constructorType = getType(constructorCall.typeSpecifier) ?: return 24 | if (constructorType.isPrimitive) return 25 | val actualParamsCount = constructorCall.exprNoAssignmentList.size 26 | val expectedParamCount = constructorType.getStructMembers().size 27 | if (expectedParamCount >= actualParamsCount) return 28 | val msg = errorMessageCode.message.format(constructorType.name) 29 | val startOffset = constructorCall.leftParen.textRangeInParent.startOffset 30 | val endOffset = constructorCall.rightParen.textRangeInParent.endOffset 31 | holder.registerProblem(constructorCall, msg, GENERIC_ERROR, TextRange(startOffset, endOffset)) 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/language/GlslFile.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.language 2 | 3 | import com.intellij.extapi.psi.PsiFileBase 4 | import com.intellij.openapi.fileTypes.FileType 5 | import com.intellij.openapi.fileTypes.LanguageFileType 6 | import com.intellij.openapi.util.IconLoader 7 | import com.intellij.psi.FileViewProvider 8 | import javax.swing.Icon 9 | 10 | 11 | /** 12 | * 13 | */ 14 | class GlslFile(viewProvider: FileViewProvider) : PsiFileBase(viewProvider, GlslLanguage.INSTANCE) { 15 | /** 16 | * 17 | */ 18 | override fun toString(): String = viewProvider.virtualFile.name 19 | 20 | /** 21 | * 22 | */ 23 | override fun getFileType(): FileType = GlslFileType() 24 | } 25 | 26 | /** 27 | * 28 | */ 29 | object GlslIcon { 30 | val PLUGIN_FILE_ICON = IconLoader.getIcon("icons/file-icon.svg", GlslIcon::class.java) 31 | } 32 | 33 | /** 34 | * 35 | */ 36 | class GlslFileType : LanguageFileType(GlslLanguage.INSTANCE) { 37 | 38 | /** 39 | * 40 | */ 41 | override fun getName(): String = "Glsl File" 42 | 43 | /** 44 | * 45 | */ 46 | override fun getDescription(): String = "OpenGL shading language file" 47 | 48 | /** 49 | * 50 | */ 51 | override fun getDefaultExtension(): String { 52 | return "glsl" 53 | } 54 | 55 | /** 56 | * 57 | */ 58 | override fun getIcon(): Icon = GlslIcon.PLUGIN_FILE_ICON 59 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/language/GlslIFileElementType.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.language 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.lang.impl.PsiBuilderImpl 5 | import com.intellij.psi.PsiElement 6 | import com.intellij.psi.tree.IFileElementType 7 | 8 | /** 9 | * 10 | */ 11 | class GlslIFileElementType : IFileElementType(GlslLanguage.INSTANCE) { 12 | override fun doParseContents(chameleon: ASTNode, psi: PsiElement): ASTNode? { 13 | val project = psi.project 14 | val parserDefinition = GlslParserDefinition() 15 | val builder = PsiBuilderImpl(project, parserDefinition, GlslLexer(project, psi.containingFile.virtualFile), chameleon, chameleon.chars) 16 | val parser = GlslParserAdapter() 17 | val rootNode = parser.parse(this, builder) 18 | return rootNode.firstChildNode 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/language/GlslLanguage.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.language 2 | 3 | import com.intellij.lang.Language 4 | import com.intellij.psi.tree.IElementType 5 | 6 | 7 | /** 8 | * 9 | */ 10 | class GlslLanguage : Language("Glsl") { 11 | companion object { 12 | val INSTANCE = GlslLanguage() 13 | } 14 | } 15 | 16 | /** 17 | * 18 | */ 19 | class GlslTokenType(debugName: String) : IElementType(debugName, GlslLanguage.INSTANCE) 20 | 21 | /** 22 | * 23 | */ 24 | class GlslElementType(debugName: String) : IElementType(debugName, GlslLanguage.INSTANCE) 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/language/GlslParserAdapter.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.language 2 | 3 | import com.intellij.lang.PsiBuilder 4 | import com.intellij.lang.parser.GeneratedParserUtilBase 5 | import com.intellij.lang.parser.GeneratedParserUtilBase.* 6 | import com.intellij.psi.tree.IElementType 7 | import glsl._GlslParser 8 | import glsl.plugin.psi.GlslPsiBuilder 9 | 10 | /** 11 | * 12 | */ 13 | class GlslParserAdapter : _GlslParser() { 14 | 15 | /** 16 | * 17 | */ 18 | override fun parseLight(root: IElementType, originalBuilder: PsiBuilder) { 19 | val state = GeneratedParserUtilBase.ErrorState() 20 | GeneratedParserUtilBase.ErrorState.initState(state, originalBuilder, root, EXTENDS_SETS_) 21 | val builder = GlslPsiBuilder(originalBuilder, state, this) 22 | val marker = enter_section_(builder, 0, _COLLAPSE_, null) 23 | val result = parse_root_(root, builder) 24 | exit_section_(builder, 0, marker, root, result, true, TRUE_CONDITION) 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/language/GlslParserDefinition.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.language 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.psi.FileViewProvider 9 | import com.intellij.psi.PsiElement 10 | import com.intellij.psi.PsiFile 11 | import com.intellij.psi.TokenType 12 | import com.intellij.psi.tree.IFileElementType 13 | import com.intellij.psi.tree.TokenSet 14 | import glsl.GlslTypes 15 | import glsl.data.GlslTokenSets 16 | 17 | /** 18 | * 19 | */ 20 | class GlslParserDefinition : ParserDefinition { 21 | 22 | /** 23 | * 24 | */ 25 | override fun createLexer(project: Project): Lexer { 26 | return GlslLexer(project) 27 | } 28 | 29 | /** 30 | * 31 | */ 32 | override fun createParser(project: Project?): PsiParser { 33 | return GlslParserAdapter() 34 | } 35 | 36 | /** 37 | * 38 | */ 39 | override fun getFileNodeType(): IFileElementType { 40 | return GlslIFileElementType() 41 | } 42 | 43 | /** 44 | * 45 | */ 46 | override fun getWhitespaceTokens(): TokenSet { 47 | return TokenSet.create(TokenType.WHITE_SPACE) 48 | } 49 | 50 | /** 51 | * 52 | */ 53 | override fun getCommentTokens(): TokenSet { 54 | return GlslTokenSets.COMMENTS 55 | } 56 | 57 | /** 58 | * 59 | */ 60 | override fun getStringLiteralElements(): TokenSet { 61 | return TokenSet.create(GlslTypes.STRING_LITERAL) 62 | } 63 | 64 | /** 65 | * 66 | */ 67 | override fun createElement(node: ASTNode?): PsiElement { 68 | return GlslTypes.Factory.createElement(node) 69 | } 70 | 71 | /** 72 | * 73 | */ 74 | override fun createFile(viewProvider: FileViewProvider): PsiFile { 75 | return GlslFile(viewProvider) 76 | } 77 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/GlslExprType.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi 2 | 3 | import com.intellij.extapi.psi.ASTWrapperPsiElement 4 | import com.intellij.lang.ASTFactory.leaf 5 | import com.intellij.lang.ASTNode 6 | import com.intellij.psi.PsiElement 7 | import com.intellij.psi.util.PsiTreeUtil 8 | import glsl.GlslTypes.* 9 | import glsl.plugin.psi.named.GlslNamedType 10 | import glsl.plugin.utils.GlslUtils.createScalarTypeElement 11 | import glsl.plugin.utils.GlslUtils.getType 12 | import glsl.psi.impl.GlslBuiltinTypeScalarImpl 13 | import glsl.psi.interfaces.* 14 | 15 | interface GlslExprType : PsiElement { 16 | fun getExprType(): GlslNamedType? 17 | } 18 | 19 | abstract class GlslExprTypeImpl(node: ASTNode) : ASTWrapperPsiElement(node), GlslExprType { 20 | 21 | /** 22 | * 23 | */ 24 | override fun getExprType(): GlslNamedType? { 25 | val expr = node.psi ?: return null 26 | when (expr) { 27 | is GlslUnaryExpr -> return getPostfixType(expr.postfixExpr) 28 | is GlslConditionalExpr -> return expr.exprNoAssignmentList.getOrNull(1)?.getExprType() 29 | is GlslRelationalExpr, 30 | is GlslEqualityExpr -> return getBooleanType() 31 | is GlslAddExpr, 32 | is GlslMulExpr, 33 | is GlslAndExpr, 34 | is GlslShiftExpr, 35 | is GlslExclusiveOrExpr, 36 | is GlslInclusiveOrExpr, 37 | is GlslLogicalAndExpr, 38 | is GlslLogicalXorExpr, 39 | is GlslLogicalOrExpr -> return getBinaryExprType(expr) 40 | } 41 | return null 42 | } 43 | 44 | /** 45 | * 46 | */ 47 | private fun getPostfixType(postfixExpr: GlslPostfixExpr?): GlslNamedType? { 48 | return when (postfixExpr) { 49 | is GlslPrimaryExpr -> getPrimaryExprType(postfixExpr) 50 | is GlslFunctionCall -> postfixExpr.variableIdentifier?.resolveReference()?.getAssociatedType() 51 | is GlslConstructorCall -> getType(postfixExpr.typeSpecifier) 52 | is GlslPostfixArrayIndex -> getArrayIndexType(postfixExpr) 53 | is GlslPostfixInc -> getPostfixType(postfixExpr.postfixExpr) 54 | is GlslPostfixFieldSelection -> getPostfixSelectionType(postfixExpr) 55 | else -> null 56 | } 57 | } 58 | 59 | /** 60 | * 61 | */ 62 | private fun getArrayIndexType(arrayIndex: GlslPostfixArrayIndex): GlslNamedType? { 63 | val variableIdentifier = (arrayIndex.postfixExpr as GlslPrimaryExpr).variableIdentifier 64 | val resolvedReference = variableIdentifier?.resolveReference() 65 | return resolvedReference?.getAssociatedType()?.getScalarType() 66 | } 67 | 68 | /** 69 | * 70 | */ 71 | private fun getPrimaryExprType(primaryExpr: GlslPrimaryExpr): GlslNamedType? { 72 | if (primaryExpr.variableIdentifier != null) { 73 | val reference = primaryExpr.variableIdentifier?.resolveReference() ?: return null 74 | return reference.getAssociatedType() 75 | } 76 | 77 | val expr = primaryExpr.expr 78 | if (expr != null) { 79 | return expr.getExprType() 80 | } 81 | if (primaryExpr.intconstant != null) { 82 | return createScalarTypeElement(INT, "int") 83 | } else if (primaryExpr.uintconstant != null) { 84 | return createScalarTypeElement(UINT, "uint") 85 | } else if (primaryExpr.boolconstant != null) { 86 | return createScalarTypeElement(BOOL, "bool") 87 | } else if (primaryExpr.floatconstant != null) { 88 | return createScalarTypeElement(FLOAT, "float") 89 | } else { 90 | return null 91 | } 92 | } 93 | 94 | 95 | /** 96 | * 97 | */ 98 | private fun getBinaryExprType(expr: PsiElement): GlslNamedType? { 99 | val exprList = PsiTreeUtil.getChildrenOfTypeAsList(expr, GlslExpr::class.java) 100 | val leftExpr = exprList.first().getExprType() ?: return null 101 | val rightExpr = exprList.last().getExprType() ?: return null 102 | val operation = expr.firstChild.nextSibling.nextSibling.text ?: "" 103 | return leftExpr.getBinaryType(rightExpr, operation) 104 | } 105 | 106 | /** 107 | * 108 | */ 109 | private fun getBooleanType(): GlslBuiltinTypeScalarImpl { 110 | val node = leaf(BOOL, "bool") 111 | val builtinType = GlslBuiltinTypeScalarImpl(node) 112 | return builtinType 113 | } 114 | 115 | /** 116 | * 117 | */ 118 | private fun getPostfixSelectionType(postfixExpr: GlslPostfixFieldSelection): GlslNamedType? { 119 | val variableIdentifiers = postfixExpr.postfixStructMemberList.mapNotNull { it.variableIdentifier } 120 | if (variableIdentifiers.isEmpty()) return null 121 | val lastExpr = variableIdentifiers.last() as? GlslVariable 122 | return lastExpr?.resolveReference()?.getAssociatedType() 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/GlslIdentifier.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi 2 | 3 | import com.intellij.psi.ContributedReferenceHost 4 | import glsl.plugin.psi.named.GlslNamedElement 5 | import glsl.plugin.reference.GlslReference 6 | 7 | 8 | /** 9 | * 10 | */ 11 | interface GlslIdentifier: ContributedReferenceHost { 12 | /** 13 | * 14 | */ 15 | override fun getReference(): GlslReference? 16 | 17 | /** 18 | * 19 | */ 20 | fun replaceElementName(newName: String?): GlslIdentifier? 21 | 22 | /** 23 | * 24 | */ 25 | fun getName(): String 26 | 27 | /** 28 | * 29 | */ 30 | fun resolveReference(): GlslNamedElement? { 31 | return reference?.resolve() 32 | } 33 | 34 | /** 35 | * 36 | */ 37 | fun getDeclaration(): GlslNamedElement? { 38 | return parent as? GlslNamedElement 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/GlslPsiBuilder.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi 2 | 3 | import com.intellij.lang.PsiBuilder 4 | import com.intellij.lang.parser.GeneratedParserUtilBase 5 | import com.intellij.lang.parser.GeneratedParserUtilBase.enter_section_ 6 | import com.intellij.lang.parser.GeneratedParserUtilBase.exit_section_ 7 | import com.intellij.psi.tree.IElementType 8 | import glsl.GlslTypes.* 9 | import glsl._GlslParser 10 | import glsl.data.GlslTokenSets.IDENTIFIERS 11 | 12 | /** 13 | * 14 | */ 15 | class GlslPsiBuilder(builder: PsiBuilder, state: GeneratedParserUtilBase.ErrorState, parser: _GlslParser) : GeneratedParserUtilBase.Builder(builder, state, parser) { 16 | /** 17 | * 18 | */ 19 | override fun getTokenType(): IElementType? { 20 | macroCall() 21 | return super.getTokenType() 22 | } 23 | 24 | /** 25 | * 26 | */ 27 | override fun getTokenText(): String? { 28 | macroCall() 29 | return super.getTokenText() 30 | } 31 | 32 | /** 33 | * 34 | */ 35 | private fun macroCall() { 36 | var myTokenType = super.getTokenType() 37 | if (myTokenType == MACRO_OBJECT_CALL) { 38 | val marker = enter_section_(this) 39 | super.advanceLexer() // Opening parenthesis 40 | exit_section_(this, marker, VARIABLE_IDENTIFIER, true) 41 | } else if (myTokenType == MACRO_FUNCTION_CALL) { 42 | var marker = enter_section_(this) 43 | super.advanceLexer() 44 | exit_section_(this, marker, VARIABLE_IDENTIFIER, true) 45 | 46 | myTokenType = super.getTokenType() 47 | if (myTokenType != LEFT_PAREN_MACRO_CALL) return 48 | 49 | marker = enter_section_(this) 50 | while (true) { 51 | if (myTokenType == null || myTokenType == RIGHT_PAREN_MACRO_CALL) break 52 | if (myTokenType in IDENTIFIERS) { 53 | val identifierMarker = enter_section_(this) 54 | super.advanceLexer() 55 | exit_section_(this, identifierMarker, VARIABLE_IDENTIFIER, true) 56 | } else { 57 | super.advanceLexer() 58 | } 59 | myTokenType = super.getTokenType() // Closing parenthesis 60 | } 61 | super.advanceLexer() 62 | exit_section_(this, marker, MACRO_FUNC_CALL_PARAMS_BLOCK, true) 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/GlslPsiUtils.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi 2 | 3 | import com.intellij.lang.PsiBuilder 4 | import com.intellij.lang.parser.GeneratedParserUtilBase 5 | import glsl.GlslTypes.* 6 | 7 | 8 | object GlslPsiUtils : GeneratedParserUtilBase() { 9 | 10 | 11 | /** 12 | * This method differentiates between a type and a variable. If we have 2 identifiers 13 | * one after the other we know the first one must be a type and the second one a variable. 14 | * Normally this method is not doing much since the lexer is doing this job already, but 15 | * the lexer will fail if an undeclared user type is used and would make the whole parser crash. 16 | * In such cases this method will secure correct parsing. 17 | */ 18 | @JvmStatic 19 | fun primaryExprVariable(builder: PsiBuilder, level: Int): Boolean { 20 | if (!recursion_guard_(builder, level, "primary_expr_variable")) return false 21 | val isCurrentTokenIdentifier = builder.tokenType == IDENTIFIER 22 | val isNextTokenIdentifier = builder.lookAhead(1) == IDENTIFIER 23 | if (isCurrentTokenIdentifier && !isNextTokenIdentifier) { 24 | builder.advanceLexer() 25 | return true 26 | } 27 | return false 28 | } 29 | 30 | /** 31 | * 32 | */ 33 | @JvmStatic 34 | fun macroIdentifierObject(builder: PsiBuilder, level: Int): Boolean { 35 | if (!recursion_guard_(builder, level, "macro_identifier_object")) return false 36 | val marker = enter_section_(builder, level, _NONE_, VARIABLE_IDENTIFIER, "") 37 | val result = consumeToken(builder, MACRO_OBJECT) 38 | exit_section_(builder, level, marker, result, false, null) 39 | return result 40 | } 41 | 42 | /** 43 | * 44 | */ 45 | @JvmStatic 46 | fun macroIdentifierFunction(builder: PsiBuilder, level: Int): Boolean { 47 | if (!recursion_guard_(builder, level, "macro_identifier_function")) return false 48 | val marker = enter_section_(builder, level, _NONE_, VARIABLE_IDENTIFIER, "") 49 | val result = consumeToken(builder, MACRO_FUNCTION) 50 | exit_section_(builder, level, marker, result, false, null) 51 | return result 52 | } 53 | 54 | /** 55 | * 56 | */ 57 | @JvmStatic 58 | fun macroBodyToken(builder: PsiBuilder, level: Int): Boolean { 59 | if (!recursion_guard_(builder, level, "macro_body_token")) return false 60 | val isPpEndOrNull = builder.tokenType == PP_END || builder.tokenType == null 61 | if (isPpEndOrNull) return false 62 | builder.advanceLexer() 63 | return true 64 | } 65 | 66 | /** 67 | * 68 | */ 69 | @JvmStatic 70 | fun ppText(builder: PsiBuilder, level: Int): Boolean { 71 | if (!recursion_guard_(builder, level, "pp_text")) return false 72 | while (builder.tokenType != PP_END && builder.tokenType != null) { 73 | builder.advanceLexer() 74 | } 75 | return true 76 | } 77 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/GlslType.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi 2 | 3 | import com.intellij.extapi.psi.ASTWrapperPsiElement 4 | import com.intellij.lang.ASTNode 5 | import com.intellij.psi.PsiFileFactory 6 | import com.intellij.psi.PsiReference 7 | import com.intellij.psi.PsiReferenceService 8 | import com.intellij.psi.util.PsiTreeUtil 9 | import glsl.plugin.language.GlslFile 10 | import glsl.plugin.language.GlslFileType 11 | import glsl.plugin.reference.GlslTypeReference 12 | import glsl.plugin.utils.GlslUtils 13 | 14 | /** 15 | * 16 | */ 17 | abstract class GlslType(node: ASTNode) : ASTWrapperPsiElement(node), GlslIdentifier { 18 | /** 19 | * 20 | */ 21 | override fun getReferences(): Array { 22 | return PsiReferenceService.getService().getContributedReferences(this) 23 | } 24 | 25 | /** 26 | * 27 | */ 28 | override fun getReference(): GlslTypeReference? { 29 | return references.firstOrNull() as? GlslTypeReference 30 | } 31 | 32 | /** 33 | * 34 | */ 35 | override fun getName(): String { 36 | return node.text.replace("IntellijIdeaRulezzz", "") 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | override fun replaceElementName(newName: String?): GlslIdentifier? { 43 | if (!GlslUtils.isShaderFile(this)) return this 44 | if (newName == null) return this 45 | val dummyDeclaration = "$newName;" 46 | val dummyElement = (PsiFileFactory.getInstance(project) 47 | .createFileFromText("dummy.glsl", GlslFileType(), dummyDeclaration) as GlslFile) 48 | .firstChild 49 | val newIdentifierNode = PsiTreeUtil.findChildOfType(dummyElement, GlslType::class.java) ?: return this 50 | return replace(newIdentifierNode) as? GlslIdentifier 51 | } 52 | 53 | /** 54 | * 55 | */ 56 | fun isEmpty(): Boolean { 57 | return node.text == "IntellijIdeaRulezzz" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/GlslVariable.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi 2 | 3 | import com.intellij.extapi.psi.ASTWrapperPsiElement 4 | import com.intellij.lang.ASTNode 5 | import com.intellij.psi.PsiFileFactory 6 | import com.intellij.psi.PsiReference 7 | import com.intellij.psi.PsiReferenceService 8 | import com.intellij.psi.util.PsiTreeUtil 9 | import glsl.plugin.language.GlslFile 10 | import glsl.plugin.language.GlslFileType 11 | import glsl.plugin.reference.GlslVariableReference 12 | import glsl.plugin.utils.GlslUtils 13 | 14 | /** 15 | * 16 | */ 17 | abstract class GlslVariable(node: ASTNode) : ASTWrapperPsiElement(node), GlslIdentifier { 18 | /** 19 | * 20 | */ 21 | override fun getReferences(): Array { 22 | return PsiReferenceService.getService().getContributedReferences(this) 23 | } 24 | 25 | /** 26 | * 27 | */ 28 | override fun getReference(): GlslVariableReference? { 29 | return references.firstOrNull() as? GlslVariableReference 30 | } 31 | 32 | /** 33 | * 34 | */ 35 | override fun getName(): String { 36 | return node.text.replace("IntellijIdeaRulezzz", "") 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | override fun replaceElementName(newName: String?): GlslIdentifier? { 43 | if (!GlslUtils.isShaderFile(this)) return this 44 | if (newName == null ) return this 45 | val dummyDeclaration = "void $newName;" 46 | val dummyElement = (PsiFileFactory.getInstance(project) 47 | .createFileFromText("dummy.glsl", GlslFileType(), dummyDeclaration) as GlslFile) 48 | .firstChild 49 | val newIdentifierNode = PsiTreeUtil.findChildOfType(dummyElement, GlslVariable::class.java) ?: return this 50 | return replace(newIdentifierNode) as? GlslIdentifier 51 | } 52 | 53 | /** 54 | * 55 | */ 56 | fun isEmpty(): Boolean { 57 | return node.text == "IntellijIdeaRulezzz" 58 | } 59 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/GlslNamedElement.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement 4 | import com.intellij.extapi.psi.ASTWrapperPsiElement 5 | import com.intellij.lang.ASTNode 6 | import com.intellij.openapi.editor.colors.TextAttributesKey 7 | import com.intellij.psi.PsiElement 8 | import com.intellij.psi.PsiNameIdentifierOwner 9 | import glsl.plugin.psi.GlslIdentifier 10 | import glsl.plugin.utils.GlslUtils 11 | import glsl.plugin.utils.GlslUtils.isShaderFile 12 | import javax.swing.Icon 13 | 14 | interface GlslNamedElement : PsiNameIdentifierOwner { 15 | /** 16 | * 17 | */ 18 | override fun setName(newName: String): PsiElement { 19 | if (!isShaderFile(this)) return this 20 | val identifier = nameIdentifier 21 | if (identifier is GlslIdentifier) { 22 | return identifier.replaceElementName(newName) ?: this 23 | } 24 | return this 25 | } 26 | 27 | /** 28 | * A bit of a weird function which solely casts the same object to the appropriate named element 29 | * in order to avoid method-injection, which can be confusing. 30 | */ 31 | fun getPsi(): GlslNamedElement 32 | 33 | /** 34 | * Syntax highlighting color 35 | */ 36 | fun getHighlightTextAttr(): TextAttributesKey 37 | 38 | /** 39 | * Used for getVariants() 40 | */ 41 | fun getLookupElement(returnTypeText: String? = null): LookupElement? 42 | 43 | /** 44 | * The icon that is shown in the popup completion. 45 | */ 46 | fun getLookupIcon(): Icon? 47 | 48 | /** 49 | * Get the type of identifier in case it's a variable or itself in case the identifier is a type 50 | */ 51 | fun getAssociatedType(): GlslNamedType? 52 | } 53 | 54 | abstract class GlslNamedElementImpl(node: ASTNode) : ASTWrapperPsiElement(node), GlslNamedElement { 55 | 56 | /** 57 | * 58 | */ 59 | override fun getName(): String? { 60 | return nameIdentifier?.text ?: return "" 61 | } 62 | 63 | /** 64 | * 65 | */ 66 | override fun getTextOffset(): Int { 67 | return nameIdentifier?.textOffset ?: super.getTextOffset() 68 | } 69 | 70 | /** 71 | * 72 | */ 73 | override fun getLookupElement(returnTypeText: String?): LookupElement? { 74 | val lookupString = getPsi().name ?: return null 75 | return GlslUtils.createLookupElement(lookupString, icon = getLookupIcon(), withBoldness = true) 76 | } 77 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/GlslNamedType.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.lang.ASTNode 5 | import com.intellij.openapi.editor.colors.TextAttributesKey 6 | import com.intellij.psi.PsiElement 7 | import com.intellij.psi.tree.IElementType 8 | import com.intellij.psi.util.elementType 9 | import glsl.plugin.editor.highlighting.GlslTextAttributes 10 | import glsl.plugin.inspections.GlslError 11 | import javax.swing.Icon 12 | 13 | 14 | /** 15 | * 16 | */ 17 | interface GlslNamedType : GlslNamedElement { 18 | var glslError: GlslError? 19 | var isPrimitive: Boolean 20 | 21 | fun getStructMembers(): List 22 | fun getStructMember(memberName: String): GlslNamedVariable? 23 | fun getDimension(): Int 24 | fun typeAsToken(): IElementType? 25 | fun canCast(other: IElementType?): Boolean 26 | fun getBinaryType(other: GlslNamedElement?, operation: String): GlslNamedType? 27 | fun getScalarType(): GlslNamedType? 28 | 29 | /** 30 | * 31 | */ 32 | fun isEqual(other: GlslNamedType?): Boolean { 33 | val thisElementType = typeAsToken() ?: return false 34 | val otherElementType = other?.typeAsToken() ?: return false 35 | return thisElementType == otherElementType || canCast(otherElementType) 36 | } 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | abstract class GlslNamedTypeImpl(node: ASTNode) : GlslNamedElementImpl(node), GlslNamedType { 43 | override var glslError: GlslError? = null 44 | 45 | /** 46 | * 47 | */ 48 | override fun typeAsToken(): IElementType? { 49 | return firstChild.elementType 50 | } 51 | 52 | /** 53 | * 54 | */ 55 | override fun getScalarType(): GlslNamedType? { 56 | return null 57 | } 58 | 59 | /** 60 | * 61 | */ 62 | override fun getHighlightTextAttr(): TextAttributesKey { 63 | return GlslTextAttributes.BUILTIN_TYPE_TEXT_ATTR 64 | } 65 | 66 | /** 67 | * 68 | */ 69 | override fun getLookupIcon(): Icon? { 70 | return AllIcons.Nodes.Type 71 | } 72 | 73 | /** 74 | * 75 | */ 76 | override fun getNameIdentifier(): PsiElement? { 77 | return firstChild 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/GlslNamedVariable.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named 2 | 3 | import com.intellij.lang.ASTNode 4 | 5 | /** 6 | * 7 | */ 8 | interface GlslNamedVariable : GlslNamedElement 9 | 10 | /** 11 | * 12 | */ 13 | abstract class GlslNamedVariableImpl(node: ASTNode) : GlslNamedElementImpl(node), GlslNamedVariable -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/types/builtins/GlslBuiltinRest.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.types.builtins 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.psi.tree.IElementType 5 | import glsl.plugin.psi.named.GlslNamedElement 6 | import glsl.plugin.psi.named.GlslNamedType 7 | import glsl.plugin.psi.named.GlslNamedVariable 8 | import glsl.psi.interfaces.GlslBuiltinTypeRest 9 | 10 | /** 11 | * 12 | */ 13 | abstract class GlslBuiltinRest(node: ASTNode) : GlslBuiltinType(node) { 14 | override var isPrimitive = true 15 | 16 | /** 17 | * 18 | */ 19 | override fun getPsi(): GlslBuiltinTypeRest { 20 | return this as GlslBuiltinTypeRest 21 | } 22 | 23 | /** 24 | * 25 | */ 26 | override fun getBinaryType(other: GlslNamedElement?, operation: String): GlslNamedType? { 27 | return null 28 | } 29 | 30 | /** 31 | * 32 | */ 33 | override fun getStructMembers(): List { 34 | return emptyList() 35 | } 36 | 37 | /** 38 | * 39 | */ 40 | override fun getStructMember(memberName: String): GlslNamedVariable? { 41 | return null 42 | } 43 | 44 | /** 45 | * 46 | */ 47 | override fun canCast(other: IElementType?): Boolean { 48 | return false 49 | } 50 | 51 | /** 52 | * 53 | */ 54 | override fun getDimension(): Int { 55 | return 1 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/types/builtins/GlslBuiltinType.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.types.builtins 2 | 3 | import com.intellij.lang.ASTNode 4 | import glsl.plugin.psi.named.GlslNamedType 5 | import glsl.plugin.psi.named.GlslNamedTypeImpl 6 | 7 | abstract class GlslBuiltinType(node: ASTNode): GlslNamedTypeImpl(node) { 8 | /** 9 | * 10 | */ 11 | override fun getAssociatedType(): GlslNamedType? { 12 | return this 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/types/builtins/GlslMatrix.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.types.builtins 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.psi.tree.IElementType 5 | import glsl.data.GlslDefinitions 6 | import glsl.plugin.inspections.GlslError 7 | import glsl.plugin.inspections.GlslErrorCode 8 | import glsl.plugin.psi.named.GlslNamedElement 9 | import glsl.plugin.psi.named.GlslNamedType 10 | import glsl.plugin.psi.named.GlslNamedVariable 11 | import glsl.psi.interfaces.GlslBuiltinTypeMatrix 12 | 13 | /** 14 | * 15 | */ 16 | abstract class GlslMatrix(node: ASTNode) : GlslBuiltinType(node) { 17 | override var isPrimitive = true 18 | 19 | /** 20 | * 21 | */ 22 | override fun getPsi(): GlslBuiltinTypeMatrix { 23 | return this as GlslBuiltinTypeMatrix 24 | } 25 | 26 | /** 27 | * 28 | */ 29 | override fun getStructMembers(): List { 30 | return emptyList() 31 | } 32 | 33 | /** 34 | * 35 | */ 36 | override fun getStructMember(memberName: String): GlslNamedVariable? { 37 | return null 38 | } 39 | 40 | /** 41 | * 42 | */ 43 | override fun getBinaryType(other: GlslNamedElement?, operation: String): GlslNamedType? { 44 | when (other) { 45 | is GlslScalar -> return this 46 | is GlslVector -> { 47 | if (operation == "*") return other 48 | val msg = GlslErrorCode.DOES_NOT_OPERATE_ON.message.format(operation, name, other.name) 49 | glslError = GlslError(GlslErrorCode.DOES_NOT_OPERATE_ON, msg) 50 | return this 51 | } 52 | is GlslMatrix -> return this 53 | } 54 | return null 55 | } 56 | 57 | /** 58 | * 59 | */ 60 | override fun canCast(other: IElementType?): Boolean { 61 | if (other == null) return false 62 | val implicitConversions = GlslDefinitions.MATRICES[other] 63 | return implicitConversions?.contains(other) ?: false 64 | } 65 | 66 | /** 67 | * 68 | */ 69 | override fun getDimension(): Int { 70 | val lastChar = name?.last() 71 | return when (lastChar) { 72 | '2' -> 2 73 | '3' -> 3 74 | '4' -> 4 75 | else -> 0 76 | } 77 | } 78 | } 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/types/builtins/GlslScalar.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.types.builtins 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.psi.tree.IElementType 5 | import glsl.data.GlslDefinitions 6 | import glsl.plugin.psi.named.GlslNamedElement 7 | import glsl.plugin.psi.named.GlslNamedType 8 | import glsl.plugin.psi.named.GlslNamedVariable 9 | import glsl.psi.interfaces.GlslBuiltinTypeScalar 10 | 11 | /** 12 | * 13 | */ 14 | abstract class GlslScalar(node: ASTNode) : GlslBuiltinType(node) { 15 | override var isPrimitive = true 16 | 17 | /** 18 | * 19 | */ 20 | override fun getPsi(): GlslBuiltinTypeScalar { 21 | return this as GlslBuiltinTypeScalar 22 | } 23 | 24 | /** 25 | * 26 | */ 27 | override fun getStructMembers(): List { 28 | return emptyList() 29 | } 30 | 31 | 32 | /** 33 | * 34 | */ 35 | override fun getStructMember(memberName: String): GlslNamedVariable? { 36 | return null 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | override fun getBinaryType(other: GlslNamedElement?, operation: String): GlslNamedType? { 43 | return when (other) { 44 | is GlslScalar -> this 45 | is GlslVector -> other 46 | is GlslMatrix -> other 47 | else -> null 48 | } 49 | } 50 | 51 | /** 52 | * 53 | */ 54 | override fun canCast(other: IElementType?): Boolean { 55 | if (other == null) return false 56 | val implicitConversions = GlslDefinitions.SCALARS[other] 57 | val element = typeAsToken() 58 | return implicitConversions?.contains(element) ?: false 59 | } 60 | 61 | /** 62 | * 63 | */ 64 | override fun getDimension(): Int { 65 | return 1 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/types/builtins/GlslVector.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.types.builtins 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.psi.tree.IElementType 5 | import com.intellij.psi.util.elementType 6 | import glsl.GlslTypes.* 7 | import glsl.data.GlslDefinitions 8 | import glsl.plugin.inspections.GlslError 9 | import glsl.plugin.inspections.GlslErrorCode 10 | import glsl.plugin.psi.named.GlslNamedElement 11 | import glsl.plugin.psi.named.GlslNamedType 12 | import glsl.plugin.psi.named.GlslNamedVariable 13 | import glsl.plugin.utils.GlslBuiltinUtils 14 | import glsl.plugin.utils.GlslUtils.createScalarTypeElement 15 | import glsl.psi.interfaces.GlslBuiltinTypeVector 16 | 17 | 18 | /** 19 | * 20 | */ 21 | abstract class GlslVector(node: ASTNode) : GlslBuiltinType(node) { 22 | override var isPrimitive = true 23 | 24 | /** 25 | * 26 | */ 27 | override fun getPsi(): GlslBuiltinTypeVector { 28 | return firstChild as GlslBuiltinTypeVector 29 | } 30 | 31 | /** 32 | * 33 | */ 34 | override fun getStructMembers(): List { 35 | val vectors = GlslBuiltinUtils.getVecStructs()[name] 36 | val vectorMembers = vectors?.values?.toList() 37 | return vectorMembers ?: emptyList() 38 | } 39 | 40 | /** 41 | * 42 | */ 43 | override fun getStructMember(memberName: String): GlslNamedVariable? { 44 | return getStructMembers().find { it.name == memberName } 45 | } 46 | 47 | /** 48 | * 49 | */ 50 | override fun getScalarType(): GlslNamedType? { 51 | val typeText = name?.first() 52 | return when (typeText) { 53 | 'v', 'f' -> createScalarTypeElement(FLOAT, "float") 54 | 'i' -> createScalarTypeElement(INT, "int") 55 | 'u' -> createScalarTypeElement(UINT, "uint") 56 | 'b' -> createScalarTypeElement(BOOL, "bool") 57 | 'd' -> createScalarTypeElement(DOUBLE, "double") 58 | else -> null 59 | } 60 | } 61 | 62 | /** 63 | * 64 | */ 65 | override fun getBinaryType(other: GlslNamedElement?, operation: String): GlslNamedType? { 66 | when (other) { 67 | is GlslScalar -> return this 68 | is GlslVector -> return this 69 | is GlslMatrix -> { 70 | if (operation == "*") return this 71 | val msg = GlslErrorCode.DOES_NOT_OPERATE_ON.message.format(operation, name, other.name) 72 | glslError = GlslError(GlslErrorCode.DOES_NOT_OPERATE_ON, msg) 73 | return this 74 | } 75 | } 76 | return null 77 | } 78 | 79 | /** 80 | * 81 | */ 82 | override fun getDimension(): Int { 83 | val lastChar = name?.last() 84 | return when (lastChar) { 85 | '2' -> 2 86 | '3' -> 3 87 | '4' -> 4 88 | else -> 0 89 | } 90 | } 91 | 92 | /** 93 | * 94 | */ 95 | override fun canCast(other: IElementType?): Boolean { 96 | if (other == null) return false 97 | val implicitConversions = GlslDefinitions.VECTORS[other] 98 | return implicitConversions?.contains(elementType) ?: false 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/types/user/GlslNamedBlockStructure.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.types.user 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement 4 | import com.intellij.icons.AllIcons 5 | import com.intellij.lang.ASTNode 6 | import com.intellij.openapi.editor.colors.TextAttributesKey 7 | import com.intellij.psi.tree.IElementType 8 | import glsl.GlslTypes 9 | import glsl.plugin.editor.highlighting.GlslTextAttributes 10 | import glsl.plugin.psi.named.GlslNamedElement 11 | import glsl.plugin.psi.named.GlslNamedType 12 | import glsl.plugin.psi.named.GlslNamedTypeImpl 13 | import glsl.plugin.psi.named.GlslNamedVariable 14 | import glsl.psi.interfaces.GlslBlockStructure 15 | import glsl.psi.interfaces.GlslStructDeclarator 16 | import glsl.psi.interfaces.GlslTypeName 17 | import javax.swing.Icon 18 | 19 | /** 20 | * block_structure 21 | */ 22 | abstract class GlslNamedBlockStructure(node: ASTNode) : GlslNamedTypeImpl(node), GlslNamedType { 23 | override var isPrimitive = false 24 | 25 | /** 26 | * 27 | */ 28 | override fun getName(): String { 29 | return getPsi().typeName.getName() 30 | } 31 | 32 | /** 33 | * 34 | */ 35 | override fun getAssociatedType(): GlslNamedType? { 36 | return this 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | override fun getPsi(): GlslBlockStructure { 43 | return this as GlslBlockStructure 44 | } 45 | 46 | /** 47 | * 48 | */ 49 | override fun getHighlightTextAttr(): TextAttributesKey { 50 | return GlslTextAttributes.USER_DEFINED_TYPE_TEXT_ATTR 51 | } 52 | 53 | /** 54 | * 55 | */ 56 | override fun getLookupElement(returnTypeText: String?): LookupElement? { 57 | return null // TODO 58 | } 59 | 60 | /** 61 | * 62 | */ 63 | override fun getLookupIcon(): Icon? { 64 | return AllIcons.Nodes.Type 65 | } 66 | 67 | /** 68 | * 69 | */ 70 | override fun getNameIdentifier(): GlslTypeName { 71 | return getPsi().typeName 72 | } 73 | 74 | /** 75 | * 76 | */ 77 | override fun getStructMembers(): List { 78 | val structDeclarationList = getPsi().structDeclarationList 79 | val structDeclarators = mutableListOf() 80 | for (structDeclaration in structDeclarationList) { 81 | for (structDeclarator in structDeclaration.structDeclaratorList) { 82 | structDeclarators.add(structDeclarator) 83 | } 84 | } 85 | return structDeclarators 86 | } 87 | 88 | /** 89 | * 90 | */ 91 | override fun getStructMember(memberName: String): GlslNamedVariable? { 92 | val structDeclarationList = getPsi().structDeclarationList 93 | for (structDeclaration in structDeclarationList) { 94 | for (structDeclarator in structDeclaration.structDeclaratorList) { 95 | if (structDeclarator.name != memberName) continue 96 | return structDeclarator 97 | } 98 | } 99 | return null 100 | } 101 | 102 | /** 103 | * 104 | */ 105 | override fun canCast(other: IElementType?): Boolean { 106 | return false 107 | } 108 | 109 | /** 110 | * 111 | */ 112 | override fun typeAsToken(): IElementType? { 113 | return GlslTypes.USER_TYPE_NAME 114 | } 115 | 116 | /** 117 | * 118 | */ 119 | override fun getBinaryType(other: GlslNamedElement?, operation: String): GlslNamedType? { 120 | return null 121 | } 122 | 123 | /** 124 | * 125 | */ 126 | override fun getDimension(): Int { 127 | return 1 128 | } 129 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/types/user/GlslNamedStructSpecifier.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.types.user 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement 4 | import com.intellij.icons.AllIcons 5 | import com.intellij.lang.ASTNode 6 | import com.intellij.openapi.editor.colors.TextAttributesKey 7 | import com.intellij.psi.tree.IElementType 8 | import glsl.GlslTypes 9 | import glsl.plugin.editor.highlighting.GlslTextAttributes 10 | import glsl.plugin.psi.named.GlslNamedElement 11 | import glsl.plugin.psi.named.GlslNamedType 12 | import glsl.plugin.psi.named.GlslNamedTypeImpl 13 | import glsl.plugin.psi.named.GlslNamedVariable 14 | import glsl.psi.interfaces.GlslStructDeclarator 15 | import glsl.psi.interfaces.GlslStructSpecifier 16 | import glsl.psi.interfaces.GlslTypeName 17 | import javax.swing.Icon 18 | 19 | /** 20 | * type_specifier 21 | */ 22 | abstract class GlslNamedStructSpecifier(node: ASTNode) : GlslNamedTypeImpl(node), GlslNamedType { 23 | override var isPrimitive = false 24 | 25 | /** 26 | * 27 | */ 28 | override fun getName(): String { 29 | return getPsi().typeName?.getName() ?: "" 30 | } 31 | 32 | /** 33 | * 34 | */ 35 | override fun getAssociatedType(): GlslNamedType? { 36 | return this 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | override fun getPsi(): GlslStructSpecifier { 43 | return this as GlslStructSpecifier 44 | } 45 | 46 | /** 47 | * 48 | */ 49 | override fun getHighlightTextAttr(): TextAttributesKey { 50 | return GlslTextAttributes.USER_DEFINED_TYPE_TEXT_ATTR 51 | } 52 | 53 | /** 54 | * 55 | */ 56 | override fun getLookupElement(returnTypeText: String?): LookupElement? { 57 | TODO("Not yet implemented") 58 | } 59 | 60 | /** 61 | * 62 | */ 63 | override fun getLookupIcon(): Icon? { 64 | return AllIcons.Nodes.Type 65 | } 66 | 67 | /** 68 | * 69 | */ 70 | override fun getNameIdentifier(): GlslTypeName? { 71 | return getPsi().typeName 72 | } 73 | 74 | /** 75 | * 76 | */ 77 | override fun getStructMembers(): List { 78 | val structDeclarationList = getPsi().structDeclarationList 79 | val structDeclarators = mutableListOf() 80 | for (structDeclaration in structDeclarationList) { 81 | for (structDeclarator in structDeclaration.structDeclaratorList) { 82 | structDeclarators.add(structDeclarator) 83 | } 84 | } 85 | return structDeclarators 86 | } 87 | 88 | /** 89 | * 90 | */ 91 | override fun getStructMember(memberName: String): GlslNamedVariable? { 92 | val structDeclarationList = getPsi().structDeclarationList 93 | for (structDeclaration in structDeclarationList) { 94 | for (structDeclarator in structDeclaration.structDeclaratorList) { 95 | if (structDeclarator.name != memberName) continue 96 | return structDeclarator 97 | } 98 | } 99 | return null 100 | } 101 | 102 | /** 103 | * 104 | */ 105 | override fun canCast(other: IElementType?): Boolean { 106 | return false 107 | } 108 | 109 | /** 110 | * 111 | */ 112 | override fun typeAsToken(): IElementType? { 113 | return GlslTypes.USER_TYPE_NAME 114 | } 115 | 116 | /** 117 | * 118 | */ 119 | override fun getBinaryType(other: GlslNamedElement?, operation: String): GlslNamedType? { 120 | return null 121 | } 122 | 123 | /** 124 | * 125 | */ 126 | override fun getDimension(): Int { 127 | return 1 128 | } 129 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/variables/GlslNamedBlockStructureWrapper.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.variables 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.openapi.editor.colors.TextAttributesKey 5 | import glsl.plugin.editor.highlighting.GlslTextAttributes 6 | import glsl.plugin.psi.named.GlslNamedType 7 | import glsl.plugin.psi.named.GlslNamedVariableImpl 8 | import glsl.psi.interfaces.GlslBlockStructureWrapper 9 | import glsl.psi.interfaces.GlslVariableIdentifier 10 | import javax.swing.Icon 11 | 12 | /** 13 | * 14 | */ 15 | abstract class GlslNamedBlockStructureWrapper(node: ASTNode) : GlslNamedVariableImpl(node) { 16 | 17 | /** 18 | * 19 | */ 20 | override fun getPsi(): GlslBlockStructureWrapper { 21 | return this as GlslBlockStructureWrapper 22 | } 23 | 24 | /** 25 | * 26 | */ 27 | override fun getLookupIcon(): Icon? { 28 | return null 29 | } 30 | 31 | /** 32 | * 33 | */ 34 | override fun getAssociatedType(): GlslNamedType? { 35 | return getPsi().blockStructure 36 | } 37 | 38 | /** 39 | * 40 | */ 41 | override fun getNameIdentifier(): GlslVariableIdentifier? { 42 | return getPsi().variableIdentifier 43 | } 44 | 45 | /** 46 | * 47 | */ 48 | override fun getHighlightTextAttr(): TextAttributesKey { 49 | return GlslTextAttributes.VARIABLE_TEXT_ATTR 50 | } 51 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/variables/GlslNamedDeclarationIdentifierWrapper.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.variables 2 | 3 | import com.intellij.lang.ASTNode 4 | import com.intellij.openapi.editor.colors.TextAttributesKey 5 | import glsl.plugin.editor.highlighting.GlslTextAttributes 6 | import glsl.plugin.psi.named.GlslNamedType 7 | import glsl.plugin.psi.named.GlslNamedVariableImpl 8 | import glsl.psi.interfaces.GlslDeclarationIdentifierWrapper 9 | import glsl.psi.interfaces.GlslVariableIdentifier 10 | import javax.swing.Icon 11 | 12 | /** 13 | * 14 | */ 15 | abstract class GlslNamedDeclarationIdentifierWrapper(node: ASTNode) : GlslNamedVariableImpl(node) { 16 | 17 | /** 18 | * 19 | */ 20 | override fun getPsi(): GlslDeclarationIdentifierWrapper { 21 | return this as GlslDeclarationIdentifierWrapper 22 | } 23 | 24 | /** 25 | * 26 | */ 27 | override fun getLookupIcon(): Icon? { 28 | return null 29 | } 30 | 31 | /** 32 | * 33 | */ 34 | override fun getAssociatedType(): GlslNamedType? { 35 | return null 36 | } 37 | 38 | /** 39 | * 40 | */ 41 | override fun getNameIdentifier(): GlslVariableIdentifier? { 42 | return getPsi().variableIdentifier 43 | } 44 | 45 | /** 46 | * 47 | */ 48 | override fun getHighlightTextAttr(): TextAttributesKey { 49 | return GlslTextAttributes.VARIABLE_TEXT_ATTR 50 | } 51 | 52 | 53 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/variables/GlslNamedFunctionDeclarator.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.variables 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement 4 | import com.intellij.icons.AllIcons 5 | import com.intellij.lang.ASTNode 6 | import com.intellij.openapi.editor.colors.TextAttributesKey 7 | import com.intellij.psi.util.parentOfType 8 | import glsl.plugin.editor.highlighting.GlslTextAttributes 9 | import glsl.plugin.psi.named.GlslNamedType 10 | import glsl.plugin.psi.named.GlslNamedVariableImpl 11 | import glsl.plugin.utils.GlslUtils 12 | import glsl.psi.interfaces.GlslFunctionDeclarator 13 | import glsl.psi.interfaces.GlslVariableIdentifier 14 | import javax.swing.Icon 15 | 16 | /** 17 | * 18 | */ 19 | abstract class GlslNamedFunctionDeclarator(node: ASTNode) : GlslNamedVariableImpl(node) { 20 | 21 | /** 22 | * 23 | */ 24 | override fun getPsi(): GlslFunctionDeclarator { 25 | return this as GlslFunctionDeclarator 26 | } 27 | 28 | /** 29 | * 30 | */ 31 | override fun getLookupIcon(): Icon { 32 | return AllIcons.Nodes.Function 33 | } 34 | 35 | /** 36 | * 37 | */ 38 | override fun getNameIdentifier(): GlslVariableIdentifier? { 39 | return getPsi().variableIdentifier 40 | } 41 | 42 | /** 43 | * 44 | */ 45 | override fun getAssociatedType(): GlslNamedType? { 46 | return GlslUtils.getType(getPsi().typeSpecifier) 47 | } 48 | 49 | /** 50 | * 51 | */ 52 | override fun getHighlightTextAttr(): TextAttributesKey { 53 | return GlslTextAttributes.FUNC_TEXT_ATTR 54 | } 55 | 56 | /** 57 | * 58 | */ 59 | override fun getLookupElement(returnTypeText: String?): LookupElement? { 60 | val functionPrototype = getPsi().parentOfType() ?: return null 61 | return GlslUtils.getFunctionLookupElement(functionPrototype, getLookupIcon()) 62 | } 63 | 64 | /** 65 | * 66 | */ 67 | fun getParameterTypes(): List? { 68 | return getPsi().funcHeaderWithParams 69 | ?.parameterDeclaratorList 70 | ?.mapNotNull { it.getAssociatedType() } 71 | } 72 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/variables/GlslNamedInitDeclaratorVariable.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.variables 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.lang.ASTNode 5 | import com.intellij.openapi.editor.colors.TextAttributesKey 6 | import glsl.plugin.editor.highlighting.GlslTextAttributes 7 | import glsl.plugin.psi.named.GlslNamedType 8 | import glsl.plugin.psi.named.GlslNamedVariableImpl 9 | import glsl.psi.interfaces.GlslDeclaration 10 | import glsl.psi.interfaces.GlslInitDeclaratorVariable 11 | import glsl.psi.interfaces.GlslVariableIdentifier 12 | import javax.swing.Icon 13 | 14 | /** 15 | * 16 | */ 17 | abstract class GlslNamedInitDeclaratorVariable(node: ASTNode) : GlslNamedVariableImpl(node) { 18 | 19 | /** 20 | * 21 | */ 22 | override fun getPsi(): GlslInitDeclaratorVariable { 23 | return this as GlslInitDeclaratorVariable 24 | } 25 | 26 | /** 27 | * 28 | */ 29 | override fun getLookupIcon(): Icon { 30 | return AllIcons.Nodes.Variable 31 | } 32 | 33 | /** 34 | * 35 | */ 36 | override fun getAssociatedType(): GlslNamedType? { 37 | val singleDeclaration = (getPsi().parent as? GlslDeclaration)?.singleDeclaration 38 | return singleDeclaration?.getAssociatedType() 39 | } 40 | 41 | /** 42 | * 43 | */ 44 | override fun getNameIdentifier(): GlslVariableIdentifier? { 45 | return getPsi().variableIdentifier 46 | } 47 | 48 | /** 49 | * 50 | */ 51 | override fun getHighlightTextAttr(): TextAttributesKey { 52 | return GlslTextAttributes.VARIABLE_TEXT_ATTR 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/variables/GlslNamedParameterDeclarator.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.variables 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.lang.ASTNode 5 | import com.intellij.openapi.editor.colors.TextAttributesKey 6 | import glsl.plugin.editor.highlighting.GlslTextAttributes 7 | import glsl.plugin.psi.named.GlslNamedType 8 | import glsl.plugin.psi.named.GlslNamedVariableImpl 9 | import glsl.plugin.utils.GlslUtils 10 | import glsl.psi.interfaces.GlslParameterDeclarator 11 | import glsl.psi.interfaces.GlslVariableIdentifier 12 | import javax.swing.Icon 13 | 14 | /** 15 | * 16 | */ 17 | abstract class GlslNamedParameterDeclarator(node: ASTNode) : GlslNamedVariableImpl(node) { 18 | /** 19 | * 20 | */ 21 | override fun getPsi(): GlslParameterDeclarator { 22 | return this as GlslParameterDeclarator 23 | } 24 | 25 | /** 26 | * 27 | */ 28 | override fun getNameIdentifier(): GlslVariableIdentifier? { 29 | return getPsi().variableIdentifier 30 | } 31 | 32 | /** 33 | * 34 | */ 35 | override fun getAssociatedType(): GlslNamedType? { 36 | return GlslUtils.getType(getPsi().typeSpecifier) 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | override fun getLookupIcon(): Icon { 43 | return AllIcons.Nodes.Parameter 44 | } 45 | 46 | /** 47 | * 48 | */ 49 | override fun getHighlightTextAttr(): TextAttributesKey { 50 | return GlslTextAttributes.FUNC_PARAM_TEXT_ATTR 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/variables/GlslNamedPpDefineFunction.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.variables 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.lang.ASTNode 5 | import com.intellij.openapi.editor.colors.TextAttributesKey 6 | import com.intellij.psi.util.childrenOfType 7 | import glsl.plugin.editor.highlighting.GlslTextAttributes 8 | import glsl.plugin.psi.named.GlslNamedType 9 | import glsl.plugin.psi.named.GlslNamedVariableImpl 10 | import glsl.psi.interfaces.GlslPpDefineFunction 11 | import glsl.psi.interfaces.GlslVariableIdentifier 12 | import javax.swing.Icon 13 | 14 | /** 15 | * 16 | */ 17 | abstract class GlslNamedPpDefineFunction(node: ASTNode) : GlslNamedVariableImpl(node) { 18 | /** 19 | * 20 | */ 21 | override fun getPsi(): GlslPpDefineFunction { 22 | return this as GlslPpDefineFunction 23 | } 24 | 25 | /** 26 | * 27 | */ 28 | override fun getNameIdentifier(): GlslVariableIdentifier? { 29 | return getPsi().childrenOfType().firstOrNull() 30 | } 31 | 32 | /** 33 | * 34 | */ 35 | override fun getAssociatedType(): GlslNamedType? { 36 | return null 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | override fun getLookupIcon(): Icon { 43 | return AllIcons.Nodes.Function 44 | } 45 | 46 | /** 47 | * 48 | */ 49 | override fun getHighlightTextAttr(): TextAttributesKey { 50 | return GlslTextAttributes.MACRO_FUNC_NAME_ATTR 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/variables/GlslNamedPpDefineObject.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.variables 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.lang.ASTNode 5 | import com.intellij.openapi.editor.colors.TextAttributesKey 6 | import com.intellij.psi.util.childrenOfType 7 | import glsl.plugin.editor.highlighting.GlslTextAttributes 8 | import glsl.plugin.psi.named.GlslNamedType 9 | import glsl.plugin.psi.named.GlslNamedVariableImpl 10 | import glsl.psi.interfaces.GlslPpDefineObject 11 | import glsl.psi.interfaces.GlslVariableIdentifier 12 | import javax.swing.Icon 13 | 14 | /** 15 | * 16 | */ 17 | abstract class GlslNamedPpDefineObject(node: ASTNode) : GlslNamedVariableImpl(node) { 18 | /** 19 | * 20 | */ 21 | override fun getPsi(): GlslPpDefineObject { 22 | return this as GlslPpDefineObject 23 | } 24 | 25 | /** 26 | * 27 | */ 28 | override fun getNameIdentifier(): GlslVariableIdentifier? { 29 | return getPsi().childrenOfType().firstOrNull() 30 | } 31 | 32 | /** 33 | * 34 | */ 35 | override fun getAssociatedType(): GlslNamedType? { 36 | return null 37 | } 38 | 39 | /** 40 | * 41 | */ 42 | override fun getLookupIcon(): Icon { 43 | return AllIcons.Nodes.Variable 44 | } 45 | 46 | /** 47 | * 48 | */ 49 | override fun getHighlightTextAttr(): TextAttributesKey { 50 | return GlslTextAttributes.MACRO_OBJECT_NAME_ATTR 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/variables/GlslNamedSingleDeclaration.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.variables 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.lang.ASTNode 5 | import com.intellij.openapi.editor.colors.TextAttributesKey 6 | import glsl.plugin.editor.highlighting.GlslTextAttributes 7 | import glsl.plugin.psi.named.GlslNamedType 8 | import glsl.plugin.psi.named.GlslNamedVariableImpl 9 | import glsl.plugin.utils.GlslUtils 10 | import glsl.psi.interfaces.GlslSingleDeclaration 11 | import glsl.psi.interfaces.GlslVariableIdentifier 12 | import javax.swing.Icon 13 | 14 | /** 15 | * 16 | */ 17 | abstract class GlslNamedSingleDeclaration(node: ASTNode) : GlslNamedVariableImpl(node) { 18 | 19 | /** 20 | * 21 | */ 22 | override fun getPsi(): GlslSingleDeclaration { 23 | return this as GlslSingleDeclaration 24 | } 25 | 26 | /** 27 | * 28 | */ 29 | override fun getNameIdentifier(): GlslVariableIdentifier? { 30 | return getPsi().variableIdentifier 31 | } 32 | 33 | /** 34 | * 35 | */ 36 | override fun getLookupIcon(): Icon { 37 | return AllIcons.Nodes.Variable 38 | } 39 | 40 | /** 41 | * 42 | */ 43 | override fun getAssociatedType(): GlslNamedType? { 44 | val typeSpecifier = getPsi().typeSpecifier 45 | return GlslUtils.getType(typeSpecifier) 46 | } 47 | 48 | /** 49 | * 50 | */ 51 | override fun getHighlightTextAttr(): TextAttributesKey { 52 | return GlslTextAttributes.VARIABLE_TEXT_ATTR 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/psi/named/variables/GlslNamedStructDeclarator.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.psi.named.variables 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement 4 | import com.intellij.icons.AllIcons 5 | import com.intellij.lang.ASTNode 6 | import com.intellij.openapi.editor.colors.TextAttributesKey 7 | import glsl.plugin.editor.highlighting.GlslTextAttributes 8 | import glsl.plugin.psi.named.GlslNamedType 9 | import glsl.plugin.psi.named.GlslNamedVariableImpl 10 | import glsl.plugin.utils.GlslUtils 11 | import glsl.psi.interfaces.GlslStructDeclaration 12 | import glsl.psi.interfaces.GlslStructDeclarator 13 | import glsl.psi.interfaces.GlslVariableIdentifier 14 | import javax.swing.Icon 15 | 16 | /** 17 | * 18 | */ 19 | abstract class GlslNamedStructDeclarator(node: ASTNode) : GlslNamedVariableImpl(node) { 20 | 21 | /** 22 | * 23 | */ 24 | override fun getPsi(): GlslStructDeclarator { 25 | return this as GlslStructDeclarator 26 | } 27 | 28 | /** 29 | * 30 | */ 31 | override fun getLookupIcon(): Icon? { 32 | return AllIcons.Nodes.Field 33 | } 34 | 35 | /** 36 | * 37 | */ 38 | override fun getAssociatedType(): GlslNamedType? { 39 | val structDeclaration = getPsi().parent as GlslStructDeclaration 40 | val typeSpecifier = structDeclaration.typeSpecifier ?: return null 41 | return GlslUtils.getType(typeSpecifier) 42 | } 43 | 44 | /** 45 | * 46 | */ 47 | override fun getNameIdentifier(): GlslVariableIdentifier? { 48 | return getPsi().variableIdentifier 49 | } 50 | 51 | /** 52 | * 53 | */ 54 | override fun getHighlightTextAttr(): TextAttributesKey { 55 | return GlslTextAttributes.VARIABLE_TEXT_ATTR 56 | } 57 | 58 | /** 59 | * 60 | */ 61 | override fun getLookupElement(returnTypeText: String?): LookupElement? { 62 | val name = getPsi().name ?: return null 63 | val typeText = getAssociatedType()?.text 64 | return GlslUtils.createLookupElement(name, icon = getLookupIcon(), returnTypeText = typeText) 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/reference/GlslFindUsageProvider.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.reference 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.psi.PsiElement 7 | import com.intellij.psi.tree.TokenSet 8 | import glsl.data.GlslTokenSets.COMMENTS 9 | import glsl.data.GlslTokenSets.IDENTIFIERS 10 | import glsl.plugin.language.GlslLexer 11 | import glsl.plugin.psi.named.GlslNamedElement 12 | import glsl.plugin.utils.GlslBuiltinUtils 13 | import glsl.psi.interfaces.GlslStructSpecifier 14 | 15 | /** 16 | * 17 | */ 18 | class GlslFindUsageProvider : FindUsagesProvider { 19 | 20 | /** 21 | * 22 | */ 23 | override fun getWordsScanner(): WordsScanner { 24 | return DefaultWordsScanner(GlslLexer(), IDENTIFIERS, COMMENTS, TokenSet.EMPTY) 25 | } 26 | 27 | /** 28 | * 29 | */ 30 | override fun canFindUsagesFor(psiElement: PsiElement): Boolean { 31 | if (psiElement !is GlslNamedElement) return false 32 | val structSpecifier = psiElement.parent?.parent as? GlslStructSpecifier ?: return true 33 | return !GlslBuiltinUtils.isBuiltin(structSpecifier.name) 34 | } 35 | 36 | /** 37 | * 38 | */ 39 | override fun getHelpId(psiElement: PsiElement): String? { 40 | return null 41 | } 42 | 43 | /** 44 | * 45 | */ 46 | override fun getType(element: PsiElement): String { 47 | if (element !is GlslNamedElement) return "" 48 | return "declaration" 49 | } 50 | 51 | /** 52 | * 53 | */ 54 | override fun getDescriptiveName(element: PsiElement): String { 55 | return if (element !is GlslNamedElement || element.name == null) "" else element.name!! 56 | } 57 | 58 | /** 59 | * 60 | */ 61 | override fun getNodeText(element: PsiElement, useFullName: Boolean): String { 62 | return if (element !is GlslNamedElement) "" else element.text 63 | } 64 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/reference/GlslRefactoring.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.reference 2 | 3 | import com.intellij.lang.refactoring.RefactoringSupportProvider 4 | import com.intellij.psi.PsiElement 5 | import glsl.plugin.psi.named.GlslNamedElement 6 | 7 | 8 | 9 | /** 10 | * 11 | */ 12 | class GlslRefactoring : RefactoringSupportProvider() { 13 | /** 14 | * 15 | */ 16 | override fun isMemberInplaceRenameAvailable(element: PsiElement, context: PsiElement?): Boolean { 17 | return element is GlslNamedElement 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/reference/GlslReference.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.reference 2 | 3 | import com.intellij.openapi.util.TextRange 4 | import com.intellij.psi.PsiElement 5 | import com.intellij.psi.PsiFile 6 | import com.intellij.psi.PsiManager 7 | import com.intellij.psi.PsiReferenceBase 8 | import com.intellij.psi.util.childrenOfType 9 | import glsl.plugin.psi.GlslIdentifier 10 | import glsl.plugin.psi.named.GlslNamedElement 11 | import glsl.plugin.psi.named.GlslNamedVariable 12 | import glsl.plugin.reference.FilterType.CONTAINS 13 | import glsl.plugin.reference.FilterType.EQUALS 14 | import glsl.plugin.utils.GlslUtils.getPathStringFromInclude 15 | import glsl.plugin.utils.GlslUtils.getVirtualFile 16 | import glsl.psi.interfaces.GlslExternalDeclaration 17 | import glsl.psi.interfaces.GlslFunctionDefinition 18 | import glsl.psi.interfaces.GlslPpIncludeDeclaration 19 | import glsl.psi.interfaces.GlslStatement 20 | 21 | 22 | class StopLookupException : Exception() 23 | 24 | enum class FilterType { 25 | EQUALS, 26 | CONTAINS 27 | } 28 | 29 | /** 30 | * 31 | */ 32 | abstract class GlslReference(private val element: GlslIdentifier, textRange: TextRange) : PsiReferenceBase(element, textRange) { 33 | abstract fun doResolve(filterType: FilterType = EQUALS) 34 | abstract fun shouldResolve(): Boolean 35 | abstract fun resolveMany(): List 36 | abstract fun lookupInExternalDeclaration(externalDeclaration: GlslExternalDeclaration?) 37 | abstract override fun resolve(): GlslNamedElement? 38 | 39 | protected var currentFilterType = EQUALS 40 | protected val project = element.project 41 | val resolvedReferences = arrayListOf() 42 | protected val includeFiles = mutableListOf() 43 | private lateinit var _currentFile: PsiFile 44 | 45 | /** 46 | * 47 | */ 48 | override fun handleElementRename(newElementName: String): PsiElement? { 49 | return element.replaceElementName(newElementName) 50 | } 51 | 52 | /** 53 | * Gets the parent scope inside a function by traversing up the tree. A new scope is 54 | * reached once a GlslStatement is encountered, otherwise returns GlslFunctionDefinition 55 | * meaning the end of the function scope. GlslFunctionDefinition must be encountered 56 | * sooner or later since statement must be a child of function_definition. 57 | * 58 | * @return GlslStatement or GlslFunctionDefinition 59 | */ 60 | protected fun getParentScope(glslStatement: GlslStatement?): PsiElement? { 61 | var elementParent = glslStatement?.parent 62 | while (elementParent != null && elementParent !is GlslStatement) { 63 | elementParent = elementParent.parent 64 | if (elementParent is GlslFunctionDefinition) { 65 | return elementParent 66 | } 67 | } 68 | return elementParent 69 | } 70 | 71 | /** 72 | * 73 | */ 74 | protected fun findReferenceInElement(namedElement: GlslNamedElement?) { 75 | val namedElementName = namedElement?.name ?: return 76 | val elementName = element.getName() 77 | if (currentFilterType == EQUALS) { 78 | if (namedElementName != elementName) return 79 | resolvedReferences.add(namedElement) 80 | throw StopLookupException() 81 | } else if (currentFilterType == CONTAINS && namedElementName.contains(elementName)) { 82 | resolvedReferences.add(namedElement) 83 | } 84 | } 85 | 86 | /** 87 | * 88 | */ 89 | protected fun findReferenceInElementList(namedElementsList: List?, addAll: Boolean = false) { 90 | if (namedElementsList == null) return 91 | if (addAll) { 92 | resolvedReferences.addAll(namedElementsList) 93 | return 94 | } 95 | for (namedElement in namedElementsList) { 96 | findReferenceInElement(namedElement) 97 | } 98 | } 99 | 100 | /** 101 | * 102 | */ 103 | protected fun findReferenceInElementMap(namedElementsMap: Map) { 104 | if (namedElementsMap.isEmpty()) return 105 | val elementName = element.getName() 106 | if (currentFilterType == EQUALS) { 107 | if (namedElementsMap.containsKey(element.getName())) { 108 | findReferenceInElement(namedElementsMap[elementName]) 109 | } 110 | } else if (currentFilterType == CONTAINS) { 111 | for ((key, value) in namedElementsMap.entries) { 112 | if (key.contains(elementName)) { 113 | findReferenceInElement(value) 114 | } 115 | } 116 | } 117 | } 118 | 119 | /** 120 | * 121 | */ 122 | protected fun lookupInIncludeDeclaration(ppIncludeDeclaration: GlslPpIncludeDeclaration?) { 123 | if (ppIncludeDeclaration == null) return 124 | includeFiles.add(ppIncludeDeclaration.containingFile) 125 | 126 | val path = getPathStringFromInclude(ppIncludeDeclaration) ?: return 127 | val vf = getVirtualFile(path, currentFile.virtualFile, project) ?: return 128 | val psiFile = PsiManager.getInstance(project).findFile(vf) ?: return 129 | 130 | if (includeFiles.contains(psiFile)) { 131 | throw StopLookupException() 132 | } 133 | 134 | val externalDeclarations = psiFile.childrenOfType() 135 | for (externalDeclaration in externalDeclarations) { 136 | lookupInExternalDeclaration(externalDeclaration) 137 | } 138 | } 139 | 140 | 141 | /** 142 | * 143 | */ 144 | private val currentFile: PsiFile 145 | get() { 146 | if (!::_currentFile.isInitialized) { 147 | _currentFile = element.containingFile 148 | } 149 | return _currentFile 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/reference/GlslReferenceContributor.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.reference 2 | 3 | import com.intellij.patterns.PlatformPatterns.psiElement 4 | import com.intellij.patterns.StandardPatterns 5 | import com.intellij.psi.* 6 | import com.intellij.util.ProcessingContext 7 | import glsl.GlslTypes 8 | import glsl.plugin.psi.GlslType 9 | import glsl.plugin.psi.GlslVariable 10 | 11 | 12 | /** 13 | * 14 | */ 15 | class GlslReferenceContributor : PsiReferenceContributor() { 16 | private val numericPattern = StandardPatterns.or( 17 | psiElement(GlslTypes.INTCONSTANT), 18 | psiElement(GlslTypes.UINTCONSTANT), 19 | psiElement(GlslTypes.FLOATCONSTANT), 20 | psiElement(GlslTypes.DOUBLECONSTANT), 21 | ) 22 | private val variablePattern = psiElement(GlslVariable::class.java) 23 | .andNot(psiElement().afterLeaf(numericPattern)) 24 | private val typePattern = psiElement(GlslType::class.java) 25 | .andNot(psiElement().afterLeaf(numericPattern)) 26 | 27 | /** 28 | * 29 | */ 30 | override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) { 31 | registrar.registerReferenceProvider(variablePattern, GlslVariableReferenceProvider()) 32 | registrar.registerReferenceProvider(typePattern, GlslTypeReferenceProvider()) 33 | } 34 | 35 | /** 36 | * 37 | */ 38 | inner class GlslVariableReferenceProvider : PsiReferenceProvider() { 39 | override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array { 40 | if (element !is GlslVariable) return emptyArray() 41 | return arrayOf(GlslVariableReference(element, element.textRangeInParent)) 42 | } 43 | } 44 | 45 | /** 46 | * 47 | */ 48 | inner class GlslTypeReferenceProvider : PsiReferenceProvider() { 49 | override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array { 50 | if (element !is GlslType) return emptyArray() 51 | return arrayOf(GlslTypeReference(element, element.textRangeInParent)) 52 | } 53 | } 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/main/kotlin/glsl/plugin/reference/GlslTypeReference.kt: -------------------------------------------------------------------------------- 1 | package glsl.plugin.reference 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement 4 | import com.intellij.openapi.util.TextRange 5 | import com.intellij.psi.impl.source.resolve.ResolveCache 6 | import com.intellij.psi.impl.source.resolve.ResolveCache.AbstractResolver 7 | import com.intellij.psi.util.PsiTreeUtil.getParentOfType 8 | import com.intellij.psi.util.PsiTreeUtil.getPrevSiblingOfType 9 | import glsl.plugin.psi.GlslType 10 | import glsl.plugin.psi.named.GlslNamedElement 11 | import glsl.plugin.psi.named.GlslNamedType 12 | import glsl.plugin.reference.FilterType.CONTAINS 13 | import glsl.psi.interfaces.GlslDeclaration 14 | import glsl.psi.interfaces.GlslExternalDeclaration 15 | import glsl.psi.interfaces.GlslStatement 16 | 17 | class GlslTypeReference(private val element: GlslType, textRange: TextRange) : GlslReference(element, textRange) { 18 | 19 | private val resolver = AbstractResolver { reference, _ -> 20 | reference.doResolve() 21 | reference.resolvedReferences.firstOrNull() as? GlslNamedType 22 | } 23 | 24 | /** 25 | * 26 | */ 27 | override fun resolve(): GlslNamedType? { 28 | if (!shouldResolve()) return null 29 | val resolveCache = ResolveCache.getInstance(project) 30 | return resolveCache.resolveWithCaching(this, resolver, true, false) 31 | } 32 | 33 | /** 34 | * 35 | */ 36 | override fun getVariants(): Array { 37 | doResolve(CONTAINS) 38 | return resolvedReferences.mapNotNull { it.getLookupElement() }.toTypedArray() 39 | } 40 | 41 | /** 42 | * 43 | */ 44 | override fun doResolve(filterType: FilterType) { 45 | try { 46 | resolvedReferences.clear() 47 | currentFilterType = filterType 48 | resolveType() 49 | } catch (_: StopLookupException) { 50 | includeFiles.clear() 51 | } 52 | } 53 | 54 | /** 55 | * 56 | */ 57 | override fun shouldResolve(): Boolean { 58 | if (currentFilterType == CONTAINS && element.isEmpty()) return true 59 | return element.getDeclaration() == null 60 | } 61 | 62 | /** 63 | * 64 | */ 65 | override fun resolveMany(): List { 66 | if (!shouldResolve()) return emptyList() 67 | val resolveCache = ResolveCache.getInstance(project) 68 | resolveCache.resolveWithCaching(this, resolver, true, false) 69 | return resolvedReferences 70 | } 71 | 72 | /** 73 | * 74 | */ 75 | private fun resolveType(): GlslNamedType? { 76 | var statementPrevSibling = getParentOfType(element, GlslStatement::class.java) 77 | while (statementPrevSibling != null) { 78 | resolveDeclarationType(statementPrevSibling.declaration) 79 | statementPrevSibling = getPrevSiblingOfType(statementPrevSibling, GlslStatement::class.java) 80 | } 81 | var externalDeclaration = getParentOfType(element, GlslExternalDeclaration::class.java) 82 | while (externalDeclaration != null) { 83 | externalDeclaration = getPrevSiblingOfType(externalDeclaration, GlslExternalDeclaration::class.java) 84 | lookupInExternalDeclaration(externalDeclaration) 85 | } 86 | return null 87 | } 88 | 89 | /** 90 | * 91 | */ 92 | override fun lookupInExternalDeclaration(externalDeclaration: GlslExternalDeclaration?) { 93 | lookupInIncludeDeclaration(externalDeclaration?.ppStatement?.ppIncludeDeclaration) 94 | resolveDeclarationType(externalDeclaration?.declaration) 95 | } 96 | 97 | /** 98 | * 99 | */ 100 | private fun resolveDeclarationType(declaration: GlslDeclaration?) { 101 | if (declaration == null) return 102 | val structSpecifier = declaration.singleDeclaration?.typeSpecifier?.structSpecifier 103 | if (structSpecifier != null) { 104 | findReferenceInElement(structSpecifier) 105 | } else if (declaration.blockStructureWrapper != null) { 106 | findReferenceInElement(declaration.blockStructureWrapper?.blockStructure) 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /src/main/resources/builtin-objects/glsl-builtin-constants.glsl: -------------------------------------------------------------------------------- 1 | const int gl_MaxVertexAttribs; 2 | const int gl_MaxVertexUniformVectors; 3 | const int gl_MaxVertexUniformComponents; 4 | const int gl_MaxVertexOutputComponents; 5 | const int gl_MaxVaryingComponents; 6 | const int gl_MaxVaryingVectors; 7 | const int gl_MaxVertexTextureImageUnits; 8 | const int gl_MaxVertexImageUniforms; 9 | const int gl_MaxVertexAtomicCounters; 10 | const int gl_MaxVertexAtomicCounterBuffers; 11 | const int gl_MaxTessPatchComponents; 12 | const int gl_MaxPatchVertices; 13 | const int gl_MaxTessGenLevel; 14 | const int gl_MaxTessControlInputComponents; 15 | const int gl_MaxTessControlOutputComponents; 16 | const int gl_MaxTessControlTextureImageUnits; 17 | const int gl_MaxTessControlUniformComponents; 18 | const int gl_MaxTessControlTotalOutputComponents; 19 | const int gl_MaxTessControlImageUniforms; 20 | const int gl_MaxTessControlAtomicCounters; 21 | const int gl_MaxTessControlAtomicCounterBuffers; 22 | const int gl_MaxTessEvaluationInputComponents; 23 | const int gl_MaxTessEvaluationOutputComponents; 24 | const int gl_MaxTessEvaluationTextureImageUnits; 25 | const int gl_MaxTessEvaluationUniformComponents; 26 | const int gl_MaxTessEvaluationImageUniforms; 27 | const int gl_MaxTessEvaluationAtomicCounters; 28 | const int gl_MaxTessEvaluationAtomicCounterBuffers; 29 | const int gl_MaxGeometryInputComponents; 30 | const int gl_MaxGeometryOutputComponents; 31 | const int gl_MaxGeometryImageUniforms; 32 | const int gl_MaxGeometryTextureImageUnits; 33 | const int gl_MaxGeometryOutputVertices; 34 | const int gl_MaxGeometryTotalOutputComponents; 35 | const int gl_MaxGeometryUniformComponents; 36 | const int gl_MaxGeometryVaryingComponents; 37 | const int gl_MaxGeometryAtomicCounters; 38 | const int gl_MaxGeometryAtomicCounterBuffers; 39 | const int gl_MaxFragmentImageUniforms; 40 | const int gl_MaxFragmentInputComponents; 41 | const int gl_MaxFragmentUniformVectors; 42 | const int gl_MaxFragmentUniformComponents; 43 | const int gl_MaxFragmentAtomicCounters; 44 | const int gl_MaxFragmentAtomicCounterBuffers; 45 | const int gl_MaxDrawBuffers; 46 | const int gl_MaxTextureImageUnits; 47 | const int gl_MinProgramTexelOffset; 48 | const int gl_MaxProgramTexelOffset; 49 | const int gl_MaxImageUnits; 50 | const int gl_MaxSamples; 51 | const int gl_MaxImageSamples; 52 | const int gl_MaxClipDistances; 53 | const int gl_MaxCullDistances; 54 | const int gl_MaxViewports; 55 | const int gl_MaxComputeImageUniforms; 56 | const ivec3 gl_MaxComputeWorkGroupCount; 57 | const ivec3 gl_MaxComputeWorkGroupSize; 58 | const int gl_MaxComputeUniformComponents; 59 | const int gl_MaxComputeTextureImageUnits; 60 | const int gl_MaxComputeAtomicCounters; 61 | const int gl_MaxComputeAtomicCounterBuffers; 62 | const int gl_MaxCombinedTextureImageUnits; 63 | const int gl_MaxCombinedImageUniforms; 64 | const int gl_MaxCombinedImageUnitsAndFragmentOutputs; 65 | const int gl_MaxCombinedShaderOutputResources; 66 | const int gl_MaxCombinedAtomicCounters; 67 | const int gl_MaxCombinedAtomicCounterBuffers; 68 | const int gl_MaxCombinedClipAndCullDistances; 69 | const int gl_MaxAtomicCounterBindings; 70 | const int gl_MaxAtomicCounterBufferSize; 71 | const int gl_MaxTransformFeedbackBuffers; 72 | const int gl_MaxTransformFeedbackInterleavedComponents; 73 | const highp int gl_MaxInputAttachments; 74 | const int gl_MaxTextureUnits; 75 | const int gl_MaxTextureCoords; 76 | const int gl_MaxClipPlanes; 77 | const int gl_MaxVaryingFloats; -------------------------------------------------------------------------------- /src/main/resources/colors/GlslColorsConfiguration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 13 | 18 | 23 | 28 | 33 | 38 | 43 | 48 | 53 | 58 | 63 | 68 | 73 | 78 | 83 | 88 | -------------------------------------------------------------------------------- /src/main/resources/colors/color-demo-text.txt: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | #include "path/to/file.glsl" 4 | 5 | layout (location = 0) in vec3 aPos; 6 | out vec3 v_uv; 7 | 8 | #define add(x, y) x + y 9 | #define PI 3.14 10 | 11 | uniform mat4 model; 12 | uniform mat4 view; 13 | uniform mat4 projection; 14 | 15 | 16 | /** 17 | * Multi line comment 18 | * Multi line comment 19 | * Multi line comment 20 | * Multi line comment 21 | */ 22 | struct VertexInput { 23 | // Line comment above 24 | vec3 position; // Line comment aside 25 | vec4 color; 26 | vec2 quad_pos; 27 | } vertexInput; 28 | 29 | 30 | void main() { 31 | for (int i = 0; 1 >= 0; i++) { 32 | if (i > 0) { 33 | float l = 0.0f; 34 | } 35 | } 36 | } 37 | 38 | void run(int param) { 39 | int maxVertexAttr = gl_MaxVertexAttribs; 40 | float a = vec4(param, 1.0); 41 | float b = normalize(4.0); 42 | gl_Position = projection * view * model * vec4(aPos, 1.0f); 43 | EmitVertex(); 44 | } 45 | -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/internal/cs-template.comp.ft: -------------------------------------------------------------------------------- 1 | #version 100 2 | 3 | void main() { 4 | 5 | } -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/internal/fs-template.frag.ft: -------------------------------------------------------------------------------- 1 | #version 100 2 | 3 | void main() { 4 | 5 | } -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/internal/gs-template.geom.ft: -------------------------------------------------------------------------------- 1 | #version 100 2 | 3 | void main() { 4 | 5 | } -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/internal/shader-template.glsl.ft: -------------------------------------------------------------------------------- 1 | #version 100 2 | 3 | void main() { 4 | 5 | } -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/internal/tc-template.tesc.ft: -------------------------------------------------------------------------------- 1 | #version 100 2 | 3 | void main() { 4 | 5 | } -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/internal/te-template.tese.ft: -------------------------------------------------------------------------------- 1 | #version 100 2 | 3 | void main() { 4 | 5 | } -------------------------------------------------------------------------------- /src/main/resources/fileTemplates/internal/vs-template.vert.ft: -------------------------------------------------------------------------------- 1 | #version 100 2 | 3 | void main() { 4 | 5 | } -------------------------------------------------------------------------------- /src/main/resources/formatter/sample-code.txt: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (triangles) in; 3 | layout (line_strip, max_vertices = 6) out; 4 | 5 | in VS_OUT { 6 | vec3 normal; 7 | } gs_in; 8 | 9 | const float MAGNITUDE = 0.2; 10 | 11 | uniform mat4 projection; 12 | 13 | void generateLine(int index, float a) { 14 | for (int i = 0; i > 10; i++) { 15 | if (i > 2) { 16 | int forLoop = i; 17 | } 18 | int forLoop = i; 19 | forLoop = i + 1; 20 | int dummy = clamp(i, 2, 8); 21 | int ternary = forLoop <= 0 ? 1 : 0; 22 | } 23 | 24 | while (true) { 25 | int bla = pow(projection[0][0]); 26 | if (bla > 10.0 && index == 2) { 27 | float newVar = 10.0; 28 | } 29 | } 30 | 31 | gl_Position = projection * 2; 32 | } 33 | 34 | void main() { 35 | generateLine(2); 36 | } -------------------------------------------------------------------------------- /src/main/resources/inspectionDescriptions/GlslInspectionConstructorNoArguments.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Constructor of primitive type must have at least one argument 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/inspectionDescriptions/GlslInspectionIncompatibleType.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Incompatible types in initialization 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/inspectionDescriptions/GlslInspectionMissingReturn.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Missing return for function 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/inspectionDescriptions/GlslInspectionNoMatchingFunction.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | No matching function for call 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/inspectionDescriptions/GlslInspectionOperatorDoesNotOperate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Operator does not operate on 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/inspectionDescriptions/GlslInspectionTooFewArguments.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Too few arguments to constructor 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/inspectionDescriptions/GlslInspectionTooManyArguments.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Too many arguments to constructor 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/live-templates/glsl-live-template.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 16 | -------------------------------------------------------------------------------- /src/test/java/VectorStructGen.java: -------------------------------------------------------------------------------- 1 | import java.io.IOException; 2 | import java.io.PrintStream; 3 | import java.io.PrintWriter; 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | import java.nio.file.Paths; 7 | import java.util.function.Consumer; 8 | 9 | public class VectorStructGen { 10 | private static final String[][] types = new String[][] { 11 | { 12 | "Vec", "vec", "float" 13 | }, 14 | { 15 | "IVec", "ivec", "int" 16 | }, 17 | { 18 | "BVec", "bvec", "bool" 19 | }, 20 | { 21 | "DVec", "dvec", "double" 22 | }, 23 | { 24 | "UVec", "uvec", "uint" 25 | } 26 | }; 27 | private static final char[][] groups = new char[][] { 28 | "xyzw".toCharArray(), 29 | "rgba".toCharArray(), 30 | "stpq".toCharArray() 31 | }; 32 | 33 | public static void main(String[] args) throws IOException { 34 | var out = new PrintWriter(Files.newBufferedWriter(Path.of("glsl-vector-structs.glsl"))); 35 | out.println("int length();"); 36 | for (var type: types) { 37 | generateStruct(type, out); 38 | } 39 | out.close(); 40 | } 41 | 42 | private static void permute(char[] symbols, int symbolCount, int length, Consumer callback) { 43 | int permutations = 1; 44 | for (int i = 0; i < length; i++) { 45 | permutations *= symbolCount; 46 | } 47 | var sb = new StringBuilder(); 48 | for (int i = 0; i < permutations; i++) { 49 | sb.setLength(0); 50 | int current = i; 51 | for (int x = 0; x < length; x++) { 52 | sb.append(symbols[current % symbolCount]); 53 | current /= symbolCount; 54 | } 55 | sb.reverse(); 56 | callback.accept(sb.toString()); 57 | } 58 | } 59 | 60 | private static void generateStruct(String[] type, PrintWriter out) { 61 | var vec = type[1]; 62 | var scalar = type[2]; 63 | for (int source = 2; source <= 4; source++) { 64 | out.printf("struct %s%d {\n", type[0], source); 65 | for (int target = 1; target <= 4; target++) { 66 | String pfx = target == 1 ? scalar : vec + target; 67 | for (var group: groups) { 68 | permute(group, source, target, (str) -> { 69 | out.printf(" %s %s;\n", pfx, str); 70 | }); 71 | } 72 | } 73 | out.println("};\n"); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/test/kotlin/GlslDocumentationTest.kt: -------------------------------------------------------------------------------- 1 | 2 | import com.intellij.codeInsight.documentation.DocumentationManager 3 | import com.intellij.testFramework.fixtures.BasePlatformTestCase 4 | import glsl.psi.interfaces.GlslFunctionCall 5 | import glsl.psi.interfaces.GlslSingleDeclaration 6 | import glsl.psi.interfaces.GlslUnaryExpr 7 | 8 | 9 | class GlslDocumentationTest : BasePlatformTestCase() { 10 | 11 | override fun getTestDataPath(): String { 12 | return "src/test/testData/documentation" 13 | } 14 | 15 | fun testDocumentationFile1() { 16 | myFixture.configureByFile("DocumentationFile1.glsl") 17 | val originalElement = myFixture.elementAtCaret as GlslSingleDeclaration 18 | val glslPostfixExpr = originalElement.exprNoAssignmentList.first() as GlslUnaryExpr 19 | val variableIdentifier = (glslPostfixExpr.postfixExpr as GlslFunctionCall).variableIdentifier 20 | val element = DocumentationManager 21 | .getInstance(project) 22 | .findTargetElement(myFixture.editor, variableIdentifier?.containingFile, variableIdentifier) 23 | val documentationProvider = DocumentationManager.getProviderFromElement(element) 24 | val doc = documentationProvider.generateDoc(element, originalElement) 25 | assertNotNull(doc) 26 | assertTrue(doc!!.contains("
")) 27 | } 28 | 29 | // fun testDocumentationFile2() { 30 | // myFixture.configureByFile("DocumentationFile2.glsl") 31 | // val originalElement = myFixture.elementAtCaret 32 | // val element = DocumentationManager 33 | // .getInstance(project) 34 | // .findTargetElement(myFixture.editor, originalElement.containingFile, originalElement) 35 | // val documentationProvider = DocumentationManager.getProviderFromElement(element) 36 | // val doc = documentationProvider.generateDoc(element, originalElement) 37 | // assertNotNull(doc) 38 | // assertTrue(doc!!.contains("Function documentation")) 39 | // } 40 | } -------------------------------------------------------------------------------- /src/test/kotlin/GlslDummyTest.kt: -------------------------------------------------------------------------------- 1 | import com.intellij.testFramework.fixtures.BasePlatformTestCase 2 | import glsl.plugin.inspections.* 3 | 4 | class GlslDummyTest : BasePlatformTestCase() { 5 | 6 | override fun setUp() { 7 | super.setUp() 8 | myFixture.enableInspections( 9 | GlslInspectionTooFewArguments(), 10 | GlslInspectionTooManyArguments(), 11 | GlslInspectionIncompatibleType(), 12 | GlslInspectionMissingReturn(), 13 | // GlslInspectionNoMatchingFunction(), 14 | GlslInspectionOperatorDoesNotOperate(), 15 | ) 16 | } 17 | 18 | override fun getTestDataPath(): String { 19 | return "src/test/testData/dummy" 20 | } 21 | 22 | fun testDummy() { 23 | // myFixture.configureByFiles("dummy.glsl") 24 | // myFixture.testHighlighting(false, false, false) 25 | // val reference = myFixture.getReferenceAtCaretPosition("dummy.glsl") 26 | // val resolve = reference?.resolve() 27 | // assertInstanceOf(resolve, GlslSingleDeclaration::class.java) 28 | // assertEquals("dummy", (resolve as GlslSingleDeclaration).name) 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/kotlin/GlslFormatterTest.kt: -------------------------------------------------------------------------------- 1 | import com.intellij.openapi.command.WriteCommandAction 2 | import com.intellij.psi.codeStyle.CodeStyleManager 3 | import com.intellij.testFramework.fixtures.BasePlatformTestCase 4 | import com.intellij.util.containers.ContainerUtil 5 | 6 | class GlslFormatterTest : BasePlatformTestCase() { 7 | 8 | override fun getTestDataPath(): String { 9 | return "src/test/testData/formatter" 10 | } 11 | 12 | fun testFormatter() { 13 | myFixture.configureByFile("formatterFile.glsl") 14 | WriteCommandAction.writeCommandAction(project).run { 15 | val codeStyleManager = CodeStyleManager.getInstance(project) 16 | codeStyleManager.reformatText(myFixture.file, listOf(myFixture.file.textRange)) 17 | } 18 | myFixture.checkResultByFile("formatterFileExpected.glsl") 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/kotlin/GlslIncludeTest.kt: -------------------------------------------------------------------------------- 1 | import com.intellij.testFramework.fixtures.BasePlatformTestCase 2 | import glsl.psi.interfaces.GlslSingleDeclaration 3 | import glsl.psi.interfaces.GlslStructSpecifier 4 | 5 | class GlslIncludeTest : BasePlatformTestCase() { 6 | 7 | override fun getTestDataPath(): String { 8 | return "src/test/testData/include" 9 | } 10 | 11 | fun testInclude1() { 12 | myFixture.configureByFiles("IncludeFile2.glsl") 13 | val reference = myFixture.getReferenceAtCaretPosition("IncludeFile1.glsl") 14 | val resolve = reference?.resolve() 15 | assertInstanceOf(resolve, GlslSingleDeclaration::class.java) 16 | assertEquals("b", (resolve as GlslSingleDeclaration).name) 17 | } 18 | 19 | fun testImportCyclesDoNotThrowErrors() { 20 | myFixture.configureByFile("IncludeFile3.glsl") 21 | myFixture.checkHighlighting() 22 | val reference = myFixture.getReferenceAtCaretPosition("IncludeFile3.glsl") 23 | assertNoThrowable { reference?.resolve() } 24 | } 25 | 26 | fun testImportCyclesDontThrowErrorsNested() { 27 | val reference = myFixture.getReferenceAtCaretPosition("IncludeFile6.glsl") 28 | assertNoThrowable { reference?.resolve() } 29 | } 30 | 31 | fun testInclude4() { 32 | myFixture.configureByFiles("shaders/shaders2/IncludeFile7.glsl", "shaders/IncludeFile7.glsl") 33 | val reference = myFixture.getReferenceAtCaretPosition("shaders/IncludeFile8.glsl") 34 | val resolve = reference?.resolve() 35 | assertNull(resolve) 36 | } 37 | 38 | fun testInclude5() { 39 | myFixture.configureByFiles("shaders/shaders2/IncludeFile7.glsl", "shaders/IncludeFile7.glsl") 40 | val reference = myFixture.getReferenceAtCaretPosition("shaders/IncludeFile9.glsl") 41 | val resolve = reference?.resolve() 42 | assertInstanceOf(resolve, GlslSingleDeclaration::class.java) 43 | assertEquals("a", (resolve as GlslSingleDeclaration).name) 44 | } 45 | 46 | fun testInclude6() { 47 | myFixture.configureByFiles("shaders/shaders2/IncludeFile7.glsl", "shaders/IncludeFile7.glsl") 48 | val reference = myFixture.getReferenceAtCaretPosition("shaders/IncludeFile10.glsl") 49 | val resolve = reference?.resolve() 50 | assertInstanceOf(resolve, GlslSingleDeclaration::class.java) 51 | assertEquals("b", (resolve as GlslSingleDeclaration).name) 52 | } 53 | 54 | fun testInclude7() { 55 | myFixture.configureByFiles("IncludeFile8.glsl") 56 | val reference = myFixture.getReferenceAtCaretPosition("IncludeFile7.glsl") 57 | val resolve = reference?.resolve() 58 | assertInstanceOf(resolve, GlslStructSpecifier::class.java) 59 | assertEquals("A", (resolve as GlslStructSpecifier).name) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/kotlin/GlslInspectionsTest.kt: -------------------------------------------------------------------------------- 1 | import com.intellij.testFramework.fixtures.BasePlatformTestCase 2 | import glsl.plugin.inspections.* 3 | 4 | class GlslInspectionsTest : BasePlatformTestCase() { 5 | 6 | override fun getTestDataPath(): String { 7 | return "src/test/testData/inspections" 8 | } 9 | 10 | fun testDoesNotOperate() { 11 | myFixture.enableInspections(GlslInspectionOperatorDoesNotOperate()) 12 | myFixture.configureByFiles("InspectionsTestDoesNotOperate.glsl") 13 | myFixture.checkHighlighting(false, false, false) 14 | } 15 | 16 | fun testIncompatibleTypes() { 17 | myFixture.enableInspections(GlslInspectionIncompatibleType()) 18 | myFixture.configureByFiles("InspectionsTestIncompatibleTypes.glsl") 19 | myFixture.checkHighlighting(false, false, false) 20 | } 21 | 22 | fun testNoMatchingFunction() { 23 | // myFixture.enableInspections(GlslInspectionNoMatchingFunction()) 24 | // myFixture.configureByFiles("InspectionsNoMatchingFunction.glsl", "InspectionsNoMatchingFunction2.glsl") 25 | // myFixture.checkHighlighting(false, false, false) 26 | } 27 | 28 | fun testMissingReturn() { 29 | myFixture.enableInspections(GlslInspectionMissingReturn()) 30 | myFixture.configureByFiles("InspectionsTestMissingReturn.glsl") 31 | myFixture.checkHighlighting(false, false, false) 32 | } 33 | 34 | fun testPrimitiveConstructorZeroArguments() { 35 | myFixture.enableInspections(GlslInspectionConstructorNoArguments()) 36 | myFixture.configureByFiles("InspectionPrimitiveConstructorNoArguments.glsl") 37 | myFixture.checkHighlighting(false, false, false) 38 | } 39 | } -------------------------------------------------------------------------------- /src/test/kotlin/GlslLanguageInjectionTest.kt: -------------------------------------------------------------------------------- 1 | import com.intellij.testFramework.fixtures.BasePlatformTestCase 2 | import glsl.psi.interfaces.GlslSingleDeclaration 3 | import glsl.psi.interfaces.GlslStructDeclarator 4 | import junit.framework.TestCase 5 | import junit.framework.TestCase.assertNull 6 | import org.junit.Test 7 | 8 | class GlslLanguageInjectionTest : BasePlatformTestCase() { 9 | 10 | override fun getTestDataPath(): String { 11 | return "src/test/testData/languageInjection" 12 | } 13 | 14 | fun testLanguageInjection1() { 15 | val reference = myFixture.getReferenceAtCaretPosition("LanguageInjectionHtml.html") 16 | val resolve = reference?.resolve() 17 | assertInstanceOf(resolve, GlslSingleDeclaration::class.java) 18 | assertEquals("projMatrix", (resolve as GlslSingleDeclaration).name) 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/kotlin/GlslParserTest.kt: -------------------------------------------------------------------------------- 1 | import com.intellij.testFramework.ParsingTestCase 2 | import glsl.plugin.language.GlslParserDefinition 3 | 4 | 5 | class GlslParserTest : ParsingTestCase("", "test", GlslParserDefinition()) { 6 | 7 | override fun getTestDataPath(): String { 8 | return "src/test/testData/parser" 9 | } 10 | 11 | override fun skipSpaces(): Boolean { 12 | return true 13 | } 14 | 15 | override fun includeRanges(): Boolean { 16 | return true 17 | } 18 | 19 | fun testParserFile() { 20 | doTest(true) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/kotlin/GlslRenamingTest.kt: -------------------------------------------------------------------------------- 1 | import com.intellij.testFramework.fixtures.BasePlatformTestCase 2 | 3 | class GlslRenamingTest : BasePlatformTestCase() { 4 | 5 | override fun getTestDataPath(): String { 6 | return "src/test/testData/renaming" 7 | } 8 | 9 | fun testRenamingIdentifier1() { 10 | myFixture.configureByFile("RenamingIdentifierFile1.glsl") 11 | myFixture.renameElementAtCaret("newName") 12 | myFixture.checkResultByFile("RenamingIdentifierFile1Expected.glsl") 13 | } 14 | 15 | fun testRenamingIdentifier2() { 16 | myFixture.configureByFile("RenamingIdentifierFile2.glsl") 17 | assertThrows(RuntimeException::class.java) { myFixture.renameElementAtCaret("newName") } 18 | } 19 | 20 | fun testRenamingIdentifier3() { 21 | myFixture.configureByFile("RenamingIdentifierFile3.glsl") 22 | myFixture.renameElementAtCaret("f_updated") 23 | myFixture.checkResultByFile("RenamingIdentifierFile3Expected.glsl") 24 | } 25 | 26 | fun testRenamingIdentifier4() { 27 | myFixture.configureByFile("RenamingIdentifierFile4.glsl") 28 | myFixture.renameElementAtCaret("VAR_UPDATED") 29 | myFixture.checkResultByFile("RenamingIdentifierFile4Expected.glsl") 30 | } 31 | 32 | fun testRenamingIdentifier5() { 33 | myFixture.configureByFile("RenamingIdentifierFile5.glsl") 34 | myFixture.renameElementAtCaret("NewName") 35 | myFixture.checkResultByFile("RenamingIdentifierFile5Expected.glsl") 36 | } 37 | 38 | fun testRenamingIdentifier6() { 39 | myFixture.configureByFile("RenamingIdentifierFile6.glsl") 40 | myFixture.renameElementAtCaret("TexCoordUpdated") 41 | myFixture.checkResultByFile("RenamingIdentifierFile6Expected.glsl") 42 | } 43 | 44 | fun testRenamingIdentifier7() { 45 | myFixture.configureByFile("RenamingIdentifierFile7.glsl") 46 | myFixture.renameElementAtCaret("func_updated") 47 | myFixture.checkResultByFile("RenamingIdentifierFile7Expected.glsl") 48 | } 49 | 50 | fun testRenamingIdentifier8() { 51 | myFixture.configureByFile("RenamingIdentifierFile8.html") 52 | myFixture.renameElementAtCaret("func_updated") 53 | myFixture.checkResultByFile("RenamingIdentifierFile8Expected.html") 54 | } 55 | 56 | fun testRenamingIdentifier9() { 57 | myFixture.configureByFile("RenamingIdentifierFile9.glsl") 58 | myFixture.renameElementAtCaret("func_updated") 59 | myFixture.checkResultByFile("RenamingIdentifierFile9Expected.glsl") 60 | } 61 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile1.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = ab 3 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile10.glsl: -------------------------------------------------------------------------------- 1 | struct A { 2 | vec4 v; 3 | } a; 4 | 5 | struct B { 6 | vec4 first; 7 | } b; 8 | 9 | int main() { 10 | int b = b.first.xy.; 11 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile11.glsl: -------------------------------------------------------------------------------- 1 | struct A { 2 | vec4 v; 3 | } a; 4 | 5 | struct B { 6 | A first; 7 | } b; 8 | 9 | int main() { 10 | int b = b.first.v.rgb.; 11 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile12.glsl: -------------------------------------------------------------------------------- 1 | struct A { 2 | vec4 v; 3 | } a; 4 | 5 | struct B { 6 | A first; 7 | } b; 8 | 9 | int main() { 10 | int b = b.first.v.; 11 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile13.glsl: -------------------------------------------------------------------------------- 1 | #version 100 2 | 3 | void main() { 4 | in 5 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile14.glsl: -------------------------------------------------------------------------------- 1 | in fl -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile15.glsl: -------------------------------------------------------------------------------- 1 | float in -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile16.glsl: -------------------------------------------------------------------------------- 1 | int a = in -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile17.glsl: -------------------------------------------------------------------------------- 1 | int main(in int a, i) -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile18.glsl: -------------------------------------------------------------------------------- 1 | in -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile19.comp: -------------------------------------------------------------------------------- 1 | int a = gl_Max; -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile2.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = ma 3 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile20.comp: -------------------------------------------------------------------------------- 1 | int a = gl_LocalInvocationID.; -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile21.glsl: -------------------------------------------------------------------------------- 1 | void main() { 2 | a = gl_LocalInvocationID.; 3 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile22.glsl: -------------------------------------------------------------------------------- 1 | struct A { 2 | vec3 vec; 3 | } a; 4 | 5 | void main() { 6 | vec3 dummy = a.; 7 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile23.glsl: -------------------------------------------------------------------------------- 1 | void main() { 2 | vec3 dummy = 1; 3 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile24a.glsl: -------------------------------------------------------------------------------- 1 | #include "" 2 | -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile3.geom: -------------------------------------------------------------------------------- 1 | int main() { 2 | ver; 3 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile4.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = em; 3 | w 4 | int a = main(); 5 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile5.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = em; 3 | while (a) { 4 | if (a) { 5 | s 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile6.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (int a = 1; s) 3 | int a = em; 4 | int a = main(); 5 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile7.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = em; 3 | int a = w; 4 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile8.glsl: -------------------------------------------------------------------------------- 1 | # 2 | int main() { 3 | int a = 1; 4 | int a = 2; 5 | } -------------------------------------------------------------------------------- /src/test/testData/completion/CompletionFile9.glsl: -------------------------------------------------------------------------------- 1 | #version 3 2 | int main() { 3 | int a = 1; 4 | int a = 2; 5 | } -------------------------------------------------------------------------------- /src/test/testData/completion/include-test/include-test2/CompletionFile24b.glsl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rmordechay/glsl-plugin-idea/3057cd24014a123109fafe4be16438d2133934f9/src/test/testData/completion/include-test/include-test2/CompletionFile24b.glsl -------------------------------------------------------------------------------- /src/test/testData/completion/include-test/include-test3/CompletionFile24c.glsl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rmordechay/glsl-plugin-idea/3057cd24014a123109fafe4be16438d2133934f9/src/test/testData/completion/include-test/include-test3/CompletionFile24c.glsl -------------------------------------------------------------------------------- /src/test/testData/documentation/DocumentationFile1.glsl: -------------------------------------------------------------------------------- 1 | int absCall = abs(); -------------------------------------------------------------------------------- /src/test/testData/documentation/DocumentationFile2.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Function documentation 3 | */ 4 | int func() {} 5 | int absCall = func(); -------------------------------------------------------------------------------- /src/test/testData/dummy/dummy.glsl: -------------------------------------------------------------------------------- 1 | struct Test { 2 | uvec3 A; 3 | } test; 4 | 5 | uint a = test.A[0]; -------------------------------------------------------------------------------- /src/test/testData/formatter/formatterFile.glsl: -------------------------------------------------------------------------------- 1 | #define VAR void a; 2 | #define VAR2( a , b ) a + b; 3 | 4 | int c = VAR2( 1 , 2 ) 5 | #version 330 6 | // One line comment 7 | /* 8 | * Multi line comment 9 | */ 10 | 11 | int mouse2 = vec2( - iTime / 148. , cos( iTime ) / 24.); 12 | int mouse3 = vec2 ( - iTime ) ; 13 | 14 | #define DEF void f(int aa, float a); 15 | #define DEF2(roi, roi2) void f(int roi, float roi2); 16 | #define DEF3 if (a > 2) { a = 2; a = 2; a = 2; } 17 | #define DEF4 (a > 2) 18 | void main() { 19 | DEF 20 | DEF2( a , b ) 21 | DEF3 22 | } 23 | 24 | 25 | #define FUN(a, b) a + b; 26 | #define DEF4 int a = 2; 27 | #define PI 3.14 28 | 29 | void main( ) { 30 | DEF 31 | FUN(1, 2) 32 | float a = normalize( a * PI ); 33 | } 34 | 35 | #define BINDLESS_TEX(ty, name) \ 36 | layout (set = BINDLESS_SET, binding = BINDLESS_TEX_BINDING) \ 37 | uniform ty name[BINDLESS_TEX_COUNT]; 38 | 39 | #include "file.h" 40 | __LINE__ 10 41 | 42 | #include < shaders/func.frag > 43 | 44 | #define f(a, b) a + \ 45 | b 46 | 47 | int dummy = f( 1, 2 ) ; 48 | 49 | // One line comment 50 | struct DummyStruct { 51 | // One line comment 52 | int struct_declarator1 ; 53 | int struct_declarator2[ ] ; 54 | int struct_declarator3 [ ] [] ; 55 | int struct_declarator4, struct_declarator5; 56 | } dummyStruct ; 57 | 58 | void func(int a, int a, int a, int a, int a); 59 | 60 | void func(int a, int a, int a, 61 | int a, int a); 62 | 63 | void func(int a, 64 | int a, 65 | int a, 66 | int a, 67 | int a); 68 | 69 | void func( 70 | int a, 71 | int a, 72 | int a, 73 | int a, 74 | int a 75 | ); 76 | 77 | void func( 78 | int a, 79 | int a, 80 | int a, 81 | int a, 82 | int a); 83 | 84 | int a = func( 85 | vec2(0.0, 0.8), 86 | vec2(-0.6, -0.8), 87 | vec2(0.6, -0.8) 88 | ); 89 | 90 | const float CONSTANT_DECLRATION = 0.2 ; 91 | float singl_declration[ ] = {1, 2 , 3 }; 92 | float singl_declration [ 2] = 0.2; 93 | int a = a.b.c.i; 94 | 95 | // One line comment 96 | float a[1 ] [2][3], b [2] [1] = 2 ; 97 | 98 | int a = a; 99 | int a = a [1] ; 100 | int a = a [1] [2]; 101 | int a = a [1] [2][3]; 102 | 103 | 104 | float _a = { 1.0, 2.0, 3.0, 4.0 }; 105 | float _a = { 1.0 + 2, 2.0 * 2, 3.0 / 2, 4.0 - 2.0 }; 106 | 107 | float[] a = float[]( 1, 2, 3); 108 | float[] a = float[3 ]( 1, 2, 3 ); 109 | 110 | int a = - (-1); 111 | int a = - 1; 112 | int a = - 1u + -1 - 1 - -2; 113 | int a = - dot(vec4(), vec4()); 114 | int a = - a [ 0 ]; 115 | int a = - a ++ ; 116 | int a = - a.a ; 117 | int a = 1 - 1u; 118 | int a = 1; 119 | int a = 1 + 2 / (2 + 2) + 1 * 2 ; 120 | 121 | int a = a( ) ; 122 | 123 | layout (location) in vec2 layout_declration; 124 | layout (location = 2) in vec2 layout_declration; 125 | layout (location = 1, max_vertices ) in vec4 layout_declration ; 126 | layout (location = 1, max_vertices = 2 > a) in vec4 layout_declration ; 127 | layout (triangles_strip, max_vertices = 3) out ; 128 | layout (triangles_strip, max_vertices = 3) ; 129 | 130 | layout (location = 3 ) centroid out float layout_declration; 131 | layout ( location) uniform UniformType { 132 | mat3 a ; 133 | mat4 b ; 134 | } uni ; 135 | 136 | 137 | void main( UserType a , UserType b) {} 138 | UserType main () {} 139 | 140 | 141 | noperspective centroid out vec2 a ; 142 | centroid out vec2 a; 143 | smooth out vec2 a[]; 144 | // One line comment 145 | int function_definition ( float x , float y ); 146 | int function_definition( DummyBlock x , float y ) { 147 | int a = 2 == b ? b : abs() ; 148 | void main(); 149 | expr_statement(); 150 | // One line comment 151 | if ( selection_statement == 1 ) { 152 | // One line comment 153 | if ( inner_id < 6 ) { 154 | dummy ; 155 | } 156 | } else if ( selection_statement_else ) { 157 | dummy; 158 | } else { 159 | dummy; 160 | } 161 | 162 | if (_x % int(a.x / 2) == 0 || _y % int(b.y / 2) == 0 ) { 163 | a = vec4 ( 0, 0, 1, 1); 164 | a = abs ( 0, 0, 1, 1); 165 | } 166 | 167 | for ( int i; i > 20; i++ ) { 168 | int a = i ; 169 | a = i + 2; 170 | } 171 | 172 | while (shouldRun) { 173 | if (!shouldRun) { 174 | call() ; 175 | } else { 176 | call(); 177 | continue ; 178 | } 179 | shouldRun = 1; 180 | } 181 | 182 | do { 183 | int shouldRun = 1; 184 | shouldRun = 0; 185 | } while ( shouldRun); 186 | 187 | switch ( switch_statement ) { 188 | case 1 : 189 | int a = 1; 190 | return 1 ; 191 | case 2 : 192 | if ( true ) { 193 | doSomthing() ; 194 | } 195 | return 2; 196 | default : 197 | int a ; 198 | return 3 ; 199 | } 200 | 201 | float declaration_statement [ 2 ] = func( g ( h(x, y), z)); 202 | 203 | demote ; 204 | continue ; 205 | break ; 206 | return jump_statement ; 207 | EmitVertex(); 208 | gl_Position = a.b * vec4( ( x * vec3( 5.0, 5.0, 0.0) ) + y[0].xyz, 1.0); 209 | } 210 | 211 | -------------------------------------------------------------------------------- /src/test/testData/formatter/formatterFileExpected.glsl: -------------------------------------------------------------------------------- 1 | #define VAR void a; 2 | #define VAR2(a, b) a + b; 3 | 4 | int c = VAR2(1, 2) 5 | #version 330 6 | // One line comment 7 | /* 8 | * Multi line comment 9 | */ 10 | 11 | int mouse2 = vec2(-iTime / 148., cos(iTime) / 24.); 12 | int mouse3 = vec2(-iTime); 13 | 14 | #define DEF void f(int aa, float a); 15 | #define DEF2(roi, roi2) void f(int roi, float roi2); 16 | #define DEF3 if (a > 2) { a = 2; a = 2; a = 2; } 17 | #define DEF4 (a > 2) 18 | void main() { 19 | DEF 20 | DEF2(a, b) 21 | DEF3 22 | } 23 | 24 | 25 | #define FUN(a, b) a + b; 26 | #define DEF4 int a = 2; 27 | #define PI 3.14 28 | 29 | void main() { 30 | DEF 31 | FUN(1, 2) 32 | float a = normalize(a * PI); 33 | } 34 | 35 | #define BINDLESS_TEX(ty, name) \ 36 | layout (set = BINDLESS_SET, binding = BINDLESS_TEX_BINDING) \ 37 | uniform ty name[BINDLESS_TEX_COUNT]; 38 | 39 | #include "file.h" 40 | __LINE__ 10 41 | 42 | #include 43 | 44 | #define f(a, b) a + \ 45 | b 46 | 47 | int dummy = f(1, 2); 48 | 49 | // One line comment 50 | struct DummyStruct { 51 | // One line comment 52 | int struct_declarator1; 53 | int struct_declarator2[]; 54 | int struct_declarator3[][]; 55 | int struct_declarator4, struct_declarator5; 56 | } dummyStruct; 57 | 58 | void func(int a, int a, int a, int a, int a); 59 | 60 | void func(int a, int a, int a, 61 | int a, int a); 62 | 63 | void func(int a, 64 | int a, 65 | int a, 66 | int a, 67 | int a); 68 | 69 | void func( 70 | int a, 71 | int a, 72 | int a, 73 | int a, 74 | int a 75 | ); 76 | 77 | void func( 78 | int a, 79 | int a, 80 | int a, 81 | int a, 82 | int a); 83 | 84 | int a = func( 85 | vec2(0.0, 0.8), 86 | vec2(-0.6, -0.8), 87 | vec2(0.6, -0.8) 88 | ); 89 | 90 | const float CONSTANT_DECLRATION = 0.2; 91 | float singl_declration[] = { 1, 2, 3 }; 92 | float singl_declration[2] = 0.2; 93 | int a = a.b.c.i; 94 | 95 | // One line comment 96 | float a[1][2][3], b[2][1] = 2; 97 | 98 | int a = a; 99 | int a = a[1]; 100 | int a = a[1][2]; 101 | int a = a[1][2][3]; 102 | 103 | 104 | float _a = { 1.0, 2.0, 3.0, 4.0 }; 105 | float _a = { 1.0 + 2, 2.0 * 2, 3.0 / 2, 4.0 - 2.0 }; 106 | 107 | float[] a = float[](1, 2, 3); 108 | float[] a = float[3](1, 2, 3); 109 | 110 | int a = -(-1); 111 | int a = -1; 112 | int a = -1u + -1 - 1 - -2; 113 | int a = -dot(vec4(), vec4()); 114 | int a = -a[0]; 115 | int a = -a++; 116 | int a = -a.a; 117 | int a = 1 - 1u; 118 | int a = 1; 119 | int a = 1 + 2 / (2 + 2) + 1 * 2; 120 | 121 | int a = a(); 122 | 123 | layout (location) in vec2 layout_declration; 124 | layout (location = 2) in vec2 layout_declration; 125 | layout (location = 1, max_vertices) in vec4 layout_declration; 126 | layout (location = 1, max_vertices = 2 > a) in vec4 layout_declration; 127 | layout (triangles_strip, max_vertices = 3) out; 128 | layout (triangles_strip, max_vertices = 3); 129 | 130 | layout (location = 3) centroid out float layout_declration; 131 | layout (location) uniform UniformType { 132 | mat3 a; 133 | mat4 b; 134 | } uni; 135 | 136 | 137 | void main(UserType a, UserType b) {} 138 | UserType main() {} 139 | 140 | 141 | noperspective centroid out vec2 a; 142 | centroid out vec2 a; 143 | smooth out vec2 a[]; 144 | // One line comment 145 | int function_definition(float x, float y); 146 | int function_definition(DummyBlock x, float y) { 147 | int a = 2 == b ? b : abs(); 148 | void main(); 149 | expr_statement(); 150 | // One line comment 151 | if (selection_statement == 1) { 152 | // One line comment 153 | if (inner_id < 6) { 154 | dummy; 155 | } 156 | } else if (selection_statement_else) { 157 | dummy; 158 | } else { 159 | dummy; 160 | } 161 | 162 | if (_x % int(a.x / 2) == 0 || _y % int(b.y / 2) == 0) { 163 | a = vec4(0, 0, 1, 1); 164 | a = abs(0, 0, 1, 1); 165 | } 166 | 167 | for (int i; i > 20; i++) { 168 | int a = i; 169 | a = i + 2; 170 | } 171 | 172 | while (shouldRun) { 173 | if (!shouldRun) { 174 | call(); 175 | } else { 176 | call(); 177 | continue; 178 | } 179 | shouldRun = 1; 180 | } 181 | 182 | do { 183 | int shouldRun = 1; 184 | shouldRun = 0; 185 | } while (shouldRun); 186 | 187 | switch (switch_statement) { 188 | case 1: 189 | int a = 1; 190 | return 1; 191 | case 2: 192 | if (true) { 193 | doSomthing(); 194 | } 195 | return 2; 196 | default: 197 | int a; 198 | return 3; 199 | } 200 | 201 | float declaration_statement[2] = func(g(h(x, y), z)); 202 | 203 | demote; 204 | continue; 205 | break; 206 | return jump_statement; 207 | EmitVertex(); 208 | gl_Position = a.b * vec4((x * vec3(5.0, 5.0, 0.0)) + y[0].xyz, 1.0); 209 | } 210 | 211 | -------------------------------------------------------------------------------- /src/test/testData/include/IncludeFile1.glsl: -------------------------------------------------------------------------------- 1 | #include "IncludeFile2.glsl" 2 | void main() { 3 | int a = b; 4 | } 5 | -------------------------------------------------------------------------------- /src/test/testData/include/IncludeFile2.glsl: -------------------------------------------------------------------------------- 1 | int b = 2; -------------------------------------------------------------------------------- /src/test/testData/include/IncludeFile3.glsl: -------------------------------------------------------------------------------- 1 | #include "IncludeFile3.glsl" 2 | int a = b; -------------------------------------------------------------------------------- /src/test/testData/include/IncludeFile4.glsl: -------------------------------------------------------------------------------- 1 | #include "IncludeFile5.glsl" 2 | -------------------------------------------------------------------------------- /src/test/testData/include/IncludeFile5.glsl: -------------------------------------------------------------------------------- 1 | #include "IncludeFile6.glsl" 2 | -------------------------------------------------------------------------------- /src/test/testData/include/IncludeFile6.glsl: -------------------------------------------------------------------------------- 1 | #include "IncludeFile4.glsl" 2 | int a = b; 3 | -------------------------------------------------------------------------------- /src/test/testData/include/IncludeFile7.glsl: -------------------------------------------------------------------------------- 1 | #include "IncludeFile8.glsl" 2 | 3 | void main() { 4 | A a = A(); 5 | } -------------------------------------------------------------------------------- /src/test/testData/include/IncludeFile8.glsl: -------------------------------------------------------------------------------- 1 | struct A { 2 | int a; 3 | }; -------------------------------------------------------------------------------- /src/test/testData/include/shaders/IncludeFile10.glsl: -------------------------------------------------------------------------------- 1 | #include "IncludeFile7.glsl" 2 | 3 | int c = b; -------------------------------------------------------------------------------- /src/test/testData/include/shaders/IncludeFile7.glsl: -------------------------------------------------------------------------------- 1 | int b = 2; 2 | -------------------------------------------------------------------------------- /src/test/testData/include/shaders/IncludeFile8.glsl: -------------------------------------------------------------------------------- 1 | #include "IncludeFile7.glsl" 2 | 3 | int c = a; -------------------------------------------------------------------------------- /src/test/testData/include/shaders/IncludeFile9.glsl: -------------------------------------------------------------------------------- 1 | #include "shaders2/IncludeFile7.glsl" 2 | 3 | int c = a; -------------------------------------------------------------------------------- /src/test/testData/include/shaders/shaders2/IncludeFile7.glsl: -------------------------------------------------------------------------------- 1 | int a = 2; 2 | -------------------------------------------------------------------------------- /src/test/testData/inspections/InspectionPrimitiveConstructorNoArguments.glsl: -------------------------------------------------------------------------------- 1 | void main() { 2 | int a = int(); 3 | int a = int(1); 4 | mat3 a = mat3(); 5 | mat3 a = mat3(1); 6 | vec3 a = vec3(); 7 | vec3 a = vec3(1); 8 | } -------------------------------------------------------------------------------- /src/test/testData/inspections/InspectionsNoMatchingFunction.glsl: -------------------------------------------------------------------------------- 1 | #include "InspectionsNoMatchingFunction2.glsl" 2 | 3 | float a = normalize(2, 2); 4 | 5 | float smoothFunc(float a, float b, float x) { 6 | float a = smoothFunc(2, 2); 7 | return smoothFunc(2); 8 | } -------------------------------------------------------------------------------- /src/test/testData/inspections/InspectionsNoMatchingFunction2.glsl: -------------------------------------------------------------------------------- 1 | float smoothFunc(float a) { 2 | return 2; 3 | } -------------------------------------------------------------------------------- /src/test/testData/inspections/InspectionsTestDoesNotOperate.glsl: -------------------------------------------------------------------------------- 1 | // Scalar-Scalar 2 | float a0 = 1 + 1; 3 | float a1 = 1 - 1; 4 | float a2 = 1 * 1; 5 | float a3 = 1 / 1; 6 | // Scalar-Vector 7 | vec3 a12 = 1 + vec3(1); 8 | vec3 a13 = 1 - vec3(1); 9 | vec3 a14 = 1 * vec3(1); 10 | vec3 a15 = 1 / vec3(1); 11 | // Scalar-Matrix 12 | mat3 a20 = 1 + mat3(1); 13 | mat3 a21 = 1 - mat3(1); 14 | mat3 a22 = 1 * mat3(1); 15 | mat3 a23 = 1 / mat3(1); 16 | // Vector-Scalar 17 | vec3 a16 = vec3(1) + 1; 18 | vec3 a17 = vec3(1) - 1; 19 | vec3 a18 = vec3(1) * 1; 20 | vec3 a19 = vec3(1) / 1; 21 | // Vector-Vector 22 | vec3 a4 = vec3(1) + vec3(1); 23 | vec3 a5 = vec3(1) - vec3(1); 24 | vec3 a6 = vec3(1) * vec3(1); 25 | vec3 a7 = vec3(1) / vec3(1); 26 | // Vector-Matrix 27 | mat3 a28 = vec3(1) + mat3(1); 28 | mat3 a29 = vec3(1) - mat3(1); 29 | vec3 a30 = vec3(1) * mat3(1); 30 | mat3 a31 = vec3(1) / mat3(1); 31 | // Matrix-Scalar 32 | mat3 a24 = mat3(1) + 1; 33 | mat3 a25 = mat3(1) - 1; 34 | mat3 a26 = mat3(1) * 1; 35 | mat3 a27 = mat3(1) / 1; 36 | // Matrix-Vector 37 | mat3 a32 = mat3(1) + vec3(1); 38 | mat3 a33 = mat3(1) - vec3(1); 39 | vec3 a34 = mat3(1) * vec3(1); 40 | mat3 a35 = mat3(1) / vec3(1); 41 | // Matrix-Matrix 42 | mat3 a8 = mat3(1) + mat3(1); 43 | mat3 a9 = mat3(1) - mat3(1); 44 | mat3 a10 = mat3(1) * mat3(1); 45 | mat3 a11 = mat3(1) / mat3(1); -------------------------------------------------------------------------------- /src/test/testData/inspections/InspectionsTestIncompatibleTypes.glsl: -------------------------------------------------------------------------------- 1 | int a = normalize(2.0); 2 | int a = normalize(2); 3 | float a = normalize(2); 4 | float a = normalize(2.0f); 5 | float a = normalize(2.f); 6 | float a = normalize(2); 7 | int b, c = a; 8 | int b, c = 2.0f; 9 | -------------------------------------------------------------------------------- /src/test/testData/inspections/InspectionsTestMissingReturn.glsl: -------------------------------------------------------------------------------- 1 | int f() {} 2 | int f() {return 0;} 3 | int f() {if (true) { return 0; }} 4 | void f() {} 5 | void f() {if (true) { }} 6 | -------------------------------------------------------------------------------- /src/test/testData/languageInjection/LanguageInjectionHtml.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/testData/reference/FindUsageFile1.glsl: -------------------------------------------------------------------------------- 1 | int a; 2 | int b = a; 3 | int main() { 4 | int b = abs(a); 5 | if (b) { 6 | a; 7 | } 8 | } -------------------------------------------------------------------------------- /src/test/testData/reference/FindUsageFile2.glsl: -------------------------------------------------------------------------------- 1 | #define VAR 10 2 | 3 | void main() { 4 | int a = VAR + 10; 5 | int b = abs(VAR); 6 | } 7 | -------------------------------------------------------------------------------- /src/test/testData/reference/FindUsageFile3.glsl: -------------------------------------------------------------------------------- 1 | #define EPSILON_NRM iResolution 2 | 3 | void main() { 4 | vec3 p; 5 | heightMapTracing(p); 6 | vec3 dist = p - ori; 7 | vec3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM); 8 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile1.glsl: -------------------------------------------------------------------------------- 1 | int a = 2; 2 | int b = a + 2; -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile10.glsl: -------------------------------------------------------------------------------- 1 | void f1(int param1, int param2) { 2 | 3 | } 4 | 5 | void f2() { 6 | int a = param1; 7 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile11.glsl: -------------------------------------------------------------------------------- 1 | void f1(int param1, int param2) { 2 | int a = param1; 3 | } 4 | -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile12.glsl: -------------------------------------------------------------------------------- 1 | void f1(int param1, int param2) { 2 | if (param2 == 1) { 3 | while (true) { 4 | int a = param1; 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile13.glsl: -------------------------------------------------------------------------------- 1 | struct A { 2 | int a; 3 | }; 4 | 5 | A c = A(1); 6 | -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile14.glsl: -------------------------------------------------------------------------------- 1 | int main(int param) { 2 | int a = param; 3 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile15.glsl: -------------------------------------------------------------------------------- 1 | struct Inner 2 | { 3 | vec4 pos; 4 | vec4 vel; 5 | }; 6 | 7 | layout (location) buffer Pos 8 | { 9 | Inner inner[]; 10 | }; 11 | 12 | void main() { 13 | int index = 1; 14 | inner[index].vel.xyz += 1; 15 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile16.glsl: -------------------------------------------------------------------------------- 1 | struct Inner { 2 | vec4 pos; 3 | vec4 vel; 4 | }; 5 | 6 | layout (location) buffer Pos { 7 | Inner inner[]; 8 | }; 9 | 10 | void main() { 11 | int index = 1; 12 | inner[index].vel.xyz += 1; 13 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile17.comp: -------------------------------------------------------------------------------- 1 | int a = gl_LocalInvocationID; -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile18.comp: -------------------------------------------------------------------------------- 1 | uint a = gl_LocalInvocationID.x; -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile19.frag: -------------------------------------------------------------------------------- 1 | void main() { 2 | gl_FragCoord = vec4(); 3 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile2.glsl: -------------------------------------------------------------------------------- 1 | struct A { 2 | int structMember; 3 | } a; 4 | 5 | int dummy = a.structMember; -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile20.frag: -------------------------------------------------------------------------------- 1 | void main() { 2 | int a = gl_MaxGeometryInputComponents; 3 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile21.glsl: -------------------------------------------------------------------------------- 1 | void main() { 2 | vec4 a = normalize(vec3()).xy; 3 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile22.glsl: -------------------------------------------------------------------------------- 1 | struct A { 2 | vec4 vec; 3 | }; 4 | 5 | in B { 6 | A a[]; 7 | } b; 8 | 9 | 10 | void main() { 11 | b.a[0].vec.w; 12 | } 13 | -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile23.glsl: -------------------------------------------------------------------------------- 1 | void main() { 2 | mat4 m; 3 | vec3 a = m[0].xyz; 4 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile24.glsl: -------------------------------------------------------------------------------- 1 | struct A { 2 | int a; 3 | }; 4 | 5 | void main() { 6 | int b = a; 7 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile25.glsl: -------------------------------------------------------------------------------- 1 | layout (location) in Pos { 2 | vec4 vec; 3 | } a; 4 | 5 | void main() { 6 | vec4 dummy = vec; 7 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile26.glsl: -------------------------------------------------------------------------------- 1 | layout (location) in Pos { 2 | vec4 vec; 3 | }; 4 | 5 | void main() { 6 | vec4 dummy = vec; 7 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile27.glsl: -------------------------------------------------------------------------------- 1 | void main() { 2 | int a = normalize(vec4(2.0, 2, 2, 2)).xz; 3 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile28.glsl: -------------------------------------------------------------------------------- 1 | void main() { 2 | float arr[10]; 3 | abs(arr[1]); 4 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile29.glsl: -------------------------------------------------------------------------------- 1 | void main() { 2 | int a = 0; 3 | a++; 4 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile3.glsl: -------------------------------------------------------------------------------- 1 | struct A { 2 | int c; 3 | } a; 4 | 5 | struct B { 6 | A a; 7 | } b; 8 | 9 | int dummy = b.a.c; -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile30.glsl: -------------------------------------------------------------------------------- 1 | #define PI 3.14 2 | int n = PI; -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile31.glsl: -------------------------------------------------------------------------------- 1 | #define f(a, b) a + b + 2 2 | 3 | int dummy = f(1, 2); -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile32.glsl: -------------------------------------------------------------------------------- 1 | #define VAR 10 2 | 3 | void main() { 4 | int a = VAR + 10; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile33.glsl: -------------------------------------------------------------------------------- 1 | #define X 2 2 | #define YY X 3 | #define ZZZ YY 4 | int a = ZZZ; -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile34.glsl: -------------------------------------------------------------------------------- 1 | int a, b, c = 1; 2 | int d = a; -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile35.glsl: -------------------------------------------------------------------------------- 1 | int a, b, c = 1; 2 | int d = b; -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile36.glsl: -------------------------------------------------------------------------------- 1 | int a, b, c = 1; 2 | int d = c; -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile37.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (int i = 1; i > 10; i++) { 3 | int dummy = i; 4 | } 5 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile4.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | int dummy = dummy; 3 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile5.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (int i = 1; i > 10; i++) { 3 | int dummy = i; 4 | } 5 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile6.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | for (int i = 1; i > 10; i++) { 3 | int dummy = i; 4 | } 5 | i; 6 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile7.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | if (true) { 3 | int a = 1; 4 | } 5 | int dummy = a; 6 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile8.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | int dummy = dummy; 3 | } -------------------------------------------------------------------------------- /src/test/testData/reference/ReferenceFile9.glsl: -------------------------------------------------------------------------------- 1 | int main() { 2 | int dummy = 1; 3 | dummy = dummy + 1; 4 | } -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile1.glsl: -------------------------------------------------------------------------------- 1 | struct Third { 2 | int i; 3 | } third; 4 | 5 | struct Second { 6 | Third third; 7 | } second; 8 | 9 | struct First { 10 | Second second; 11 | } first; 12 | 13 | int dummy = first.second.third; -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile1Expected.glsl: -------------------------------------------------------------------------------- 1 | struct Third { 2 | int i; 3 | } third; 4 | 5 | struct Second { 6 | Third newName; 7 | } second; 8 | 9 | struct First { 10 | Second second; 11 | } first; 12 | 13 | int dummy = first.second.newName; -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile2.glsl: -------------------------------------------------------------------------------- 1 | struct Third { 2 | vec4 v; 3 | } third; 4 | 5 | struct Second { 6 | Third third; 7 | } second; 8 | 9 | struct First { 10 | Second second; 11 | } first; 12 | 13 | int dummy = first.second.third.v.xyz; -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile2Expected.glsl: -------------------------------------------------------------------------------- 1 | struct Third { 2 | vec4 v; 3 | } third; 4 | 5 | struct Second { 6 | Third third; 7 | } second; 8 | 9 | struct First { 10 | Second second; 11 | } first; 12 | 13 | int dummy = first.second.third.v.xyz; -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile3.glsl: -------------------------------------------------------------------------------- 1 | #define f(a, b) 10 2 | 3 | void main() { 4 | int a = f(1, 2) + 10; 5 | int b = abs(f(1, 2)); 6 | } 7 | -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile3Expected.glsl: -------------------------------------------------------------------------------- 1 | #define f_updated(a, b) 10 2 | 3 | void main() { 4 | int a = f_updated(1, 2) + 10; 5 | int b = abs(f_updated(1, 2)); 6 | } 7 | -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile4.glsl: -------------------------------------------------------------------------------- 1 | #define VAR 10 2 | 3 | void main() { 4 | int a = VAR + 10; 5 | int b = abs(VAR); 6 | } 7 | -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile4Expected.glsl: -------------------------------------------------------------------------------- 1 | #define VAR_UPDATED 10 2 | 3 | void main() { 4 | int a = VAR_UPDATED + 10; 5 | int b = abs(VAR_UPDATED); 6 | } 7 | -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile5.glsl: -------------------------------------------------------------------------------- 1 | struct Third { 2 | int i; 3 | } third; 4 | 5 | struct Second { 6 | Third third; 7 | } second; 8 | 9 | struct First { 10 | Second second; 11 | } first; 12 | 13 | Third dummy = first.second.third; -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile5Expected.glsl: -------------------------------------------------------------------------------- 1 | struct NewName { 2 | int i; 3 | } third; 4 | 5 | struct Second { 6 | NewName third; 7 | } second; 8 | 9 | struct First { 10 | Second second; 11 | } first; 12 | 13 | NewName dummy = first.second.third; -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile6.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | #define PI 3.14 3 | #define func(a, b) if (a > b) { int num = 2; } 4 | #include "different/file.glsl" 5 | 6 | precision mediump float; 7 | layout (location = 0) in vec3 aPos; 8 | layout (location = 1) in vec2 aTexCoord; 9 | 10 | out vec2 TexCoord; 11 | 12 | uniform mat4 model; 13 | uniform mat4 view; 14 | uniform mat4 projection2; 15 | 16 | void main() { 17 | TexCoord = vec2(1, 1); 18 | } -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile6Expected.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | #define PI 3.14 3 | #define func(a, b) if (a > b) { int num = 2; } 4 | #include "different/file.glsl" 5 | 6 | precision mediump float; 7 | layout (location = 0) in vec3 aPos; 8 | layout (location = 1) in vec2 aTexCoord; 9 | 10 | out vec2 TexCoordUpdated; 11 | 12 | uniform mat4 model; 13 | uniform mat4 view; 14 | uniform mat4 projection2; 15 | 16 | void main() { 17 | TexCoordUpdated = vec2(1, 1); 18 | } -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile7.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | #define PI 3.14 3 | #define func(a, b) if (a > b) { int num = 2; } 4 | #include "different/file.glsl" 5 | 6 | precision mediump float; 7 | layout (location = 0) in vec3 aPos; 8 | layout (location = 1) in vec2 aTexCoord; 9 | 10 | out vec2 TexCoord; 11 | 12 | uniform mat4 model; 13 | uniform mat4 view; 14 | uniform mat4 projection2; 15 | 16 | /** 17 | * 18 | */ 19 | int addd2(int a, int b) { 20 | func(1, 2) 21 | float v = normalize(a * PI); 22 | return a + b; 23 | } 24 | 25 | void main() { 26 | gl_Position = projection * view * model * vec4(abs(aPos), 1.0f); 27 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 28 | } -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile7Expected.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | #define PI 3.14 3 | #define func_updated(a, b) if (a > b) { int num = 2; } 4 | #include "different/file.glsl" 5 | 6 | precision mediump float; 7 | layout (location = 0) in vec3 aPos; 8 | layout (location = 1) in vec2 aTexCoord; 9 | 10 | out vec2 TexCoord; 11 | 12 | uniform mat4 model; 13 | uniform mat4 view; 14 | uniform mat4 projection2; 15 | 16 | /** 17 | * 18 | */ 19 | int addd2(int a, int b) { 20 | func_updated(1, 2) 21 | float v = normalize(a * PI); 22 | return a + b; 23 | } 24 | 25 | void main() { 26 | gl_Position = projection * view * model * vec4(abs(aPos), 1.0f); 27 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 28 | } -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile8.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 40 | 41 | -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile8Expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 40 | 41 | -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile9.glsl: -------------------------------------------------------------------------------- 1 | int a = 2; -------------------------------------------------------------------------------- /src/test/testData/renaming/RenamingIdentifierFile9Expected.glsl: -------------------------------------------------------------------------------- 1 | int a = 2; --------------------------------------------------------------------------------