From 0dd8eca961eada173810e5ebba1ba758b5ce4933 Mon Sep 17 00:00:00 2001 From: JohnHake Date: Wed, 5 Feb 2020 19:28:43 -0800 Subject: [PATCH 1/3] Add simple_language and updates to simple_language_plugin --- simple_language/build.gradle | 37 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 58702 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + simple_language/gradlew | 183 ++++++ simple_language/gradlew.bat | 100 ++++ simple_language/settings.gradle | 2 + .../intellij/sdk/language/SimpleLexer.java | 535 ++++++++++++++++++ .../sdk/language/parser/SimpleParser.java | 127 +++++ .../sdk/language/psi/SimpleProperty.java | 23 + .../sdk/language/psi/SimpleTypes.java | 28 + .../sdk/language/psi/SimpleVisitor.java | 22 + .../language/psi/impl/SimplePropertyImpl.java | 59 ++ .../java/com/intellij/sdk/language/Simple.bnf | 30 + .../com/intellij/sdk/language/Simple.flex | 44 ++ .../sdk/language/SimpleAnnotator.java | 59 ++ .../intellij/sdk/language/SimpleBlock.java | 54 ++ .../SimpleChooseByNameContributor.java | 33 ++ .../sdk/language/SimpleCodeStyleSettings.java | 11 + .../SimpleCodeStyleSettingsProvider.java | 37 ++ .../sdk/language/SimpleColorSettingsPage.java | 73 +++ .../sdk/language/SimpleCommenter.java | 38 ++ .../language/SimpleCompletionContributor.java | 28 + .../SimpleCreatePropertyQuickFix.java | 92 +++ .../intellij/sdk/language/SimpleFileType.java | 39 ++ .../sdk/language/SimpleFileTypeFactory.java | 16 + .../language/SimpleFindUsagesProvider.java | 63 +++ .../sdk/language/SimpleFoldingBuilder.java | 78 +++ .../SimpleFormattingModelBuilder.java | 39 ++ .../intellij/sdk/language/SimpleIcons.java | 9 + .../intellij/sdk/language/SimpleLanguage.java | 11 + ...mpleLanguageCodeStyleSettingsProvider.java | 42 ++ .../sdk/language/SimpleLexerAdapter.java | 11 + .../language/SimpleLineMarkerProvider.java | 40 ++ .../sdk/language/SimpleParserDefinition.java | 68 +++ .../SimpleRefactoringSupportProvider.java | 20 + .../sdk/language/SimpleReference.java | 57 ++ .../language/SimpleReferenceContributor.java | 34 ++ .../language/SimpleStructureViewElement.java | 74 +++ .../language/SimpleStructureViewFactory.java | 23 + .../language/SimpleStructureViewModel.java | 32 ++ .../sdk/language/SimpleSyntaxHighlighter.java | 57 ++ .../SimpleSyntaxHighlighterFactory.java | 14 + .../com/intellij/sdk/language/SimpleUtil.java | 54 ++ .../language/psi/SimpleElementFactory.java | 29 + .../sdk/language/psi/SimpleElementType.java | 12 + .../intellij/sdk/language/psi/SimpleFile.java | 31 + .../sdk/language/psi/SimpleNamedElement.java | 8 + .../sdk/language/psi/SimpleTokenType.java | 16 + .../psi/impl/SimpleNamedElementImpl.java | 14 + .../language/psi/impl/SimplePsiImplUtil.java | 79 +++ .../src/main/resources/META-INF/plugin.xml | 66 +++ .../main/resources/META-INF/pluginIcon.svg | 58 ++ .../src/main/resources/icons/jar-gray.png | Bin 0 -> 717 bytes .../sdk/language/SimpleCodeInsightTest.java | 83 +++ .../sdk/language/SimpleParsingTest.java | 32 ++ .../src/test/testData/AnnotatorTestData.java | 7 + .../src/test/testData/CompleteTestData.java | 5 + .../src/test/testData/DefaultTestData.simple | 14 + .../src/test/testData/FindUsagesTestData.java | 5 + .../test/testData/FindUsagesTestData.simple | 13 + .../src/test/testData/FoldingTestData.java | 11 + .../test/testData/FormatterTestData.simple | 15 + .../src/test/testData/ParsingTestData.simple | 17 + .../src/test/testData/ParsingTestData.txt | 66 +++ .../src/test/testData/ReferenceTestData.java | 5 + .../src/test/testData/RenameTestData.java | 5 + .../src/test/testData/RenameTestData.simple | 13 + .../test/testData/RenameTestDataAfter.simple | 13 + .../simpleplugin/SimpleFoldingBuilder.java | 16 +- .../simpleplugin/SimpleParserDefinition.java | 8 +- .../testData/AnnotatorTestData.java | 2 +- .../simpleplugin/SimpleCodeInsightTest.java | 5 +- 72 files changed, 3037 insertions(+), 12 deletions(-) create mode 100644 simple_language/build.gradle create mode 100644 simple_language/gradle/wrapper/gradle-wrapper.jar create mode 100644 simple_language/gradle/wrapper/gradle-wrapper.properties create mode 100755 simple_language/gradlew create mode 100644 simple_language/gradlew.bat create mode 100644 simple_language/settings.gradle create mode 100644 simple_language/src/main/gen/com/intellij/sdk/language/SimpleLexer.java create mode 100644 simple_language/src/main/gen/com/intellij/sdk/language/parser/SimpleParser.java create mode 100644 simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleProperty.java create mode 100644 simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleTypes.java create mode 100644 simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleVisitor.java create mode 100644 simple_language/src/main/gen/com/intellij/sdk/language/psi/impl/SimplePropertyImpl.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/Simple.bnf create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/Simple.flex create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleAnnotator.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleBlock.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleChooseByNameContributor.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettings.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleColorSettingsPage.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleCommenter.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleCompletionContributor.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleCreatePropertyQuickFix.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleFileType.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleFileTypeFactory.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleFindUsagesProvider.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleFoldingBuilder.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleFormattingModelBuilder.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleIcons.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleLanguage.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleLexerAdapter.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleLineMarkerProvider.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleParserDefinition.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleRefactoringSupportProvider.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleReference.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleReferenceContributor.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewElement.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewFactory.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewModel.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleSyntaxHighlighter.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleSyntaxHighlighterFactory.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/SimpleUtil.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleElementFactory.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleElementType.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleFile.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleNamedElement.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleTokenType.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/psi/impl/SimpleNamedElementImpl.java create mode 100644 simple_language/src/main/java/com/intellij/sdk/language/psi/impl/SimplePsiImplUtil.java create mode 100644 simple_language/src/main/resources/META-INF/plugin.xml create mode 100644 simple_language/src/main/resources/META-INF/pluginIcon.svg create mode 100644 simple_language/src/main/resources/icons/jar-gray.png create mode 100644 simple_language/src/test/java/com/intellij/sdk/language/SimpleCodeInsightTest.java create mode 100644 simple_language/src/test/java/com/intellij/sdk/language/SimpleParsingTest.java create mode 100644 simple_language/src/test/testData/AnnotatorTestData.java create mode 100644 simple_language/src/test/testData/CompleteTestData.java create mode 100644 simple_language/src/test/testData/DefaultTestData.simple create mode 100644 simple_language/src/test/testData/FindUsagesTestData.java create mode 100644 simple_language/src/test/testData/FindUsagesTestData.simple create mode 100644 simple_language/src/test/testData/FoldingTestData.java create mode 100644 simple_language/src/test/testData/FormatterTestData.simple create mode 100644 simple_language/src/test/testData/ParsingTestData.simple create mode 100644 simple_language/src/test/testData/ParsingTestData.txt create mode 100644 simple_language/src/test/testData/ReferenceTestData.java create mode 100644 simple_language/src/test/testData/RenameTestData.java create mode 100644 simple_language/src/test/testData/RenameTestData.simple create mode 100644 simple_language/src/test/testData/RenameTestDataAfter.simple diff --git a/simple_language/build.gradle b/simple_language/build.gradle new file mode 100644 index 000000000..34c2bd394 --- /dev/null +++ b/simple_language/build.gradle @@ -0,0 +1,37 @@ +plugins { + id 'java' + id 'org.jetbrains.intellij' version '0.4.15' +} + +group 'com.intellij.sdk' +version '2.0.0' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +test { + // Set idea.home.path to the absolute path to the intellij-community source + // on your local machine. + systemProperty "idea.home.path", "/Users/jhake/Documents/source/comm" +} + +// Include the generated files in the source set +sourceSets.main.java.srcDirs 'src/main/gen' + +dependencies { + testCompile group: 'junit', name: 'junit', version: '4.12' +} + +// See https://github.com/JetBrains/gradle-intellij-plugin/ +intellij { + version '2019.3.2' + type = 'IC' + plugins 'java' + updateSinceUntilBuild = false +} +patchPluginXml { + version = project.version +} diff --git a/simple_language/gradle/wrapper/gradle-wrapper.jar b/simple_language/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..cc4fdc293d0e50b0ad9b65c16e7ddd1db2f6025b GIT binary patch literal 58702 zcma&OV~}W3vL#%;<*Hk@ZQHhO+qTVHwr$(CZQFL$+?np4n10i5zVAmKMC6WrGGd+F zD|4@NHj-D$z)bJV;MYNJ&!D%)v-fQ%q0JG$_z5GVUJTPg0MHPf1TvicY#6DXYBBQ4M`$iC~gA;06+%@0HFQPLj-JXogAJ1j+fRqw^4M` zcW^RxAfl%+w9SiS>QwBUTAfuFAjPXc2DHf6*sr+V+jLQj^m@DQgHTPmAb@F z8%GyCfcQkhWWlT31%4$PtV4tV*LI?J#C4orYI~WU(cSR{aEs^ycxY`1>j1po>yDMi zh4W$pMaecV*mCsOsPLxQ#Xc!RXhpXy*p3S2Hl8t}H7x#p5V6G5va4jV;5^S^+>+x&#zzv4!R}wB;)TyU zE_N~}nN>DTG+uZns%_eI=DL1E#<--Sccx30gvMT}^eu`2-u|{qQZ58(rA2aBYE*ZD zm|*12zg*@J$n|tbH%Mp|d|O9W%VT~xG})R=Ld5z<(z%DOO6=MF3Xh-aF%9Hf$?1N9%8Pkev{wun$jZ2 z^i*EhRt8Ve<7`Wyz~iMZDye+XVn}O%qbhV`wHL+%P+n)K&-UMuZw^RRfeQ)%K=k*m zq5l7mf`4K_WkV5B73~MxajljrjGiJqpiV#>0FkyyrB)@HY!;Ln(7JJ*W(>d5#^ubU zVAkTMs*CHzzvUa^nRu0*f-(ek+VZw+@P~}a;;(K=|!9Mhv(~y-mlW);J zb&bB=vySHG`u?j&_6dh^*se*l_B3avjlE|!!Cb0pXyEXRbLy*@WEQ4|)M<`p8Q!rfDJ2RI!u1hPzNjy&)(kcY~GaD6?)7#dCbm`NFh?Y_g$#!+Qrie7%<7P}<-+W@{sxi4JYI{iY zk0(>m$DxOI=~-&eXf2bfh^&(U@o)>(iA1_wJ%B(+nFH+ceib%HEck32QL=J(BNFh`f>St1%llF8chX7#cp*;z}& zcTeXkwsXhf+e;##!FS2yi=2cChcYfzm$wQJ z9%4kAq)wLHf5wfcj!A|xDsAiAOHRzf*)Z-|daN9y5jK-*R{Q0?xaSX-3m|WeuZ`BJ z>eTi@uQ{OGSDIJ#Iu@JPtOy!C?q)g*6SHORg)eAJGh8b-I*X_+xNqZ|OXEsQ-RWte ze`zjjeV9PpE3ac2za+Rs=PA;%QZ>T{x(TRzwWLp_X^2yC-DOEMUy5So!npzL&-@}u z#>uK#&`i&c%J$!bsntEJhY@rF(>6eY;6RoI5Qkn!&<80X5+1(x$T|wR-ad?4N1N^a0)nBj#&EkVvQ?I_+8t*%l#VK&I?uo$ERI1HMu4P2rLMeH%m3 zZ|HA^*O^dA$gb$`Cw;z9?G?m3@nH6TNYJ04Fd-M2wp8@(;vAvJ ztFoni)BLwncQ3@cO*^+6u;(&D<;N;RKb)_NQ_Qu&?@h3MWvo>6FHG%%*smTwj3;dG zQJnT7Wb?4!XmV^>N@ZkA7Jv9kAfD-gCHu2i+!A!}y98SO><8g}t;1JOOxj>#l zM!?y|j5fR3WY2(&_HSGjgMa?Zif<M@d8W z)4>Ptm@zj|xX=bbt$=j}@a_s|xdp6-tRlq6D|xb_;`9oJlkYF1AH%?Pzv$eIAogMi zf(_H*5t({Arfs5XAPj46pjiudQw?dulW-=OUqBVa)OW9E;^R+NDr&LES&m_nmP>Ga zPf)7_&Gn(3v1qu_a^qW9w4#XIEfgiHOQ(LDi=E&(-DcUSfuQE0`ULsRvS}fpS@<)3 z|CbQSi49rU{<4|XU;kiV|C7}Gld$}Yh5YXjg^W$~ovobybuZ^&YwBR^=qP3G=wxhT z?C_5Trbu~95mOoIXUmEOY646_j4ZL)ubCM{qFkl1u*%xs%#18a4!(*b<&edy<8t2w z_zUxWS5fypUp9ue+eswoJSyv*J&=*3;2;q9U?j>n^q?)}c8+}4Ns8oToBJgD;Ug=y zOa0>{VFrLJutjR{PJmm(P9lPzoPi{K!I{l)pGwDy59p-uxHB9I&7zl11lkCu(}*A< zh492AmxsgwEondBpB^{`I*L&Ut40fjM^JS8VdAWQMlwc>_RUM5|Mjes!36DGqW`xs z4tU4`CpOk|vew8!(L}fEvv5&-3#GqZ(#1EZF4ekDQ@y*$tMDEeG?nOUiS-KXG=rAZ zHUDlMo@X&yzo1TdE6b6!s#f{*45V-T3`e2)w5Ra3l>JWf46`v?Y6B&7*1$eS4M(3% z9C~G@N@RXm)8~EXL*9IObA+PwD)`%64fON_8}&pqjrg|2LmP{W^<0@W`9s^*i#F}V;E8~`-}(4@R4kz?t(RjA;y-r%s^=)15%C> zbF;NZET~nybEsmUr8sH^Hgq^xc^n$ZP=GcZ!-X-Go7J4nByj8%?aQ`c{88;p15Kf>|0h+5BLkM&@KI-(flp^npO3MC~W@Uyjv* z6Hu!4#(NtZJ0*;_{8^xcLrC4-zK$BVo7S5V=eg?R8P;BOpK3Xwms+Jt-8R6us zf_rUHFYHn~lu!)U$e$#%UBz7d8YS;mq}xx$T1PIi=4={c-_cY6OVc<=){mOVn>~J$ zW*2PB%*40eE^c+d=PP7J@bqIX_h4u6b6#W|ir<;IlR`#s`Q*_Z8Q?*s_&emuu8D;NSiPX9mK?>$CwcbjhCuv zO&u(0)@}8nZe=Fl*0uMri02oYDjs#g$OHCZ6oTXV2Y0TrZ}+o%{%i)OAJBj2xHC|F5o+`Qmq`$`2EaL=uePwq%k<;6S2n=w%_9vj$8NO|{` zTEg*tK8PU#DnQ#dQ2mMJaaL|HV;BCn?eQ%d0vY@S7Pu@7 zsf5u`T=bL7NfyYO?K^PR_|jap@K|qQ zmO8CK+&O3fzgEnp2|_=^K9ln~QhxjgMM>EQqY@k@@#np@FnZq|C{EyEP7^NurUm0q zW5rKmiy%__KE>YItATyMhE({0%ve10la=mUd<^AcB{T_$Y`2_N-x;F#3xTORXvhPZ7psmqhXy?WxxB5w!m*4&Q;?t$4Kt?m_em-htVDxora24&6~5z$MG(RT{trtp(L( zy&VDT{@p9_DGoq+I|abw$E!TyTO7j6dWQ25dqdKV*z3E?n-p|IG42ZUnNok? zY4K{y{27bUT@#|Zcni!tIgjE`j=-0rl(tVlWEn>5x7BJBkt0iw6j^4n1f2i^6ebo; zt^&Yb##}W0$3xhH&Nz*nANYpO$emARR6-FWX;C?(l7+}<97Ay#!y%BI6^st=LaJ>n zu{ORVJ9%`f*oy85MUf@Fek@T_+ML0-0b$lkEE2y8h%#P^X6+cn)IEXa@T7CQ{fV z-{^wJGN*+T!NsAH@VNM3tWG;%y{pVF2m z2*0+i?o40zSKVq_S18#=0RrJIse+;5cv#a`*`wNs+B%Ln8#e0v^I>7a_33h?lHo14 zg)CbDfGMyH2cj%7C`>|Rrg;U?$&y!z(U10>(dHKQsf9*=z)&@9u@w%y+e@*CnUS|E z*O^cQqM*!sD|e!u(yhXPi$Sl<$daf3sq@Iexafxt3F#2R&=cK z!gT-qto{oVdGUIxC0q`tg)B-Zy(pxGx}&svoA}7p=}jb3jEjQ!v6=afKI!2`&M{#tY$~3LR}#G#U2up2L{} zMGSX>Yjg6-^vWgeX0i;Nb0=gQmYa!|r0rRUshm2+z3AlehjfTqRGnRAmGhHY3`R_@ zPh4GAF@=nkRz;xMO3TPh$)9Iq?Fs5B@~)QIntSyeBy^10!ts?9Z@tK&L6xJd9 zNzaaz6zvrtr&MPQ@UD)njFUtFupwB zv+8%r`c@#asm}cKW^*x0%v_k3faHOnRLt7vzVFlqslue32rt(NNXnkS+fMSM&^u)8 zC`p{on>0pf=1id|vzdTnBLB;v%*ta`o_lzj21u+U-cTRXR%sxE%4k<(bU!orfsJ&v z3FLM2UT_*)BJm1^W;Z{0;z^_e=N&QXSO>rdB`*cp>yGnjHJt$ zcJd~52X&k1b<-`2R{bqLm*E(W{=|-)RTB*i$h4TdV12@beTkR&*iJ==ck*QlFiQ52 zBZ|o_LP06C?Sgs3VJ=oZQU0vK6#}f9gHSs)JB7TU2h~}UVe%unJA!URBgJ# zI~26)lGD4yk~ngKRg;(s4f@PccDZaL{Y=%6UKHl&k|M@Zc4vdx-DX4{belQ);URF? zyxW+|Ziv}%Y!sFdY@YO))Z|f34L(WjN*v#EfZHn6m)X@;TzQ@wIjl4B_TieZY}qY`mG}3VL{w?; z&O>sZ8)YnW+eLuW@rhClOOCZe2YP@4YWKN?P{c~zFUj*U?OayavPUo!r{uqA1<8h! zs0=rKKlwJYk~34F9$q6fQ&jnw_|@cTn{_kA8sUZ#2(Lb@R$NL*u>08yYGx{p6OeX~ zr7!lwGqMSury(v5=1_9%#*MORl2apGf(MQIQTMN35yE3l`^OS7r;SKS6&v-5q}Gw* zNWI*4OKBD&2YbCr8c{ifn~-9w-v+mV49W+k)$jjU@WA+Aok01SA#X$Sspj}*r52!- zNqOS<0%uMUZeSp+*i1TEO$KGKn7EwzW=s?(b5X^@3s5k*80ns2I2|bTHU+bWZ$x;j z`k@>)1G#JgT=F!8awgol?DqK^S4R*g?e}2rOYRVMUKKxSudO(hOLnnL zQqpxPNouLiQFYJs3?7!9f6!-#Pi83{q3-GgOA|{btKup4fYDu-JFOK~Q1c3KD@fdJ z?uABYOkHA^Fc~l0gTAy4geF<-1UqdS=b=UM6Xi30mPhy1-f^aQh9H(jwFl5w*X`Mh z=Ee5C?038GEqSVTd!67bn9*zQg-r8RIH3$$ zf8vWEBbOc`_0U{b)t)Toa~~<7c-K_=G%*iTW^?6mj9{#)@|# zku9R^IDzbzzERz~fpxFrU*it;-Iu&m!CAtM&$)6^2rMyV4 z$+e!$(e)!UY(Sc9n6hkr^n&cvqy8}NfZz+AQc8fU9lNczlP>5D3qzWoR55YvH94^* z-S%SVQ96pK3|Yo`75D&85)xij9Dl8AO8{J*{_yhs-KtsLXUYqwieO(nfrkB@%|OyI>yF+1G?m7>X&djb(HBNNw3KX;Ma*oMV)cV0xzxmIy+5>yz>l_LLH)VyRnYYce zw$?q!hJzX0TlE0+o5QJDM~sPrjVCN7#|32#rUkc>?-eN6Q0RqQTAl~`&isrQg)ass z+x5XapaYh{Dj`+V096?w)w2!Cnmh?x1WmFC$jEFY4;V)XAl3*tBS)V)3TbL)g46_g zCw9pl^!3OCTOcaEP!?==guEAw;VZ}fE6K-;@qD-Rx~td+j(N>)Wv$_mqFTH_wVZNEEuDG!0T`HXLsf+_E=X3lw4`_&d5&YMl%H733ckO){vZm znFLS`;5J#^`5~unet`V#*Y5In3yb|Ax z|A6b^F37!_z$_{6h{7l~<{u7{Fx*A*#zw{GD)6e}n6f<|)&7`S-txiz3Jm4S5hV&8 zm|Ncc{j_~`^pQ*I#w21;(jwi8GnH4efO;R|r4$tH~i;Bcmp^sP9) zjhJne@yzU&XvFNoc~i(wQ?nE`o6Hk~!;x(%xh7?zvigH2g`!v8L-vEN0DvV3?m( zSW(TZ%2AWf`rS}GGMqUj!8yCp#|fR--Vxfj=9}YD97Gocdj=S z0zkF-jsO>EcPTB1zRO$++k^bH%O`=UkHdHT^5?{$)ot<-K2XIE7js*4OjF)BsVjCJ z*KN)!FdM*sh=fB$p8*EzZmGJp?B_=a-90$FI{S$LLjBU$(lxUj;9 zIBszmA*129W+YE;Yy{J~3uyOr<2A(`*cu0IJN#tmUfz2jIWQi_h)_-V6o+5CjbX!1$lz6?QYU za&|O#F%~hmGUhil{M+J|*0<3&{a1%ONp-^!Qx*LOTYY}L!r9BbTxCjHMuUR0E(uH` z!b$*ZMdnB{b2vsb<&P6})+%O=%a8@~$fjbtfF@Z>^Q@enTOJ%VT)Rdc!wX|@iq9i}HaFZAeY6g8xGZY7h-r1sy_<#YU6}I?L zwvf0ePE5PKbK>2RiJOFO5xNhMY+kt`Qi?Oxo&@xH$<^Q;Nb(&rjPBAcv;XtmSY90z z;oIFFl%lDq$o&kYQ;aSHZHD@W({Y1hw<-I>7f_X8wc?%hNDlo~Ig;63RlHNhw~#R3 zA*f5D_Qo`4_ajY4Gr{mLs*(Fxh(U%oua_u3r%`H!TI)@R!!iqV8IOhIOzI@=7QJ=G zV$(9mEVL(7DvPn0j%_cOZN|vvNg8*PHma`6+oS;PDz%iOFyo0n0e%$<#A3r~$=I0T zDL*{AREUGx&C2}?I9cVL`UcPyawTqA4j-4%Mr-4`9#8GX1jiJkKGpHVr1~Rj#zFaZ zqmE!<|1JCi!LDG?1^Ys62xz(p;Uu!QZB7!C0#piy1_9=e?^s@-sd1gs!h$;Q`TNtf z3N4Elsgl#={#U`~&}FNvH78MLjjavl1x*4pNVr338>%sfHu>bxo2#eZN2ee9q#*Jg zDk_=OBR;8t6=pBN0aj)&Nj}pzqqUYW(tfk?bXTdKbNQFSUMCyN-!b0#3?Z;ijzx$M z^Eo6Eq*NO!Y8K;84H4MHj_xwBYc|3>+D(PFj7ejhECG@5@Pk&8dG<)HwwO2~j7KV6 z0$s}=*D;ek#8$a*sxVlC_`qFkM0%BQQ@v2H&Aq@G9XCQt^^x<8w*=MbZV)@aPrrn; z`6r*&f`x&1lp)`5>-|-4%l&W4jy~LydfN;iq?Y8Xx>Sh#2Lx@FXo|5{WKp@y-x;)7 zl;;_Y*-Nu3pcH-)p0(tP~3xO_u~>HpCdEfgyq7V-!ZZ{?`6v_b-vx< zuu|gm5mG6c@D{FYMLuzvG+A2T&6&`n>XM%s`+Qtj)5XdpyFOnz3KLSCOxaCEUl()M z3b~FYqA3FT1#SY{p36h%M^gBQpB2QzEdtM9hMBMRMu{|rf}(;S85&|A!|Aj}?fMKaju!y>_AS}#hRe_!&%8V=6+oPPtE zOOJ-Rcrf>hNq@lG{{@$H?6ikt@!A2OePLe{MBIWSPz7{u(I} z$PXzD;leHG?Xl0FnWt+Wrkrk*|e3P~YVF@N$y&L929cc=#-!*k)HZKDo8!#+t|?9p0z1KSDKclB&M6~hN5<9~^DIltXKR$+iK*h9k$|@Qoy9H}PSI;b(v>w`8(k70@sfa4nRweeiwZ-syP3zPSsyK_8Te9*(FQdm+ z84ZDah4PGehH72w=Q8bx;pK5juT67rJKb|ovD#COI^l6z0eBidn$!Y?T2;5sN+vTV z$`%Edb<%-Oq@NPZy<2Z3m;$}!9JzIuVK6;fJi>>m3q!Lr!2xXRq+l0LvZIR_PNYrP57E#sCvD^4UU2GVr*Rx`QcT}yQanF z3i~!-2Vkk4S%4Hd2baDvrM2g(&1jZaA1!vLi!I#5wX6g^&PE`0-TovM(%wuaPXAno z`a&j{ai=TsgKpc1C3|)tY#!4>SPBbMnchi}glCBwaNE(4`gi}JY0;`|m`s{HtaP@& zHxwCt#2&z9A7O+=v>za}LW~}G>_tWo$dsRX)f1L=+tZF5E&RBA#jUC|N9ZPa_&z5= zekCOsIfOh`p(&S8dnkE~9#(;BAh8qzi5JYT0nP7x&Hga3v`XFdRN|$5Ry#mq*AN$J zV)l~LSq}2d{EJ@%{TLnkRVn*sdM{_b|4!x73|Ux9{%S;FPyhfZ{xg;P2ZmMuA*cMG zipYNeI7{u98`22!_phwRk|lyX#49r%Lq1aZAabxs6MP79J3Kxh0z1E>MzLS6Ee5u+ z@od~O#6yMa;R}eI*a|ZB$ar0BT`%X4+kyxqW4s+D3rV176EAsfS**6-swZ9OIPRZ& zlmIH>ppe;l28`Kd0z(alw^r<%RlDpI6hv)6Gs?GIpffKApgx^)2-6jAzjZE0BtPBC z0z8!#C5AP${zTF$-Z^v%^ie8LI*rvR+*xc=>fa;`SRUSLAio?qL;jVFV1Bw4K>D+i zyEQ}vyG2HTx>W?Ul&MhxUXK7n;yfN)QS`foM!4>4-(PGwxW!^^UyKOz(v+1BejI*& zQSkV|m5=JF4T0k*+|h|3dx`ZKBVX7H4{5iakAxnD#J=9igW@LS;HE_8$lZy1l|$wX zn<8-$u=7&li+^MB(1y~Mz7lj7?oYf%1k{wT#?(Mep094qqnPv7*OYkQ#7$pkU5U24 zzPLEwAb<VIp_uUE~+r5)jt(>>Bg48_{)twH$QJDSBrUS!j{lX z)SK$6dfLWt)c9%Cml+sRp*OHXB?e4hbYZQo!@=6 zBPTpi&6&atD*#Cn6f@5<>79Mq7o0^E!NH)bD26g}?@qg%*AYeE6Tec@F?y9Q8i}^s zz`)l`8>;h75!kL!`&*_hsX1%2)(lWr|7!}@gn%MfwY8vN0=pMm3WesCRv5e*5m4z|u(zbYCpuxO9$bY)hkL|}mRj{3dlRgNK)#PJp#vR=ka^TZ(tKVI<>M~ekIfd2 zm3UDUNW*ZvS5L|SF334|YD>LJk(EqgPpVxtzwclUNaH70zWDVt^1+cz|F?RdF4HHn z@4~Gs`lj!0dWi2n#>7C@B$Qf7|t{1!3mtrO1H7 zi{=I#^Oa1jJiFI!j>PualW+ncHJ)TelW$bv2MqUG1xK7R z%TsQfTn)7D3}XYU+{?Hq!I&fqi4>DmryMiO?!aN!T4fnwq2vsuB^s6fPW@u*h-JwG zNniJFR(RI*?5HV=tqO)lv}CRv_eNEBR%z}Vnftv0+DUH^OCODH#&;{+aw^1vR z-c~|Mk+o?j-^Z+rR4s z-gNA5guTuab7N`{Y@eT&)!xF8#AeetvQ6d!W4BlO;0#0TxS_( zMm-A-u+h7-PjmOQHlh{Hxn+J$jh?uEtc8RG8tu->og@ z86A%eUt+P8E3oLXIrq#K(nCF@L12>=DVT3ec6Vn=B^B;>D=O%op+0BT;T)FHZ`I93 z^5|bpJC_kB92`alM40Am>Yz5o1gxkIGRYQ)x^+R|TCK)r;Qyq6+~S9Uy9nr^nkvc- zxw~#_9eBBJcZNK0yFZxUK4h>u$8;4k-KpNTblRgS(y&u~u&J;O!aqAMYJp+(BED*d z^I#F7vPOEADj}Pziprs=a{%qgz#eso$j`At7pN~bDw%&ba-+4pI}T*?w-z^_~DfD~Z3Tg+#M#u{s&uRF^dr5RFZh7<|WNEG;P z-_SzXTbHc^yD$r;WJqqJkA7^(zN`nzQ5V16nG~Zobuy)a)(T@Ik>V!qOfw;e z)?AZXjzDJg%BkIEY&bm&BczLuWY~k}3Zyx#)jxg1A9R`sz!_dCb!|13b*3PiA@(E6 z9HmG2R>-YrW93UMQO}XE4loI(*er9J*wDUd1se!pzdpoB_v6^lQl}+!6e5MS`+bU#_b*a5Pkt;o+lOV4loyn2P z$3;z-cX>$R{6M4q%b}aMBF}6N+0RCE70bB;XwHV~JLO&!EB)Cgo9ta_>>Os1HNfaY z4PNu7BGhw`6}cm>glh6i^)Ja{rpLHix?C?u;(e&GI{?!E7$9hd*5c^iL?;6Kwn z@qbBE|3UMF|F$Ok>7YY?CeMzMes@CZJQ?&|R8v5M@XvW}jjxhjl`gzl;rvy6Nn9$K z;1TKGpUgZs`vR!t-sD~2ar{58-;2k`H(MIWr_cujtSCpjue(R z(a7R{q`G+;8qD8D1e?1zWv+pPFtk=k#>f`yqZo)3KwCBgABgQbq%hu4q}h+Bdyh?* z#Rlr*$38^Ru%m9FUTQL2Xy^j|f%*4H*{zWFRsMbs6@u{JM{48fq;F;QFV%6Dn!6X0 zEAr2G{RmY8;Jlmws#%7Hl_TvQMbLnN0KGK=9)1u=Vb&#V27UwM#U+)$hn#hlXxBxO zM~<3s(W;fe-0%mVWtZ)oN|h-01@5z=u(z!V>)I9-IepH|_q6NR_DA>2hxGKt-QX;H6(^FXwcBndi1s%qn2sH-rsuON7*ARP6Qt$2XIy3d#cn8sLh&7#USTFn3 zQm-o6-Bnofon2V;oq-v1@Ye@NuH$Z~+th}Cs>F7=H#=4PKLp%-!EwR&0`a}XL=br< zF>&?HNr}9ahB-EA7a({^_6`taBwmB~hJG)p>8r^vq0J_+o`sOq<{s2~2t}W&1f5`l zj;E0nmt?YRp{ONhti9{4&rvt5uoS0CO@%+Yv>+}ROQAGP3VLu^S4fe{ZRoGviEXMF zhM=I=Eg2~^5PIwEq{~Wt?inz13!axZU3knx_)Ey9<)z<=!TnCPHvs1l^spF`@INYQ zY|J1RWri-^D9mVY5Z{u+bXg#}3rUwSXX>&@PN+017W@!L5H8CvZf0wZxQ=UrHJ{Um z$Z;~3t6ARGql*O1^YY(h4awy!h_brE6&k9B&5l;ya>jDyW5?o$q~=1iV!t7#8&QOx6P zhQIm55sij*Ef-G_?k^$AjK2j?=QQ?^=r{MDaGZ7`Yo*Kp1uoZ=&5|O)D#xAHL)n9_l6-E!b zVV@8ny;`XU#X2((4cTmv5unmYzUmJ>Hm+Kvht&a+j3nr!sljTHUZn^0w@L|WKw2TO zRO>T!>jutIzNI5U_KL}vd00oi6$aJqPeJwq)lIr(2Gt#52i@sqCFaWC)pS$pYoRCK zd*$)r6FCClYp+n>gCqVF>x)ghAbl+h${~Mc_sQGk@+sR@b(88l zcx?*Usr}v|kV!RPfS%HK>Bn{7tdEV$CB5Z@=uy4>^(o(%@R|_7dq69s1(X_8szPZ! zSS~$LCX>-}F=io=YcY~9!vqo3&dh9_Mosio`zO6i|$&p;-9%+~sdYNrVE?Q8rS+eHx z4O$l|b3FUT#2jb(WU<`oKAjGQUsoCgE1(c>3byBNPhKeJ7f4S-hBRqRyePY)im;>H z)hyFuFTDqx*ZgXo$hn+u>TGs~=Bjqr3bhPmXG)v8){EU;N*58NKU5;EIZl z9%|JomX+b6M#jS2`B%~!+`EStMD{|y^P=`xPbD$o6;|!((h!+y%7Y{DuC!NCKDIN1 zER-J?vZ$2el4y~!-0vWjNRoC|ARB`IX@M&;?ZpULcAIu`zlH9 z&JK#H);Ij~fqoT{59}OI#ViA%!lPYyd@kHg*hyI;iMdCtw2&eLHOd1*N%2Y!BG*H_ zu@E?VbtZlI{7B{C>A^b3njh=KdF!=rQ!)oIjwkP{t^I{2q&emQ-C1&U&fPC_viACTbT;(A3qRJeGINz^!0N26vQ~o|#pmjp-Zq46%+{X9n zLGKqhLh4`-(*oDHqHU~-45_+pe(BICF$*0jD&FW?ED=vn=t?p9X(%AH9+;6NcJ8JF zASkf}LfT7Z3u*#i$ml`gKIS>3jrTla--x##EDM{w{>Iu9qV!x95ECU*W_O`q>hcCa zswU!;H3R{}(A6aQ(B)lImTF$BzF;$V_?It*+8ZeiZa|b8n_DN4jUfI0jIA6Q6*c0f(uq~DxrNm!$~G=Uz=qP*)?qc(}|7MQZT&B=Um zr{Lj_R7QJAlwD=CoYpjQsUyu1)C9p5CE)%3nb)~WtP;@6(qGG`*qDT zS(zM>&R<;Z23V|80%3s!`0QpTt0Ay;*xLJeE|DP5@x?a!1)`g= z-1}G_LxiiO(*?R*{(yH#&yl|Seyx6*+ETayQtv7Htk3WPvI;U!@h-e$)gw9>pyKmB zk8#$3BF-ou%=`9_3)Q`0ttk$cymvULFS`Khmjes=2(-QY@eVjJ)rSD)z)1No&o+dz zrGItPZ$QuD;Nqt~U{J?9VlM0g{kx!4$?!?=o?um>#7tjMzrLfv<@pI&cp*5H>XPPZ zu8Xh&6y7v0pGDiQqd-~tBjK%-SO8$8kG&44|{09|FO5BoNkV6~JX>g{b#NHJW?gmM# zhbcS|M9fDc44(seG%$hK#va#4YL98mddGDi2qr;@CeiWO!!`DrF<%=_^*3JgoZiSj zdEv30G5`7ex`XP4#6cG;AQ}(|>CcCTGiom^pc*j-Mz1_oGp4iP*>N125YeWCw#L4H z*>u2Ih8jVRJ?rOj-7KbU7KXpYs2UZf)Vf}(lsM(oiB>tgqX2tILJitw_x z&7gq;`b}qrL{lEA3DaXDOi~HQ!^?xxjjVW|#Z+Ek&GKA2dYgO@zB2V*eY zx>@D06X)(FUz3xz99V3v*k7x|wxiFxv>=N$1Chfp>CErJq)gnf=P!u-QKrYnulzdQ zP56u!AH2^QVnuxTJjcQtlflq>PSm4C!$^fv4V_XsIO2d=O8|J`4bUDtjBchJ!14~3 z#mgUPYF*Z?k;Y)Igdx3yQg8L)M=c%}p3!P-0KOuXI+{*LXJ&w)$gzxeTyr`)h-Nc! z`$xa<>T2pbuU0VR?#FPEM44XDRw+cM6U1R2aLQpGHX40=4Er=lp&2aN#P1IA3|r+L z?5jaRyCgN)b(KuS+(x9rPLLjY&4^YY{0T2Ai%`f0p}sG*R!}{DSf7GdPJ=C2MT1ND zUJ@#y06`CNc9n?13R2KY1K*SYeV87wG%bjcIbn+AR8*FS<{?wWomTT5@`}~z3bFAJ zLR-wmE$iwwJ-TnVEhl{{?+??DJ?DWk~VaX-L3-RLtprT2%z-GfD{UVBR~T}zymA0 z6VZ;1Qr%5q#+Oz#3)`D(%WVWWS4BW6%ZvAtt!u25FO@e{X`)_LH>p&pFzx(wvNEO- z!2$Z}`iynmY2j&UCmRNB)9Cn3MXRls&PFVHzkzr;)B^BCMY~6lYY>0rsKT zm4}RV`Q7tbn)Aseay%@-I6ZT~PBsO?D|>kG*%(PGo=|gZ#0zsmE})xxtAvaCe&$1? z(7GyH&^jm!cguuMo@CPA&-lrdE&Aq8GIOuUK9jt{K0ldcvJJp7I`ZMx-EYj$)hl~) zFM!U~HxgO+lb$1cIK-nvz<5OPs(@d4tB6DUa3?-bJ98|dv-kIdtMS;9BuLc{a~_wW zO$u`rNymsAeMH9zh(|w=<*V z&&B{&O0Am`<$iBa)>pNZ6cO`d^3B5%=gmsH(HYZw6!U(c@}#)19F}`BT+yOfamJY$ zYOmy2m^k+ADH2klhAJMLq;6>t3)NREUgk*cjJHg{NBkVhDORNK;v5362&NN=y*Ef- z$vxYTG5Ga{SI&C93^Gsu9G-osqbC9PbsC&@xxGlF?o{!rs9|YpEE?P8ix#yS`7JUy z%ez(_Q%I^RwPrW%rFF(+mE}rp#Wtg@^>O7T(@LFA7j{LNrL=XGDyB-|3<*mqLL_UA zUZz?ulF$5O59-WWZ!d@hRxC@4d6?okW%`1$#<5w9eh>4Cyr#xe5%VPG@TBe#HA^O} z1&q{T_TMTr($f<()ah%TXapiGp}`MAC7>0I=Cx*t+bXy+gMyk*#(A~ft=&4YBdQki zQ}I=c;etc@sD4?l`eYaksPtJnx5OUaZ6u;7p64DUuI`omrWjht5$8+cqb6Hw75WNX z@D(fl7tDl2H)H%QYyX3>cL0*DZPv8+ZgaP7+t_W}wr$(CZQHhO+qUig`^@>y%s1~j z6Y)pXii(P=SQS<4iS=aOnR(rqe#b*BR~GN+bMNQSnhcMHxhVf6D7_zYs}@oo$eK9sZig1_lH0|C z&<1W;8dh6lutS+|02t0VqRfh9R+%!~9YsQ>cw-uGi!YMSo?19?Sty(u{GRqmTx8Zv zLz|nph}CNn+4a~dDzMog(j+NForDvDjLwub!b;p@dLHSBO0kjaI0CPZ)8B2(HNL&A zdr8Pw@u(POF1J*groJ~!1|E(GmnR3L6`P*3C;v?R zDw-pBC=u%}<}P_);mn-_cE}am&b1_WlqnWVzFS;*NhwoOb%+#0nI|H*Bw6_0R(=Kj z;7@eEqYkW2OvWkoz|yY1gZAJw8=>KShthS*ANzYdDT61^AK)>0H%LV4q3}hw?bkA$ zF$tz;<5T59v0Zd$)unmJ{vu_7eGDP6+pe(H&n^3E)g^rB?pn?GT9l1gztAUpR*+Kvt=FE~M zq5rZM&9v>ww1mzrK)vx*0;;?tnqA@Q;FBC@$2~=gy#jW$bAJUNIl_YpT)``*9nnkV zF!&XBK8(PeQfnScH*JaYqy{1bN4MwF=&g2)`!Kuo165*d^1Sc_d{I4>6V=>74c%g4 zXE_M`b@syq%jQx9VRp@ba!rY|MRhr!S3bN!1RT}^I(2gXE`KT57Y;maGA&dHM#`4* zy%@6YB0A6Z^?fg!$4Gq0auM47(jE$Y4osH zhydBwQ-S~vMS7)hg;AC=MRf~AHZu|Ue*bk=ff`!Ol1%=|W-a+~l)QH04q^oeMZHj~ z8$8jQn(n1#O!_7sg1hi;{v%?nd&gK7tfN3I{A0j zcg`ISk^Ir4G=(SvV$v}DE(nE+%rgFkT%cu5VR0Qa^H4-xPC*7Y*+E8#xvyepS#xYE+FyIIi0|5$J%mKAB58%MgleT%Zx42e^L`TdA~Ips z=NvgHNpYZju?*J>oNcmd^(nFUc+-bu4*+9)qIwU^g?1_4-&-`uZm&f7F^1?@3IvJc{gnlh?no$E9jFIfJ8i+33;o-!b2hD@}}{o}J4{l{44v z3Cd{3Lj%9^E43SBXmIvwsA2_8sXgRu=4=H{j9R(fYcCzOXriTZ51l+HcXr@)^?rK* zmc89=w8MW+txdobBh`X4rMvY#vuv0GIEO67sgL}mIw$pNW6s8Fd=t z@58{pFs^Oz&g}CPr8EL~QyUjk&}1qyO4;-6m0MRd4J9T2r5_j+YdeKP%Q+jnWNdV| zUJLU&d%m|g&3B83R^8K^WM{0at+=9UdVAzTnL+CqdcT#($38|-fQ|BJbHY4vk=ANj zvX?ek_oYp6t8bQz-T){|-5OGrv`IGd?>X*h(s{MvQ{j>fZbx<^-)&(j8(N+z^sftB z;V$0+Wd0oUR^&)Q+2bHfLt#V~jZT$UPUbkd#vD#zZJ&huG+-;T%sU~ONA?a`Va|T%I0yd%0*Xr3>p#slVg7Y<6o&Bx856S zg;7Q>mCFF?xq_m}VG5`(0fIX(V=yvQ;xjpwNhrLFMui8xdBw2aFOvI3t6-NG3%+d= z>1un%A{1+tFrn2nu2%`-hiqYhXDga3%{ZVkC@ROtTcA;g*E@K4i_G1&^P#Pl_9*m& zwBVKqZhrf4bhw@M)78cm zBMB!;A)H{6h6AjEv&|DGxYRmY|e_ARf_dMIvm*-i4hR#IU_#A_QYP@L|sHs zo@Ky_Bx6e2??_k;7vjibD#pM*T7`h9V&s(moOn_x^N|9{gkOtFY~gDqSo+7meUjBR zK2jiOsA%PwD|1*KC^m(-WZ5j2AWi;81kCi5t)KouHKt|R6m{m!!n|4YN3yyBo0mSZ zN^yj9>I9Y6dI&$!T7&$%3Ccxua0-&DoNJFbCV%1;h^-U&1Q+@47qrKld+QNGOrh{a z27PfD|L06XuL1+ZMc{_7rB7bd&WD%*lbypj>|K|<#2#t+qPXH zTm`5QC)ktLW5+G&4lhvX8DgOK)|mvQ_b^HuJ&=wP%Z6%;E+Bx|#|Q}vOoGR(jK}sD zk9x4A-V%Hs#G>J5XldT-W&|Kv(!mEi;J38jdK>L|Q7~<_no&|~Fdc~yhC~%VqQc2e z2|pva(YaxgaE`xa5=u=WkhtI|f`XRHhA6|>1`)hDgYzt9kByS$l*OQ2O-a#Iq%SLz zV^&-mn{^KrM6&BueyiV}>&)9rr)de2+DkV8##PSmko(<`nqPVr^n_V~UoIi`_yVdB zzcj4`b5QijKNrR%0AYi<`{NDb!y1^#Pv|K2N8<&wlO7-JDa5Yp?eM)pf>PbMq@)Wr zvki0Y1yLr2WfDb`RBPgq^VC(KH;ofR#9^i$TaMi9J6p5TP5F8<&ofnvL|`*(;urRO z?0k?7WiOd&^v);ux~R9Hznc3moOxE+O$lYV0Ku|hENFV~?Lt!QZlMNp1%d#^Rv!pC zfq`*V)n<`Io8N2XGBOjLYB}#{g#>o-?Hmb6$VyvSN@nI?3{y-pdNvcYe%&%CIeh?s zWfdM@$o~R)P|M>ElHW0BAMI=ozdH-Fle#Dvq-bpmPg-!rDY|1*o|1dvDh9{`{gt%n zFemDyrWMrywXJ+rV5r%UR~0T*75`i&rM4=%7}ulJyHu{rZw;C$r+nn@cLyLgh0d-A z(3SS5tW>ZK0in8bOH$vW>HIcipgUXYGUq49#>Ixff27cCfWz$0vR4Dmq}CBw<~4Sh zDe9adM$vVItE_)3FJT5Bgk}V=1g+Qvf5+hpxwh78gHe$<|r1^Nh?B&_~xSq+nVdY+~dc4GJ?e5EpV zXs-H~6poV`Kh5kok2qSUMD?0&WXKs7T0?Z-J8zti^WD-*_fo zhAqM(p+l2*(|b>aZC+?aK~^_VCZkP0>}TxdEC-KcmAx*YS?wTK?cW>PjS+NxM==Wg zg}e_*NcH%2(J=+WVL+;P)kz0c@48^4ZuemowCO=rriJFSD|#7D2oO{}$kCbL0#0%2 zQe&D2wwJ3%d|+L`bE=&9k_~(BOe$ZFap$YMGL$&$D0=mJ9n%He#RRlC3f=|WyrI0L zA_qS=kzzw8f_QiJYg_b?xA6UgBS0tT_Y$!9>(J-Q|m=O+8+wIPlb5i=-aU~kBf=4dD zd6Q8*EoKqRCcMNO5q%nez-osz1XT6PZ+r7r7A_{!vpDIfE$$yCUU66H>HOUO>u7aE zs*>|KS24COy<^3O^xXssCI`2iF%;A&7{j1UDk9dvv< zsUbj2HMoFr%{j!bRrmyt%jM|4UKza#}%Vf*_fEvi$*6J-h}oRdsdinr_W1-)p24zB*p9tfDdUa27+yi5W`#8+~eE_NyvNZgCP48jF8P; zgYS#IP!@sLe^SeCy4jwre}sC*A4Vk3|EzFISR4QEai+j{bL%-B#Nlt4WJN3eh+Uo) zVtaBF&A%PtbaaH`A~$h0I(5#|WARn>4Hbxy+Jn-$LdJWL+&({?oGdxCC?@gw`D44O zZ)fV$Yi@4u-zGU|!cfh6Eq?2C3Nn%TL2ZoA1+5g5O#q6$QGS|1C!;H{)PU?dDlSGU zLGKxOa;zm!C-Zghet4U7l(%LaEQnKF+>ECNt@`F07q-JO?%%X~*k}Yndc#f*iq0`hgW#iOvymYI0Ur}T;8qZ+%f1paM#v7e! zUS~+CMQqEbYZ%Ix+4iKAGa>>DLya7d_5zQo_zm&bP6F_75Qk^L7A%?p74r#_+3V6R z@m)%h$SZlQi)PpLLYyya^FulLkrPuM%+!YnWBCX|f#M*ph-`6S5IH3F;Os;ZZ&cDq z<~WF?be7SQre3OHq63A%t27ee4>e--Q*N)lFkAI_P@Yoq?Bd0s)IIqLY)xtXU`k>x zfQK0;b2n0v{oPhQju4$`uD>)Syw=X_l}YEfVF8)awhULL-sJNdq;z8~(wyAEW&sDx zxqHk8ufaTXHNnIUP~eE&k>D!g#IVt73wHY+ugJwtuy74u* z1qC32jRV4EWbz*0B5d5qGm7FB;V0Z>C63g4n6hW?!BfHU=hqZbuGx&ccdij#|lWok>4#{m^Fy>{`JdOS zjIM(Tuf4sYrJltP%2vW!U)Mt5hd5_vs^{onYW=T{?nF6taSUF>uPLMY@>8Y#vd&fU zJg$MqI>EOkIj}Gpu%?+k{%zvX7zqvMeuMm%YD6eLoHxL?e6eW>J~|~Z&lHB^r_Ag0 z{*SlMeG(r}i;4UY6e1TDhAnY@tyh=*e7>7?vlwq>&py69o*=hIE389P!iE)Fe1v;HN5fVGS&&jBzQk*Q}Rb%{FF5H zt;vL@*J)TU^_AGy%>+&9)+R@9XQHe9%Cr#w>Q$NM0~WAiktZl>9`I-Ypc0UjVU1rn z_FPNg@88w2iz;NHBJ8)vM$%1oe7QzSs;NxSieG5h->Cq6`M#YqU;tx=1hYym@h%fi zzWLOcEgsbZ>jW|mkR)qpxv-Z}J6iTzy?L3sZiv!nbZ3a;A~Hu3j6-^%FcrouBW^*9 zwOO;eD$2J8edza=ZDF&}5X#=B9O(;A4zyM&5yTvxuoqjP+FZY!ZYI`_D=;czTJF-e z1-$=(BE%9~*+c%p5UT&+n27&>tc8D77L`o(F_e)w^~KRuv4^AdNE-D~2I(p(SCPRP zc{V^gm}JdYd(~~{max0nhdPp5j3){eJ z$LuzR9V>9)451K&?27Aps3vsd_bU(1EDOA~g;@vOO2Ty`4MFO9u=`!_wEKPQp>9L& zzuUbCBGHhsuxYBy-^Uw`)=n5pSF5)!a6qfH$^u&=0GA(}B-Ixjj|ce?Bp(~$q^7BqWU|H8 zKU!?5P@+8*_63=^7)|h<=`vW)2%PZF(`Q0Lr0x5QLjWKIQZB9)OOB_ISy!Mx`E{lJ z1=1d&Ic*{{_h#6sNH^Hz)~vB7gCTbuUkVrOm(pCye57-0NUsKiFMeA#@NBB+F5<+s{(H7mQAPQx`OR z8xRz&uf&f&-?8paW&Q%EHCq$Lv~}lCIW%s>Wxj&$Majn9D~*{Yn8jBZ3b9-fuz!82Hn?&ZI2_JZYAy$kb_?7m*?J z7EcrbL2*)gJ(Wl`yg~c)vC1w>dR$LezB90-T0%EZo|KuQOirNpKJAd) zr+w2F#9m@j64vevMEx_$M}ESx!oajKsI7|Q#c-fWRsS7nAgMlxf$l`eoBx6_u1LP` z5wVEEAYNPN*iXKJza7=aP+z_r$z;5})SQGWl0SrU7qL5T>MpzjZPVq~an6pv29s{gIn1Rh z$*Vp>0p=05JN|HRiyOCbpgpZ@;9Xj|o3DNV!%Xn6t3hE>(=2$dFuEx{osGXYv`m73 z@j>86*-gsSS^3mR)HB6Bj1fy+E{@9e{bcRLU_iAqDzdQUqG)+sqNE`h1 z$3w4loJ+!{F4NdK!E7Vu6L}j5d=VnffP!j5b(b5(u}{;?o9PB`YLsrEsOeE8IUM8F zj!}~kYF^$l^i7CS$AnS+a4#EnWySE!?hNnzWe>=ETyc4WCXpNzZ9R&vLWR9n2)aFS zeT`FE>ZzLpjPr*qdk%A3<`U8cpr3K~?abpqM})l-j}Hz+9tJcw;_-BzCtzpYoNVk^ zd4xI@9~_|+Y_6S*Kx+?A$c)OqC718Wiat0Sl%qFMhix0?j{gw1XO9$zQhjjoeDj|S z8hS*$R7Ol=9=Sd-9s*OgZAC1sMC*(iexn}3CMYJdNZu8^S5)5@Bxo7ayS4fG2D@ns z(Y9t_4DB(20CAx~=eL=RM?RRc4|4V{?Qe z=>g3K7H^2nxwHm|*N+zhk9ET-=0ak5wZAxM<)DFY7|^q+@a_=>AXMj@vZG11mH%nQ zn9XfRt7)!V&u0~v+`DaED;5~WX_cQ6~@iQ$)`#bKdk&+uvYtZMGQ??&zRmpw zbc5donS&q;jPQE_7rh5{ONJKBM;cxKH>r!f)K=VDf}bfc1B4Nv3C}__D{B|kU4Q04E((6!W^q+&Xb=m`c#S!$wEEp4py_0 zDJO?v%A16hzF;#-Lt+DUyec?VXUS?%21=wBiJ<}TTQMa&n$+5wnHr4sni_Hb`tFO; z((Kg?Xh0p)JZnUc=-mE(Ls`z5)+Qr8;F0R92sj9yEJx1kK&wQ8S2S`)h+Qk?^jShBw0n z^g^Pht7xCZvs&|5W95{bypf4acXhX`O_>*QyEk183j48^Ws>JcasVrhs5G9;&2dyi z%>jCf;J1W^x5i(=Cvt|^PAWSdNG}XTJ@;UD+R!_#xn5!VD8@`C$I>Ipes@q*x>0`l z)z8=i*VF~+bxTYjaCr)lzaDau^|9V&q!IlGwQu0TKbn4oBljDL$D`d(xUR1D_M2H5 z_D)E{)YMOgPe9j&Ta=X`w!K8L8Fz1tOon!uWan9)huounS4Mh4dF)BRXPW~rZ){=b z8GKrX8h<5U_7;gkNu2?Vha=mHR?g_-tDJ7e(~;kBqw^DncZb0-heR1$Eu84i7(X`&aR*AQIwovW z>fz)N@L0uBeI%!;>fF*(y?aB?LspSl*h;#V3|hH@lSBCC>z%=##r4vBD?~% zIcaMD#Ep&MMR|QloYSVm4m`6&D~o=K)KUR!2dn`e7}AFYi4ni=M| zwlXp`cKoTc{O?pVGTu@effshzIQL;~Uran3$O8b$6lS*o0sT!BoyZd(zz&P7axA%@Nz)_qI zkD$LWxQoOtM=CJA^aux0eMxT|$TTV{XcUf%R6YWWWpb~~Wr+7tk~!$o(-O!M!{#H? z)jCw2taNz0WO)=*Gud3!7Hi9?DqB;9JQ_pLDASj_PC!c^M|om%q>Zz+S3oK5Y^V&l+!?6vHO@6@c? z%)vqVE`pRD|ItbFC1kt4ApdNC)&9im8NW=RUr>

@up^y4&I8N>~wvL%f(S2W%NN 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 D613UA literal 0 HcmV?d00001 diff --git a/simple_language/gradle/wrapper/gradle-wrapper.properties b/simple_language/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..94920145f --- /dev/null +++ b/simple_language/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/simple_language/gradlew b/simple_language/gradlew new file mode 100755 index 000000000..2fe81a7d9 --- /dev/null +++ b/simple_language/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/simple_language/gradlew.bat b/simple_language/gradlew.bat new file mode 100644 index 000000000..9618d8d96 --- /dev/null +++ b/simple_language/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/simple_language/settings.gradle b/simple_language/settings.gradle new file mode 100644 index 000000000..8a3935957 --- /dev/null +++ b/simple_language/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'language' + diff --git a/simple_language/src/main/gen/com/intellij/sdk/language/SimpleLexer.java b/simple_language/src/main/gen/com/intellij/sdk/language/SimpleLexer.java new file mode 100644 index 000000000..d29665ebe --- /dev/null +++ b/simple_language/src/main/gen/com/intellij/sdk/language/SimpleLexer.java @@ -0,0 +1,535 @@ +/* The following code was generated by JFlex 1.7.0 tweaked for IntelliJ platform */ + +package com.intellij.sdk.language; + +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.tree.IElementType; +import com.intellij.sdk.language.psi.SimpleTypes; +import com.intellij.psi.TokenType; + + +/** + * This class is a scanner generated by + * JFlex 1.7.0 + * from the specification file Simple.flex + */ +class SimpleLexer implements FlexLexer { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int YYINITIAL = 0; + public static final int WAITING_VALUE = 2; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0, 1, 1 + }; + + /** + * Translates characters to character classes + * Chosen bits are [9, 6, 6] + * Total runtime size is 1568 bytes + */ + public static int ZZ_CMAP(int ch) { + return ZZ_CMAP_A[(ZZ_CMAP_Y[ZZ_CMAP_Z[ch>>12]|((ch>>6)&0x3f)]<<6)|(ch&0x3f)]; + } + + /* The ZZ_CMAP_Z table has 272 entries */ + static final char ZZ_CMAP_Z[] = zzUnpackCMap( + "\1\0\1\100\1\200\u010d\100"); + + /* The ZZ_CMAP_Y table has 192 entries */ + static final char ZZ_CMAP_Y[] = zzUnpackCMap( + "\1\0\1\1\1\2\175\3\1\4\77\3"); + + /* The ZZ_CMAP_A table has 320 entries */ + static final char ZZ_CMAP_A[] = zzUnpackCMap( + "\11\0\1\4\1\2\1\1\1\5\1\3\22\0\1\7\1\10\1\0\1\10\26\0\1\11\2\0\1\11\36\0\1"+ + "\6\50\0\1\1\242\0\2\1\26\0"); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\2\0\2\1\1\2\1\3\1\4\1\5\2\6\2\7"+ + "\1\3\1\7\1\0\2\4\1\0\1\2\2\6"; + + private static int [] zzUnpackAction() { + int [] result = new int[21]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\12\0\24\0\36\0\50\0\62\0\74\0\106"+ + "\0\120\0\132\0\50\0\144\0\156\0\170\0\62\0\202"+ + "\0\214\0\156\0\132\0\226\0\240"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[21]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\1\3\1\4\1\5\1\4\2\5\1\6\1\5\1\7"+ + "\1\10\1\11\1\12\1\13\1\12\1\14\1\13\1\15"+ + "\1\16\2\11\2\3\1\0\1\3\2\0\1\17\1\0"+ + "\1\3\1\0\1\3\1\4\1\5\1\4\2\5\1\17"+ + "\1\5\1\3\2\0\5\5\1\0\1\5\11\0\1\3"+ + "\2\0\2\7\1\0\1\3\2\20\1\21\1\20\1\7"+ + "\1\20\12\0\2\11\1\0\2\11\1\0\1\22\4\11"+ + "\1\23\1\5\2\23\1\5\1\22\1\23\3\11\1\24"+ + "\1\16\1\24\1\14\1\16\1\22\1\14\5\11\1\25"+ + "\6\11\1\0\1\5\1\16\1\5\2\16\1\0\1\16"+ + "\2\0\2\20\2\0\10\20\2\0\3\20\1\7\2\20"+ + "\1\11\1\24\1\5\2\24\1\5\1\22\1\24\7\11"+ + "\1\0\1\22\3\11"; + + private static int [] zzUnpackTrans() { + int [] result = new int[170]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String[] ZZ_ERROR_MSG = { + "Unknown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\2\0\5\1\1\11\6\1\1\0\2\1\1\0\3\1"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[21]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private CharSequence zzBuffer = ""; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + + /** + * Creates a new scanner + * + * @param in the java.io.Reader to read input from. + */ + SimpleLexer(java.io.Reader in) { + this.zzReader = in; + } + + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + int size = 0; + for (int i = 0, length = packed.length(); i < length; i += 2) { + size += packed.charAt(i); + } + char[] map = new char[size]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < packed.length()) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + public final int getTokenStart() { + return zzStartRead; + } + + public final int getTokenEnd() { + return getTokenStart() + yylength(); + } + + public void reset(CharSequence buffer, int start, int end, int initialState) { + zzBuffer = buffer; + zzCurrentPos = zzMarkedPos = zzStartRead = start; + zzAtEOF = false; + zzAtBOL = true; + zzEndRead = end; + yybegin(initialState); + } + + /** + * Refills the input buffer. + * + * @return {@code false}, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + return true; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final CharSequence yytext() { + return zzBuffer.subSequence(zzStartRead, zzMarkedPos); + } + + + /** + * Returns the character at position {@code pos} from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer.charAt(zzStartRead+pos); + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occurred while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Contains user EOF-code, which will be executed exactly once, + * when the end of file is reached + */ + private void zzDoEOF() { + if (!zzEOFDone) { + zzEOFDone = true; + + } + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public IElementType advance() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + CharSequence zzBufferL = zzBuffer; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; + + // set up zzAction for empty match case: + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + } + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL/*, zzEndReadL*/); + zzCurrentPosL += Character.charCount(zzInput); + } + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL/*, zzEndReadL*/); + zzCurrentPosL += Character.charCount(zzInput); + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + ZZ_CMAP(zzInput) ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + zzDoEOF(); + return null; + } + else { + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 1: + { yybegin(YYINITIAL); return SimpleTypes.KEY; + } + // fall through + case 8: break; + case 2: + { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; + } + // fall through + case 9: break; + case 3: + { return TokenType.BAD_CHARACTER; + } + // fall through + case 10: break; + case 4: + { yybegin(YYINITIAL); return SimpleTypes.COMMENT; + } + // fall through + case 11: break; + case 5: + { yybegin(WAITING_VALUE); return SimpleTypes.SEPARATOR; + } + // fall through + case 12: break; + case 6: + { yybegin(YYINITIAL); return SimpleTypes.VALUE; + } + // fall through + case 13: break; + case 7: + { yybegin(WAITING_VALUE); return TokenType.WHITE_SPACE; + } + // fall through + case 14: break; + default: + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/simple_language/src/main/gen/com/intellij/sdk/language/parser/SimpleParser.java b/simple_language/src/main/gen/com/intellij/sdk/language/parser/SimpleParser.java new file mode 100644 index 000000000..a70231e85 --- /dev/null +++ b/simple_language/src/main/gen/com/intellij/sdk/language/parser/SimpleParser.java @@ -0,0 +1,127 @@ +// This is a generated file. Not intended for manual editing. +package com.intellij.sdk.language.parser; + +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiBuilder.Marker; +import static com.intellij.sdk.language.psi.SimpleTypes.*; +import static com.intellij.lang.parser.GeneratedParserUtilBase.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.lang.ASTNode; +import com.intellij.psi.tree.TokenSet; +import com.intellij.lang.PsiParser; +import com.intellij.lang.LightPsiParser; + +@SuppressWarnings({"SimplifiableIfStatement", "UnusedAssignment"}) +public class SimpleParser implements PsiParser, LightPsiParser { + + public ASTNode parse(IElementType t, PsiBuilder b) { + parseLight(t, b); + return b.getTreeBuilt(); + } + + public void parseLight(IElementType t, PsiBuilder b) { + boolean r; + b = adapt_builder_(t, b, this, null); + Marker m = enter_section_(b, 0, _COLLAPSE_, null); + r = parse_root_(t, b); + exit_section_(b, 0, m, t, r, true, TRUE_CONDITION); + } + + protected boolean parse_root_(IElementType t, PsiBuilder b) { + return parse_root_(t, b, 0); + } + + static boolean parse_root_(IElementType t, PsiBuilder b, int l) { + return simpleFile(b, l + 1); + } + + /* ********************************************************** */ + // property|COMMENT|CRLF + static boolean item_(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "item_")) return false; + boolean r; + Marker m = enter_section_(b); + r = property(b, l + 1); + if (!r) r = consumeToken(b, COMMENT); + if (!r) r = consumeToken(b, CRLF); + exit_section_(b, m, null, r); + return r; + } + + /* ********************************************************** */ + // (KEY? SEPARATOR VALUE?) | KEY + public static boolean property(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property")) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, PROPERTY, ""); + r = property_0(b, l + 1); + if (!r) r = consumeToken(b, KEY); + exit_section_(b, l, m, r, false, recover_property_parser_); + return r; + } + + // KEY? SEPARATOR VALUE? + private static boolean property_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = property_0_0(b, l + 1); + r = r && consumeToken(b, SEPARATOR); + r = r && property_0_2(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // KEY? + private static boolean property_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property_0_0")) return false; + consumeToken(b, KEY); + return true; + } + + // VALUE? + private static boolean property_0_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property_0_2")) return false; + consumeToken(b, VALUE); + return true; + } + + /* ********************************************************** */ + // !(KEY|SEPARATOR|COMMENT) + static boolean recover_property(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "recover_property")) return false; + boolean r; + Marker m = enter_section_(b, l, _NOT_); + r = !recover_property_0(b, l + 1); + exit_section_(b, l, m, r, false, null); + return r; + } + + // KEY|SEPARATOR|COMMENT + private static boolean recover_property_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "recover_property_0")) return false; + boolean r; + r = consumeToken(b, KEY); + if (!r) r = consumeToken(b, SEPARATOR); + if (!r) r = consumeToken(b, COMMENT); + return r; + } + + /* ********************************************************** */ + // item_* + static boolean simpleFile(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "simpleFile")) return false; + while (true) { + int c = current_position_(b); + if (!item_(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "simpleFile", c)) break; + } + return true; + } + + static final Parser recover_property_parser_ = new Parser() { + public boolean parse(PsiBuilder b, int l) { + return recover_property(b, l + 1); + } + }; +} diff --git a/simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleProperty.java b/simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleProperty.java new file mode 100644 index 000000000..75a0af3b5 --- /dev/null +++ b/simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleProperty.java @@ -0,0 +1,23 @@ +// This is a generated file. Not intended for manual editing. +package com.intellij.sdk.language.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; +import com.intellij.navigation.ItemPresentation; + +public interface SimpleProperty extends SimpleNamedElement { + + String getKey(); + + String getValue(); + + String getName(); + + PsiElement setName(String newName); + + PsiElement getNameIdentifier(); + + ItemPresentation getPresentation(); + +} diff --git a/simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleTypes.java b/simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleTypes.java new file mode 100644 index 000000000..558678ca9 --- /dev/null +++ b/simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleTypes.java @@ -0,0 +1,28 @@ +// This is a generated file. Not intended for manual editing. +package com.intellij.sdk.language.psi; + +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.PsiElement; +import com.intellij.lang.ASTNode; +import com.intellij.sdk.language.psi.impl.*; + +public interface SimpleTypes { + + IElementType PROPERTY = new SimpleElementType("PROPERTY"); + + IElementType COMMENT = new SimpleTokenType("COMMENT"); + IElementType CRLF = new SimpleTokenType("CRLF"); + IElementType KEY = new SimpleTokenType("KEY"); + IElementType SEPARATOR = new SimpleTokenType("SEPARATOR"); + IElementType VALUE = new SimpleTokenType("VALUE"); + + class Factory { + public static PsiElement createElement(ASTNode node) { + IElementType type = node.getElementType(); + if (type == PROPERTY) { + return new SimplePropertyImpl(node); + } + throw new AssertionError("Unknown element type: " + type); + } + } +} diff --git a/simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleVisitor.java b/simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleVisitor.java new file mode 100644 index 000000000..aeacbe65d --- /dev/null +++ b/simple_language/src/main/gen/com/intellij/sdk/language/psi/SimpleVisitor.java @@ -0,0 +1,22 @@ +// This is a generated file. Not intended for manual editing. +package com.intellij.sdk.language.psi; + +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiElement; + +public class SimpleVisitor extends PsiElementVisitor { + + public void visitProperty(@NotNull SimpleProperty o) { + visitNamedElement(o); + } + + public void visitNamedElement(@NotNull SimpleNamedElement o) { + visitPsiElement(o); + } + + public void visitPsiElement(@NotNull PsiElement o) { + visitElement(o); + } + +} diff --git a/simple_language/src/main/gen/com/intellij/sdk/language/psi/impl/SimplePropertyImpl.java b/simple_language/src/main/gen/com/intellij/sdk/language/psi/impl/SimplePropertyImpl.java new file mode 100644 index 000000000..e9fc3a070 --- /dev/null +++ b/simple_language/src/main/gen/com/intellij/sdk/language/psi/impl/SimplePropertyImpl.java @@ -0,0 +1,59 @@ +// This is a generated file. Not intended for manual editing. +package com.intellij.sdk.language.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static com.intellij.sdk.language.psi.SimpleTypes.*; +import com.intellij.sdk.language.psi.*; +import com.intellij.navigation.ItemPresentation; + +public class SimplePropertyImpl extends SimpleNamedElementImpl implements SimpleProperty { + + public SimplePropertyImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull SimpleVisitor visitor) { + visitor.visitProperty(this); + } + + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof SimpleVisitor) accept((SimpleVisitor)visitor); + else super.accept(visitor); + } + + @Override + public String getKey() { + return SimplePsiImplUtil.getKey(this); + } + + @Override + public String getValue() { + return SimplePsiImplUtil.getValue(this); + } + + @Override + public String getName() { + return SimplePsiImplUtil.getName(this); + } + + @Override + public PsiElement setName(String newName) { + return SimplePsiImplUtil.setName(this, newName); + } + + @Override + public PsiElement getNameIdentifier() { + return SimplePsiImplUtil.getNameIdentifier(this); + } + + @Override + public ItemPresentation getPresentation() { + return SimplePsiImplUtil.getPresentation(this); + } + +} diff --git a/simple_language/src/main/java/com/intellij/sdk/language/Simple.bnf b/simple_language/src/main/java/com/intellij/sdk/language/Simple.bnf new file mode 100644 index 000000000..3ae45df60 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/Simple.bnf @@ -0,0 +1,30 @@ +{ + parserClass="com.intellij.sdk.language.parser.SimpleParser" + + extends="com.intellij.extapi.psi.ASTWrapperPsiElement" + + psiClassPrefix="Simple" + psiImplClassSuffix="Impl" + psiPackage="com.intellij.sdk.language.psi" + psiImplPackage="com.intellij.sdk.language.psi.impl" + + elementTypeHolderClass="com.intellij.sdk.language.psi.SimpleTypes" + elementTypeClass="com.intellij.sdk.language.psi.SimpleElementType" + tokenTypeClass="com.intellij.sdk.language.psi.SimpleTokenType" + + psiImplUtilClass="com.intellij.sdk.language.psi.impl.SimplePsiImplUtil" +} + +simpleFile ::= item_* + +private item_ ::= (property|COMMENT|CRLF) + +property ::= (KEY? SEPARATOR VALUE?) | KEY { + pin=3 + recoverWhile="recover_property" + mixin="com.intellij.sdk.language.psi.impl.SimpleNamedElementImpl" + implements="com.intellij.sdk.language.psi.SimpleNamedElement" + methods=[getKey getValue getName setName getNameIdentifier getPresentation] +} + +private recover_property ::= !(KEY|SEPARATOR|COMMENT) \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/Simple.flex b/simple_language/src/main/java/com/intellij/sdk/language/Simple.flex new file mode 100644 index 000000000..d71c2a4a9 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/Simple.flex @@ -0,0 +1,44 @@ +package com.intellij.sdk.language; + +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.tree.IElementType; +import com.intellij.sdk.language.psi.SimpleTypes; +import com.intellij.psi.TokenType; + +%% + +%class SimpleLexer +%implements FlexLexer +%unicode +%function advance +%type IElementType +%eof{ return; +%eof} + +CRLF=\R +WHITE_SPACE=[\ \n\t\f] +FIRST_VALUE_CHARACTER=[^ \n\f\\] | "\\"{CRLF} | "\\". +VALUE_CHARACTER=[^\n\f\\] | "\\"{CRLF} | "\\". +END_OF_LINE_COMMENT=("#"|"!")[^\r\n]* +SEPARATOR=[:=] +KEY_CHARACTER=[^:=\ \n\t\f\\] | "\\ " + +%state WAITING_VALUE + +%% + + {END_OF_LINE_COMMENT} { yybegin(YYINITIAL); return SimpleTypes.COMMENT; } + + {KEY_CHARACTER}+ { yybegin(YYINITIAL); return SimpleTypes.KEY; } + + {SEPARATOR} { yybegin(WAITING_VALUE); return SimpleTypes.SEPARATOR; } + + {CRLF}({CRLF}|{WHITE_SPACE})+ { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; } + + {WHITE_SPACE}+ { yybegin(WAITING_VALUE); return TokenType.WHITE_SPACE; } + + {FIRST_VALUE_CHARACTER}{VALUE_CHARACTER}* { yybegin(YYINITIAL); return SimpleTypes.VALUE; } + +({CRLF}|{WHITE_SPACE})+ { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; } + +[^] { return TokenType.BAD_CHARACTER; } diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleAnnotator.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleAnnotator.java new file mode 100644 index 000000000..2ab72f2b4 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleAnnotator.java @@ -0,0 +1,59 @@ +package com.intellij.sdk.language; + +import com.intellij.lang.annotation.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.sdk.language.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; + +import java.util.List; + + +public class SimpleAnnotator implements Annotator { + // Define strings for the Simple language prefix - used for annotations, line markers, etc. + public static final String SIMPLE_PREFIX_STR = "simple"; + public static final String SIMPLE_SEPARATOR_STR = ":"; + + @Override + public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) { + // Ensure the Psi element is an expression + if ( !( element instanceof PsiLiteralExpression ) ) return; + + // Ensure the Psi element contains a string that starts with the key and separator + PsiLiteralExpression literalExpression = (PsiLiteralExpression) element; + String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; + if ( ( value == null ) || !value.startsWith( SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR ) ) return; + + // Define the text ranges (start is inclusive, end is exclusive) + // "simple:key" + // 01234567890 + TextRange prefixRange = TextRange.from( element.getTextRange().getStartOffset(), SIMPLE_PREFIX_STR.length() + 1 ); + TextRange separatorRange = TextRange.from( prefixRange.getEndOffset(), SIMPLE_SEPARATOR_STR.length() ); + TextRange keyRange = new TextRange( separatorRange.getEndOffset(), element.getTextRange().getEndOffset() - 1 ); + + // Get the list of properties from the Project + String possibleProperties = value.substring( SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length() ); + Project project = element.getProject(); + List< SimpleProperty > properties = SimpleUtil.findProperties( project, possibleProperties ); + + // Set the annotations using the text ranges. + Annotation keyAnnotation = holder.createInfoAnnotation( prefixRange, null ); + keyAnnotation.setTextAttributes( DefaultLanguageHighlighterColors.KEYWORD ); + Annotation separatorAnnotation = holder.createInfoAnnotation( separatorRange, null ); + separatorAnnotation.setTextAttributes( SimpleSyntaxHighlighter.SEPARATOR ); + if ( properties.isEmpty() ) { + // No well-formed property found following the key-separator + Annotation badProperty = holder.createErrorAnnotation( keyRange, "Unresolved property" ); + badProperty.setTextAttributes( SimpleSyntaxHighlighter.BAD_CHARACTER ); + // ** Tutorial step 18.3 - Add a quick fix for the string containing possible properties + badProperty.registerFix(new SimpleCreatePropertyQuickFix(possibleProperties)); + } else { + // Found at least one property + Annotation annotation = holder.createInfoAnnotation( keyRange, null ); + annotation.setTextAttributes( SimpleSyntaxHighlighter.VALUE ); + } + } + +} diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleBlock.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleBlock.java new file mode 100644 index 000000000..1e7b05f7f --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleBlock.java @@ -0,0 +1,54 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.formatting.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.TokenType; +import com.intellij.psi.formatter.common.AbstractBlock; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class SimpleBlock extends AbstractBlock { + private SpacingBuilder spacingBuilder; + + protected SimpleBlock(@NotNull ASTNode node, @Nullable Wrap wrap, @Nullable Alignment alignment, + SpacingBuilder spacingBuilder) { + super(node, wrap, alignment); + this.spacingBuilder = spacingBuilder; + } + + @Override + protected List buildChildren() { + List blocks = new ArrayList(); + ASTNode child = myNode.getFirstChildNode(); + while (child != null) { + if (child.getElementType() != TokenType.WHITE_SPACE) { + Block block = new SimpleBlock(child, Wrap.createWrap(WrapType.NONE, false), Alignment.createAlignment(), + spacingBuilder); + blocks.add(block); + } + child = child.getTreeNext(); + } + return blocks; + } + + @Override + public Indent getIndent() { + return Indent.getNoneIndent(); + } + + @Nullable + @Override + public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) { + return spacingBuilder.getSpacing(this, child1, child2); + } + + @Override + public boolean isLeaf() { + return myNode.getFirstChildNode() == null; + } +} diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleChooseByNameContributor.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleChooseByNameContributor.java new file mode 100644 index 000000000..e172c0bdd --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleChooseByNameContributor.java @@ -0,0 +1,33 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.navigation.*; +import com.intellij.openapi.project.Project; +import com.intellij.sdk.language.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class SimpleChooseByNameContributor implements ChooseByNameContributor { + @NotNull + @Override + public String[] getNames(Project project, boolean includeNonProjectItems) { + List properties = SimpleUtil.findProperties(project); + List names = new ArrayList(properties.size()); + for (SimpleProperty property : properties) { + if (property.getKey() != null && property.getKey().length() > 0) { + names.add(property.getKey()); + } + } + return names.toArray(new String[names.size()]); + } + + @NotNull + @Override + public NavigationItem[] getItemsByName(String name, String pattern, Project project, boolean includeNonProjectItems) { + // TODO: include non project items + List properties = SimpleUtil.findProperties(project, name); + return properties.toArray(new NavigationItem[properties.size()]); + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettings.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettings.java new file mode 100644 index 000000000..35c41c8a8 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettings.java @@ -0,0 +1,11 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.psi.codeStyle.*; + +public class SimpleCodeStyleSettings extends CustomCodeStyleSettings { + public SimpleCodeStyleSettings(CodeStyleSettings settings) { + super("SimpleCodeStyleSettings", settings); + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java new file mode 100644 index 000000000..27823e310 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java @@ -0,0 +1,37 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.application.options.*; +import com.intellij.psi.codeStyle.*; +import org.jetbrains.annotations.*; + +public class SimpleCodeStyleSettingsProvider extends CodeStyleSettingsProvider { + @Override + public CustomCodeStyleSettings createCustomSettings(CodeStyleSettings settings) { + return new SimpleCodeStyleSettings(settings); + } + + @Nullable + @Override + public String getConfigurableDisplayName() { + return "Simple"; + } + + + @NotNull + public CodeStyleConfigurable createConfigurable(@NotNull CodeStyleSettings settings, @NotNull CodeStyleSettings modelSettings) { + return new CodeStyleAbstractConfigurable(settings, modelSettings, this.getConfigurableDisplayName()) { + @Override + protected CodeStyleAbstractPanel createPanel(CodeStyleSettings settings) { + return new SimpleCodeStyleMainPanel(getCurrentSettings(), settings); + } + }; + } + + private static class SimpleCodeStyleMainPanel extends TabbedLanguageCodeStylePanel { + public SimpleCodeStyleMainPanel(CodeStyleSettings currentSettings, CodeStyleSettings settings) { + super(SimpleLanguage.INSTANCE, currentSettings, settings); + } + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleColorSettingsPage.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleColorSettingsPage.java new file mode 100644 index 000000000..a0ee3f616 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleColorSettingsPage.java @@ -0,0 +1,73 @@ +package com.intellij.sdk.language; + +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.options.colors.*; +import org.jetbrains.annotations.*; + +import javax.swing.*; +import java.util.Map; + +import static com.intellij.sdk.language.SimpleLanguage.*; + +public class SimpleColorSettingsPage implements ColorSettingsPage { + private static final AttributesDescriptor[] DESCRIPTORS = new AttributesDescriptor[]{ + new AttributesDescriptor("Key", SimpleSyntaxHighlighter.KEY), + new AttributesDescriptor("Separator", SimpleSyntaxHighlighter.SEPARATOR), + new AttributesDescriptor("Value", SimpleSyntaxHighlighter.VALUE), + new AttributesDescriptor("Bad Value", SimpleSyntaxHighlighter.BAD_CHARACTER) + }; + + @Nullable + @Override + public Icon getIcon() { + return SimpleIcons.FILE; + } + + @NotNull + @Override + public SyntaxHighlighter getHighlighter() { + return new SimpleSyntaxHighlighter(); + } + + @NotNull + @Override + public String getDemoText() { + return "# You are reading the \".properties\" entry.\n" + + "! The exclamation mark can also mark text as comments.\n" + + "website = http://en.wikipedia.org/\n" + + "language = English\n" + + "# The backslash below tells the application to continue reading\n" + + "# the value onto the next line.\n" + + "message = Welcome to \\\n" + + " Wikipedia!\n" + + "# Add spaces to the key\n" + + "key\\ with\\ spaces = This is the value that could be looked up with the key \"key with spaces\".\n" + + "# Unicode\n" + + "tab : \\u0009"; + } + + @Nullable + @Override + public Map getAdditionalHighlightingTagToDescriptorMap() { + return null; + } + + @NotNull + @Override + public AttributesDescriptor[] getAttributeDescriptors() { + return DESCRIPTORS; + } + + @NotNull + @Override + public ColorDescriptor[] getColorDescriptors() { + return ColorDescriptor.EMPTY_ARRAY; + } + + @NotNull + @Override + public String getDisplayName() { + return "Simple"; + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleCommenter.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleCommenter.java new file mode 100644 index 000000000..a8c5be9de --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleCommenter.java @@ -0,0 +1,38 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.lang.Commenter; +import org.jetbrains.annotations.Nullable; + +public class SimpleCommenter implements Commenter { + @Nullable + @Override + public String getLineCommentPrefix() { + return "#"; + } + + @Nullable + @Override + public String getBlockCommentPrefix() { + return ""; + } + + @Nullable + @Override + public String getBlockCommentSuffix() { + return null; + } + + @Nullable + @Override + public String getCommentedBlockCommentPrefix() { + return null; + } + + @Nullable + @Override + public String getCommentedBlockCommentSuffix() { + return null; + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleCompletionContributor.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleCompletionContributor.java new file mode 100644 index 000000000..ec29657ef --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleCompletionContributor.java @@ -0,0 +1,28 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.util.ProcessingContext; +import com.intellij.sdk.language.psi.SimpleTypes; +import org.jetbrains.annotations.NotNull; + +public class SimpleCompletionContributor extends CompletionContributor { + public SimpleCompletionContributor() { + // Register the completion providers + extend( CompletionType.BASIC, + PlatformPatterns.psiElement(SimpleTypes.VALUE).withLanguage(SimpleLanguage.INSTANCE), + new CompletionProvider() { + // Define candidate completions + public void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet resultSet) { + // Create a completion independent of context for Simple language + resultSet.addElement(LookupElementBuilder.create("Hello")); + } + } + ); + } +} diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleCreatePropertyQuickFix.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleCreatePropertyQuickFix.java new file mode 100644 index 000000000..bdb3d0f12 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleCreatePropertyQuickFix.java @@ -0,0 +1,92 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.codeInsight.intention.impl.BaseIntentionAction; +import com.intellij.lang.ASTNode; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.FileTypeIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.IncorrectOperationException; +import com.intellij.sdk.language.psi.SimpleElementFactory; +import com.intellij.sdk.language.psi.SimpleFile; +import com.intellij.sdk.language.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +class SimpleCreatePropertyQuickFix extends BaseIntentionAction { + private String key; + + SimpleCreatePropertyQuickFix(String key) { + this.key = key; + } + + @NotNull + @Override + public String getText() { + return "Create property"; + } + + @NotNull + @Override + public String getFamilyName() { + return "Simple properties"; + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return true; + } + + @Override + public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws + IncorrectOperationException { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + Collection virtualFiles = + FileTypeIndex.getFiles(SimpleFileType.INSTANCE, GlobalSearchScope.allScope(project) ); + if (virtualFiles.size() == 1) { + createProperty(project, virtualFiles.iterator().next()); + } else { + final FileChooserDescriptor descriptor = + FileChooserDescriptorFactory.createSingleFileDescriptor(SimpleFileType.INSTANCE); + descriptor.setRoots(ProjectUtil.guessProjectDir(project)); + final VirtualFile file = FileChooser.chooseFile(descriptor, project, null); + if (file != null) { + createProperty(project, file); + } + } + } + }); + } + + private void createProperty(final Project project, final VirtualFile file) { + WriteCommandAction.writeCommandAction(project).run(() -> { + SimpleFile simpleFile = (SimpleFile) PsiManager.getInstance(project).findFile(file); + ASTNode lastChildNode = simpleFile.getNode().getLastChildNode(); + // TODO: Add another check for CRLF + if (lastChildNode != null/* && !lastChildNode.getElementType().equals(SimpleTypes.CRLF)*/) { + simpleFile.getNode().addChild(SimpleElementFactory.createCRLF(project).getNode()); + } + // IMPORTANT: change spaces to escaped spaces or the new node will only have the first word for the key + SimpleProperty property = SimpleElementFactory.createProperty(project, key.replaceAll(" ", "\\\\ "), ""); + simpleFile.getNode().addChild(property.getNode()); + ((Navigatable) property.getLastChild().getNavigationElement()).navigate(true); + FileEditorManager.getInstance(project).getSelectedTextEditor().getCaretModel().moveCaretRelatively(2, 0, false, false, false); + }); + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleFileType.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleFileType.java new file mode 100644 index 000000000..f1564fe64 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleFileType.java @@ -0,0 +1,39 @@ +package com.intellij.sdk.language; + +import com.intellij.openapi.fileTypes.LanguageFileType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class SimpleFileType extends LanguageFileType { + public static final SimpleFileType INSTANCE = new SimpleFileType(); + + private SimpleFileType() { + super(SimpleLanguage.INSTANCE); + } + + @NotNull + @Override + public String getName() { + return "Simple file"; + } + + @NotNull + @Override + public String getDescription() { + return "Simple language file"; + } + + @NotNull + @Override + public String getDefaultExtension() { + return "simple"; + } + + @Nullable + @Override + public Icon getIcon() { + return SimpleIcons.FILE; + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleFileTypeFactory.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleFileTypeFactory.java new file mode 100644 index 000000000..6d823c42c --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleFileTypeFactory.java @@ -0,0 +1,16 @@ +package com.intellij.sdk.language; + +import com.intellij.openapi.fileTypes.FileTypeConsumer; +import com.intellij.openapi.fileTypes.FileTypeFactory; +import org.jetbrains.annotations.NotNull; + +/** + * Note: This class is only used with the fileTypeFactory extension point + * for versions of the IntelliJ Platform prior to v2019.2 + */ +public class SimpleFileTypeFactory extends FileTypeFactory { + @Override + public void createFileTypes(@NotNull FileTypeConsumer fileTypeConsumer) { + fileTypeConsumer.consume(SimpleFileType.INSTANCE); + } +} diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleFindUsagesProvider.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleFindUsagesProvider.java new file mode 100644 index 000000000..aa308a388 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleFindUsagesProvider.java @@ -0,0 +1,63 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.lang.cacheBuilder.*; +import com.intellij.lang.findUsages.FindUsagesProvider; +import com.intellij.psi.*; +import com.intellij.psi.tree.TokenSet; +import com.intellij.sdk.language.psi.*; +import org.jetbrains.annotations.*; +import static com.intellij.sdk.language.SimpleAnnotator.*; + +public class SimpleFindUsagesProvider implements FindUsagesProvider { + @Nullable + @Override + public WordsScanner getWordsScanner() { + return new DefaultWordsScanner(new SimpleLexerAdapter(), + TokenSet.create(SimpleTypes.KEY), + TokenSet.create(SimpleTypes.COMMENT), + TokenSet.EMPTY); + } + + @Override + public boolean canFindUsagesFor(@NotNull PsiElement psiElement) { + return psiElement instanceof PsiNamedElement; + } + + @Nullable + @Override + public String getHelpId(@NotNull PsiElement psiElement) { + return null; + } + + @NotNull + @Override + public String getType(@NotNull PsiElement element) { + if (element instanceof SimpleProperty) { + return "simple property"; + } else { + return ""; + } + } + + @NotNull + @Override + public String getDescriptiveName(@NotNull PsiElement element) { + if (element instanceof SimpleProperty) { + return ((SimpleProperty) element).getKey(); + } else { + return ""; + } + } + + @NotNull + @Override + public String getNodeText(@NotNull PsiElement element, boolean useFullName) { + if (element instanceof SimpleProperty) { + return ((SimpleProperty) element).getKey() + SIMPLE_SEPARATOR_STR + ((SimpleProperty) element).getValue(); + } else { + return ""; + } + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleFoldingBuilder.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleFoldingBuilder.java new file mode 100644 index 000000000..457f835bd --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleFoldingBuilder.java @@ -0,0 +1,78 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.folding.*; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.project.*; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.sdk.language.psi.SimpleProperty; +import org.jetbrains.annotations.*; + +import static com.intellij.sdk.language.SimpleAnnotator.*; + +import java.util.*; + +public class SimpleFoldingBuilder extends FoldingBuilderEx implements DumbAware { + @NotNull + @Override + public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) { + // Initialize the group of folding regions that will expand/collapse together. + FoldingGroup group = FoldingGroup.newGroup(SIMPLE_PREFIX_STR); + // Initialize the list of folding regions + List< FoldingDescriptor > descriptors = new ArrayList< FoldingDescriptor >(); + // Get a collection of the literal expressions in the document below root + Collection< PsiLiteralExpression > literalExpressions = + PsiTreeUtil.findChildrenOfType(root, PsiLiteralExpression.class); + // Evaluate the collection, using only Simple language literalExpressions + for ( final PsiLiteralExpression literalExpression : literalExpressions ) { + String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; + if ( value != null && value.startsWith(SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR) ) { + Project project = literalExpression.getProject(); + String key = value.substring(SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length()); + // Get a list of properties for the project + final List< SimpleProperty > properties = SimpleUtil.findProperties(project, key); + if ( properties.size() == 1 ) { + // Add a folding descriptor for the literal expression at this node. + descriptors.add(new FoldingDescriptor(literalExpression.getNode(), + new TextRange(literalExpression.getTextRange().getStartOffset() + 1, + literalExpression.getTextRange().getEndOffset() - 1), + group) ); + } + } + } + return descriptors.toArray(new FoldingDescriptor[descriptors.size()]); + } + + /** + * Gets the Simple Language 'value' string corresponding to the 'key' + * @param node Node corresponding to PsiLiteralExpression containing a string in the format + * SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR + Key, where Key is + * defined by the Simple language file. + * @return String corresponding to the "website" key. + */ + @Nullable + @Override + public String getPlaceholderText(@NotNull ASTNode node) { + String retTxt = "..."; + if ( node.getPsi() instanceof PsiLiteralExpression ) { + PsiLiteralExpression nodeElement = (PsiLiteralExpression) node.getPsi(); + String key = ((String) nodeElement.getValue()).substring(SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length()); + final List< SimpleProperty > properties = SimpleUtil.findProperties(nodeElement.getProject(), key); + String place = properties.get(0).getValue(); + // IMPORTANT: keys can come with no values, so a test for null is needed + // IMPORTANT: Convert embedded \n to backslash n, so that the string will look + // like it has LF embedded in it and embedded " to escaped " + return place == null ? retTxt : place.replaceAll("\n", "\\n").replaceAll("\"", "\\\\\""); + } + return retTxt; + } + + @Override + public boolean isCollapsedByDefault(@NotNull ASTNode node) { + return true; + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleFormattingModelBuilder.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleFormattingModelBuilder.java new file mode 100644 index 000000000..31e179678 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleFormattingModelBuilder.java @@ -0,0 +1,39 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.formatting.*; +import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.sdk.language.psi.SimpleTypes; +import org.jetbrains.annotations.*; + +public class SimpleFormattingModelBuilder implements FormattingModelBuilder { + @NotNull + @Override + public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) { + return FormattingModelProvider + .createFormattingModelForPsiFile(element.getContainingFile(), + new SimpleBlock(element.getNode(), + Wrap.createWrap(WrapType.NONE, false), + Alignment.createAlignment(), + createSpaceBuilder(settings)), + settings); + } + + private static SpacingBuilder createSpaceBuilder(CodeStyleSettings settings) { + return new SpacingBuilder(settings, SimpleLanguage.INSTANCE) + .around(SimpleTypes.SEPARATOR) + .spaceIf(settings.getCommonSettings(SimpleLanguage.INSTANCE.getID()).SPACE_AROUND_ASSIGNMENT_OPERATORS) + .before(SimpleTypes.PROPERTY) + .none(); + } + + @Nullable + @Override + public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) { + return null; + } +} diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleIcons.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleIcons.java new file mode 100644 index 000000000..f891e06af --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleIcons.java @@ -0,0 +1,9 @@ +package com.intellij.sdk.language; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class SimpleIcons { + public static final Icon FILE = IconLoader.getIcon("/icons/jar-gray.png"); +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleLanguage.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleLanguage.java new file mode 100644 index 000000000..49e3d2eda --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleLanguage.java @@ -0,0 +1,11 @@ +package com.intellij.sdk.language; + +import com.intellij.lang.Language; + +public class SimpleLanguage extends Language { + public static final SimpleLanguage INSTANCE = new SimpleLanguage(); + + private SimpleLanguage() { + super("Simple"); + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java new file mode 100644 index 000000000..974c1e223 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java @@ -0,0 +1,42 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.lang.Language; +import com.intellij.psi.codeStyle.*; +import org.jetbrains.annotations.NotNull; + +public class SimpleLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettingsProvider { + @NotNull + @Override + public Language getLanguage() { + return SimpleLanguage.INSTANCE; + } + + @Override + public void customizeSettings(@NotNull CodeStyleSettingsCustomizable consumer, @NotNull SettingsType settingsType) { + if (settingsType == SettingsType.SPACING_SETTINGS) { + consumer.showStandardOptions("SPACE_AROUND_ASSIGNMENT_OPERATORS"); + consumer.renameStandardOption("SPACE_AROUND_ASSIGNMENT_OPERATORS", "Separator"); + } else if (settingsType == SettingsType.BLANK_LINES_SETTINGS) { + consumer.showStandardOptions("KEEP_BLANK_LINES_IN_CODE"); + } + } + + @Override + public String getCodeSample(@NotNull SettingsType settingsType) { + return "# You are reading the \".properties\" entry.\n" + + "! The exclamation mark can also mark text as comments.\n" + + "website = http://en.wikipedia.org/\n" + + "\n" + + "language = English\n" + + "# The backslash below tells the application to continue reading\n" + + "# the value onto the next line.\n" + + "message = Welcome to \\\n" + + " Wikipedia!\n" + + "# Add spaces to the key\n" + + "key\\ with\\ spaces = This is the value that could be looked up with the key \"key with spaces\".\n" + + "# Unicode\n" + + "tab : \\u0009"; + } +} diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleLexerAdapter.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleLexerAdapter.java new file mode 100644 index 000000000..426ac5226 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleLexerAdapter.java @@ -0,0 +1,11 @@ +package com.intellij.sdk.language; + +import com.intellij.lexer.FlexAdapter; + +import java.io.Reader; + +public class SimpleLexerAdapter extends FlexAdapter { + public SimpleLexerAdapter() { + super(new SimpleLexer((Reader) null)); + } +} diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleLineMarkerProvider.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleLineMarkerProvider.java new file mode 100644 index 000000000..a70ec514e --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleLineMarkerProvider.java @@ -0,0 +1,40 @@ +package com.intellij.sdk.language; + +import com.intellij.codeInsight.daemon.*; +import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl; +import com.intellij.sdk.language.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; +import static com.intellij.sdk.language.SimpleAnnotator.*; + +import java.util.*; + +public class SimpleLineMarkerProvider extends RelatedItemLineMarkerProvider { + @Override + protected void collectNavigationMarkers( @NotNull PsiElement element, + @NotNull Collection< ? super RelatedItemLineMarkerInfo > result ) { + // This must be an element with a literal expression as a parent + if ( !(element instanceof PsiJavaTokenImpl) || !(element.getParent() instanceof PsiLiteralExpression) ) return; + + // The literal expression must start with the Simple language literal expression + PsiLiteralExpression literalExpression = (PsiLiteralExpression) element.getParent(); + String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; + if ( ( value == null ) || !value.startsWith( SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR ) ) return; + + // Get the Simple language property usage + Project project = element.getProject(); + String possibleProperties = value.substring( SIMPLE_PREFIX_STR.length()+SIMPLE_SEPARATOR_STR.length() ); + final List< SimpleProperty > properties = SimpleUtil.findProperties( project, possibleProperties ); + if ( properties.size() > 0 ) { + // Add the property to a collection of line marker info + NavigationGutterIconBuilder< PsiElement > builder = + NavigationGutterIconBuilder.create( SimpleIcons.FILE ) + .setTargets( properties ) + .setTooltipText( "Navigate to Simple language property" ); + result.add( builder.createLineMarkerInfo( element ) ); + } + } + +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleParserDefinition.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleParserDefinition.java new file mode 100644 index 000000000..838c1b9fd --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleParserDefinition.java @@ -0,0 +1,68 @@ +package com.intellij.sdk.language; + +import com.intellij.lang.*; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.tree.*; +import com.intellij.sdk.language.parser.SimpleParser; +import com.intellij.sdk.language.psi.*; +import org.jetbrains.annotations.NotNull; + +public class SimpleParserDefinition implements ParserDefinition { + public static final TokenSet WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE); + public static final TokenSet COMMENTS = TokenSet.create(SimpleTypes.COMMENT); + + public static final IFileElementType FILE = new IFileElementType(SimpleLanguage.INSTANCE); + + @NotNull + @Override + public Lexer createLexer(Project project) { + return new SimpleLexerAdapter(); + } + + @NotNull + @Override + public TokenSet getWhitespaceTokens() { + return WHITE_SPACES; + } + + @NotNull + @Override + public TokenSet getCommentTokens() { + return COMMENTS; + } + + @NotNull + @Override + public TokenSet getStringLiteralElements() { + return TokenSet.EMPTY; + } + + @NotNull + @Override + public PsiParser createParser(final Project project) { + return new SimpleParser(); + } + + @Override + public IFileElementType getFileNodeType() { + return FILE; + } + + @Override + public PsiFile createFile(FileViewProvider viewProvider) { + return new SimpleFile(viewProvider); + } + + @Override + public SpaceRequirements spaceExistenceTypeBetweenTokens(ASTNode left, ASTNode right) { + return SpaceRequirements.MAY; + } + + @NotNull + @Override + public PsiElement createElement(ASTNode node) { + return SimpleTypes.Factory.createElement(node); + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleRefactoringSupportProvider.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleRefactoringSupportProvider.java new file mode 100644 index 000000000..95da8b291 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleRefactoringSupportProvider.java @@ -0,0 +1,20 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.lang.refactoring.RefactoringSupportProvider; +import com.intellij.psi.PsiElement; +import com.intellij.sdk.language.psi.SimpleProperty; +import org.jetbrains.annotations.*; + +public class SimpleRefactoringSupportProvider extends RefactoringSupportProvider { + @Override + public boolean isMemberInplaceRenameAvailable(@NotNull PsiElement elementToRename, @Nullable PsiElement context) { + return (elementToRename instanceof SimpleProperty); + } +} + +/* +2020-01-10 21:59:36,392 [ 74521] WARN - name.RenamePsiElementProcessor - org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinTypeParameterProcessor overrides deprecated findReferences(..). +Override findReferences(PsiElement, SearchScope, boolean) instead. +*/ \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleReference.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleReference.java new file mode 100644 index 000000000..859ddbaf0 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleReference.java @@ -0,0 +1,57 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.codeInsight.lookup.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.sdk.language.psi.SimpleProperty; +import org.jetbrains.annotations.*; + +import java.util.*; + +public class SimpleReference extends PsiReferenceBase implements PsiPolyVariantReference { + private String key; + + public SimpleReference(@NotNull PsiElement element, TextRange textRange) { + super(element, textRange); + key = element.getText().substring(textRange.getStartOffset(), textRange.getEndOffset()); + } + + @NotNull + @Override + public ResolveResult[] multiResolve(boolean incompleteCode) { + Project project = myElement.getProject(); + final List properties = SimpleUtil.findProperties(project, key); + List results = new ArrayList(); + for (SimpleProperty property : properties) { + results.add(new PsiElementResolveResult(property)); + } + return results.toArray(new ResolveResult[results.size()]); + } + + @Nullable + @Override + public PsiElement resolve() { + ResolveResult[] resolveResults = multiResolve(false); + return resolveResults.length == 1 ? resolveResults[0].getElement() : null; + } + + @NotNull + @Override + public Object[] getVariants() { + Project project = myElement.getProject(); + List properties = SimpleUtil.findProperties(project); + List variants = new ArrayList(); + for (final SimpleProperty property : properties) { + if (property.getKey() != null && property.getKey().length() > 0) { + variants.add(LookupElementBuilder + .create(property).withIcon(SimpleIcons.FILE) + .withTypeText(property.getContainingFile().getName()) + ); + } + } + return variants.toArray(); + } +} diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleReferenceContributor.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleReferenceContributor.java new file mode 100644 index 000000000..886111cfa --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleReferenceContributor.java @@ -0,0 +1,34 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.openapi.util.TextRange; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.psi.*; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; + +import static com.intellij.sdk.language.SimpleAnnotator.*; + +public class SimpleReferenceContributor extends PsiReferenceContributor { + @Override + public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { + registrar.registerReferenceProvider( PlatformPatterns.psiElement( PsiLiteralExpression.class ), + new PsiReferenceProvider() { + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, + @NotNull ProcessingContext context) { + PsiLiteralExpression literalExpression = (PsiLiteralExpression) element; + String value = literalExpression.getValue() instanceof String ? + (String) literalExpression.getValue() : null; + if ( ( value != null && value.startsWith( SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR ) ) ) { + TextRange property = new TextRange( SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length() + 1, + value.length() + 1 ); + return new PsiReference[]{ new SimpleReference( element, property ) }; + } + return PsiReference.EMPTY_ARRAY; + } + } ); + } +} diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewElement.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewElement.java new file mode 100644 index 000000000..8d3629202 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewElement.java @@ -0,0 +1,74 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.util.treeView.smartTree.SortableTreeElement; +import com.intellij.ide.util.treeView.smartTree.TreeElement; +import com.intellij.navigation.ItemPresentation; +import com.intellij.psi.NavigatablePsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.sdk.language.psi.SimpleFile; +import com.intellij.sdk.language.psi.SimpleProperty; +import com.intellij.sdk.language.psi.impl.SimplePropertyImpl; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class SimpleStructureViewElement implements StructureViewTreeElement, SortableTreeElement { + private NavigatablePsiElement element; + + public SimpleStructureViewElement(NavigatablePsiElement element) { + this.element = element; + } + + @Override + public Object getValue() { + return element; + } + + @Override + public void navigate(boolean requestFocus) { + element.navigate(requestFocus); + } + + @Override + public boolean canNavigate() { + return element.canNavigate(); + } + + @Override + public boolean canNavigateToSource() { + return element.canNavigateToSource(); + } + + @NotNull + @Override + public String getAlphaSortKey() { + String name = element.getName(); + return name != null ? name : ""; + } + + @NotNull + @Override + public ItemPresentation getPresentation() { + ItemPresentation presentation = element.getPresentation(); + return presentation != null ? presentation : new PresentationData(); + } + + @Override + public TreeElement[] getChildren() { + if (element instanceof SimpleFile) { + SimpleProperty[] properties = PsiTreeUtil.getChildrenOfType(element, SimpleProperty.class); + List treeElements = new ArrayList(properties.length); + for (SimpleProperty property : properties) { + treeElements.add(new SimpleStructureViewElement((SimplePropertyImpl) property)); + } + return treeElements.toArray(new TreeElement[treeElements.size()]); + } else { + return EMPTY_ARRAY; + } + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewFactory.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewFactory.java new file mode 100644 index 000000000..4ef9a11d9 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewFactory.java @@ -0,0 +1,23 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.ide.structureView.*; +import com.intellij.lang.PsiStructureViewFactory; +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.*; + +public class SimpleStructureViewFactory implements PsiStructureViewFactory { + @Nullable + @Override + public StructureViewBuilder getStructureViewBuilder(final PsiFile psiFile) { + return new TreeBasedStructureViewBuilder() { + @NotNull + @Override + public StructureViewModel createStructureViewModel(@Nullable Editor editor) { + return new SimpleStructureViewModel(psiFile); + } + }; + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewModel.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewModel.java new file mode 100644 index 000000000..e7352cf82 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleStructureViewModel.java @@ -0,0 +1,32 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language; + +import com.intellij.ide.structureView.*; +import com.intellij.ide.util.treeView.smartTree.Sorter; +import com.intellij.psi.PsiFile; +import com.intellij.sdk.language.psi.SimpleFile; +import org.jetbrains.annotations.NotNull; + +public class SimpleStructureViewModel extends StructureViewModelBase implements + StructureViewModel.ElementInfoProvider { + public SimpleStructureViewModel(PsiFile psiFile) { + super(psiFile, new SimpleStructureViewElement(psiFile)); + } + + @NotNull + public Sorter[] getSorters() { + return new Sorter[]{Sorter.ALPHA_SORTER}; + } + + + @Override + public boolean isAlwaysShowsPlus(StructureViewTreeElement element) { + return false; + } + + @Override + public boolean isAlwaysLeaf(StructureViewTreeElement element) { + return element instanceof SimpleFile; + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleSyntaxHighlighter.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleSyntaxHighlighter.java new file mode 100644 index 000000000..44ea221ab --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleSyntaxHighlighter.java @@ -0,0 +1,57 @@ +package com.intellij.sdk.language; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.SyntaxHighlighterBase; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.sdk.language.psi.SimpleTypes; +import org.jetbrains.annotations.NotNull; + +import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey; + +public class SimpleSyntaxHighlighter extends SyntaxHighlighterBase { + public static final TextAttributesKey SEPARATOR = + createTextAttributesKey("SIMPLE_SEPARATOR", DefaultLanguageHighlighterColors.OPERATION_SIGN); + public static final TextAttributesKey KEY = + createTextAttributesKey("SIMPLE_KEY", DefaultLanguageHighlighterColors.KEYWORD); + public static final TextAttributesKey VALUE = + createTextAttributesKey("SIMPLE_VALUE", DefaultLanguageHighlighterColors.STRING); + public static final TextAttributesKey COMMENT = + createTextAttributesKey("SIMPLE_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT); + public static final TextAttributesKey BAD_CHARACTER = + createTextAttributesKey("SIMPLE_BAD_CHARACTER", HighlighterColors.BAD_CHARACTER); + + + private static final TextAttributesKey[] BAD_CHAR_KEYS = new TextAttributesKey[]{BAD_CHARACTER}; + private static final TextAttributesKey[] SEPARATOR_KEYS = new TextAttributesKey[]{SEPARATOR}; + private static final TextAttributesKey[] KEY_KEYS = new TextAttributesKey[]{KEY}; + private static final TextAttributesKey[] VALUE_KEYS = new TextAttributesKey[]{VALUE}; + private static final TextAttributesKey[] COMMENT_KEYS = new TextAttributesKey[]{COMMENT}; + private static final TextAttributesKey[] EMPTY_KEYS = new TextAttributesKey[0]; + + @NotNull + @Override + public Lexer getHighlightingLexer() { + return new SimpleLexerAdapter(); + } + + @NotNull + @Override + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + if (tokenType.equals(SimpleTypes.SEPARATOR)) { + return SEPARATOR_KEYS; + } else if (tokenType.equals(SimpleTypes.KEY)) { + return KEY_KEYS; + } else if (tokenType.equals(SimpleTypes.VALUE)) { + return VALUE_KEYS; + } else if (tokenType.equals(SimpleTypes.COMMENT)) { + return COMMENT_KEYS; + } else if (tokenType.equals(TokenType.BAD_CHARACTER)) { + return BAD_CHAR_KEYS; + } else { + return EMPTY_KEYS; + } + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleSyntaxHighlighterFactory.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleSyntaxHighlighterFactory.java new file mode 100644 index 000000000..d8fd3732b --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleSyntaxHighlighterFactory.java @@ -0,0 +1,14 @@ +package com.intellij.sdk.language; + +import com.intellij.openapi.fileTypes.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +public class SimpleSyntaxHighlighterFactory extends SyntaxHighlighterFactory { + @NotNull + @Override + public SyntaxHighlighter getSyntaxHighlighter(Project project, VirtualFile virtualFile) { + return new SimpleSyntaxHighlighter(); + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/SimpleUtil.java b/simple_language/src/main/java/com/intellij/sdk/language/SimpleUtil.java new file mode 100644 index 000000000..3511323d0 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/SimpleUtil.java @@ -0,0 +1,54 @@ +package com.intellij.sdk.language; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.indexing.FileBasedIndex; +import com.intellij.sdk.language.psi.*; + +import java.util.*; + +public class SimpleUtil { + + // Searches the entire project for Simple language files with instances of the Simple property + public static List findProperties(Project project, String key) { + List result = null; + Collection virtualFiles = + FileTypeIndex.getFiles(SimpleFileType.INSTANCE, GlobalSearchScope.allScope(project)); + for (VirtualFile virtualFile : virtualFiles) { + SimpleFile simpleFile = (SimpleFile) PsiManager.getInstance(project).findFile(virtualFile); + if (simpleFile != null) { + SimpleProperty[] properties = PsiTreeUtil.getChildrenOfType(simpleFile, SimpleProperty.class); + if (properties != null) { + for (SimpleProperty property : properties) { + if (key.equals(property.getKey())) { + if (result == null) { + result = new ArrayList(); + } + result.add(property); + } + } + } + } + } + return result != null ? result : Collections.emptyList(); + } + + public static List findProperties(Project project) { + List result = new ArrayList(); + Collection virtualFiles = + FileTypeIndex.getFiles(SimpleFileType.INSTANCE, GlobalSearchScope.allScope(project)); + for (VirtualFile virtualFile : virtualFiles) { + SimpleFile simpleFile = (SimpleFile) PsiManager.getInstance(project).findFile(virtualFile); + if (simpleFile != null) { + SimpleProperty[] properties = PsiTreeUtil.getChildrenOfType(simpleFile, SimpleProperty.class); + if (properties != null) { + Collections.addAll(result, properties); + } + } + } + return result; + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleElementFactory.java b/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleElementFactory.java new file mode 100644 index 000000000..5789a7f1e --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleElementFactory.java @@ -0,0 +1,29 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language.psi; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.sdk.language.SimpleFileType; + +public class SimpleElementFactory { + public static SimpleProperty createProperty(Project project, String name) { + final SimpleFile file = createFile(project, name); + return (SimpleProperty) file.getFirstChild(); + } + + public static SimpleProperty createProperty(Project project, String name, String value) { + final SimpleFile file = createFile(project, name + " = " + value); + return (SimpleProperty) file.getFirstChild(); + } + + public static PsiElement createCRLF(Project project) { + final SimpleFile file = createFile(project, "\n"); + return file.getFirstChild(); + } + + public static SimpleFile createFile(Project project, String text) { + String name = "dummy.simple"; + return (SimpleFile) PsiFileFactory.getInstance( project).createFileFromText(name, SimpleFileType.INSTANCE, text); + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleElementType.java b/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleElementType.java new file mode 100644 index 000000000..cbc6b76d8 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleElementType.java @@ -0,0 +1,12 @@ +package com.intellij.sdk.language.psi; + +import com.intellij.psi.tree.IElementType; +import com.intellij.sdk.language.SimpleLanguage; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class SimpleElementType extends IElementType { + public SimpleElementType( @NotNull @NonNls String debugName) { + super(debugName, SimpleLanguage.INSTANCE); + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleFile.java b/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleFile.java new file mode 100644 index 000000000..3d012cd5a --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleFile.java @@ -0,0 +1,31 @@ +package com.intellij.sdk.language.psi; + +import com.intellij.extapi.psi.PsiFileBase; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.psi.FileViewProvider; +import com.intellij.sdk.language.*; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +public class SimpleFile extends PsiFileBase { + public SimpleFile(@NotNull FileViewProvider viewProvider) { + super(viewProvider, SimpleLanguage.INSTANCE); + } + + @NotNull + @Override + public FileType getFileType() { + return SimpleFileType.INSTANCE; + } + + @Override + public String toString() { + return "Simple File"; + } + + @Override + public Icon getIcon(int flags) { + return super.getIcon(flags); + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleNamedElement.java b/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleNamedElement.java new file mode 100644 index 000000000..0cb18830a --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleNamedElement.java @@ -0,0 +1,8 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language.psi; + +import com.intellij.psi.PsiNameIdentifierOwner; + +public interface SimpleNamedElement extends PsiNameIdentifierOwner { +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleTokenType.java b/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleTokenType.java new file mode 100644 index 000000000..3300afdc0 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/psi/SimpleTokenType.java @@ -0,0 +1,16 @@ +package com.intellij.sdk.language.psi; + +import com.intellij.psi.tree.IElementType; +import com.intellij.sdk.language.SimpleLanguage; +import org.jetbrains.annotations.*; + +public class SimpleTokenType extends IElementType { + public SimpleTokenType(@NotNull @NonNls String debugName) { + super(debugName, SimpleLanguage.INSTANCE); + } + + @Override + public String toString() { + return "SimpleTokenType." + super.toString(); + } +} diff --git a/simple_language/src/main/java/com/intellij/sdk/language/psi/impl/SimpleNamedElementImpl.java b/simple_language/src/main/java/com/intellij/sdk/language/psi/impl/SimpleNamedElementImpl.java new file mode 100644 index 000000000..367dd8f99 --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/psi/impl/SimpleNamedElementImpl.java @@ -0,0 +1,14 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package com.intellij.sdk.language.psi.impl; + +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.intellij.lang.ASTNode; +import com.intellij.sdk.language.psi.SimpleNamedElement; +import org.jetbrains.annotations.NotNull; + +public abstract class SimpleNamedElementImpl extends ASTWrapperPsiElement implements SimpleNamedElement { + public SimpleNamedElementImpl(@NotNull ASTNode node) { + super(node); + } +} \ No newline at end of file diff --git a/simple_language/src/main/java/com/intellij/sdk/language/psi/impl/SimplePsiImplUtil.java b/simple_language/src/main/java/com/intellij/sdk/language/psi/impl/SimplePsiImplUtil.java new file mode 100644 index 000000000..25ccc748c --- /dev/null +++ b/simple_language/src/main/java/com/intellij/sdk/language/psi/impl/SimplePsiImplUtil.java @@ -0,0 +1,79 @@ +package com.intellij.sdk.language.psi.impl; + +import com.intellij.lang.ASTNode; +import com.intellij.navigation.ItemPresentation; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.sdk.language.SimpleIcons; +import com.intellij.sdk.language.psi.*; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class SimplePsiImplUtil { + public static String getKey(SimpleProperty element) { + ASTNode keyNode = element.getNode().findChildByType(SimpleTypes.KEY); + if (keyNode != null) { + // IMPORTANT: Convert embedded escaped spaces to simple spaces + return keyNode.getText().replaceAll("\\\\ ", " "); + } else { + return null; + } + } + + public static String getValue(SimpleProperty element) { + ASTNode valueNode = element.getNode().findChildByType(SimpleTypes.VALUE); + if (valueNode != null) { + return valueNode.getText(); + } else { + return null; + } + } + + public static String getName(SimpleProperty element) { + return getKey(element); + } + + public static PsiElement setName(SimpleProperty element, String newName) { + ASTNode keyNode = element.getNode().findChildByType(SimpleTypes.KEY); + if (keyNode != null) { + SimpleProperty property = SimpleElementFactory.createProperty(element.getProject(), newName); + ASTNode newKeyNode = property.getFirstChild().getNode(); + element.getNode().replaceChild(keyNode, newKeyNode); + } + return element; + } + + public static PsiElement getNameIdentifier( SimpleProperty element) { + ASTNode keyNode = element.getNode().findChildByType(SimpleTypes.KEY); + if (keyNode != null) { + return keyNode.getPsi(); + } else { + return null; + } + } + + public static ItemPresentation getPresentation( final SimpleProperty element) { + return new ItemPresentation() { + @Nullable + @Override + public String getPresentableText() { + return element.getKey(); + } + + @Nullable + @Override + public String getLocationString() { + PsiFile containingFile = element.getContainingFile(); + return containingFile == null ? null : containingFile.getName(); + } + + @Nullable + @Override + public Icon getIcon( boolean unused) { + return SimpleIcons.FILE; + } + }; + } + +} \ No newline at end of file diff --git a/simple_language/src/main/resources/META-INF/plugin.xml b/simple_language/src/main/resources/META-INF/plugin.xml new file mode 100644 index 000000000..d822c4b6f --- /dev/null +++ b/simple_language/src/main/resources/META-INF/plugin.xml @@ -0,0 +1,66 @@ + + + + + + com.intellij.sdk.simple_language + + + SDK: Simple Language Sample Project + + + 2.0.0 + + + + + + com.intellij.modules.platform + com.intellij.modules.java + + + + Defines a new language, Simple language with support for syntax highlighting, annotations, code completion, and other features. +
See the Custom Language Tutorial for more information. + ]]> +
+ + +

  • 2.0.0 Convert to Gradle-based plugin.
  • +
  • 1.0.0 Release 2018.3 and earlier.
  • + + ]]> + + + + IntelliJ Platform SDK + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/simple_language/src/main/resources/META-INF/pluginIcon.svg b/simple_language/src/main/resources/META-INF/pluginIcon.svg new file mode 100644 index 000000000..613290897 --- /dev/null +++ b/simple_language/src/main/resources/META-INF/pluginIcon.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/simple_language/src/main/resources/icons/jar-gray.png b/simple_language/src/main/resources/icons/jar-gray.png new file mode 100644 index 0000000000000000000000000000000000000000..2642d51e5f6a169ba59e833271f752a874c46029 GIT binary patch literal 717 zcmV;;0y6!HP) z&r2d<7{}jZ=RNFS;Bo(gJuDtP2!-S!EejD1GnJ)7ZKn=Fd5P>`Qic@ti##l%qKDE< ztj0m2L_=--flalUii8cF;@#(o-eq=o-~+?F-|y#rXXYVJr<2H;oSbwT42C_OPWN+Q zU?8PdtFwcHgNd=RvB1Q{#1yO(IRwIgF)}g|ESJml>gtLnlS#V2zfXg~AU!%dqI$hP zG(0>^*!tMvr}0eWz7Ks_E0ou8klD=RB>V`GEj8fGxddU8P@@C`6j zDwV|j{e40d#YC-EOO{HdWT8+<;o3*0?>_*%ply-M_t4x4d)*~j9 ziD5&*+1VKng*u43Fc0F+&W`B!`^C-8%{mBq6kwM1h|y?d*iirjQ%|SUuP_JnwE%=x;9*@(- z#l;Y~nsl2>KvV00000NkvXXu0mjfaH literal 0 HcmV?d00001 diff --git a/simple_language/src/test/java/com/intellij/sdk/language/SimpleCodeInsightTest.java b/simple_language/src/test/java/com/intellij/sdk/language/SimpleCodeInsightTest.java new file mode 100644 index 000000000..1dc8048b0 --- /dev/null +++ b/simple_language/src/test/java/com/intellij/sdk/language/SimpleCodeInsightTest.java @@ -0,0 +1,83 @@ +package com.intellij.sdk.language; + +import com.intellij.application.options.CodeStyle; +import com.intellij.codeInsight.completion.CompletionType; +import com.intellij.codeInsight.generation.actions.CommentByLineCommentAction; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.psi.PsiElement; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.sdk.language.psi.SimpleProperty; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class SimpleCodeInsightTest extends LightJavaCodeInsightFixtureTestCase { + + /** + * + * @return path to test data file directory relative to working directory in the run configuration for this test. + */ + @Override + protected String getTestDataPath() { + return "src/test/testData"; + } + + public void testCompletion() { + myFixture.configureByFiles("CompleteTestData.java", "DefaultTestData.simple"); + myFixture.complete(CompletionType.BASIC, 1); + List strings = myFixture.getLookupElementStrings(); + assertTrue(strings.containsAll(Arrays.asList("key with spaces", "language", "message", "tab", "website"))); + assertEquals(5, strings.size()); + } + + public void testAnnotator() { + myFixture.configureByFiles("AnnotatorTestData.java", "DefaultTestData.simple"); + myFixture.checkHighlighting(false, false, true, true); + } + + public void testFormatter() { + myFixture.configureByFiles("FormatterTestData.simple"); + CodeStyle.getLanguageSettings(myFixture.getFile()).SPACE_AROUND_ASSIGNMENT_OPERATORS = true; + CodeStyle.getLanguageSettings(myFixture.getFile()).KEEP_BLANK_LINES_IN_CODE = 2; + WriteCommandAction.writeCommandAction(getProject()).run(() -> { + CodeStyleManager.getInstance(getProject()).reformatText(myFixture.getFile(), + ContainerUtil.newArrayList(myFixture.getFile().getTextRange())); + }); + myFixture.checkResultByFile("DefaultTestData.simple"); + } + + public void testRename() { + myFixture.configureByFiles("RenameTestData.java", "RenameTestData.simple"); + myFixture.renameElementAtCaret("websiteUrl"); + myFixture.checkResultByFile("RenameTestData.simple", "RenameTestDataAfter.simple", false); + } + + public void testFolding() { + myFixture.configureByFiles("DefaultTestData.simple"); + myFixture.testFolding(getTestDataPath() + "/FoldingTestData.java"); + } + + public void testFindUsages() { + Collection usageInfos = myFixture.testFindUsages("FindUsagesTestData.simple", "FindUsagesTestData.java"); + assertEquals(1, usageInfos.size()); + } + + public void testCommenter() { + myFixture.configureByText(SimpleFileType.INSTANCE, "website = http://en.wikipedia.org/"); + CommentByLineCommentAction commentAction = new CommentByLineCommentAction(); + commentAction.actionPerformedImpl(getProject(), myFixture.getEditor()); + myFixture.checkResult("#website = http://en.wikipedia.org/"); + commentAction.actionPerformedImpl(getProject(), myFixture.getEditor()); + myFixture.checkResult("website = http://en.wikipedia.org/"); + } + + public void testReference() { + myFixture.configureByFiles("ReferenceTestData.java", "DefaultTestData.simple"); + PsiElement element = myFixture.getFile().findElementAt(myFixture.getCaretOffset()).getParent(); + assertEquals("http://en.wikipedia.org/", ((SimpleProperty) element.getReferences()[0].resolve()).getValue()); + } +} diff --git a/simple_language/src/test/java/com/intellij/sdk/language/SimpleParsingTest.java b/simple_language/src/test/java/com/intellij/sdk/language/SimpleParsingTest.java new file mode 100644 index 000000000..98a3b9d11 --- /dev/null +++ b/simple_language/src/test/java/com/intellij/sdk/language/SimpleParsingTest.java @@ -0,0 +1,32 @@ +package com.intellij.sdk.language; + +import com.intellij.testFramework.ParsingTestCase; + +public class SimpleParsingTest extends ParsingTestCase { + public SimpleParsingTest() { + super("", "simple", new SimpleParserDefinition()); + } + + public void testParsingTestData() { + doTest(true); + } + + /** + * + * @return path to test data file directory relative to root of this module. + */ + @Override + protected String getTestDataPath() { + return "src/test/testData"; + } + + @Override + protected boolean skipSpaces() { + return false; + } + + @Override + protected boolean includeRanges() { + return true; + } +} diff --git a/simple_language/src/test/testData/AnnotatorTestData.java b/simple_language/src/test/testData/AnnotatorTestData.java new file mode 100644 index 000000000..eae0b79de --- /dev/null +++ b/simple_language/src/test/testData/AnnotatorTestData.java @@ -0,0 +1,7 @@ +public class Test { + public static void main(String[] args) { + System.out.println("simple:website"); + System.out.println("simple:key with spaces"); + System.out.println("simple:websit"); + } +} diff --git a/simple_language/src/test/testData/CompleteTestData.java b/simple_language/src/test/testData/CompleteTestData.java new file mode 100644 index 000000000..7c2c666a1 --- /dev/null +++ b/simple_language/src/test/testData/CompleteTestData.java @@ -0,0 +1,5 @@ +public class Test { + public static void main(String[] args) { + System.out.println("simple:"); + } +} diff --git a/simple_language/src/test/testData/DefaultTestData.simple b/simple_language/src/test/testData/DefaultTestData.simple new file mode 100644 index 000000000..ebe624812 --- /dev/null +++ b/simple_language/src/test/testData/DefaultTestData.simple @@ -0,0 +1,14 @@ +# You are reading the ".properties" entry. +! The exclamation mark can also mark text as comments. +website = http://en.wikipedia.org/ + + +language = English +# The backslash below tells the application to continue reading +# the value onto the next line. +message = Welcome to \ + Wikipedia! +# Add spaces to the key +key\ with\ spaces = This is the value that could be looked up with the key "key with spaces". +# Unicode +tab : \u0009 diff --git a/simple_language/src/test/testData/FindUsagesTestData.java b/simple_language/src/test/testData/FindUsagesTestData.java new file mode 100644 index 000000000..727681239 --- /dev/null +++ b/simple_language/src/test/testData/FindUsagesTestData.java @@ -0,0 +1,5 @@ +public class Test { + public static void main(String[] args) { + System.out.println("simple:key with spaces"); + } +} diff --git a/simple_language/src/test/testData/FindUsagesTestData.simple b/simple_language/src/test/testData/FindUsagesTestData.simple new file mode 100644 index 000000000..2f31ab9e2 --- /dev/null +++ b/simple_language/src/test/testData/FindUsagesTestData.simple @@ -0,0 +1,13 @@ +# You are reading the ".properties" entry. +! The exclamation mark can also mark text as comments. +website = http://en.wikipedia.org/ + +language = English +# The backslash below tells the application to continue reading +# the value onto the next line. +message = Welcome to \ + Wikipedia! +# Add spaces to the key +key\ with\ spaces = This is the value that could be looked up with the key "key with spaces". +# Unicode +tab : \u0009 diff --git a/simple_language/src/test/testData/FoldingTestData.java b/simple_language/src/test/testData/FoldingTestData.java new file mode 100644 index 000000000..1920b5fae --- /dev/null +++ b/simple_language/src/test/testData/FoldingTestData.java @@ -0,0 +1,11 @@ +public class Test { + public static void main(String[] args) { + System.out.println("simple:website"); + } + public static void main1(String[] args) { + System.out.println("simple:key with spaces"); + } + public static void main2(String[] args) { + System.out.println("simple:message"); + } +} diff --git a/simple_language/src/test/testData/FormatterTestData.simple b/simple_language/src/test/testData/FormatterTestData.simple new file mode 100644 index 000000000..44a78fa68 --- /dev/null +++ b/simple_language/src/test/testData/FormatterTestData.simple @@ -0,0 +1,15 @@ +# You are reading the ".properties" entry. +! The exclamation mark can also mark text as comments. +website=http://en.wikipedia.org/ + + + +language= English +# The backslash below tells the application to continue reading +# the value onto the next line. +message = Welcome to \ + Wikipedia! +# Add spaces to the key +key\ with\ spaces = This is the value that could be looked up with the key "key with spaces". +# Unicode +tab :\u0009 diff --git a/simple_language/src/test/testData/ParsingTestData.simple b/simple_language/src/test/testData/ParsingTestData.simple new file mode 100644 index 000000000..e11fdcef3 --- /dev/null +++ b/simple_language/src/test/testData/ParsingTestData.simple @@ -0,0 +1,17 @@ +# You are reading the ".properties" entry. +! The exclamation mark can also mark text as comments. +website = http://en.wikipedia.org/ + +language = English +# The backslash below tells the application to continue reading +# the value onto the next line. +message = Welcome to \ + Wikipedia! +# Add spaces to the key +key\ with\ spaces = This is the value that could be looked up with the key "key with spaces". +# Unicode +tab : \u0009 +# test for illegal key attempt +key\ +with\ +endofline = test diff --git a/simple_language/src/test/testData/ParsingTestData.txt b/simple_language/src/test/testData/ParsingTestData.txt new file mode 100644 index 000000000..012fa0291 --- /dev/null +++ b/simple_language/src/test/testData/ParsingTestData.txt @@ -0,0 +1,66 @@ +Simple File(0,492) + PsiComment(SimpleTokenType.COMMENT)('# You are reading the ".properties" entry.')(0,42) + PsiWhiteSpace('\n')(42,43) + PsiComment(SimpleTokenType.COMMENT)('! The exclamation mark can also mark text as comments.')(43,97) + PsiWhiteSpace('\n')(97,98) + SimplePropertyImpl(PROPERTY)(98,132) + PsiElement(SimpleTokenType.KEY)('website')(98,105) + PsiWhiteSpace(' ')(105,106) + PsiElement(SimpleTokenType.SEPARATOR)('=')(106,107) + PsiWhiteSpace(' ')(107,108) + PsiElement(SimpleTokenType.VALUE)('http://en.wikipedia.org/')(108,132) + PsiWhiteSpace('\n\n')(132,134) + SimplePropertyImpl(PROPERTY)(134,152) + PsiElement(SimpleTokenType.KEY)('language')(134,142) + PsiWhiteSpace(' ')(142,143) + PsiElement(SimpleTokenType.SEPARATOR)('=')(143,144) + PsiWhiteSpace(' ')(144,145) + PsiElement(SimpleTokenType.VALUE)('English')(145,152) + PsiWhiteSpace('\n')(152,153) + PsiComment(SimpleTokenType.COMMENT)('# The backslash below tells the application to continue reading')(153,216) + PsiWhiteSpace('\n')(216,217) + PsiComment(SimpleTokenType.COMMENT)('# the value onto the next line.')(217,248) + PsiWhiteSpace('\n')(248,249) + SimplePropertyImpl(PROPERTY)(249,292) + PsiElement(SimpleTokenType.KEY)('message')(249,256) + PsiWhiteSpace(' ')(256,257) + PsiElement(SimpleTokenType.SEPARATOR)('=')(257,258) + PsiWhiteSpace(' ')(258,259) + PsiElement(SimpleTokenType.VALUE)('Welcome to \\n Wikipedia!')(259,292) + PsiWhiteSpace('\n')(292,293) + PsiComment(SimpleTokenType.COMMENT)('# Add spaces to the key')(293,316) + PsiWhiteSpace('\n')(316,317) + SimplePropertyImpl(PROPERTY)(317,410) + PsiElement(SimpleTokenType.KEY)('key\ with\ spaces')(317,334) + PsiWhiteSpace(' ')(334,335) + PsiElement(SimpleTokenType.SEPARATOR)('=')(335,336) + PsiWhiteSpace(' ')(336,337) + PsiElement(SimpleTokenType.VALUE)('This is the value that could be looked up with the key "key with spaces".')(337,410) + PsiWhiteSpace('\n')(410,411) + PsiComment(SimpleTokenType.COMMENT)('# Unicode')(411,420) + PsiWhiteSpace('\n')(420,421) + SimplePropertyImpl(PROPERTY)(421,433) + PsiElement(SimpleTokenType.KEY)('tab')(421,424) + PsiWhiteSpace(' ')(424,425) + PsiElement(SimpleTokenType.SEPARATOR)(':')(425,426) + PsiWhiteSpace(' ')(426,427) + PsiElement(SimpleTokenType.VALUE)('\u0009')(427,433) + PsiWhiteSpace('\n')(433,434) + PsiComment(SimpleTokenType.COMMENT)('# test for illegal key attempt')(434,464) + PsiWhiteSpace('\n')(464,465) + SimplePropertyImpl(PROPERTY)(465,469) + PsiElement(SimpleTokenType.KEY)('key')(465,468) + PsiErrorElement:SimpleTokenType.SEPARATOR expected, got '\'(468,469) + PsiElement(BAD_CHARACTER)('\')(468,469) + PsiWhiteSpace('\n')(469,470) + SimplePropertyImpl(PROPERTY)(470,475) + PsiElement(SimpleTokenType.KEY)('with')(470,474) + PsiErrorElement:SimpleTokenType.SEPARATOR expected, got '\'(474,475) + PsiElement(BAD_CHARACTER)('\')(474,475) + PsiWhiteSpace('\n')(475,476) + SimplePropertyImpl(PROPERTY)(476,492) + PsiElement(SimpleTokenType.KEY)('endofline')(476,485) + PsiWhiteSpace(' ')(485,486) + PsiElement(SimpleTokenType.SEPARATOR)('=')(486,487) + PsiWhiteSpace(' ')(487,488) + PsiElement(SimpleTokenType.VALUE)('test')(488,492) \ No newline at end of file diff --git a/simple_language/src/test/testData/ReferenceTestData.java b/simple_language/src/test/testData/ReferenceTestData.java new file mode 100644 index 000000000..92c55dfd5 --- /dev/null +++ b/simple_language/src/test/testData/ReferenceTestData.java @@ -0,0 +1,5 @@ +public class Test { + public static void main(String[] args) { + System.out.println("simple:website"); + } +} diff --git a/simple_language/src/test/testData/RenameTestData.java b/simple_language/src/test/testData/RenameTestData.java new file mode 100644 index 000000000..92c55dfd5 --- /dev/null +++ b/simple_language/src/test/testData/RenameTestData.java @@ -0,0 +1,5 @@ +public class Test { + public static void main(String[] args) { + System.out.println("simple:website"); + } +} diff --git a/simple_language/src/test/testData/RenameTestData.simple b/simple_language/src/test/testData/RenameTestData.simple new file mode 100644 index 000000000..31492ca75 --- /dev/null +++ b/simple_language/src/test/testData/RenameTestData.simple @@ -0,0 +1,13 @@ +# You are reading the ".properties" entry. +! The exclamation mark can also mark text as comments. +website = http://en.wikipedia.org/ + +language = English +# The backslash below tells the application to continue reading +# the value onto the next line. +message = Welcome to \ + Wikipedia! +# Add spaces to the key +key\ with\ spaces = This is the value that could be looked up with the key "key with spaces". +# Unicode +tab : \u0009 \ No newline at end of file diff --git a/simple_language/src/test/testData/RenameTestDataAfter.simple b/simple_language/src/test/testData/RenameTestDataAfter.simple new file mode 100644 index 000000000..71bf7bf73 --- /dev/null +++ b/simple_language/src/test/testData/RenameTestDataAfter.simple @@ -0,0 +1,13 @@ +# You are reading the ".properties" entry. +! The exclamation mark can also mark text as comments. +websiteUrl = http://en.wikipedia.org/ + +language = English +# The backslash below tells the application to continue reading +# the value onto the next line. +message = Welcome to \ + Wikipedia! +# Add spaces to the key +key\ with\ spaces = This is the value that could be looked up with the key "key with spaces". +# Unicode +tab : \u0009 \ No newline at end of file diff --git a/simple_language_plugin/src/com/simpleplugin/SimpleFoldingBuilder.java b/simple_language_plugin/src/com/simpleplugin/SimpleFoldingBuilder.java index 70bf45d93..e2ef7cdb6 100644 --- a/simple_language_plugin/src/com/simpleplugin/SimpleFoldingBuilder.java +++ b/simple_language_plugin/src/com/simpleplugin/SimpleFoldingBuilder.java @@ -3,6 +3,7 @@ package com.simpleplugin; import com.intellij.lang.ASTNode; import com.intellij.lang.folding.*; import com.intellij.openapi.editor.*; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; @@ -12,7 +13,7 @@ import org.jetbrains.annotations.*; import java.util.*; -public class SimpleFoldingBuilder extends FoldingBuilderEx { +public class SimpleFoldingBuilder extends FoldingBuilderEx implements DumbAware { @NotNull @Override public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) { @@ -52,7 +53,18 @@ public class SimpleFoldingBuilder extends FoldingBuilderEx { @Nullable @Override public String getPlaceholderText(@NotNull ASTNode node) { - return "..."; + String retTxt = "..."; + if ( node.getPsi() instanceof PsiLiteralExpression ) { + PsiLiteralExpression nodeElement = (PsiLiteralExpression) node.getPsi(); + String key = ((String) nodeElement.getValue()).substring("simple:".length()); + final List< SimpleProperty > properties = SimpleUtil.findProperties(nodeElement.getProject(), key); + String place = properties.get(0).getValue(); + // IMPORTANT: keys can come with no values, so a test for null is needed + // IMPORTANT: Convert embedded \n to backslash n, so that the string will look + // like it has LF embedded in it and embedded " to escaped " + return place == null ? retTxt : place.replaceAll("\n", "\\n").replaceAll("\"", "\\\\\""); + } + return retTxt; } @Override diff --git a/simple_language_plugin/src/com/simpleplugin/SimpleParserDefinition.java b/simple_language_plugin/src/com/simpleplugin/SimpleParserDefinition.java index 787b97857..67bd581ea 100644 --- a/simple_language_plugin/src/com/simpleplugin/SimpleParserDefinition.java +++ b/simple_language_plugin/src/com/simpleplugin/SimpleParserDefinition.java @@ -27,19 +27,16 @@ public class SimpleParserDefinition implements ParserDefinition { } @NotNull - @Override public TokenSet getCommentTokens() { return COMMENTS; } @NotNull - @Override public TokenSet getStringLiteralElements() { return TokenSet.EMPTY; } @NotNull - @Override public PsiParser createParser(final Project project) { return new SimpleParser(); } @@ -49,19 +46,16 @@ public class SimpleParserDefinition implements ParserDefinition { return FILE; } - @Override public PsiFile createFile(FileViewProvider viewProvider) { return new SimpleFile(viewProvider); } - @Override public SpaceRequirements spaceExistenceTypeBetweenTokens(ASTNode left, ASTNode right) { return SpaceRequirements.MAY; } @NotNull - @Override public PsiElement createElement(ASTNode node) { return SimpleTypes.Factory.createElement(node); } -} +} \ No newline at end of file diff --git a/simple_language_plugin/testData/AnnotatorTestData.java b/simple_language_plugin/testData/AnnotatorTestData.java index 8bcbf8db3..eae0b79de 100644 --- a/simple_language_plugin/testData/AnnotatorTestData.java +++ b/simple_language_plugin/testData/AnnotatorTestData.java @@ -2,6 +2,6 @@ public class Test { public static void main(String[] args) { System.out.println("simple:website"); System.out.println("simple:key with spaces"); - System.out.println("simple:websit"); + System.out.println("simple:websit"); } } diff --git a/simple_language_plugin/tests/com/simpleplugin/SimpleCodeInsightTest.java b/simple_language_plugin/tests/com/simpleplugin/SimpleCodeInsightTest.java index f8059d075..6ce61b42e 100644 --- a/simple_language_plugin/tests/com/simpleplugin/SimpleCodeInsightTest.java +++ b/simple_language_plugin/tests/com/simpleplugin/SimpleCodeInsightTest.java @@ -6,7 +6,7 @@ import com.intellij.codeInsight.generation.actions.CommentByLineCommentAction; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.PsiElement; import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase; import com.intellij.usageView.UsageInfo; import com.intellij.util.containers.ContainerUtil; import com.simpleplugin.psi.SimpleProperty; @@ -15,12 +15,13 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; -public class SimpleCodeInsightTest extends LightCodeInsightFixtureTestCase { +public class SimpleCodeInsightTest extends LightJavaCodeInsightFixtureTestCase { @Override protected void setUp() throws Exception { super.setUp(); } + // path to test data file directory relative to working directory in the run configuration for this test. @Override protected String getTestDataPath() { return "testData"; } From f4fb5b1b31c724b89a9ac1d5158e9718d27c97d7 Mon Sep 17 00:00:00 2001 From: JohnHake Date: Wed, 5 Feb 2020 20:39:11 -0800 Subject: [PATCH 2/3] Delete DevKit, add Gradle simple_language_plugin --- simple_language/settings.gradle | 2 - simple_language_plugin/.idea/misc.xml | 6 - simple_language_plugin/.idea/modules.xml | 8 - .../.idea/simple_language_plugin.iml | 12 - simple_language_plugin/.idea/workspace.xml | 495 ---------------- .../build.gradle | 0 .../com/simpleplugin/parser/SimpleParser.java | 121 ---- .../com/simpleplugin/psi/SimpleProperty.java | 23 - .../gen/com/simpleplugin/psi/SimpleTypes.java | 27 - .../com/simpleplugin/psi/SimpleVisitor.java | 22 - .../psi/impl/SimplePropertyImpl.java | 53 -- .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../gradlew | 0 .../gradlew.bat | 0 .../resources/META-INF/plugin.xml | 37 -- simple_language_plugin/settings.gradle | 2 + .../simple_language_plugin.iml | 15 - .../simpleplugin/CreatePropertyQuickFix.java | 91 --- .../src/com/simpleplugin/Simple.bnf | 28 - .../src/com/simpleplugin/Simple.flex | 44 -- .../src/com/simpleplugin/SimpleAnnotator.java | 37 -- .../src/com/simpleplugin/SimpleBlock.java | 52 -- .../SimpleChooseByNameContributor.java | 31 - .../simpleplugin/SimpleCodeStyleSettings.java | 9 - .../SimpleCodeStyleSettingsProvider.java | 36 -- .../simpleplugin/SimpleColorSettingsPage.java | 70 --- .../src/com/simpleplugin/SimpleCommenter.java | 36 -- .../SimpleCompletionContributor.java | 23 - .../src/com/simpleplugin/SimpleFileType.java | 38 -- .../simpleplugin/SimpleFileTypeFactory.java | 11 - .../com/simpleplugin/SimpleFilterLexer.java | 18 - .../SimpleFindUsagesProvider.java | 60 -- .../simpleplugin/SimpleFoldingBuilder.java | 74 --- .../SimpleFormattingModelBuilder.java | 37 -- .../src/com/simpleplugin/SimpleIcons.java | 9 - .../src/com/simpleplugin/SimpleIdIndexer.java | 17 - .../src/com/simpleplugin/SimpleLanguage.java | 11 - ...mpleLanguageCodeStyleSettingsProvider.java | 42 -- .../src/com/simpleplugin/SimpleLexer.java | 528 ------------------ .../com/simpleplugin/SimpleLexerAdapter.java | 11 - .../SimpleLineMarkerProvider.java | 33 -- .../simpleplugin/SimpleParserDefinition.java | 61 -- .../SimpleRefactoringSupportProvider.java | 12 - .../src/com/simpleplugin/SimpleReference.java | 55 -- .../SimpleReferenceContributor.java | 30 - .../SimpleStructureViewElement.java | 72 --- .../SimpleStructureViewFactory.java | 21 - .../SimpleStructureViewModel.java | 30 - .../simpleplugin/SimpleSyntaxHighlighter.java | 56 -- .../SimpleSyntaxHighlighterFactory.java | 14 - .../com/simpleplugin/SimpleTodoIndexer.java | 12 - .../src/com/simpleplugin/SimpleUtil.java | 52 -- .../src/com/simpleplugin/icons/jar-gray.png | Bin 717 -> 0 bytes .../psi/SimpleElementFactory.java | 28 - .../simpleplugin/psi/SimpleElementType.java | 11 - .../src/com/simpleplugin/psi/SimpleFile.java | 31 - .../simpleplugin/psi/SimpleNamedElement.java | 6 - .../com/simpleplugin/psi/SimpleTokenType.java | 16 - .../psi/impl/SimpleNamedElementImpl.java | 12 - .../psi/impl/SimplePsiImplUtil.java | 77 --- .../intellij/sdk/language/SimpleLexer.java | 0 .../sdk/language/parser/SimpleParser.java | 0 .../sdk/language/psi/SimpleProperty.java | 0 .../sdk/language/psi/SimpleTypes.java | 0 .../sdk/language/psi/SimpleVisitor.java | 0 .../language/psi/impl/SimplePropertyImpl.java | 0 .../java/com/intellij/sdk/language/Simple.bnf | 0 .../com/intellij/sdk/language/Simple.flex | 0 .../sdk/language/SimpleAnnotator.java | 0 .../intellij/sdk/language/SimpleBlock.java | 0 .../SimpleChooseByNameContributor.java | 0 .../sdk/language/SimpleCodeStyleSettings.java | 0 .../SimpleCodeStyleSettingsProvider.java | 0 .../sdk/language/SimpleColorSettingsPage.java | 0 .../sdk/language/SimpleCommenter.java | 0 .../language/SimpleCompletionContributor.java | 0 .../SimpleCreatePropertyQuickFix.java | 0 .../intellij/sdk/language/SimpleFileType.java | 0 .../sdk/language/SimpleFileTypeFactory.java | 0 .../language/SimpleFindUsagesProvider.java | 0 .../sdk/language/SimpleFoldingBuilder.java | 0 .../SimpleFormattingModelBuilder.java | 0 .../intellij/sdk/language/SimpleIcons.java | 0 .../intellij/sdk/language/SimpleLanguage.java | 0 ...mpleLanguageCodeStyleSettingsProvider.java | 0 .../sdk/language/SimpleLexerAdapter.java | 0 .../language/SimpleLineMarkerProvider.java | 0 .../sdk/language/SimpleParserDefinition.java | 0 .../SimpleRefactoringSupportProvider.java | 0 .../sdk/language/SimpleReference.java | 0 .../language/SimpleReferenceContributor.java | 0 .../language/SimpleStructureViewElement.java | 0 .../language/SimpleStructureViewFactory.java | 0 .../language/SimpleStructureViewModel.java | 0 .../sdk/language/SimpleSyntaxHighlighter.java | 0 .../SimpleSyntaxHighlighterFactory.java | 0 .../com/intellij/sdk/language/SimpleUtil.java | 0 .../language/psi/SimpleElementFactory.java | 0 .../sdk/language/psi/SimpleElementType.java | 0 .../intellij/sdk/language/psi/SimpleFile.java | 0 .../sdk/language/psi/SimpleNamedElement.java | 0 .../sdk/language/psi/SimpleTokenType.java | 0 .../psi/impl/SimpleNamedElementImpl.java | 0 .../language/psi/impl/SimplePsiImplUtil.java | 0 .../src/main/resources/META-INF/plugin.xml | 0 .../main/resources/META-INF/pluginIcon.svg | 0 .../src/main/resources/icons/jar-gray.png | Bin .../sdk/language/SimpleCodeInsightTest.java | 0 .../sdk/language/SimpleParsingTest.java | 0 .../src/test/testData/AnnotatorTestData.java | 0 .../src/test/testData/CompleteTestData.java | 0 .../src/test/testData/DefaultTestData.simple | 0 .../src/test/testData/FindUsagesTestData.java | 0 .../test/testData/FindUsagesTestData.simple | 0 .../src/test/testData/FoldingTestData.java | 0 .../test/testData/FormatterTestData.simple | 0 .../src/test/testData/ParsingTestData.simple | 0 .../src/test/testData/ParsingTestData.txt | 0 .../src/test/testData/ReferenceTestData.java | 0 .../src/test/testData/RenameTestData.java | 0 .../src/test/testData/RenameTestData.simple | 0 .../test/testData/RenameTestDataAfter.simple | 0 .../testData/AnnotatorTestData.java | 7 - .../testData/CompleteTestData.java | 5 - .../testData/DefaultTestData.simple | 14 - .../testData/FindUsagesTestData.java | 5 - .../testData/FindUsagesTestData.simple | 13 - .../testData/FoldingTestData.java | 11 - .../testData/FormatterTestData.simple | 15 - .../testData/ParsingTestData.simple | 17 - .../testData/ParsingTestData.txt | 66 --- .../testData/ReferenceTestData.java | 5 - .../testData/RenameTestData.java | 5 - .../testData/RenameTestData.simple | 13 - .../testData/RenameTestDataAfter.simple | 13 - .../simpleplugin/SimpleCodeInsightTest.java | 82 --- .../com/simpleplugin/SimpleParsingTest.java | 28 - 138 files changed, 2 insertions(+), 3062 deletions(-) delete mode 100644 simple_language/settings.gradle delete mode 100644 simple_language_plugin/.idea/misc.xml delete mode 100644 simple_language_plugin/.idea/modules.xml delete mode 100644 simple_language_plugin/.idea/simple_language_plugin.iml delete mode 100644 simple_language_plugin/.idea/workspace.xml rename {simple_language => simple_language_plugin}/build.gradle (100%) delete mode 100644 simple_language_plugin/gen/com/simpleplugin/parser/SimpleParser.java delete mode 100644 simple_language_plugin/gen/com/simpleplugin/psi/SimpleProperty.java delete mode 100644 simple_language_plugin/gen/com/simpleplugin/psi/SimpleTypes.java delete mode 100644 simple_language_plugin/gen/com/simpleplugin/psi/SimpleVisitor.java delete mode 100644 simple_language_plugin/gen/com/simpleplugin/psi/impl/SimplePropertyImpl.java rename {simple_language => simple_language_plugin}/gradle/wrapper/gradle-wrapper.jar (100%) rename {simple_language => simple_language_plugin}/gradle/wrapper/gradle-wrapper.properties (100%) rename {simple_language => simple_language_plugin}/gradlew (100%) rename {simple_language => simple_language_plugin}/gradlew.bat (100%) delete mode 100644 simple_language_plugin/resources/META-INF/plugin.xml create mode 100644 simple_language_plugin/settings.gradle delete mode 100644 simple_language_plugin/simple_language_plugin.iml delete mode 100644 simple_language_plugin/src/com/simpleplugin/CreatePropertyQuickFix.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/Simple.bnf delete mode 100644 simple_language_plugin/src/com/simpleplugin/Simple.flex delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleAnnotator.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleBlock.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleChooseByNameContributor.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleCodeStyleSettings.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleCodeStyleSettingsProvider.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleColorSettingsPage.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleCommenter.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleCompletionContributor.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleFileType.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleFileTypeFactory.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleFilterLexer.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleFindUsagesProvider.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleFoldingBuilder.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleFormattingModelBuilder.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleIcons.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleIdIndexer.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleLanguage.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleLanguageCodeStyleSettingsProvider.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleLexer.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleLexerAdapter.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleLineMarkerProvider.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleParserDefinition.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleRefactoringSupportProvider.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleReference.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleReferenceContributor.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleStructureViewElement.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleStructureViewFactory.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleStructureViewModel.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleSyntaxHighlighter.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleSyntaxHighlighterFactory.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleTodoIndexer.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/SimpleUtil.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/icons/jar-gray.png delete mode 100644 simple_language_plugin/src/com/simpleplugin/psi/SimpleElementFactory.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/psi/SimpleElementType.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/psi/SimpleFile.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/psi/SimpleNamedElement.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/psi/SimpleTokenType.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/psi/impl/SimpleNamedElementImpl.java delete mode 100644 simple_language_plugin/src/com/simpleplugin/psi/impl/SimplePsiImplUtil.java rename {simple_language => simple_language_plugin}/src/main/gen/com/intellij/sdk/language/SimpleLexer.java (100%) rename {simple_language => simple_language_plugin}/src/main/gen/com/intellij/sdk/language/parser/SimpleParser.java (100%) rename {simple_language => simple_language_plugin}/src/main/gen/com/intellij/sdk/language/psi/SimpleProperty.java (100%) rename {simple_language => simple_language_plugin}/src/main/gen/com/intellij/sdk/language/psi/SimpleTypes.java (100%) rename {simple_language => simple_language_plugin}/src/main/gen/com/intellij/sdk/language/psi/SimpleVisitor.java (100%) rename {simple_language => simple_language_plugin}/src/main/gen/com/intellij/sdk/language/psi/impl/SimplePropertyImpl.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/Simple.bnf (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/Simple.flex (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleAnnotator.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleBlock.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleChooseByNameContributor.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettings.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleColorSettingsPage.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleCommenter.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleCompletionContributor.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleCreatePropertyQuickFix.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleFileType.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleFileTypeFactory.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleFindUsagesProvider.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleFoldingBuilder.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleFormattingModelBuilder.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleIcons.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleLanguage.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleLexerAdapter.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleLineMarkerProvider.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleParserDefinition.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleRefactoringSupportProvider.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleReference.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleReferenceContributor.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleStructureViewElement.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleStructureViewFactory.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleStructureViewModel.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleSyntaxHighlighter.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleSyntaxHighlighterFactory.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/SimpleUtil.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/psi/SimpleElementFactory.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/psi/SimpleElementType.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/psi/SimpleFile.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/psi/SimpleNamedElement.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/psi/SimpleTokenType.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/psi/impl/SimpleNamedElementImpl.java (100%) rename {simple_language => simple_language_plugin}/src/main/java/com/intellij/sdk/language/psi/impl/SimplePsiImplUtil.java (100%) rename {simple_language => simple_language_plugin}/src/main/resources/META-INF/plugin.xml (100%) rename {simple_language => simple_language_plugin}/src/main/resources/META-INF/pluginIcon.svg (100%) rename {simple_language => simple_language_plugin}/src/main/resources/icons/jar-gray.png (100%) rename {simple_language => simple_language_plugin}/src/test/java/com/intellij/sdk/language/SimpleCodeInsightTest.java (100%) rename {simple_language => simple_language_plugin}/src/test/java/com/intellij/sdk/language/SimpleParsingTest.java (100%) rename {simple_language => simple_language_plugin}/src/test/testData/AnnotatorTestData.java (100%) rename {simple_language => simple_language_plugin}/src/test/testData/CompleteTestData.java (100%) rename {simple_language => simple_language_plugin}/src/test/testData/DefaultTestData.simple (100%) rename {simple_language => simple_language_plugin}/src/test/testData/FindUsagesTestData.java (100%) rename {simple_language => simple_language_plugin}/src/test/testData/FindUsagesTestData.simple (100%) rename {simple_language => simple_language_plugin}/src/test/testData/FoldingTestData.java (100%) rename {simple_language => simple_language_plugin}/src/test/testData/FormatterTestData.simple (100%) rename {simple_language => simple_language_plugin}/src/test/testData/ParsingTestData.simple (100%) rename {simple_language => simple_language_plugin}/src/test/testData/ParsingTestData.txt (100%) rename {simple_language => simple_language_plugin}/src/test/testData/ReferenceTestData.java (100%) rename {simple_language => simple_language_plugin}/src/test/testData/RenameTestData.java (100%) rename {simple_language => simple_language_plugin}/src/test/testData/RenameTestData.simple (100%) rename {simple_language => simple_language_plugin}/src/test/testData/RenameTestDataAfter.simple (100%) delete mode 100644 simple_language_plugin/testData/AnnotatorTestData.java delete mode 100644 simple_language_plugin/testData/CompleteTestData.java delete mode 100644 simple_language_plugin/testData/DefaultTestData.simple delete mode 100644 simple_language_plugin/testData/FindUsagesTestData.java delete mode 100644 simple_language_plugin/testData/FindUsagesTestData.simple delete mode 100644 simple_language_plugin/testData/FoldingTestData.java delete mode 100644 simple_language_plugin/testData/FormatterTestData.simple delete mode 100644 simple_language_plugin/testData/ParsingTestData.simple delete mode 100644 simple_language_plugin/testData/ParsingTestData.txt delete mode 100644 simple_language_plugin/testData/ReferenceTestData.java delete mode 100644 simple_language_plugin/testData/RenameTestData.java delete mode 100644 simple_language_plugin/testData/RenameTestData.simple delete mode 100644 simple_language_plugin/testData/RenameTestDataAfter.simple delete mode 100644 simple_language_plugin/tests/com/simpleplugin/SimpleCodeInsightTest.java delete mode 100644 simple_language_plugin/tests/com/simpleplugin/SimpleParsingTest.java diff --git a/simple_language/settings.gradle b/simple_language/settings.gradle deleted file mode 100644 index 8a3935957..000000000 --- a/simple_language/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -rootProject.name = 'language' - diff --git a/simple_language_plugin/.idea/misc.xml b/simple_language_plugin/.idea/misc.xml deleted file mode 100644 index 5c95974fd..000000000 --- a/simple_language_plugin/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/simple_language_plugin/.idea/modules.xml b/simple_language_plugin/.idea/modules.xml deleted file mode 100644 index 7dd689510..000000000 --- a/simple_language_plugin/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/simple_language_plugin/.idea/simple_language_plugin.iml b/simple_language_plugin/.idea/simple_language_plugin.iml deleted file mode 100644 index 3033e705b..000000000 --- a/simple_language_plugin/.idea/simple_language_plugin.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/simple_language_plugin/.idea/workspace.xml b/simple_language_plugin/.idea/workspace.xml deleted file mode 100644 index 53bd5fa5f..000000000 --- a/simple_language_plugin/.idea/workspace.xml +++ /dev/null @@ -1,495 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - DEFINITION_ORDER - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -