Razor 545 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163
  1. commit 44b4bf6bc607a3748feb6b1b8a91c42b5e539579
  2. Author: N. Taylor Mullen <[email protected]>
  3. Date: Mon Nov 13 15:15:47 2017 -0800
  4. Cleanup legacy and unintentionally public bits.
  5. - Made `RazorTemplateEngineFactoryService`, `TagHelperResolver`, `RazorDiagnosticJsonConverter` and `RazorLanguageServiceException` internal.
  6. - Deleted all items in the Legacy folder in VisualStudio.LanguageServices.Razor and `RazorLanguageServiceException`.
  7. #1762
  8. diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/RazorTemplateEngineFactoryService.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/RazorTemplateEngineFactoryService.cs
  9. index 7908a9f1169..26ff5b803af 100644
  10. --- a/src/Microsoft.CodeAnalysis.Razor.Workspaces/RazorTemplateEngineFactoryService.cs
  11. +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/RazorTemplateEngineFactoryService.cs
  12. @@ -7,7 +7,7 @@ using Microsoft.CodeAnalysis.Host;
  13. namespace Microsoft.CodeAnalysis.Razor
  14. {
  15. - public abstract class RazorTemplateEngineFactoryService : ILanguageService
  16. + internal abstract class RazorTemplateEngineFactoryService : ILanguageService
  17. {
  18. public abstract RazorTemplateEngine Create(string projectPath, Action<IRazorEngineBuilder> configure);
  19. }
  20. diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolver.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolver.cs
  21. index d246743f59d..a16f46400b7 100644
  22. --- a/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolver.cs
  23. +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperResolver.cs
  24. @@ -7,7 +7,7 @@ using Microsoft.CodeAnalysis.Host;
  25. namespace Microsoft.CodeAnalysis.Razor
  26. {
  27. - public abstract class TagHelperResolver : ILanguageService
  28. + internal abstract class TagHelperResolver : ILanguageService
  29. {
  30. public abstract TagHelperResolutionResult GetTagHelpers(Compilation compilation);
  31. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDirectiveResolver.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDirectiveResolver.cs
  32. index f0ce0e7e3f5..9c1eadae887 100644
  33. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDirectiveResolver.cs
  34. +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDirectiveResolver.cs
  35. @@ -29,9 +29,10 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
  36. }
  37. catch (Exception exception)
  38. {
  39. - throw new RazorLanguageServiceException(
  40. - typeof(DefaultRazorEngineDirectiveResolver).FullName,
  41. - nameof(GetRazorEngineDirectivesAsync),
  42. + throw new InvalidOperationException(
  43. + Resources.FormatUnexpectedException(
  44. + typeof(DefaultRazorEngineDirectiveResolver).FullName,
  45. + nameof(GetRazorEngineDirectivesAsync)),
  46. exception);
  47. }
  48. }
  49. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDocumentGenerator.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDocumentGenerator.cs
  50. index 09b3f66ce8b..b7c0cce0614 100644
  51. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDocumentGenerator.cs
  52. +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultRazorEngineDocumentGenerator.cs
  53. @@ -27,9 +27,10 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
  54. }
  55. catch (Exception exception)
  56. {
  57. - throw new RazorLanguageServiceException(
  58. - typeof(DefaultRazorEngineDocumentGenerator).FullName,
  59. - nameof(GenerateDocumentAsync),
  60. + throw new InvalidOperationException(
  61. + Resources.FormatUnexpectedException(
  62. + typeof(DefaultRazorEngineDocumentGenerator).FullName,
  63. + nameof(GenerateDocumentAsync)),
  64. exception);
  65. }
  66. }
  67. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs
  68. index 5ed80730d77..31713fb3b25 100644
  69. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs
  70. +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperResolver.cs
  71. @@ -74,9 +74,10 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
  72. {
  73. _errorReporter.ReportError(exception, project);
  74. - throw new RazorLanguageServiceException(
  75. - typeof(DefaultTagHelperResolver).FullName,
  76. - nameof(GetTagHelpersAsync),
  77. + throw new InvalidOperationException(
  78. + Resources.FormatUnexpectedException(
  79. + typeof(DefaultTagHelperResolver).FullName,
  80. + nameof(GetTagHelpersAsync)),
  81. exception);
  82. }
  83. }
  84. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/AcceptedCharacters.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/AcceptedCharacters.cs
  85. deleted file mode 100644
  86. index 034dda92983..00000000000
  87. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/AcceptedCharacters.cs
  88. +++ /dev/null
  89. @@ -1,28 +0,0 @@
  90. -// Copyright (c) .NET Foundation. All rights reserved.
  91. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  92. -
  93. -using System;
  94. -using System.Collections.Generic;
  95. -using Microsoft.AspNetCore.Razor.Language;
  96. -
  97. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  98. -{
  99. - // ----------------------------------------------------------------------------------------------------
  100. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  101. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  102. - // ----------------------------------------------------------------------------------------------------
  103. - [Flags]
  104. - public enum AcceptedCharacters
  105. - {
  106. - None = 0,
  107. - NewLine = 1,
  108. - WhiteSpace = 2,
  109. -
  110. - NonWhiteSpace = 4,
  111. -
  112. - AllWhiteSpace = NewLine | WhiteSpace,
  113. - Any = AllWhiteSpace | NonWhiteSpace,
  114. -
  115. - AnyExceptNewline = NonWhiteSpace | WhiteSpace
  116. - }
  117. -}
  118. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/AttributeCompletionContext.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/AttributeCompletionContext.cs
  119. deleted file mode 100644
  120. index f859c1d5c19..00000000000
  121. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/AttributeCompletionContext.cs
  122. +++ /dev/null
  123. @@ -1,69 +0,0 @@
  124. -// Copyright (c) .NET Foundation. All rights reserved.
  125. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  126. -
  127. -using System;
  128. -using System.Collections.Generic;
  129. -using Microsoft.AspNetCore.Razor.Language;
  130. -
  131. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  132. -{
  133. - // ----------------------------------------------------------------------------------------------------
  134. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  135. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  136. - // ----------------------------------------------------------------------------------------------------
  137. - public class AttributeCompletionContext
  138. - {
  139. - public AttributeCompletionContext(
  140. - TagHelperDocumentContext documentContext,
  141. - IEnumerable<string> existingCompletions,
  142. - string currentTagName,
  143. - IEnumerable<KeyValuePair<string, string>> attributes,
  144. - string currentParentTagName,
  145. - Func<string, bool> inHTMLSchema)
  146. - {
  147. - if (documentContext == null)
  148. - {
  149. - throw new ArgumentNullException(nameof(documentContext));
  150. - }
  151. -
  152. - if (existingCompletions == null)
  153. - {
  154. - throw new ArgumentNullException(nameof(existingCompletions));
  155. - }
  156. -
  157. - if (currentTagName == null)
  158. - {
  159. - throw new ArgumentNullException(nameof(currentTagName));
  160. - }
  161. -
  162. - if (attributes == null)
  163. - {
  164. - throw new ArgumentNullException(nameof(attributes));
  165. - }
  166. -
  167. - if (inHTMLSchema == null)
  168. - {
  169. - throw new ArgumentNullException(nameof(inHTMLSchema));
  170. - }
  171. -
  172. - DocumentContext = documentContext;
  173. - ExistingCompletions = existingCompletions;
  174. - CurrentTagName = currentTagName;
  175. - Attributes = attributes;
  176. - CurrentParentTagName = currentParentTagName;
  177. - InHTMLSchema = inHTMLSchema;
  178. - }
  179. -
  180. - public TagHelperDocumentContext DocumentContext { get; }
  181. -
  182. - public IEnumerable<string> ExistingCompletions { get; }
  183. -
  184. - public string CurrentTagName { get; }
  185. -
  186. - public IEnumerable<KeyValuePair<string, string>> Attributes { get; }
  187. -
  188. - public string CurrentParentTagName { get; }
  189. -
  190. - public Func<string, bool> InHTMLSchema { get; }
  191. - }
  192. -}
  193. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/AttributeCompletionResult.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/AttributeCompletionResult.cs
  194. deleted file mode 100644
  195. index 066d438054a..00000000000
  196. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/AttributeCompletionResult.cs
  197. +++ /dev/null
  198. @@ -1,45 +0,0 @@
  199. -// Copyright (c) .NET Foundation. All rights reserved.
  200. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  201. -
  202. -using System.Collections.Generic;
  203. -using System.Linq;
  204. -using Microsoft.AspNetCore.Razor.Language;
  205. -
  206. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  207. -{
  208. - // ----------------------------------------------------------------------------------------------------
  209. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  210. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  211. - // ----------------------------------------------------------------------------------------------------
  212. - public abstract class AttributeCompletionResult
  213. - {
  214. - private AttributeCompletionResult()
  215. - {
  216. - }
  217. -
  218. - public abstract IReadOnlyDictionary<string, IEnumerable<BoundAttributeDescriptor>> Completions { get; }
  219. -
  220. - internal static AttributeCompletionResult Create(Dictionary<string, HashSet<BoundAttributeDescriptor>> completions)
  221. - {
  222. - var readonlyCompletions = completions.ToDictionary(
  223. - key => key.Key,
  224. - value => (IEnumerable<BoundAttributeDescriptor>)value.Value,
  225. - completions.Comparer);
  226. - var result = new DefaultAttributeCompletionResult(readonlyCompletions);
  227. -
  228. - return result;
  229. - }
  230. -
  231. - private class DefaultAttributeCompletionResult : AttributeCompletionResult
  232. - {
  233. - private readonly IReadOnlyDictionary<string, IEnumerable<BoundAttributeDescriptor>> _completions;
  234. -
  235. - public DefaultAttributeCompletionResult(IReadOnlyDictionary<string, IEnumerable<BoundAttributeDescriptor>> completions)
  236. - {
  237. - _completions = completions;
  238. - }
  239. -
  240. - public override IReadOnlyDictionary<string, IEnumerable<BoundAttributeDescriptor>> Completions => _completions;
  241. - }
  242. - }
  243. -}
  244. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/BlockKind.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/BlockKind.cs
  245. deleted file mode 100644
  246. index 5591b319437..00000000000
  247. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/BlockKind.cs
  248. +++ /dev/null
  249. @@ -1,28 +0,0 @@
  250. -// Copyright (c) .NET Foundation. All rights reserved.
  251. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  252. -
  253. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  254. -{
  255. - // ----------------------------------------------------------------------------------------------------
  256. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  257. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  258. - // ----------------------------------------------------------------------------------------------------
  259. - public enum BlockKind
  260. - {
  261. - // Code
  262. - Statement,
  263. - Directive,
  264. - Functions,
  265. - Expression,
  266. - Helper,
  267. -
  268. - // Markup
  269. - Markup,
  270. - Section,
  271. - Template,
  272. -
  273. - // Special
  274. - Comment,
  275. - Tag
  276. - }
  277. -}
  278. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ClassifiedSpan.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ClassifiedSpan.cs
  279. deleted file mode 100644
  280. index a254d862dc3..00000000000
  281. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ClassifiedSpan.cs
  282. +++ /dev/null
  283. @@ -1,33 +0,0 @@
  284. -// Copyright (c) .NET Foundation. All rights reserved.
  285. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  286. -
  287. -using Microsoft.AspNetCore.Razor.Language;
  288. -
  289. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  290. -{
  291. - // ----------------------------------------------------------------------------------------------------
  292. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  293. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  294. - // ----------------------------------------------------------------------------------------------------
  295. - public struct ClassifiedSpan
  296. - {
  297. - public ClassifiedSpan(SourceSpan span, SourceSpan blockSpan, SpanKind spanKind, BlockKind blockKind, AcceptedCharacters acceptedCharacters)
  298. - {
  299. - Span = span;
  300. - BlockSpan = blockSpan;
  301. - SpanKind = spanKind;
  302. - BlockKind = blockKind;
  303. - AcceptedCharacters = acceptedCharacters;
  304. - }
  305. -
  306. - public AcceptedCharacters AcceptedCharacters { get; }
  307. -
  308. - public BlockKind BlockKind { get; }
  309. -
  310. - public SourceSpan BlockSpan { get; }
  311. -
  312. - public SourceSpan Span { get; }
  313. -
  314. - public SpanKind SpanKind { get; }
  315. - }
  316. -}
  317. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DefaultRazorSyntaxFactsService.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DefaultRazorSyntaxFactsService.cs
  318. deleted file mode 100644
  319. index 944942048bd..00000000000
  320. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DefaultRazorSyntaxFactsService.cs
  321. +++ /dev/null
  322. @@ -1,352 +0,0 @@
  323. -// Copyright (c) .NET Foundation. All rights reserved.
  324. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  325. -
  326. -using System;
  327. -using System.Collections.Generic;
  328. -using System.ComponentModel.Composition;
  329. -using System.Linq;
  330. -using Microsoft.AspNetCore.Razor.Language;
  331. -using Microsoft.AspNetCore.Razor.Language.Legacy;
  332. -using Microsoft.VisualStudio.Text;
  333. -using Span = Microsoft.AspNetCore.Razor.Language.Legacy.Span;
  334. -
  335. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  336. -{
  337. - // ----------------------------------------------------------------------------------------------------
  338. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  339. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  340. - // ----------------------------------------------------------------------------------------------------
  341. - [Export(typeof(RazorSyntaxFactsService))]
  342. - internal class DefaultRazorSyntaxFactsService : RazorSyntaxFactsService
  343. - {
  344. - public override IReadOnlyList<ClassifiedSpan> GetClassifiedSpans(RazorSyntaxTree syntaxTree)
  345. - {
  346. - if (syntaxTree == null)
  347. - {
  348. - throw new ArgumentNullException(nameof(syntaxTree));
  349. - }
  350. -
  351. - var spans = Flatten(syntaxTree);
  352. -
  353. - var result = new ClassifiedSpan[spans.Count];
  354. - for (var i = 0; i < spans.Count; i++)
  355. - {
  356. - var span = spans[i];
  357. - result[i] = new ClassifiedSpan(
  358. - new SourceSpan(
  359. - span.Start.FilePath ?? syntaxTree.Source.FilePath,
  360. - span.Start.AbsoluteIndex,
  361. - span.Start.LineIndex,
  362. - span.Start.CharacterIndex,
  363. - span.Length),
  364. - new SourceSpan(
  365. - span.Parent.Start.FilePath ?? syntaxTree.Source.FilePath,
  366. - span.Parent.Start.AbsoluteIndex,
  367. - span.Parent.Start.LineIndex,
  368. - span.Parent.Start.CharacterIndex,
  369. - span.Parent.Length),
  370. - (SpanKind)span.Kind,
  371. - (BlockKind)span.Parent.Type,
  372. - (AcceptedCharacters)span.EditHandler.AcceptedCharacters);
  373. - }
  374. -
  375. - return result;
  376. - }
  377. -
  378. - private List<Span> Flatten(RazorSyntaxTree syntaxTree)
  379. - {
  380. - var result = new List<Span>();
  381. - AppendFlattenedSpans(syntaxTree.Root, result);
  382. - return result;
  383. -
  384. - void AppendFlattenedSpans(SyntaxTreeNode node, List<Span> foundSpans)
  385. - {
  386. - Span spanNode = node as Span;
  387. - if (spanNode != null)
  388. - {
  389. - foundSpans.Add(spanNode);
  390. - }
  391. - else
  392. - {
  393. - TagHelperBlock tagHelperNode = node as TagHelperBlock;
  394. - if (tagHelperNode != null)
  395. - {
  396. - // These aren't in document order, sort them first and then dig in
  397. - List<SyntaxTreeNode> attributeNodes = tagHelperNode.Attributes.Select(kvp => kvp.Value).Where(att => att != null).ToList();
  398. - attributeNodes.Sort((x, y) => x.Start.AbsoluteIndex.CompareTo(y.Start.AbsoluteIndex));
  399. -
  400. - foreach (SyntaxTreeNode curNode in attributeNodes)
  401. - {
  402. - AppendFlattenedSpans(curNode, foundSpans);
  403. - }
  404. - }
  405. -
  406. - Block blockNode = node as Block;
  407. - if (blockNode != null)
  408. - {
  409. - foreach (SyntaxTreeNode curNode in blockNode.Children)
  410. - {
  411. - AppendFlattenedSpans(curNode, foundSpans);
  412. - }
  413. - }
  414. - }
  415. - }
  416. - }
  417. -
  418. - public override IReadOnlyList<TagHelperSpan> GetTagHelperSpans(RazorSyntaxTree syntaxTree)
  419. - {
  420. - if (syntaxTree == null)
  421. - {
  422. - throw new ArgumentNullException(nameof(syntaxTree));
  423. - }
  424. -
  425. - var results = new List<TagHelperSpan>();
  426. -
  427. - List<Block> toProcess = new List<Block>();
  428. - List<Block> blockChildren = new List<Block>();
  429. - toProcess.Add(syntaxTree.Root);
  430. -
  431. - for (var i = 0; i < toProcess.Count; i++)
  432. - {
  433. - var blockNode = toProcess[i];
  434. - TagHelperBlock tagHelperNode = blockNode as TagHelperBlock;
  435. - if (tagHelperNode != null)
  436. - {
  437. - results.Add(new TagHelperSpan(
  438. - new SourceSpan(
  439. - tagHelperNode.Start.FilePath ?? syntaxTree.Source.FilePath,
  440. - tagHelperNode.Start.AbsoluteIndex,
  441. - tagHelperNode.Start.LineIndex,
  442. - tagHelperNode.Start.CharacterIndex,
  443. - tagHelperNode.Length),
  444. - tagHelperNode.Binding));
  445. - }
  446. -
  447. - // collect all child blocks and inject into toProcess as a single InsertRange
  448. - foreach (SyntaxTreeNode curNode in blockNode.Children)
  449. - {
  450. - Block curBlock = curNode as Block;
  451. - if (curBlock != null)
  452. - {
  453. - blockChildren.Add(curBlock);
  454. - }
  455. - }
  456. -
  457. - if (blockChildren.Count > 0)
  458. - {
  459. - toProcess.InsertRange(i + 1, blockChildren);
  460. - blockChildren.Clear();
  461. - }
  462. - }
  463. -
  464. - return results;
  465. - }
  466. -
  467. - public override int? GetDesiredIndentation(RazorSyntaxTree syntaxTree, ITextSnapshot syntaxTreeSnapshot, ITextSnapshotLine line, int indentSize, int tabSize)
  468. - {
  469. - if (syntaxTree == null)
  470. - {
  471. - throw new ArgumentNullException(nameof(syntaxTree));
  472. - }
  473. -
  474. - if (syntaxTreeSnapshot == null)
  475. - {
  476. - throw new ArgumentNullException(nameof(syntaxTreeSnapshot));
  477. - }
  478. -
  479. - if (line == null)
  480. - {
  481. - throw new ArgumentNullException(nameof(line));
  482. - }
  483. -
  484. - if (indentSize < 0)
  485. - {
  486. - throw new ArgumentOutOfRangeException(nameof(indentSize));
  487. - }
  488. -
  489. - if (tabSize < 0)
  490. - {
  491. - throw new ArgumentOutOfRangeException(nameof(tabSize));
  492. - }
  493. -
  494. - // The tricky thing here is that line.Snapshot is very likely newer
  495. - var previousLine = line.Snapshot.GetLineFromLineNumber(line.LineNumber - 1);
  496. - var trackingPoint = line.Snapshot.CreateTrackingPoint(line.End, PointTrackingMode.Negative);
  497. - var previousLineEnd = trackingPoint.GetPosition(syntaxTreeSnapshot);
  498. -
  499. - var simulatedChange = new SourceChange(previousLineEnd, 0, string.Empty);
  500. - var owningSpan = LocateOwner(syntaxTree.Root, simulatedChange);
  501. -
  502. - int? desiredIndentation = null;
  503. -
  504. - if (owningSpan.Kind != SpanKindInternal.Code)
  505. - {
  506. - SyntaxTreeNode owningChild = owningSpan;
  507. - while ((owningChild.Parent != null) && !desiredIndentation.HasValue)
  508. - {
  509. - Block owningParent = owningChild.Parent;
  510. - List<SyntaxTreeNode> children = new List<SyntaxTreeNode>(owningParent.Children);
  511. - for (int i = 0; i < children.Count; i++)
  512. - {
  513. - SyntaxTreeNode curChild = children[i];
  514. - if (!curChild.IsBlock)
  515. - {
  516. - Span curSpan = curChild as Span;
  517. - if (curSpan.Kind == SpanKindInternal.MetaCode)
  518. - {
  519. - // yay! We want to use the start of this span to determine the indent level.
  520. - var startLine = line.Snapshot.GetLineFromLineNumber(curSpan.Start.LineIndex);
  521. - var extraIndent = 0;
  522. -
  523. - // Dev11 337312: Only indent one level deeper if the item after the metacode is a markup block
  524. - if (i < children.Count - 1)
  525. - {
  526. - SyntaxTreeNode nextChild = children[i + 1];
  527. - if (nextChild.IsBlock && ((nextChild as Block).Type == BlockKindInternal.Markup))
  528. - {
  529. - extraIndent = indentSize;
  530. - }
  531. - }
  532. -
  533. - desiredIndentation = GetIndentLevelOfLine(startLine, tabSize) + indentSize;
  534. - }
  535. - }
  536. -
  537. - if (curChild == owningChild)
  538. - {
  539. - break;
  540. - }
  541. - }
  542. -
  543. - owningChild = owningParent;
  544. - }
  545. - }
  546. -
  547. - return desiredIndentation;
  548. - }
  549. -
  550. - private Span LocateOwner(Block root, SourceChange change)
  551. - {
  552. - // Ask each child recursively
  553. - Span owner = null;
  554. - foreach (SyntaxTreeNode element in root.Children)
  555. - {
  556. - if (element.Start.AbsoluteIndex > change.Span.AbsoluteIndex)
  557. - {
  558. - // too far
  559. - break;
  560. - }
  561. -
  562. - int elementLen = element.Length;
  563. - if (element.Start.AbsoluteIndex + elementLen < change.Span.AbsoluteIndex)
  564. - {
  565. - // not far enough
  566. - continue;
  567. - }
  568. -
  569. - if (element.IsBlock)
  570. - {
  571. - Block block = element as Block;
  572. -
  573. - if (element.Start.AbsoluteIndex + elementLen == change.Span.AbsoluteIndex)
  574. - {
  575. - Span lastDescendant = block.FindLastDescendentSpan();
  576. - if ((lastDescendant == null) && (block is TagHelperBlock))
  577. - {
  578. - TagHelperBlock tagHelperBlock = (TagHelperBlock)block;
  579. - if (tagHelperBlock.SourceEndTag != null)
  580. - {
  581. - lastDescendant = tagHelperBlock.SourceEndTag.FindLastDescendentSpan();
  582. - }
  583. - else if (tagHelperBlock.SourceStartTag != null)
  584. - {
  585. - lastDescendant = tagHelperBlock.SourceStartTag.FindLastDescendentSpan();
  586. - }
  587. - }
  588. -
  589. - // Conceptually, lastDescendant should always be non-null, but runtime errs on some
  590. - // cases and makes empty blocks. Runtime will fix these issues as we find them, but make
  591. - // no guarantee that they catch them all.
  592. - if (lastDescendant == null)
  593. - {
  594. - owner = LocateOwner(block, change);
  595. - if (owner != null)
  596. - {
  597. - break;
  598. - }
  599. - }
  600. - else if (lastDescendant.EditHandler.OwnsChange(lastDescendant, change))
  601. - {
  602. - owner = lastDescendant;
  603. - break;
  604. - }
  605. - }
  606. - else
  607. - {
  608. - owner = LocateOwner(block, change);
  609. - if (owner != null)
  610. - {
  611. - break;
  612. - }
  613. - }
  614. - }
  615. - else
  616. - {
  617. - Span span = element as Span;
  618. - if (span.EditHandler.OwnsChange(span, change))
  619. - {
  620. - owner = span;
  621. - break;
  622. - }
  623. - }
  624. - }
  625. -
  626. - if (owner == null)
  627. - {
  628. - TagHelperBlock tagHelperNode = root as TagHelperBlock;
  629. - if (tagHelperNode != null)
  630. - {
  631. - Block sourceStartTag = tagHelperNode.SourceStartTag;
  632. - Block sourceEndTag = tagHelperNode.SourceEndTag;
  633. - if ((sourceStartTag.Start.AbsoluteIndex <= change.Span.AbsoluteIndex) &&
  634. - (sourceStartTag.Start.AbsoluteIndex + sourceStartTag.Length >= change.Span.AbsoluteIndex))
  635. - {
  636. - // intersects the start tag
  637. - return LocateOwner(sourceStartTag, change);
  638. - }
  639. - else if ((sourceEndTag.Start.AbsoluteIndex <= change.Span.AbsoluteIndex) &&
  640. - (sourceEndTag.Start.AbsoluteIndex + sourceEndTag.Length >= change.Span.AbsoluteIndex))
  641. - {
  642. - // intersects the end tag
  643. - return LocateOwner(sourceEndTag, change);
  644. - }
  645. - }
  646. - }
  647. -
  648. - return owner;
  649. - }
  650. -
  651. - private int GetIndentLevelOfLine(ITextSnapshotLine line, int tabSize)
  652. - {
  653. - var indentLevel = 0;
  654. -
  655. - foreach (var c in line.GetText())
  656. - {
  657. - if (!char.IsWhiteSpace(c))
  658. - {
  659. - break;
  660. - }
  661. - else if (c == '\t')
  662. - {
  663. - indentLevel += tabSize;
  664. - }
  665. - else
  666. - {
  667. - indentLevel++;
  668. - }
  669. - }
  670. -
  671. - return indentLevel;
  672. - }
  673. - }
  674. -}
  675. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DefaultTagHelperCompletionService.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DefaultTagHelperCompletionService.cs
  676. deleted file mode 100644
  677. index e81e01ccce5..00000000000
  678. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DefaultTagHelperCompletionService.cs
  679. +++ /dev/null
  680. @@ -1,285 +0,0 @@
  681. -// Copyright (c) .NET Foundation. All rights reserved.
  682. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  683. -
  684. -using System;
  685. -using System.Collections.Generic;
  686. -using System.ComponentModel.Composition;
  687. -using System.Diagnostics;
  688. -using System.Linq;
  689. -using Microsoft.AspNetCore.Razor.Language;
  690. -
  691. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  692. -{
  693. - // ----------------------------------------------------------------------------------------------------
  694. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  695. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  696. - // ----------------------------------------------------------------------------------------------------
  697. - [Export(typeof(TagHelperCompletionService))]
  698. - internal class DefaultTagHelperCompletionService : TagHelperCompletionService
  699. - {
  700. - private readonly TagHelperFactsService _tagHelperFactsService;
  701. - private static readonly HashSet<TagHelperDescriptor> _emptyHashSet = new HashSet<TagHelperDescriptor>();
  702. -
  703. - [ImportingConstructor]
  704. - public DefaultTagHelperCompletionService(TagHelperFactsService tagHelperFactsService)
  705. - {
  706. - _tagHelperFactsService = tagHelperFactsService;
  707. - }
  708. -
  709. - /*
  710. - * This API attempts to understand a users context as they're typing in a Razor file to provide TagHelper based attribute IntelliSense.
  711. - *
  712. - * Scenarios for TagHelper attribute IntelliSense follows:
  713. - * 1. TagHelperDescriptor's have matching required attribute names
  714. - * -> Provide IntelliSense for the required attributes of those descriptors to lead users towards a TagHelperified element.
  715. - * 2. TagHelperDescriptor entirely applies to current element. Tag name, attributes, everything is fulfilled.
  716. - * -> Provide IntelliSense for the bound attributes for the applied descriptors.
  717. - *
  718. - * Within each of the above scenarios if an attribute completion has a corresponding bound attribute we associate it with the corresponding
  719. - * BoundAttributeDescriptor. By doing this a user can see what C# type a TagHelper expects for the attribute.
  720. - */
  721. - public override AttributeCompletionResult GetAttributeCompletions(AttributeCompletionContext completionContext)
  722. - {
  723. - if (completionContext == null)
  724. - {
  725. - throw new ArgumentNullException(nameof(completionContext));
  726. - }
  727. -
  728. - var attributeCompletions = completionContext.ExistingCompletions.ToDictionary(
  729. - completion => completion,
  730. - _ => new HashSet<BoundAttributeDescriptor>(),
  731. - StringComparer.OrdinalIgnoreCase);
  732. -
  733. - var documentContext = completionContext.DocumentContext;
  734. - var descriptorsForTag = _tagHelperFactsService.GetTagHelpersGivenTag(documentContext, completionContext.CurrentTagName, completionContext.CurrentParentTagName);
  735. - if (descriptorsForTag.Count == 0)
  736. - {
  737. - // If the current tag has no possible descriptors then we can't have any additional attributes.
  738. - var defaultResult = AttributeCompletionResult.Create(attributeCompletions);
  739. - return defaultResult;
  740. - }
  741. -
  742. - var prefix = documentContext.Prefix ?? string.Empty;
  743. - Debug.Assert(completionContext.CurrentTagName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));
  744. -
  745. - var applicableTagHelperBinding = _tagHelperFactsService.GetTagHelperBinding(
  746. - documentContext,
  747. - completionContext.CurrentTagName,
  748. - completionContext.Attributes,
  749. - completionContext.CurrentParentTagName);
  750. -
  751. - var applicableDescriptors = applicableTagHelperBinding?.Descriptors ?? Enumerable.Empty<TagHelperDescriptor>();
  752. - var unprefixedTagName = completionContext.CurrentTagName.Substring(prefix.Length);
  753. -
  754. - if (!completionContext.InHTMLSchema(unprefixedTagName) &&
  755. - applicableDescriptors.All(descriptor => descriptor.TagOutputHint == null))
  756. - {
  757. - // This isn't a known HTML tag and no descriptor has an output element hint. Remove all previous completions.
  758. - attributeCompletions.Clear();
  759. - }
  760. -
  761. - for (var i = 0; i < descriptorsForTag.Count; i++)
  762. - {
  763. - var descriptor = descriptorsForTag[i];
  764. -
  765. - if (applicableDescriptors.Contains(descriptor))
  766. - {
  767. - foreach (var attributeDescriptor in descriptor.BoundAttributes)
  768. - {
  769. - UpdateCompletions(attributeDescriptor.Name, attributeDescriptor);
  770. - }
  771. - }
  772. - else
  773. - {
  774. - var htmlNameToBoundAttribute = descriptor.BoundAttributes.ToDictionary(attribute => attribute.Name, StringComparer.OrdinalIgnoreCase);
  775. -
  776. - foreach (var rule in descriptor.TagMatchingRules)
  777. - {
  778. - foreach (var requiredAttribute in rule.Attributes)
  779. - {
  780. - if (htmlNameToBoundAttribute.TryGetValue(requiredAttribute.Name, out var attributeDescriptor))
  781. - {
  782. - UpdateCompletions(requiredAttribute.Name, attributeDescriptor);
  783. - }
  784. - else
  785. - {
  786. - UpdateCompletions(requiredAttribute.Name, possibleDescriptor: null);
  787. - }
  788. - }
  789. - }
  790. - }
  791. - }
  792. -
  793. - var completionResult = AttributeCompletionResult.Create(attributeCompletions);
  794. - return completionResult;
  795. -
  796. - void UpdateCompletions(string attributeName, BoundAttributeDescriptor possibleDescriptor)
  797. - {
  798. - if (completionContext.Attributes.Any(attribute => string.Equals(attribute.Key, attributeName, StringComparison.OrdinalIgnoreCase)))
  799. - {
  800. - // Attribute is already present on this element it shouldn't exist in the completion list.
  801. - return;
  802. - }
  803. -
  804. - if (!attributeCompletions.TryGetValue(attributeName, out var rules))
  805. - {
  806. - rules = new HashSet<BoundAttributeDescriptor>();
  807. - attributeCompletions[attributeName] = rules;
  808. - }
  809. -
  810. - if (possibleDescriptor != null)
  811. - {
  812. - rules.Add(possibleDescriptor);
  813. - }
  814. - }
  815. - }
  816. -
  817. - public override ElementCompletionResult GetElementCompletions(ElementCompletionContext completionContext)
  818. - {
  819. - if (completionContext == null)
  820. - {
  821. - throw new ArgumentNullException(nameof(completionContext));
  822. - }
  823. -
  824. - var elementCompletions = new Dictionary<string, HashSet<TagHelperDescriptor>>(StringComparer.OrdinalIgnoreCase);
  825. -
  826. - AddAllowedChildrenCompletions(completionContext, elementCompletions);
  827. -
  828. - if (elementCompletions.Count > 0)
  829. - {
  830. - // If the containing element is already a TagHelper and only allows certain children.
  831. - var emptyResult = ElementCompletionResult.Create(elementCompletions);
  832. - return emptyResult;
  833. - }
  834. -
  835. - elementCompletions = completionContext.ExistingCompletions.ToDictionary(
  836. - completion => completion,
  837. - _ => new HashSet<TagHelperDescriptor>(),
  838. - StringComparer.OrdinalIgnoreCase);
  839. -
  840. - var catchAllDescriptors = new HashSet<TagHelperDescriptor>();
  841. - var prefix = completionContext.DocumentContext.Prefix ?? string.Empty;
  842. - var possibleChildDescriptors = _tagHelperFactsService.GetTagHelpersGivenParent(completionContext.DocumentContext, completionContext.ContainingTagName);
  843. - foreach (var possibleDescriptor in possibleChildDescriptors)
  844. - {
  845. - var addRuleCompletions = false;
  846. - var outputHint = possibleDescriptor.TagOutputHint;
  847. -
  848. - foreach (var rule in possibleDescriptor.TagMatchingRules)
  849. - {
  850. - if (rule.TagName == TagHelperMatchingConventions.ElementCatchAllName)
  851. - {
  852. - catchAllDescriptors.Add(possibleDescriptor);
  853. - }
  854. - else if (elementCompletions.ContainsKey(rule.TagName))
  855. - {
  856. - addRuleCompletions = true;
  857. - }
  858. - else if (outputHint != null)
  859. - {
  860. - // If the current descriptor has an output hint we need to make sure it shows up only when its output hint would normally show up.
  861. - // Example: We have a MyTableTagHelper that has an output hint of "table" and a MyTrTagHelper that has an output hint of "tr".
  862. - // If we try typing in a situation like this: <body > | </body>
  863. - // We'd expect to only get "my-table" as a completion because the "body" tag doesn't allow "tr" tags.
  864. - addRuleCompletions = elementCompletions.ContainsKey(outputHint);
  865. - }
  866. - else if (!completionContext.InHTMLSchema(rule.TagName))
  867. - {
  868. - // If there is an unknown HTML schema tag that doesn't exist in the current completion we should add it. This happens for
  869. - // TagHelpers that target non-schema oriented tags.
  870. - addRuleCompletions = true;
  871. - }
  872. -
  873. - if (addRuleCompletions)
  874. - {
  875. - UpdateCompletions(prefix + rule.TagName, possibleDescriptor);
  876. - }
  877. - }
  878. - }
  879. -
  880. - // We needed to track all catch-alls and update their completions after all other completions have been completed.
  881. - // This way, any TagHelper added completions will also have catch-alls listed under their entries.
  882. - foreach (var catchAllDescriptor in catchAllDescriptors)
  883. - {
  884. - foreach (var completionTagName in elementCompletions.Keys)
  885. - {
  886. - if (elementCompletions[completionTagName].Count > 0 ||
  887. - !string.IsNullOrEmpty(prefix) && completionTagName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
  888. - {
  889. - // The current completion either has other TagHelper's associated with it or is prefixed with a non-empty
  890. - // TagHelper prefix.
  891. - UpdateCompletions(completionTagName, catchAllDescriptor);
  892. - }
  893. - }
  894. - }
  895. -
  896. - var result = ElementCompletionResult.Create(elementCompletions);
  897. - return result;
  898. -
  899. - void UpdateCompletions(string tagName, TagHelperDescriptor possibleDescriptor)
  900. - {
  901. - if (!elementCompletions.TryGetValue(tagName, out var existingRuleDescriptors))
  902. - {
  903. - existingRuleDescriptors = new HashSet<TagHelperDescriptor>();
  904. - elementCompletions[tagName] = existingRuleDescriptors;
  905. - }
  906. -
  907. - existingRuleDescriptors.Add(possibleDescriptor);
  908. - }
  909. - }
  910. -
  911. - private void AddAllowedChildrenCompletions(
  912. - ElementCompletionContext completionContext,
  913. - Dictionary<string, HashSet<TagHelperDescriptor>> elementCompletions)
  914. - {
  915. - if (completionContext.ContainingTagName == null)
  916. - {
  917. - // If we're at the root then there's no containing TagHelper to specify allowed children.
  918. - return;
  919. - }
  920. -
  921. - var prefix = completionContext.DocumentContext.Prefix ?? string.Empty;
  922. - var binding = _tagHelperFactsService.GetTagHelperBinding(
  923. - completionContext.DocumentContext,
  924. - completionContext.ContainingTagName,
  925. - completionContext.Attributes,
  926. - completionContext.ContainingParentTagName);
  927. -
  928. - if (binding == null)
  929. - {
  930. - // Containing tag is not a TagHelper; therefore, it allows any children.
  931. - return;
  932. - }
  933. -
  934. - foreach (var descriptor in binding.Descriptors)
  935. - {
  936. - foreach (var childTag in descriptor.AllowedChildTags)
  937. - {
  938. - var prefixedName = string.Concat(prefix, childTag.Name);
  939. - var descriptors = _tagHelperFactsService.GetTagHelpersGivenTag(
  940. - completionContext.DocumentContext,
  941. - prefixedName,
  942. - completionContext.ContainingTagName);
  943. -
  944. - if (descriptors.Count == 0)
  945. - {
  946. - if (!elementCompletions.ContainsKey(prefixedName))
  947. - {
  948. - elementCompletions[prefixedName] = _emptyHashSet;
  949. - }
  950. -
  951. - continue;
  952. - }
  953. -
  954. - if (!elementCompletions.TryGetValue(prefixedName, out var existingRuleDescriptors))
  955. - {
  956. - existingRuleDescriptors = new HashSet<TagHelperDescriptor>();
  957. - elementCompletions[prefixedName] = existingRuleDescriptors;
  958. - }
  959. -
  960. - existingRuleDescriptors.UnionWith(descriptors);
  961. - }
  962. - }
  963. - }
  964. - }
  965. -}
  966. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DefaultTagHelperFactsService.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DefaultTagHelperFactsService.cs
  967. deleted file mode 100644
  968. index 8e0b34b431c..00000000000
  969. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DefaultTagHelperFactsService.cs
  970. +++ /dev/null
  971. @@ -1,168 +0,0 @@
  972. -// Copyright (c) .NET Foundation. All rights reserved.
  973. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  974. -
  975. -using System;
  976. -using System.Collections.Generic;
  977. -using System.ComponentModel.Composition;
  978. -using System.Linq;
  979. -using Microsoft.AspNetCore.Razor.Language;
  980. -
  981. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  982. -{
  983. - // ----------------------------------------------------------------------------------------------------
  984. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  985. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  986. - // ----------------------------------------------------------------------------------------------------
  987. - [Export(typeof(TagHelperFactsService))]
  988. - internal class DefaultTagHelperFactsService : TagHelperFactsService
  989. - {
  990. - public override TagHelperBinding GetTagHelperBinding(
  991. - TagHelperDocumentContext documentContext,
  992. - string tagName,
  993. - IEnumerable<KeyValuePair<string, string>> attributes,
  994. - string parentTag)
  995. - {
  996. - if (documentContext == null)
  997. - {
  998. - throw new ArgumentNullException(nameof(documentContext));
  999. - }
  1000. -
  1001. - if (tagName == null)
  1002. - {
  1003. - throw new ArgumentNullException(nameof(tagName));
  1004. - }
  1005. -
  1006. - if (attributes == null)
  1007. - {
  1008. - throw new ArgumentNullException(nameof(attributes));
  1009. - }
  1010. -
  1011. - var descriptors = documentContext.TagHelpers;
  1012. - if (descriptors == null || descriptors.Count == 0)
  1013. - {
  1014. - return null;
  1015. - }
  1016. -
  1017. - var prefix = documentContext.Prefix;
  1018. - var tagHelperBinder = new TagHelperBinder(prefix, descriptors);
  1019. - var binding = tagHelperBinder.GetBinding(tagName, attributes.ToList(), parentTag, parentIsTagHelper: false);
  1020. -
  1021. - return binding;
  1022. - }
  1023. -
  1024. - public override IEnumerable<BoundAttributeDescriptor> GetBoundTagHelperAttributes(
  1025. - TagHelperDocumentContext documentContext,
  1026. - string attributeName,
  1027. - TagHelperBinding binding)
  1028. - {
  1029. - if (documentContext == null)
  1030. - {
  1031. - throw new ArgumentNullException(nameof(documentContext));
  1032. - }
  1033. -
  1034. - if (attributeName == null)
  1035. - {
  1036. - throw new ArgumentNullException(nameof(attributeName));
  1037. - }
  1038. -
  1039. - if (binding == null)
  1040. - {
  1041. - throw new ArgumentNullException(nameof(binding));
  1042. - }
  1043. -
  1044. - var matchingBoundAttributes = new List<BoundAttributeDescriptor>();
  1045. - foreach (var descriptor in binding.Descriptors)
  1046. - {
  1047. - foreach (var boundAttributeDescriptor in descriptor.BoundAttributes)
  1048. - {
  1049. - if (TagHelperMatchingConventions.CanSatisfyBoundAttribute(attributeName, boundAttributeDescriptor))
  1050. - {
  1051. - matchingBoundAttributes.Add(boundAttributeDescriptor);
  1052. -
  1053. - // Only one bound attribute can match an attribute
  1054. - break;
  1055. - }
  1056. - }
  1057. - }
  1058. -
  1059. - return matchingBoundAttributes;
  1060. - }
  1061. -
  1062. - public override IReadOnlyList<TagHelperDescriptor> GetTagHelpersGivenTag(
  1063. - TagHelperDocumentContext documentContext,
  1064. - string tagName,
  1065. - string parentTag)
  1066. - {
  1067. - if (documentContext == null)
  1068. - {
  1069. - throw new ArgumentNullException(nameof(documentContext));
  1070. - }
  1071. -
  1072. - if (tagName == null)
  1073. - {
  1074. - throw new ArgumentNullException(nameof(tagName));
  1075. - }
  1076. -
  1077. - var matchingDescriptors = new List<TagHelperDescriptor>();
  1078. - var descriptors = documentContext?.TagHelpers;
  1079. - if (descriptors?.Count == 0)
  1080. - {
  1081. - return matchingDescriptors;
  1082. - }
  1083. -
  1084. - var prefix = documentContext.Prefix ?? string.Empty;
  1085. - if (!tagName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
  1086. - {
  1087. - // Can't possibly match TagHelpers, it doesn't start with the TagHelperPrefix.
  1088. - return matchingDescriptors;
  1089. - }
  1090. -
  1091. - var tagNameWithoutPrefix = tagName.Substring(prefix.Length);
  1092. - for (var i = 0; i < descriptors.Count; i++)
  1093. - {
  1094. - var descriptor = descriptors[i];
  1095. - foreach (var rule in descriptor.TagMatchingRules)
  1096. - {
  1097. - if (TagHelperMatchingConventions.SatisfiesTagName(tagNameWithoutPrefix, rule) &&
  1098. - TagHelperMatchingConventions.SatisfiesParentTag(parentTag, rule))
  1099. - {
  1100. - matchingDescriptors.Add(descriptor);
  1101. - break;
  1102. - }
  1103. - }
  1104. - }
  1105. -
  1106. - return matchingDescriptors;
  1107. - }
  1108. -
  1109. - public override IReadOnlyList<TagHelperDescriptor> GetTagHelpersGivenParent(TagHelperDocumentContext documentContext, string parentTag)
  1110. - {
  1111. - if (documentContext == null)
  1112. - {
  1113. - throw new ArgumentNullException(nameof(documentContext));
  1114. - }
  1115. -
  1116. - var matchingDescriptors = new List<TagHelperDescriptor>();
  1117. - var descriptors = documentContext?.TagHelpers;
  1118. - if (descriptors?.Count == 0)
  1119. - {
  1120. - return matchingDescriptors;
  1121. - }
  1122. -
  1123. - for (var i = 0; i < descriptors.Count; i++)
  1124. - {
  1125. - var descriptor = descriptors[i];
  1126. - foreach (var rule in descriptor.TagMatchingRules)
  1127. - {
  1128. - if (TagHelperMatchingConventions.SatisfiesParentTag(parentTag, rule))
  1129. - {
  1130. - matchingDescriptors.Add(descriptor);
  1131. - break;
  1132. - }
  1133. - }
  1134. - }
  1135. -
  1136. - return matchingDescriptors;
  1137. - }
  1138. - }
  1139. -}
  1140. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DocumentParseCompleteEventArgs.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DocumentParseCompleteEventArgs.cs
  1141. deleted file mode 100644
  1142. index c8dc5065c8e..00000000000
  1143. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/DocumentParseCompleteEventArgs.cs
  1144. +++ /dev/null
  1145. @@ -1,47 +0,0 @@
  1146. -// Copyright (c) .NET Foundation. All rights reserved.
  1147. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  1148. -
  1149. -using System;
  1150. -using Microsoft.AspNetCore.Razor.Language;
  1151. -using Microsoft.VisualStudio.Text;
  1152. -
  1153. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  1154. -{
  1155. - /// <summary>
  1156. - /// Arguments for the <see cref="RazorEditorParser.DocumentParseComplete"/> event in <see cref="RazorEditorParser"/>.
  1157. - /// </summary>
  1158. - public sealed class DocumentParseCompleteEventArgs : EventArgs
  1159. - {
  1160. - public DocumentParseCompleteEventArgs(
  1161. - SourceChange change,
  1162. - ITextSnapshot buffer,
  1163. - bool treeStructureChanged,
  1164. - RazorCodeDocument codeDocument)
  1165. - {
  1166. - SourceChange = change;
  1167. - Buffer = buffer;
  1168. - TreeStructureChanged = treeStructureChanged;
  1169. - CodeDocument = codeDocument;
  1170. - }
  1171. -
  1172. - /// <summary>
  1173. - /// The <see cref="AspNetCore.Razor.Language.SourceChange"/> which triggered the re-parse.
  1174. - /// </summary>
  1175. - public SourceChange SourceChange { get; }
  1176. -
  1177. - /// <summary>
  1178. - /// The text snapshot used in the re-parse.
  1179. - /// </summary>
  1180. - public ITextSnapshot Buffer { get; }
  1181. -
  1182. - /// <summary>
  1183. - /// Indicates if the tree structure has actually changed since the previous re-parse.
  1184. - /// </summary>
  1185. - public bool TreeStructureChanged { get; }
  1186. -
  1187. - /// <summary>
  1188. - /// The result of the parsing and code generation.
  1189. - /// </summary>
  1190. - public RazorCodeDocument CodeDocument { get; }
  1191. - }
  1192. -}
  1193. \ No newline at end of file
  1194. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ElementCompletionContext.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ElementCompletionContext.cs
  1195. deleted file mode 100644
  1196. index c38c8485c71..00000000000
  1197. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ElementCompletionContext.cs
  1198. +++ /dev/null
  1199. @@ -1,59 +0,0 @@
  1200. -// Copyright (c) .NET Foundation. All rights reserved.
  1201. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  1202. -
  1203. -using System;
  1204. -using System.Collections.Generic;
  1205. -using Microsoft.AspNetCore.Razor.Language;
  1206. -
  1207. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  1208. -{
  1209. - // ----------------------------------------------------------------------------------------------------
  1210. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  1211. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  1212. - // ----------------------------------------------------------------------------------------------------
  1213. - public sealed class ElementCompletionContext
  1214. - {
  1215. - public ElementCompletionContext(
  1216. - TagHelperDocumentContext documentContext,
  1217. - IEnumerable<string> existingCompletions,
  1218. - string containingTagName,
  1219. - IEnumerable<KeyValuePair<string, string>> attributes,
  1220. - string containingParentTagName,
  1221. - Func<string, bool> inHTMLSchema)
  1222. - {
  1223. - if (documentContext == null)
  1224. - {
  1225. - throw new ArgumentNullException(nameof(documentContext));
  1226. - }
  1227. -
  1228. - if (existingCompletions == null)
  1229. - {
  1230. - throw new ArgumentNullException(nameof(existingCompletions));
  1231. - }
  1232. -
  1233. - if (inHTMLSchema == null)
  1234. - {
  1235. - throw new ArgumentNullException(nameof(inHTMLSchema));
  1236. - }
  1237. -
  1238. - DocumentContext = documentContext;
  1239. - ExistingCompletions = existingCompletions;
  1240. - ContainingTagName = containingTagName;
  1241. - Attributes = attributes;
  1242. - ContainingParentTagName = containingParentTagName;
  1243. - InHTMLSchema = inHTMLSchema;
  1244. - }
  1245. -
  1246. - public TagHelperDocumentContext DocumentContext { get; }
  1247. -
  1248. - public IEnumerable<string> ExistingCompletions { get; }
  1249. -
  1250. - public string ContainingTagName { get; }
  1251. -
  1252. - public IEnumerable<KeyValuePair<string, string>> Attributes { get; }
  1253. -
  1254. - public string ContainingParentTagName { get; }
  1255. -
  1256. - public Func<string, bool> InHTMLSchema { get; }
  1257. - }
  1258. -}
  1259. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ElementCompletionResult.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ElementCompletionResult.cs
  1260. deleted file mode 100644
  1261. index 88dc0c6a56f..00000000000
  1262. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ElementCompletionResult.cs
  1263. +++ /dev/null
  1264. @@ -1,45 +0,0 @@
  1265. -// Copyright (c) .NET Foundation. All rights reserved.
  1266. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  1267. -
  1268. -using System.Collections.Generic;
  1269. -using System.Linq;
  1270. -using Microsoft.AspNetCore.Razor.Language;
  1271. -
  1272. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  1273. -{
  1274. - // ----------------------------------------------------------------------------------------------------
  1275. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  1276. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  1277. - // ----------------------------------------------------------------------------------------------------
  1278. - public abstract class ElementCompletionResult
  1279. - {
  1280. - private ElementCompletionResult()
  1281. - {
  1282. - }
  1283. -
  1284. - public abstract IReadOnlyDictionary<string, IEnumerable<TagHelperDescriptor>> Completions { get; }
  1285. -
  1286. - internal static ElementCompletionResult Create(Dictionary<string, HashSet<TagHelperDescriptor>> completions)
  1287. - {
  1288. - var readonlyCompletions = completions.ToDictionary(
  1289. - key => key.Key,
  1290. - value => (IEnumerable<TagHelperDescriptor>)value.Value,
  1291. - completions.Comparer);
  1292. - var result = new DefaultElementCompletionResult(readonlyCompletions);
  1293. -
  1294. - return result;
  1295. - }
  1296. -
  1297. - private class DefaultElementCompletionResult : ElementCompletionResult
  1298. - {
  1299. - private readonly IReadOnlyDictionary<string, IEnumerable<TagHelperDescriptor>> _completions;
  1300. -
  1301. - public DefaultElementCompletionResult(IReadOnlyDictionary<string, IEnumerable<TagHelperDescriptor>> completions)
  1302. - {
  1303. - _completions = completions;
  1304. - }
  1305. -
  1306. - public override IReadOnlyDictionary<string, IEnumerable<TagHelperDescriptor>> Completions => _completions;
  1307. - }
  1308. - }
  1309. -}
  1310. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ITagHelperResolver.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ITagHelperResolver.cs
  1311. deleted file mode 100644
  1312. index 80c25027148..00000000000
  1313. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/ITagHelperResolver.cs
  1314. +++ /dev/null
  1315. @@ -1,18 +0,0 @@
  1316. -// Copyright (c) .NET Foundation. All rights reserved.
  1317. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  1318. -
  1319. -using System.Threading.Tasks;
  1320. -using Microsoft.CodeAnalysis;
  1321. -using Microsoft.CodeAnalysis.Razor;
  1322. -
  1323. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  1324. -{
  1325. - // ----------------------------------------------------------------------------------------------------
  1326. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  1327. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  1328. - // ----------------------------------------------------------------------------------------------------
  1329. - public interface ITagHelperResolver
  1330. - {
  1331. - Task<TagHelperResolutionResult> GetTagHelpersAsync(Project project);
  1332. - }
  1333. -}
  1334. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/LegacyTagHelperResolver.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/LegacyTagHelperResolver.cs
  1335. deleted file mode 100644
  1336. index a646026ba1b..00000000000
  1337. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/LegacyTagHelperResolver.cs
  1338. +++ /dev/null
  1339. @@ -1,24 +0,0 @@
  1340. -// Copyright (c) .NET Foundation. All rights reserved.
  1341. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  1342. -
  1343. -using System.ComponentModel.Composition;
  1344. -using Microsoft.CodeAnalysis;
  1345. -using Microsoft.CodeAnalysis.Razor;
  1346. -
  1347. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  1348. -{
  1349. - // ----------------------------------------------------------------------------------------------------
  1350. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  1351. - // use TagHelperResolver.
  1352. - // ----------------------------------------------------------------------------------------------------
  1353. - [Export(typeof(ITagHelperResolver))]
  1354. - internal class LegacyTagHelperResolver : DefaultTagHelperResolver, ITagHelperResolver
  1355. - {
  1356. - [ImportingConstructor]
  1357. - public LegacyTagHelperResolver(
  1358. - [Import(typeof(VisualStudioWorkspace))] Workspace workspace)
  1359. - : base(workspace.Services.GetRequiredService<ErrorReporter>(), workspace)
  1360. - {
  1361. - }
  1362. - }
  1363. -}
  1364. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/LegacyTemplateEngineFactoryService.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/LegacyTemplateEngineFactoryService.cs
  1365. deleted file mode 100644
  1366. index fcae83b4eca..00000000000
  1367. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/LegacyTemplateEngineFactoryService.cs
  1368. +++ /dev/null
  1369. @@ -1,62 +0,0 @@
  1370. -// Copyright (c) .NET Foundation. All rights reserved.
  1371. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  1372. -
  1373. -using System;
  1374. -using System.ComponentModel.Composition;
  1375. -using Microsoft.AspNetCore.Razor.Language;
  1376. -using Microsoft.CodeAnalysis;
  1377. -using Microsoft.CodeAnalysis.Razor;
  1378. -using Inner = Microsoft.CodeAnalysis.Razor.RazorTemplateEngineFactoryService;
  1379. -
  1380. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  1381. -{
  1382. - // ----------------------------------------------------------------------------------------------------
  1383. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  1384. - // use DefaultTemplateEngineFactoryService.
  1385. - // ----------------------------------------------------------------------------------------------------
  1386. - [Export(typeof(RazorTemplateEngineFactoryService))]
  1387. - internal class LegacyTemplateEngineFactoryService : RazorTemplateEngineFactoryService
  1388. - {
  1389. - private readonly Inner _inner;
  1390. - private readonly Workspace _workspace;
  1391. -
  1392. - [ImportingConstructor]
  1393. - public LegacyTemplateEngineFactoryService([Import(typeof(VisualStudioWorkspace))] Workspace workspace)
  1394. - {
  1395. - if (workspace == null)
  1396. - {
  1397. - throw new ArgumentNullException(nameof(workspace));
  1398. - }
  1399. -
  1400. - _workspace = workspace;
  1401. - _inner = workspace.Services.GetLanguageServices(RazorLanguage.Name).GetRequiredService<Inner>();
  1402. - }
  1403. -
  1404. - // internal for testing
  1405. - internal LegacyTemplateEngineFactoryService(Workspace workspace, Inner inner)
  1406. - {
  1407. - if (workspace == null)
  1408. - {
  1409. - throw new ArgumentNullException(nameof(workspace));
  1410. - }
  1411. -
  1412. - if (inner == null)
  1413. - {
  1414. - throw new ArgumentNullException(nameof(inner));
  1415. - }
  1416. -
  1417. - _workspace = workspace;
  1418. - _inner = inner;
  1419. - }
  1420. -
  1421. - public override RazorTemplateEngine Create(string projectPath, Action<IRazorEngineBuilder> configure)
  1422. - {
  1423. - if (projectPath == null)
  1424. - {
  1425. - throw new ArgumentNullException(nameof(projectPath));
  1426. - }
  1427. -
  1428. - return _inner.Create(projectPath, configure);
  1429. - }
  1430. - }
  1431. -}
  1432. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/LegacyTextBufferCodeDocumentProvider.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/LegacyTextBufferCodeDocumentProvider.cs
  1433. deleted file mode 100644
  1434. index 963dfc9fe84..00000000000
  1435. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/LegacyTextBufferCodeDocumentProvider.cs
  1436. +++ /dev/null
  1437. @@ -1,40 +0,0 @@
  1438. -// Copyright (c) .NET Foundation. All rights reserved.
  1439. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  1440. -
  1441. -using System;
  1442. -using System.ComponentModel.Composition;
  1443. -using Microsoft.AspNetCore.Razor.Language;
  1444. -using Microsoft.VisualStudio.Editor.Razor;
  1445. -using Microsoft.VisualStudio.Text;
  1446. -
  1447. -namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
  1448. -{
  1449. - [System.Composition.Shared]
  1450. - [Export(typeof(TextBufferCodeDocumentProvider))]
  1451. - internal class LegacyTextBufferCodeDocumentProvider : TextBufferCodeDocumentProvider
  1452. - {
  1453. - public override bool TryGetFromBuffer(ITextBuffer textBuffer, out RazorCodeDocument codeDocument)
  1454. - {
  1455. - if (textBuffer == null)
  1456. - {
  1457. - throw new ArgumentNullException(nameof(textBuffer));
  1458. - }
  1459. -
  1460. - if (textBuffer.Properties.TryGetProperty(typeof(VisualStudioRazorParser), out VisualStudioRazorParser parser) && parser.CodeDocument != null)
  1461. - {
  1462. - codeDocument = parser.CodeDocument;
  1463. - return true;
  1464. - }
  1465. -
  1466. - // Support the legacy parser for code document extraction.
  1467. - if (textBuffer.Properties.TryGetProperty(typeof(RazorEditorParser), out RazorEditorParser legacyParser) && legacyParser.CodeDocument != null)
  1468. - {
  1469. - codeDocument = legacyParser.CodeDocument;
  1470. - return true;
  1471. - }
  1472. -
  1473. - codeDocument = null;
  1474. - return false;
  1475. - }
  1476. - }
  1477. -}
  1478. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/PartialParseResult.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/PartialParseResult.cs
  1479. deleted file mode 100644
  1480. index 2571342f690..00000000000
  1481. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/PartialParseResult.cs
  1482. +++ /dev/null
  1483. @@ -1,21 +0,0 @@
  1484. -// Copyright (c) .NET Foundation. All rights reserved.
  1485. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  1486. -
  1487. -using System;
  1488. -
  1489. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  1490. -{
  1491. - [Flags]
  1492. - public enum PartialParseResult
  1493. - {
  1494. - Rejected = 1,
  1495. -
  1496. - Accepted = 2,
  1497. -
  1498. - Provisional = 4,
  1499. -
  1500. - SpanContextChanged = 8,
  1501. -
  1502. - AutoCompleteBlock = 16
  1503. - }
  1504. -}
  1505. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/RazorEditorParser.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/RazorEditorParser.cs
  1506. deleted file mode 100644
  1507. index de7fbc9977f..00000000000
  1508. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/RazorEditorParser.cs
  1509. +++ /dev/null
  1510. @@ -1,623 +0,0 @@
  1511. -// Copyright (c) .NET Foundation. All rights reserved.
  1512. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  1513. -
  1514. -using System;
  1515. -using System.Collections.Generic;
  1516. -using System.Diagnostics;
  1517. -using System.IO;
  1518. -using System.Linq;
  1519. -using System.Threading;
  1520. -using Microsoft.AspNetCore.Razor.Language;
  1521. -using Microsoft.AspNetCore.Razor.Language.Legacy;
  1522. -using Microsoft.VisualStudio.Editor.Razor;
  1523. -using Microsoft.VisualStudio.Text;
  1524. -
  1525. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  1526. -{
  1527. - public class RazorEditorParser : IDisposable
  1528. - {
  1529. - private RazorTemplateEngine _templateEngine;
  1530. -
  1531. - private AspNetCore.Razor.Language.Legacy.Span _lastChangeOwner;
  1532. - private AspNetCore.Razor.Language.Legacy.Span _lastAutoCompleteSpan;
  1533. - private BackgroundParser _parser;
  1534. -
  1535. - // For testing only.
  1536. - internal RazorEditorParser(RazorCodeDocument codeDocument)
  1537. - {
  1538. - CodeDocument = codeDocument;
  1539. - }
  1540. -
  1541. - public RazorEditorParser(RazorTemplateEngine templateEngine, string filePath)
  1542. - {
  1543. - if (templateEngine == null)
  1544. - {
  1545. - throw new ArgumentNullException(nameof(templateEngine));
  1546. - }
  1547. -
  1548. - if (string.IsNullOrEmpty(filePath))
  1549. - {
  1550. - throw new ArgumentException(
  1551. - AspNetCore.Razor.Language.Resources.ArgumentCannotBeNullOrEmpty,
  1552. - nameof(filePath));
  1553. - }
  1554. -
  1555. - TemplateEngine = templateEngine;
  1556. - FilePath = filePath;
  1557. - _parser = new BackgroundParser(this, filePath);
  1558. - _parser.ResultsReady += (sender, args) => OnDocumentParseComplete(args);
  1559. - _parser.Start();
  1560. - }
  1561. -
  1562. - /// <summary>
  1563. - /// Event fired when a full reparse of the document completes.
  1564. - /// </summary>
  1565. - public event EventHandler<DocumentParseCompleteEventArgs> DocumentParseComplete;
  1566. -
  1567. - public RazorTemplateEngine TemplateEngine
  1568. - {
  1569. - get => _templateEngine;
  1570. - set
  1571. - {
  1572. - if (value == null)
  1573. - {
  1574. - throw new ArgumentNullException(nameof(value));
  1575. - }
  1576. -
  1577. - _templateEngine = value;
  1578. - }
  1579. - }
  1580. -
  1581. - public string FilePath { get; }
  1582. -
  1583. - // Internal for testing.
  1584. - internal RazorSyntaxTree CurrentSyntaxTree { get; private set; }
  1585. -
  1586. - internal RazorCodeDocument CodeDocument { get; private set; }
  1587. -
  1588. - // Internal for testing.
  1589. - internal bool LastResultProvisional { get; private set; }
  1590. -
  1591. - public virtual string GetAutoCompleteString()
  1592. - {
  1593. - if (_lastAutoCompleteSpan?.EditHandler is AutoCompleteEditHandler editHandler)
  1594. - {
  1595. - return editHandler.AutoCompleteString;
  1596. - }
  1597. -
  1598. - return null;
  1599. - }
  1600. -
  1601. - public virtual PartialParseResult CheckForStructureChanges(SourceChange change, ITextSnapshot snapshot)
  1602. - {
  1603. - if (snapshot == null)
  1604. - {
  1605. - throw new ArgumentNullException(nameof(snapshot));
  1606. - }
  1607. -
  1608. - var result = PartialParseResultInternal.Rejected;
  1609. -
  1610. - using (_parser.SynchronizeMainThreadState())
  1611. - {
  1612. - // Check if we can partial-parse
  1613. - if (CurrentSyntaxTree != null && _parser.IsIdle)
  1614. - {
  1615. - result = TryPartialParse(change);
  1616. - }
  1617. - }
  1618. -
  1619. - // If partial parsing failed or there were outstanding parser tasks, start a full reparse
  1620. - if ((result & PartialParseResultInternal.Rejected) == PartialParseResultInternal.Rejected)
  1621. - {
  1622. - _parser.QueueChange(change, snapshot);
  1623. - }
  1624. -
  1625. - // Otherwise, remember if this was provisionally accepted for next partial parse
  1626. - LastResultProvisional = (result & PartialParseResultInternal.Provisional) == PartialParseResultInternal.Provisional;
  1627. - VerifyFlagsAreValid(result);
  1628. -
  1629. - return (PartialParseResult)result;
  1630. - }
  1631. -
  1632. - /// <summary>
  1633. - /// Disposes of this parser. Should be called when the editor window is closed and the document is unloaded.
  1634. - /// </summary>
  1635. - public void Dispose()
  1636. - {
  1637. - _parser.Dispose();
  1638. - GC.SuppressFinalize(this);
  1639. - }
  1640. -
  1641. - private PartialParseResultInternal TryPartialParse(SourceChange change)
  1642. - {
  1643. - var result = PartialParseResultInternal.Rejected;
  1644. -
  1645. - // Try the last change owner
  1646. - if (_lastChangeOwner != null && _lastChangeOwner.EditHandler.OwnsChange(_lastChangeOwner, change))
  1647. - {
  1648. - var editResult = _lastChangeOwner.EditHandler.ApplyChange(_lastChangeOwner, change);
  1649. - result = editResult.Result;
  1650. - if ((editResult.Result & PartialParseResultInternal.Rejected) != PartialParseResultInternal.Rejected)
  1651. - {
  1652. - _lastChangeOwner.ReplaceWith(editResult.EditedSpan);
  1653. - }
  1654. -
  1655. - return result;
  1656. - }
  1657. -
  1658. - // Locate the span responsible for this change
  1659. - _lastChangeOwner = CurrentSyntaxTree.Root.LocateOwner(change);
  1660. -
  1661. - if (LastResultProvisional)
  1662. - {
  1663. - // Last change owner couldn't accept this, so we must do a full reparse
  1664. - result = PartialParseResultInternal.Rejected;
  1665. - }
  1666. - else if (_lastChangeOwner != null)
  1667. - {
  1668. - var editResult = _lastChangeOwner.EditHandler.ApplyChange(_lastChangeOwner, change);
  1669. - result = editResult.Result;
  1670. - if ((editResult.Result & PartialParseResultInternal.Rejected) != PartialParseResultInternal.Rejected)
  1671. - {
  1672. - _lastChangeOwner.ReplaceWith(editResult.EditedSpan);
  1673. - }
  1674. - if ((result & PartialParseResultInternal.AutoCompleteBlock) == PartialParseResultInternal.AutoCompleteBlock)
  1675. - {
  1676. - _lastAutoCompleteSpan = _lastChangeOwner;
  1677. - }
  1678. - else
  1679. - {
  1680. - _lastAutoCompleteSpan = null;
  1681. - }
  1682. - }
  1683. -
  1684. - return result;
  1685. - }
  1686. -
  1687. - private void OnDocumentParseComplete(DocumentParseCompleteEventArgs args)
  1688. - {
  1689. - using (_parser.SynchronizeMainThreadState())
  1690. - {
  1691. - CurrentSyntaxTree = args.CodeDocument.GetSyntaxTree();
  1692. - CodeDocument = args.CodeDocument;
  1693. - _lastChangeOwner = null;
  1694. - }
  1695. -
  1696. - Debug.Assert(args != null, "Event arguments cannot be null");
  1697. - EventHandler<DocumentParseCompleteEventArgs> handler = DocumentParseComplete;
  1698. - if (handler != null)
  1699. - {
  1700. - try
  1701. - {
  1702. - handler(this, args);
  1703. - }
  1704. - catch (Exception ex)
  1705. - {
  1706. - Debug.WriteLine("[RzEd] Document Parse Complete Handler Threw: " + ex.ToString());
  1707. - }
  1708. - }
  1709. - }
  1710. -
  1711. - [Conditional("DEBUG")]
  1712. - private static void VerifyFlagsAreValid(PartialParseResultInternal result)
  1713. - {
  1714. - Debug.Assert(((result & PartialParseResultInternal.Accepted) == PartialParseResultInternal.Accepted) ||
  1715. - ((result & PartialParseResultInternal.Rejected) == PartialParseResultInternal.Rejected),
  1716. - "Partial Parse result does not have either of Accepted or Rejected flags set");
  1717. - Debug.Assert(((result & PartialParseResultInternal.Rejected) == PartialParseResultInternal.Rejected) ||
  1718. - ((result & PartialParseResultInternal.SpanContextChanged) != PartialParseResultInternal.SpanContextChanged),
  1719. - "Partial Parse result was Accepted AND had SpanContextChanged flag set");
  1720. - Debug.Assert(((result & PartialParseResultInternal.Rejected) == PartialParseResultInternal.Rejected) ||
  1721. - ((result & PartialParseResultInternal.AutoCompleteBlock) != PartialParseResultInternal.AutoCompleteBlock),
  1722. - "Partial Parse result was Accepted AND had AutoCompleteBlock flag set");
  1723. - Debug.Assert(((result & PartialParseResultInternal.Accepted) == PartialParseResultInternal.Accepted) ||
  1724. - ((result & PartialParseResultInternal.Provisional) != PartialParseResultInternal.Provisional),
  1725. - "Partial Parse result was Rejected AND had Provisional flag set");
  1726. - }
  1727. -
  1728. - internal class BackgroundParser : IDisposable
  1729. - {
  1730. - private MainThreadState _main;
  1731. - private BackgroundThread _bg;
  1732. -
  1733. - public BackgroundParser(RazorEditorParser parser, string filePath)
  1734. - {
  1735. - _main = new MainThreadState(filePath);
  1736. - _bg = new BackgroundThread(_main, parser, filePath);
  1737. -
  1738. - _main.ResultsReady += (sender, args) => OnResultsReady(args);
  1739. - }
  1740. -
  1741. - /// <summary>
  1742. - /// Fired on the main thread.
  1743. - /// </summary>
  1744. - public event EventHandler<DocumentParseCompleteEventArgs> ResultsReady;
  1745. -
  1746. - public bool IsIdle
  1747. - {
  1748. - get { return _main.IsIdle; }
  1749. - }
  1750. -
  1751. - public void Start()
  1752. - {
  1753. - _bg.Start();
  1754. - }
  1755. -
  1756. - public void Cancel()
  1757. - {
  1758. - _main.Cancel();
  1759. - }
  1760. -
  1761. - public void QueueChange(SourceChange change, ITextSnapshot snapshot)
  1762. - {
  1763. - var edit = new Edit(change, snapshot);
  1764. - _main.QueueChange(edit);
  1765. - }
  1766. -
  1767. - public void Dispose()
  1768. - {
  1769. - _main.Cancel();
  1770. - }
  1771. -
  1772. - public IDisposable SynchronizeMainThreadState()
  1773. - {
  1774. - return _main.Lock();
  1775. - }
  1776. -
  1777. - protected virtual void OnResultsReady(DocumentParseCompleteEventArgs args)
  1778. - {
  1779. - var handler = ResultsReady;
  1780. - if (handler != null)
  1781. - {
  1782. - handler(this, args);
  1783. - }
  1784. - }
  1785. -
  1786. - private static bool TreesAreDifferent(RazorSyntaxTree leftTree, RazorSyntaxTree rightTree, IEnumerable<Edit> edits, CancellationToken cancelToken)
  1787. - {
  1788. - return TreesAreDifferent(leftTree.Root, rightTree.Root, edits.Select(edit => edit.Change), cancelToken);
  1789. - }
  1790. -
  1791. - internal static bool TreesAreDifferent(Block leftTree, Block rightTree, IEnumerable<SourceChange> changes, CancellationToken cancelToken)
  1792. - {
  1793. - // Apply all the pending changes to the original tree
  1794. - // PERF: If this becomes a bottleneck, we can probably do it the other way around,
  1795. - // i.e. visit the tree and find applicable changes for each node.
  1796. - foreach (var change in changes)
  1797. - {
  1798. - cancelToken.ThrowIfCancellationRequested();
  1799. -
  1800. - var changeOwner = leftTree.LocateOwner(change);
  1801. -
  1802. - // Apply the change to the tree
  1803. - if (changeOwner == null)
  1804. - {
  1805. - return true;
  1806. - }
  1807. -
  1808. - var result = changeOwner.EditHandler.ApplyChange(changeOwner, change, force: true);
  1809. - changeOwner.ReplaceWith(result.EditedSpan);
  1810. - }
  1811. -
  1812. - // Now compare the trees
  1813. - var treesDifferent = !leftTree.EquivalentTo(rightTree);
  1814. - return treesDifferent;
  1815. - }
  1816. -
  1817. - private abstract class ThreadStateBase
  1818. - {
  1819. -#if DEBUG
  1820. - private int _id = -1;
  1821. -#endif
  1822. - protected ThreadStateBase()
  1823. - {
  1824. - }
  1825. -
  1826. - [Conditional("DEBUG")]
  1827. - protected void SetThreadId(int id)
  1828. - {
  1829. -#if DEBUG
  1830. - _id = id;
  1831. -#endif
  1832. - }
  1833. -
  1834. - [Conditional("DEBUG")]
  1835. - protected void EnsureOnThread()
  1836. - {
  1837. -#if DEBUG
  1838. - Debug.Assert(_id != -1, "SetThreadId was never called!");
  1839. - Debug.Assert(Thread.CurrentThread.ManagedThreadId == _id, "Called from an unexpected thread!");
  1840. -#endif
  1841. - }
  1842. -
  1843. - [Conditional("DEBUG")]
  1844. - protected void EnsureNotOnThread()
  1845. - {
  1846. -#if DEBUG
  1847. - Debug.Assert(_id != -1, "SetThreadId was never called!");
  1848. - Debug.Assert(Thread.CurrentThread.ManagedThreadId != _id, "Called from an unexpected thread!");
  1849. -#endif
  1850. - }
  1851. - }
  1852. -
  1853. - private class MainThreadState : ThreadStateBase, IDisposable
  1854. - {
  1855. - private readonly CancellationTokenSource _cancelSource = new CancellationTokenSource();
  1856. - private readonly ManualResetEventSlim _hasParcel = new ManualResetEventSlim(false);
  1857. - private CancellationTokenSource _currentParcelCancelSource;
  1858. -
  1859. - private string _fileName;
  1860. - private readonly object _stateLock = new object();
  1861. - private IList<Edit> _changes = new List<Edit>();
  1862. -
  1863. - public MainThreadState(string fileName)
  1864. - {
  1865. - _fileName = fileName;
  1866. -
  1867. - SetThreadId(Thread.CurrentThread.ManagedThreadId);
  1868. - }
  1869. -
  1870. - public event EventHandler<DocumentParseCompleteEventArgs> ResultsReady;
  1871. -
  1872. - public CancellationToken CancelToken
  1873. - {
  1874. - get { return _cancelSource.Token; }
  1875. - }
  1876. -
  1877. - public bool IsIdle
  1878. - {
  1879. - get
  1880. - {
  1881. - lock (_stateLock)
  1882. - {
  1883. - return _currentParcelCancelSource == null;
  1884. - }
  1885. - }
  1886. - }
  1887. -
  1888. - public void Cancel()
  1889. - {
  1890. - EnsureOnThread();
  1891. - _cancelSource.Cancel();
  1892. - }
  1893. -
  1894. - public IDisposable Lock()
  1895. - {
  1896. - Monitor.Enter(_stateLock);
  1897. - return new DisposableAction(() => Monitor.Exit(_stateLock));
  1898. - }
  1899. -
  1900. - public void QueueChange(Edit edit)
  1901. - {
  1902. - EnsureOnThread();
  1903. - lock (_stateLock)
  1904. - {
  1905. - // CurrentParcel token source is not null ==> There's a parse underway
  1906. - if (_currentParcelCancelSource != null)
  1907. - {
  1908. - _currentParcelCancelSource.Cancel();
  1909. - }
  1910. -
  1911. - _changes.Add(edit);
  1912. - _hasParcel.Set();
  1913. - }
  1914. - }
  1915. -
  1916. - public WorkParcel GetParcel()
  1917. - {
  1918. - EnsureNotOnThread(); // Only the background thread can get a parcel
  1919. - _hasParcel.Wait(_cancelSource.Token);
  1920. - _hasParcel.Reset();
  1921. - lock (_stateLock)
  1922. - {
  1923. - // Create a cancellation source for this parcel
  1924. - _currentParcelCancelSource = new CancellationTokenSource();
  1925. -
  1926. - var changes = _changes;
  1927. - _changes = new List<Edit>();
  1928. - return new WorkParcel(changes, _currentParcelCancelSource.Token);
  1929. - }
  1930. - }
  1931. -
  1932. - public void ReturnParcel(DocumentParseCompleteEventArgs args)
  1933. - {
  1934. - lock (_stateLock)
  1935. - {
  1936. - // Clear the current parcel cancellation source
  1937. - if (_currentParcelCancelSource != null)
  1938. - {
  1939. - _currentParcelCancelSource.Dispose();
  1940. - _currentParcelCancelSource = null;
  1941. - }
  1942. -
  1943. - // If there are things waiting to be parsed, just don't fire the event because we're already out of date
  1944. - if (_changes.Any())
  1945. - {
  1946. - return;
  1947. - }
  1948. - }
  1949. - var handler = ResultsReady;
  1950. - if (handler != null)
  1951. - {
  1952. - handler(this, args);
  1953. - }
  1954. - }
  1955. -
  1956. - public void Dispose()
  1957. - {
  1958. - Dispose(true);
  1959. - GC.SuppressFinalize(this);
  1960. - }
  1961. -
  1962. - protected virtual void Dispose(bool disposing)
  1963. - {
  1964. - if (disposing)
  1965. - {
  1966. - if (_currentParcelCancelSource != null)
  1967. - {
  1968. - _currentParcelCancelSource.Dispose();
  1969. - _currentParcelCancelSource = null;
  1970. - }
  1971. - _cancelSource.Dispose();
  1972. - _hasParcel.Dispose();
  1973. - }
  1974. - }
  1975. - }
  1976. -
  1977. - private class BackgroundThread : ThreadStateBase
  1978. - {
  1979. - private MainThreadState _main;
  1980. - private Thread _backgroundThread;
  1981. - private CancellationToken _shutdownToken;
  1982. - private RazorEditorParser _parser;
  1983. - private string _filePath;
  1984. - private RazorSyntaxTree _currentSyntaxTree;
  1985. - private IList<Edit> _previouslyDiscarded = new List<Edit>();
  1986. -
  1987. - public BackgroundThread(MainThreadState main, RazorEditorParser parser, string fileName)
  1988. - {
  1989. - // Run on MAIN thread!
  1990. - _main = main;
  1991. - _shutdownToken = _main.CancelToken;
  1992. - _parser = parser;
  1993. - _filePath = fileName;
  1994. -
  1995. - _backgroundThread = new Thread(WorkerLoop);
  1996. - SetThreadId(_backgroundThread.ManagedThreadId);
  1997. - }
  1998. -
  1999. - // **** ANY THREAD ****
  2000. - public void Start()
  2001. - {
  2002. - _backgroundThread.Start();
  2003. - }
  2004. -
  2005. - // **** BACKGROUND THREAD ****
  2006. - private void WorkerLoop()
  2007. - {
  2008. - var fileNameOnly = Path.GetFileName(_filePath);
  2009. -
  2010. - try
  2011. - {
  2012. - EnsureOnThread();
  2013. -
  2014. - while (!_shutdownToken.IsCancellationRequested)
  2015. - {
  2016. - // Grab the parcel of work to do
  2017. - var parcel = _main.GetParcel();
  2018. - if (parcel.Edits.Any())
  2019. - {
  2020. - try
  2021. - {
  2022. - DocumentParseCompleteEventArgs args = null;
  2023. - using (var linkedCancel = CancellationTokenSource.CreateLinkedTokenSource(_shutdownToken, parcel.CancelToken))
  2024. - {
  2025. - if (!linkedCancel.IsCancellationRequested)
  2026. - {
  2027. - // Collect ALL changes
  2028. - List<Edit> allEdits;
  2029. -
  2030. - if (_previouslyDiscarded != null)
  2031. - {
  2032. - allEdits = Enumerable.Concat(_previouslyDiscarded, parcel.Edits).ToList();
  2033. - }
  2034. - else
  2035. - {
  2036. - allEdits = parcel.Edits.ToList();
  2037. - }
  2038. -
  2039. - var finalEdit = allEdits.Last();
  2040. -
  2041. - var results = ParseChange(finalEdit.Snapshot, linkedCancel.Token);
  2042. -
  2043. - if (results != null && !linkedCancel.IsCancellationRequested)
  2044. - {
  2045. - // Clear discarded changes list
  2046. - _previouslyDiscarded = null;
  2047. -
  2048. - var treeStructureChanged = _currentSyntaxTree == null || TreesAreDifferent(_currentSyntaxTree, results.GetSyntaxTree(), allEdits, parcel.CancelToken);
  2049. - _currentSyntaxTree = results.GetSyntaxTree();
  2050. -
  2051. - // Build Arguments
  2052. - args = new DocumentParseCompleteEventArgs(
  2053. - finalEdit.Change,
  2054. - finalEdit.Snapshot,
  2055. - treeStructureChanged,
  2056. - results);
  2057. - }
  2058. - else
  2059. - {
  2060. - // Parse completed but we were cancelled in the mean time. Add these to the discarded changes set
  2061. - _previouslyDiscarded = allEdits;
  2062. - }
  2063. - }
  2064. - }
  2065. - if (args != null)
  2066. - {
  2067. - _main.ReturnParcel(args);
  2068. - }
  2069. - }
  2070. - catch (OperationCanceledException)
  2071. - {
  2072. - }
  2073. - }
  2074. - else
  2075. - {
  2076. - Thread.Yield();
  2077. - }
  2078. - }
  2079. - }
  2080. - catch (OperationCanceledException)
  2081. - {
  2082. - // Do nothing. Just shut down.
  2083. - }
  2084. - finally
  2085. - {
  2086. - // Clean up main thread resources
  2087. - _main.Dispose();
  2088. - }
  2089. - }
  2090. -
  2091. - private RazorCodeDocument ParseChange(ITextSnapshot snapshot, CancellationToken token)
  2092. - {
  2093. - EnsureOnThread();
  2094. -
  2095. - var templateEngine = _parser.TemplateEngine;
  2096. - var sourceDocument = new TextSnapshotSourceDocument(snapshot, _filePath);
  2097. - var imports = templateEngine.GetImports(_filePath);
  2098. -
  2099. - var codeDocument = RazorCodeDocument.Create(sourceDocument, imports);
  2100. -
  2101. - templateEngine.GenerateCode(codeDocument);
  2102. - return codeDocument;
  2103. - }
  2104. - }
  2105. -
  2106. - private class WorkParcel
  2107. - {
  2108. - public WorkParcel(IList<Edit> changes, CancellationToken cancelToken)
  2109. - {
  2110. - Edits = changes;
  2111. - CancelToken = cancelToken;
  2112. - }
  2113. -
  2114. - public CancellationToken CancelToken { get; }
  2115. -
  2116. - public IList<Edit> Edits { get; }
  2117. - }
  2118. -
  2119. - private class Edit
  2120. - {
  2121. - public Edit(SourceChange change, ITextSnapshot snapshot)
  2122. - {
  2123. - Change = change;
  2124. - Snapshot = snapshot;
  2125. - }
  2126. -
  2127. - public SourceChange Change { get; }
  2128. -
  2129. - public ITextSnapshot Snapshot { get; set; }
  2130. - }
  2131. - }
  2132. - }
  2133. -}
  2134. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/RazorSyntaxFactsService.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/RazorSyntaxFactsService.cs
  2135. deleted file mode 100644
  2136. index 6b187680e92..00000000000
  2137. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/RazorSyntaxFactsService.cs
  2138. +++ /dev/null
  2139. @@ -1,22 +0,0 @@
  2140. -// Copyright (c) .NET Foundation. All rights reserved.
  2141. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2142. -
  2143. -using System.Collections.Generic;
  2144. -using Microsoft.AspNetCore.Razor.Language;
  2145. -using Microsoft.VisualStudio.Text;
  2146. -
  2147. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  2148. -{
  2149. - // ----------------------------------------------------------------------------------------------------
  2150. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  2151. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  2152. - // ----------------------------------------------------------------------------------------------------
  2153. - public abstract class RazorSyntaxFactsService
  2154. - {
  2155. - public abstract IReadOnlyList<ClassifiedSpan> GetClassifiedSpans(RazorSyntaxTree syntaxTree);
  2156. -
  2157. - public abstract IReadOnlyList<TagHelperSpan> GetTagHelperSpans(RazorSyntaxTree syntaxTree);
  2158. -
  2159. - public abstract int? GetDesiredIndentation(RazorSyntaxTree syntaxTree, ITextSnapshot syntaxTreeSnapshot, ITextSnapshotLine line, int indentSize, int tabSize);
  2160. - }
  2161. -}
  2162. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/RazorTemplateEngineFactoryService.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/RazorTemplateEngineFactoryService.cs
  2163. deleted file mode 100644
  2164. index 784437df224..00000000000
  2165. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/RazorTemplateEngineFactoryService.cs
  2166. +++ /dev/null
  2167. @@ -1,17 +0,0 @@
  2168. -// Copyright (c) .NET Foundation. All rights reserved.
  2169. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2170. -
  2171. -using System;
  2172. -using Microsoft.AspNetCore.Razor.Language;
  2173. -
  2174. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  2175. -{
  2176. - // ----------------------------------------------------------------------------------------------------
  2177. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  2178. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  2179. - // ----------------------------------------------------------------------------------------------------
  2180. - public abstract class RazorTemplateEngineFactoryService
  2181. - {
  2182. - public abstract RazorTemplateEngine Create(string projectPath, Action<IRazorEngineBuilder> configure);
  2183. - }
  2184. -}
  2185. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/SpanKind.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/SpanKind.cs
  2186. deleted file mode 100644
  2187. index d557849f6d3..00000000000
  2188. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/SpanKind.cs
  2189. +++ /dev/null
  2190. @@ -1,18 +0,0 @@
  2191. -// Copyright (c) .NET Foundation. All rights reserved.
  2192. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2193. -
  2194. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  2195. -{
  2196. - // ----------------------------------------------------------------------------------------------------
  2197. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  2198. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  2199. - // ----------------------------------------------------------------------------------------------------
  2200. - public enum SpanKind
  2201. - {
  2202. - Transition,
  2203. - MetaCode,
  2204. - Comment,
  2205. - Code,
  2206. - Markup
  2207. - }
  2208. -}
  2209. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/TagHelperCompletionService.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/TagHelperCompletionService.cs
  2210. deleted file mode 100644
  2211. index 78f3e4b8216..00000000000
  2212. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/TagHelperCompletionService.cs
  2213. +++ /dev/null
  2214. @@ -1,16 +0,0 @@
  2215. -// Copyright (c) .NET Foundation. All rights reserved.
  2216. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2217. -
  2218. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  2219. -{
  2220. - // ----------------------------------------------------------------------------------------------------
  2221. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  2222. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  2223. - // ----------------------------------------------------------------------------------------------------
  2224. - public abstract class TagHelperCompletionService
  2225. - {
  2226. - public abstract AttributeCompletionResult GetAttributeCompletions(AttributeCompletionContext completionContext);
  2227. -
  2228. - public abstract ElementCompletionResult GetElementCompletions(ElementCompletionContext completionContext);
  2229. - }
  2230. -}
  2231. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/TagHelperFactsService.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/TagHelperFactsService.cs
  2232. deleted file mode 100644
  2233. index 5fca65c2189..00000000000
  2234. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/TagHelperFactsService.cs
  2235. +++ /dev/null
  2236. @@ -1,23 +0,0 @@
  2237. -// Copyright (c) .NET Foundation. All rights reserved.
  2238. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2239. -
  2240. -using System.Collections.Generic;
  2241. -using Microsoft.AspNetCore.Razor.Language;
  2242. -
  2243. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  2244. -{
  2245. - // ----------------------------------------------------------------------------------------------------
  2246. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  2247. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  2248. - // ----------------------------------------------------------------------------------------------------
  2249. - public abstract class TagHelperFactsService
  2250. - {
  2251. - public abstract TagHelperBinding GetTagHelperBinding(TagHelperDocumentContext documentContext, string tagName, IEnumerable<KeyValuePair<string, string>> attributes, string parentTag);
  2252. -
  2253. - public abstract IEnumerable<BoundAttributeDescriptor> GetBoundTagHelperAttributes(TagHelperDocumentContext documentContext, string attributeName, TagHelperBinding binding);
  2254. -
  2255. - public abstract IReadOnlyList<TagHelperDescriptor> GetTagHelpersGivenTag(TagHelperDocumentContext documentContext, string tagName, string parentTag);
  2256. -
  2257. - public abstract IReadOnlyList<TagHelperDescriptor> GetTagHelpersGivenParent(TagHelperDocumentContext documentContext, string parentTag);
  2258. - }
  2259. -}
  2260. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/TagHelperSpan.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/TagHelperSpan.cs
  2261. deleted file mode 100644
  2262. index 337234f3d00..00000000000
  2263. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/Legacy/TagHelperSpan.cs
  2264. +++ /dev/null
  2265. @@ -1,33 +0,0 @@
  2266. -// Copyright (c) .NET Foundation. All rights reserved.
  2267. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2268. -
  2269. -using System;
  2270. -using System.Collections.Generic;
  2271. -using Microsoft.AspNetCore.Razor.Language;
  2272. -
  2273. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  2274. -{
  2275. - // ----------------------------------------------------------------------------------------------------
  2276. - // NOTE: This is only here for VisualStudio binary compatibility. This type should not be used; instead
  2277. - // use the Microsoft.CodeAnalysis.Razor variant from Microsoft.CodeAnalysis.Razor.Workspaces
  2278. - // ----------------------------------------------------------------------------------------------------
  2279. - public struct TagHelperSpan
  2280. - {
  2281. - public TagHelperSpan(SourceSpan span, TagHelperBinding binding)
  2282. - {
  2283. - if (binding == null)
  2284. - {
  2285. - throw new ArgumentNullException(nameof(binding));
  2286. - }
  2287. -
  2288. - Span = span;
  2289. - Binding = binding;
  2290. - }
  2291. -
  2292. - public TagHelperBinding Binding { get; }
  2293. -
  2294. - public IEnumerable<TagHelperDescriptor> TagHelpers => Binding.Descriptors;
  2295. -
  2296. - public SourceSpan Span { get; }
  2297. - }
  2298. -}
  2299. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/RazorDiagnosticJsonConverter.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/RazorDiagnosticJsonConverter.cs
  2300. index 96db50dc928..d9d4d966e16 100644
  2301. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/RazorDiagnosticJsonConverter.cs
  2302. +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/RazorDiagnosticJsonConverter.cs
  2303. @@ -9,7 +9,7 @@ using Newtonsoft.Json.Linq;
  2304. namespace Microsoft.VisualStudio.LanguageServices.Razor
  2305. {
  2306. - public class RazorDiagnosticJsonConverter : JsonConverter
  2307. + internal class RazorDiagnosticJsonConverter : JsonConverter
  2308. {
  2309. public static readonly RazorDiagnosticJsonConverter Instance = new RazorDiagnosticJsonConverter();
  2310. private const string RazorDiagnosticMessageKey = "Message";
  2311. diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/RazorLanguageServiceException.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/RazorLanguageServiceException.cs
  2312. deleted file mode 100644
  2313. index 80c5d88a61b..00000000000
  2314. --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/RazorLanguageServiceException.cs
  2315. +++ /dev/null
  2316. @@ -1,15 +0,0 @@
  2317. -// Copyright (c) .NET Foundation. All rights reserved.
  2318. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2319. -
  2320. -using System;
  2321. -
  2322. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  2323. -{
  2324. - public sealed class RazorLanguageServiceException : Exception
  2325. - {
  2326. - internal RazorLanguageServiceException(string callerClass, string callerMethod, Exception innerException)
  2327. - : base(Resources.FormatUnexpectedException(callerClass, callerMethod), innerException)
  2328. - {
  2329. - }
  2330. - }
  2331. -}
  2332. diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Editor/LegacyTextBufferCodeDocumentProviderTest.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Editor/LegacyTextBufferCodeDocumentProviderTest.cs
  2333. deleted file mode 100644
  2334. index 41278519286..00000000000
  2335. --- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Editor/LegacyTextBufferCodeDocumentProviderTest.cs
  2336. +++ /dev/null
  2337. @@ -1,99 +0,0 @@
  2338. -// Copyright (c) .NET Foundation. All rights reserved.
  2339. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2340. -
  2341. -using Microsoft.AspNetCore.Razor.Language;
  2342. -using Microsoft.VisualStudio.Editor.Razor;
  2343. -using Microsoft.VisualStudio.Text;
  2344. -using Microsoft.VisualStudio.Utilities;
  2345. -using Moq;
  2346. -using Xunit;
  2347. -
  2348. -namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
  2349. -{
  2350. - public class LegacyTextBufferCodeDocumentProviderTest
  2351. - {
  2352. - [Fact]
  2353. - public void TryGetFromBuffer_UsesVisualStudioRazorParserIfAvailable()
  2354. - {
  2355. - // Arrange
  2356. - var expectedCodeDocument = TestRazorCodeDocument.Create("Hello World");
  2357. - var parser = new DefaultVisualStudioRazorParser(expectedCodeDocument);
  2358. - var properties = new PropertyCollection();
  2359. - properties.AddProperty(typeof(VisualStudioRazorParser), parser);
  2360. - var textBuffer = new Mock<ITextBuffer>();
  2361. - textBuffer.Setup(buffer => buffer.Properties)
  2362. - .Returns(properties);
  2363. - var provider = new LegacyTextBufferCodeDocumentProvider();
  2364. -
  2365. - // Act
  2366. - var result = provider.TryGetFromBuffer(textBuffer.Object, out var codeDocument);
  2367. -
  2368. - // Assert
  2369. - Assert.True(result);
  2370. - Assert.Same(expectedCodeDocument, codeDocument);
  2371. - }
  2372. -
  2373. - [Fact]
  2374. - public void TryGetFromBuffer_UsesRazorEditorParserIfAvailable()
  2375. - {
  2376. - // Arrange
  2377. - var expectedCodeDocument = TestRazorCodeDocument.Create("Hello World");
  2378. - var parser = new RazorEditorParser(expectedCodeDocument);
  2379. - var properties = new PropertyCollection();
  2380. - properties.AddProperty(typeof(RazorEditorParser), parser);
  2381. - var textBuffer = new Mock<ITextBuffer>();
  2382. - textBuffer.Setup(buffer => buffer.Properties)
  2383. - .Returns(properties);
  2384. - var provider = new LegacyTextBufferCodeDocumentProvider();
  2385. -
  2386. - // Act
  2387. - var result = provider.TryGetFromBuffer(textBuffer.Object, out var codeDocument);
  2388. -
  2389. - // Assert
  2390. - Assert.True(result);
  2391. - Assert.Same(expectedCodeDocument, codeDocument);
  2392. - }
  2393. -
  2394. - [Fact]
  2395. - public void TryGetFromBuffer_PrefersVisualStudioRazorParserIfRazorEditorParserIsAvailable()
  2396. - {
  2397. - // Arrange
  2398. - var properties = new PropertyCollection();
  2399. - var expectedCodeDocument = TestRazorCodeDocument.Create("Hello World");
  2400. - var parser = new DefaultVisualStudioRazorParser(expectedCodeDocument);
  2401. - properties.AddProperty(typeof(VisualStudioRazorParser), parser);
  2402. - var unexpectedCodeDocument = TestRazorCodeDocument.Create("Unexpected");
  2403. - var legacyParser = new RazorEditorParser(unexpectedCodeDocument);
  2404. - properties.AddProperty(typeof(RazorEditorParser), legacyParser);
  2405. - var textBuffer = new Mock<ITextBuffer>();
  2406. - textBuffer.Setup(buffer => buffer.Properties)
  2407. - .Returns(properties);
  2408. - var provider = new LegacyTextBufferCodeDocumentProvider();
  2409. -
  2410. - // Act
  2411. - var result = provider.TryGetFromBuffer(textBuffer.Object, out var codeDocument);
  2412. -
  2413. - // Assert
  2414. - Assert.True(result);
  2415. - Assert.Same(expectedCodeDocument, codeDocument);
  2416. - }
  2417. -
  2418. - [Fact]
  2419. - public void TryGetFromBuffer_FailsIfNoParserIsAvailable()
  2420. - {
  2421. - // Arrange
  2422. - var properties = new PropertyCollection();
  2423. - var textBuffer = new Mock<ITextBuffer>();
  2424. - textBuffer.Setup(buffer => buffer.Properties)
  2425. - .Returns(properties);
  2426. - var provider = new LegacyTextBufferCodeDocumentProvider();
  2427. -
  2428. - // Act
  2429. - var result = provider.TryGetFromBuffer(textBuffer.Object, out var codeDocument);
  2430. -
  2431. - // Assert
  2432. - Assert.False(result);
  2433. - Assert.Null(codeDocument);
  2434. - }
  2435. - }
  2436. -}
  2437. diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Legacy/DefaultTagHelperCompletionServiceTest.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Legacy/DefaultTagHelperCompletionServiceTest.cs
  2438. deleted file mode 100644
  2439. index 5d6ad363bc8..00000000000
  2440. --- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Legacy/DefaultTagHelperCompletionServiceTest.cs
  2441. +++ /dev/null
  2442. @@ -1,964 +0,0 @@
  2443. -// Copyright (c) .NET Foundation. All rights reserved.
  2444. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2445. -
  2446. -using Microsoft.AspNetCore.Razor.Language;
  2447. -using System.Collections.Generic;
  2448. -using System.Linq;
  2449. -using Xunit;
  2450. -
  2451. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  2452. -{
  2453. - public class DefaultTagHelperCompletionServiceTest
  2454. - {
  2455. - [Fact]
  2456. - public void GetAttributeCompletions_DoesNotReturnCompletionsForAlreadySuppliedAttributes()
  2457. - {
  2458. - // Arrange
  2459. - var documentDescriptors = new[]
  2460. - {
  2461. - TagHelperDescriptorBuilder.Create("DivTagHelper", "TestAssembly")
  2462. - .TagMatchingRuleDescriptor(rule => rule
  2463. - .RequireTagName("div")
  2464. - .RequireAttributeDescriptor(attribute => attribute.Name("repeat")))
  2465. - .BoundAttributeDescriptor(attribute => attribute
  2466. - .Name("visible")
  2467. - .TypeName(typeof(bool).FullName)
  2468. - .PropertyName("Visible"))
  2469. - .Build(),
  2470. - TagHelperDescriptorBuilder.Create("StyleTagHelper", "TestAssembly")
  2471. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
  2472. - .BoundAttributeDescriptor(attribute => attribute
  2473. - .Name("class")
  2474. - .TypeName(typeof(string).FullName)
  2475. - .PropertyName("Class"))
  2476. - .Build(),
  2477. - };
  2478. - var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
  2479. - {
  2480. - ["onclick"] = new HashSet<BoundAttributeDescriptor>(),
  2481. - ["visible"] = new HashSet<BoundAttributeDescriptor>()
  2482. - {
  2483. - documentDescriptors[0].BoundAttributes.Last()
  2484. - }
  2485. - });
  2486. -
  2487. - var existingCompletions = new[] { "onclick" };
  2488. - var completionContext = BuildAttributeCompletionContext(
  2489. - documentDescriptors,
  2490. - existingCompletions,
  2491. - attributes: new Dictionary<string, string>()
  2492. - {
  2493. - ["class"] = "something",
  2494. - ["repeat"] = "4"
  2495. - },
  2496. - currentTagName: "div");
  2497. - var service = CreateTagHelperCompletionFactsService();
  2498. -
  2499. - // Act
  2500. - var completions = service.GetAttributeCompletions(completionContext);
  2501. -
  2502. - // Assert
  2503. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2504. - }
  2505. -
  2506. - [Fact]
  2507. - public void GetAttributeCompletions_PossibleDescriptorsReturnUnboundRequiredAttributesWithExistingCompletions()
  2508. - {
  2509. - // Arrange
  2510. - var documentDescriptors = new[]
  2511. - {
  2512. - TagHelperDescriptorBuilder.Create("DivTagHelper", "TestAssembly")
  2513. - .TagMatchingRuleDescriptor(rule => rule
  2514. - .RequireTagName("div")
  2515. - .RequireAttributeDescriptor(attribute => attribute.Name("repeat")))
  2516. - .Build(),
  2517. - TagHelperDescriptorBuilder.Create("StyleTagHelper", "TestAssembly")
  2518. - .TagMatchingRuleDescriptor(rule => rule
  2519. - .RequireTagName("*")
  2520. - .RequireAttributeDescriptor(attribute => attribute.Name("class")))
  2521. - .Build(),
  2522. - };
  2523. - var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
  2524. - {
  2525. - ["class"] = new HashSet<BoundAttributeDescriptor>(),
  2526. - ["onclick"] = new HashSet<BoundAttributeDescriptor>(),
  2527. - ["repeat"] = new HashSet<BoundAttributeDescriptor>()
  2528. - });
  2529. -
  2530. - var existingCompletions = new[] { "onclick", "class" };
  2531. - var completionContext = BuildAttributeCompletionContext(
  2532. - documentDescriptors,
  2533. - existingCompletions,
  2534. - currentTagName: "div");
  2535. - var service = CreateTagHelperCompletionFactsService();
  2536. -
  2537. - // Act
  2538. - var completions = service.GetAttributeCompletions(completionContext);
  2539. -
  2540. - // Assert
  2541. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2542. - }
  2543. -
  2544. - [Fact]
  2545. - public void GetAttributeCompletions_PossibleDescriptorsReturnBoundRequiredAttributesWithExistingCompletions()
  2546. - {
  2547. - // Arrange
  2548. - var documentDescriptors = new[]
  2549. - {
  2550. - TagHelperDescriptorBuilder.Create("DivTagHelper", "TestAssembly")
  2551. - .TagMatchingRuleDescriptor(rule => rule
  2552. - .RequireTagName("div")
  2553. - .RequireAttributeDescriptor(attribute => attribute.Name("repeat")))
  2554. - .BoundAttributeDescriptor(attribute => attribute
  2555. - .Name("repeat")
  2556. - .TypeName(typeof(bool).FullName)
  2557. - .PropertyName("Repeat"))
  2558. - .BoundAttributeDescriptor(attribute => attribute
  2559. - .Name("visible")
  2560. - .TypeName(typeof(bool).FullName)
  2561. - .PropertyName("Visible"))
  2562. - .Build(),
  2563. - TagHelperDescriptorBuilder.Create("StyleTagHelper", "TestAssembly")
  2564. - .TagMatchingRuleDescriptor(rule => rule
  2565. - .RequireTagName("*")
  2566. - .RequireAttributeDescriptor(attribute => attribute.Name("class")))
  2567. - .BoundAttributeDescriptor(attribute => attribute
  2568. - .Name("class")
  2569. - .TypeName(typeof(string).FullName)
  2570. - .PropertyName("Class"))
  2571. - .Build(),
  2572. - };
  2573. - var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
  2574. - {
  2575. - ["class"] = new HashSet<BoundAttributeDescriptor>(documentDescriptors[1].BoundAttributes),
  2576. - ["onclick"] = new HashSet<BoundAttributeDescriptor>(),
  2577. - ["repeat"] = new HashSet<BoundAttributeDescriptor>()
  2578. - {
  2579. - documentDescriptors[0].BoundAttributes.First()
  2580. - }
  2581. - });
  2582. -
  2583. - var existingCompletions = new[] { "onclick" };
  2584. - var completionContext = BuildAttributeCompletionContext(
  2585. - documentDescriptors,
  2586. - existingCompletions,
  2587. - currentTagName: "div");
  2588. - var service = CreateTagHelperCompletionFactsService();
  2589. -
  2590. - // Act
  2591. - var completions = service.GetAttributeCompletions(completionContext);
  2592. -
  2593. - // Assert
  2594. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2595. - }
  2596. -
  2597. - [Fact]
  2598. - public void GetAttributeCompletions_AppliedDescriptorsReturnAllBoundAttributesWithExistingCompletionsForSchemaTags()
  2599. - {
  2600. - // Arrange
  2601. - var documentDescriptors = new[]
  2602. - {
  2603. - TagHelperDescriptorBuilder.Create("DivTagHelper", "TestAssembly")
  2604. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
  2605. - .BoundAttributeDescriptor(attribute => attribute
  2606. - .Name("repeat")
  2607. - .TypeName(typeof(bool).FullName)
  2608. - .PropertyName("Repeat"))
  2609. - .BoundAttributeDescriptor(attribute => attribute
  2610. - .Name("visible")
  2611. - .TypeName(typeof(bool).FullName)
  2612. - .PropertyName("Visible"))
  2613. - .Build(),
  2614. - TagHelperDescriptorBuilder.Create("StyleTagHelper", "TestAssembly")
  2615. - .TagMatchingRuleDescriptor(rule => rule
  2616. - .RequireTagName("*")
  2617. - .RequireAttributeDescriptor(attribute => attribute.Name("class")))
  2618. - .BoundAttributeDescriptor(attribute => attribute
  2619. - .Name("class")
  2620. - .TypeName(typeof(string).FullName)
  2621. - .PropertyName("Class"))
  2622. - .Build(),
  2623. - TagHelperDescriptorBuilder.Create("StyleTagHelper", "TestAssembly")
  2624. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
  2625. - .BoundAttributeDescriptor(attribute => attribute
  2626. - .Name("visible")
  2627. - .TypeName(typeof(bool).FullName)
  2628. - .PropertyName("Visible"))
  2629. - .Build(),
  2630. - };
  2631. - var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
  2632. - {
  2633. - ["onclick"] = new HashSet<BoundAttributeDescriptor>(),
  2634. - ["class"] = new HashSet<BoundAttributeDescriptor>(documentDescriptors[1].BoundAttributes),
  2635. - ["repeat"] = new HashSet<BoundAttributeDescriptor>()
  2636. - {
  2637. - documentDescriptors[0].BoundAttributes.First()
  2638. - },
  2639. - ["visible"] = new HashSet<BoundAttributeDescriptor>()
  2640. - {
  2641. - documentDescriptors[0].BoundAttributes.Last(),
  2642. - documentDescriptors[2].BoundAttributes.First(),
  2643. - }
  2644. - });
  2645. -
  2646. - var existingCompletions = new[] { "class", "onclick" };
  2647. - var completionContext = BuildAttributeCompletionContext(
  2648. - documentDescriptors,
  2649. - existingCompletions,
  2650. - currentTagName: "div");
  2651. - var service = CreateTagHelperCompletionFactsService();
  2652. -
  2653. - // Act
  2654. - var completions = service.GetAttributeCompletions(completionContext);
  2655. -
  2656. - // Assert
  2657. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2658. - }
  2659. -
  2660. - [Fact]
  2661. - public void GetAttributeCompletions_AppliedTagOutputHintDescriptorsReturnBoundAttributesWithExistingCompletionsForNonSchemaTags()
  2662. - {
  2663. - // Arrange
  2664. - var documentDescriptors = new[]
  2665. - {
  2666. - TagHelperDescriptorBuilder.Create("CustomTagHelper", "TestAssembly")
  2667. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("custom"))
  2668. - .BoundAttributeDescriptor(attribute => attribute
  2669. - .Name("repeat")
  2670. - .TypeName(typeof(bool).FullName)
  2671. - .PropertyName("Repeat"))
  2672. - .TagOutputHint("div")
  2673. - .Build(),
  2674. - };
  2675. - var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
  2676. - {
  2677. - ["class"] = new HashSet<BoundAttributeDescriptor>(),
  2678. - ["repeat"] = new HashSet<BoundAttributeDescriptor>(documentDescriptors[0].BoundAttributes)
  2679. - });
  2680. -
  2681. - var existingCompletions = new[] { "class" };
  2682. - var completionContext = BuildAttributeCompletionContext(
  2683. - documentDescriptors,
  2684. - existingCompletions,
  2685. - currentTagName: "custom");
  2686. - var service = CreateTagHelperCompletionFactsService();
  2687. -
  2688. - // Act
  2689. - var completions = service.GetAttributeCompletions(completionContext);
  2690. -
  2691. - // Assert
  2692. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2693. - }
  2694. -
  2695. - [Fact]
  2696. - public void GetAttributeCompletions_AppliedDescriptorsReturnBoundAttributesCompletionsForNonSchemaTags()
  2697. - {
  2698. - // Arrange
  2699. - var documentDescriptors = new[]
  2700. - {
  2701. - TagHelperDescriptorBuilder.Create("CustomTagHelper", "TestAssembly")
  2702. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("custom"))
  2703. - .BoundAttributeDescriptor(attribute => attribute
  2704. - .Name("repeat")
  2705. - .TypeName(typeof(bool).FullName)
  2706. - .PropertyName("Repeat"))
  2707. - .Build(),
  2708. - };
  2709. - var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
  2710. - {
  2711. - ["repeat"] = new HashSet<BoundAttributeDescriptor>(documentDescriptors[0].BoundAttributes)
  2712. - });
  2713. -
  2714. - var existingCompletions = new[] { "class" };
  2715. - var completionContext = BuildAttributeCompletionContext(
  2716. - documentDescriptors,
  2717. - existingCompletions,
  2718. - currentTagName: "custom");
  2719. - var service = CreateTagHelperCompletionFactsService();
  2720. -
  2721. - // Act
  2722. - var completions = service.GetAttributeCompletions(completionContext);
  2723. -
  2724. - // Assert
  2725. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2726. - }
  2727. -
  2728. - [Fact]
  2729. - public void GetAttributeCompletions_AppliedDescriptorsReturnBoundAttributesWithExistingCompletionsForSchemaTags()
  2730. - {
  2731. - // Arrange
  2732. - var documentDescriptors = new[]
  2733. - {
  2734. - TagHelperDescriptorBuilder.Create("DivTagHelper", "TestAssembly")
  2735. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
  2736. - .BoundAttributeDescriptor(attribute => attribute
  2737. - .Name("repeat")
  2738. - .TypeName(typeof(bool).FullName)
  2739. - .PropertyName("Repeat"))
  2740. - .Build(),
  2741. - };
  2742. - var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
  2743. - {
  2744. - ["class"] = new HashSet<BoundAttributeDescriptor>(),
  2745. - ["repeat"] = new HashSet<BoundAttributeDescriptor>(documentDescriptors[0].BoundAttributes)
  2746. - });
  2747. -
  2748. - var existingCompletions = new[] { "class" };
  2749. - var completionContext = BuildAttributeCompletionContext(
  2750. - documentDescriptors,
  2751. - existingCompletions,
  2752. - currentTagName: "div");
  2753. - var service = CreateTagHelperCompletionFactsService();
  2754. -
  2755. - // Act
  2756. - var completions = service.GetAttributeCompletions(completionContext);
  2757. -
  2758. - // Assert
  2759. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2760. - }
  2761. -
  2762. - [Fact]
  2763. - public void GetAttributeCompletions_NoDescriptorsReturnsExistingCompletions()
  2764. - {
  2765. - // Arrange
  2766. - var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
  2767. - {
  2768. - ["class"] = new HashSet<BoundAttributeDescriptor>(),
  2769. - });
  2770. -
  2771. - var existingCompletions = new[] { "class" };
  2772. - var completionContext = BuildAttributeCompletionContext(
  2773. - Enumerable.Empty<TagHelperDescriptor>(),
  2774. - existingCompletions,
  2775. - currentTagName: "div");
  2776. - var service = CreateTagHelperCompletionFactsService();
  2777. -
  2778. - // Act
  2779. - var completions = service.GetAttributeCompletions(completionContext);
  2780. -
  2781. - // Assert
  2782. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2783. - }
  2784. -
  2785. - [Fact]
  2786. - public void GetAttributeCompletions_NoDescriptorsForUnprefixedTagReturnsExistingCompletions()
  2787. - {
  2788. - // Arrange
  2789. - var documentDescriptors = new[]
  2790. - {
  2791. - TagHelperDescriptorBuilder.Create("DivTagHelper", "TestAssembly")
  2792. - .TagMatchingRuleDescriptor(rule => rule
  2793. - .RequireTagName("div")
  2794. - .RequireAttributeDescriptor(attribute => attribute.Name("special")))
  2795. - .Build(),
  2796. - };
  2797. - var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
  2798. - {
  2799. - ["class"] = new HashSet<BoundAttributeDescriptor>(),
  2800. - });
  2801. -
  2802. - var existingCompletions = new[] { "class" };
  2803. - var completionContext = BuildAttributeCompletionContext(
  2804. - documentDescriptors,
  2805. - existingCompletions,
  2806. - currentTagName: "div",
  2807. - tagHelperPrefix: "th:");
  2808. - var service = CreateTagHelperCompletionFactsService();
  2809. -
  2810. - // Act
  2811. - var completions = service.GetAttributeCompletions(completionContext);
  2812. -
  2813. - // Assert
  2814. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2815. - }
  2816. -
  2817. - [Fact]
  2818. - public void GetAttributeCompletions_NoDescriptorsForTagReturnsExistingCompletions()
  2819. - {
  2820. - // Arrange
  2821. - var documentDescriptors = new[]
  2822. - {
  2823. - TagHelperDescriptorBuilder.Create("MyTableTagHelper", "TestAssembly")
  2824. - .TagMatchingRuleDescriptor(rule => rule
  2825. - .RequireTagName("table")
  2826. - .RequireAttributeDescriptor(attribute => attribute.Name("special")))
  2827. - .Build(),
  2828. - };
  2829. - var expectedCompletions = AttributeCompletionResult.Create(new Dictionary<string, HashSet<BoundAttributeDescriptor>>()
  2830. - {
  2831. - ["class"] = new HashSet<BoundAttributeDescriptor>(),
  2832. - });
  2833. -
  2834. - var existingCompletions = new[] { "class" };
  2835. - var completionContext = BuildAttributeCompletionContext(
  2836. - documentDescriptors,
  2837. - existingCompletions,
  2838. - currentTagName: "div");
  2839. - var service = CreateTagHelperCompletionFactsService();
  2840. -
  2841. - // Act
  2842. - var completions = service.GetAttributeCompletions(completionContext);
  2843. -
  2844. - // Assert
  2845. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2846. - }
  2847. -
  2848. - [Fact]
  2849. - public void GetElementCompletions_TagOutputHintDoesNotFallThroughToSchemaCheck()
  2850. - {
  2851. - // Arrange
  2852. - var documentDescriptors = new[]
  2853. - {
  2854. - TagHelperDescriptorBuilder.Create("MyTableTagHelper", "TestAssembly")
  2855. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("my-table"))
  2856. - .TagOutputHint("table")
  2857. - .Build(),
  2858. - TagHelperDescriptorBuilder.Create("MyTrTagHelper", "TestAssembly")
  2859. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("my-tr"))
  2860. - .TagOutputHint("tr")
  2861. - .Build(),
  2862. - };
  2863. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  2864. - {
  2865. - ["my-table"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] },
  2866. - ["table"] = new HashSet<TagHelperDescriptor>(),
  2867. - });
  2868. -
  2869. - var existingCompletions = new[] { "table" };
  2870. - var completionContext = BuildElementCompletionContext(
  2871. - documentDescriptors,
  2872. - existingCompletions,
  2873. - containingTagName: "body",
  2874. - containingParentTagName: null);
  2875. - var service = CreateTagHelperCompletionFactsService();
  2876. -
  2877. - // Act
  2878. - var completions = service.GetElementCompletions(completionContext);
  2879. -
  2880. - // Assert
  2881. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2882. - }
  2883. -
  2884. - [Fact]
  2885. - public void GetElementCompletions_CatchAllsOnlyApplyToCompletionsStartingWithPrefix()
  2886. - {
  2887. - // Arrange
  2888. - var documentDescriptors = new[]
  2889. - {
  2890. - TagHelperDescriptorBuilder.Create("CatchAllTagHelper", "TestAssembly")
  2891. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
  2892. - .Build(),
  2893. - TagHelperDescriptorBuilder.Create("LiTagHelper", "TestAssembly")
  2894. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("li"))
  2895. - .Build(),
  2896. - };
  2897. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  2898. - {
  2899. - ["th:li"] = new HashSet<TagHelperDescriptor> { documentDescriptors[1], documentDescriptors[0] },
  2900. - ["li"] = new HashSet<TagHelperDescriptor>(),
  2901. - });
  2902. -
  2903. - var existingCompletions = new[] { "li" };
  2904. - var completionContext = BuildElementCompletionContext(
  2905. - documentDescriptors,
  2906. - existingCompletions,
  2907. - containingTagName: "ul",
  2908. - tagHelperPrefix: "th:");
  2909. - var service = CreateTagHelperCompletionFactsService();
  2910. -
  2911. - // Act
  2912. - var completions = service.GetElementCompletions(completionContext);
  2913. -
  2914. - // Assert
  2915. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2916. - }
  2917. -
  2918. - [Fact]
  2919. - public void GetElementCompletions_TagHelperPrefixIsPrependedToTagHelperCompletions()
  2920. - {
  2921. - // Arrange
  2922. - var documentDescriptors = new[]
  2923. - {
  2924. - TagHelperDescriptorBuilder.Create("SuperLiTagHelper", "TestAssembly")
  2925. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("superli"))
  2926. - .Build(),
  2927. - TagHelperDescriptorBuilder.Create("LiTagHelper", "TestAssembly")
  2928. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("li"))
  2929. - .Build(),
  2930. - };
  2931. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  2932. - {
  2933. - ["th:superli"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] },
  2934. - ["th:li"] = new HashSet<TagHelperDescriptor> { documentDescriptors[1] },
  2935. - ["li"] = new HashSet<TagHelperDescriptor>(),
  2936. - });
  2937. -
  2938. - var existingCompletions = new[] { "li" };
  2939. - var completionContext = BuildElementCompletionContext(
  2940. - documentDescriptors,
  2941. - existingCompletions,
  2942. - containingTagName: "ul",
  2943. - tagHelperPrefix: "th:");
  2944. - var service = CreateTagHelperCompletionFactsService();
  2945. -
  2946. - // Act
  2947. - var completions = service.GetElementCompletions(completionContext);
  2948. -
  2949. - // Assert
  2950. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2951. - }
  2952. -
  2953. - [Fact]
  2954. - public void GetElementCompletions_CatchAllsApplyToOnlyTagHelperCompletions()
  2955. - {
  2956. - // Arrange
  2957. - var documentDescriptors = new[]
  2958. - {
  2959. - TagHelperDescriptorBuilder.Create("SuperLiTagHelper", "TestAssembly")
  2960. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("superli"))
  2961. - .Build(),
  2962. - TagHelperDescriptorBuilder.Create("CatchAll", "TestAssembly")
  2963. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
  2964. - .Build(),
  2965. - };
  2966. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  2967. - {
  2968. - ["superli"] = new HashSet<TagHelperDescriptor>() { documentDescriptors[0], documentDescriptors[1] },
  2969. - ["li"] = new HashSet<TagHelperDescriptor>(),
  2970. - });
  2971. -
  2972. - var existingCompletions = new[] { "li" };
  2973. - var completionContext = BuildElementCompletionContext(
  2974. - documentDescriptors,
  2975. - existingCompletions,
  2976. - containingTagName: "ul");
  2977. - var service = CreateTagHelperCompletionFactsService();
  2978. -
  2979. - // Act
  2980. - var completions = service.GetElementCompletions(completionContext);
  2981. -
  2982. - // Assert
  2983. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  2984. - }
  2985. -
  2986. - [Fact]
  2987. - public void GetElementCompletions_CatchAllsApplyToNonTagHelperCompletionsIfStartsWithTagHelperPrefix()
  2988. - {
  2989. - // Arrange
  2990. - var documentDescriptors = new[]
  2991. - {
  2992. - TagHelperDescriptorBuilder.Create("SuperLiTagHelper", "TestAssembly")
  2993. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("superli"))
  2994. - .Build(),
  2995. - TagHelperDescriptorBuilder.Create("CatchAll", "TestAssembly")
  2996. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
  2997. - .Build(),
  2998. - };
  2999. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  3000. - {
  3001. - ["th:superli"] = new HashSet<TagHelperDescriptor>() { documentDescriptors[0], documentDescriptors[1] },
  3002. - ["th:li"] = new HashSet<TagHelperDescriptor>() { documentDescriptors[1] },
  3003. - });
  3004. -
  3005. - var existingCompletions = new[] { "th:li" };
  3006. - var completionContext = BuildElementCompletionContext(
  3007. - documentDescriptors,
  3008. - existingCompletions,
  3009. - containingTagName: "ul",
  3010. - tagHelperPrefix: "th:");
  3011. - var service = CreateTagHelperCompletionFactsService();
  3012. -
  3013. - // Act
  3014. - var completions = service.GetElementCompletions(completionContext);
  3015. -
  3016. - // Assert
  3017. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  3018. - }
  3019. -
  3020. - [Fact]
  3021. - public void GetElementCompletions_AllowsMultiTargetingTagHelpers()
  3022. - {
  3023. - // Arrange
  3024. - var documentDescriptors = new[]
  3025. - {
  3026. - TagHelperDescriptorBuilder.Create("BoldTagHelper1", "TestAssembly")
  3027. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong"))
  3028. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("b"))
  3029. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("bold"))
  3030. - .Build(),
  3031. - TagHelperDescriptorBuilder.Create("BoldTagHelper2", "TestAssembly")
  3032. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong"))
  3033. - .Build(),
  3034. - };
  3035. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  3036. - {
  3037. - ["strong"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0], documentDescriptors[1] },
  3038. - ["b"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] },
  3039. - ["bold"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] },
  3040. - });
  3041. -
  3042. - var existingCompletions = new[] { "strong", "b", "bold" };
  3043. - var completionContext = BuildElementCompletionContext(
  3044. - documentDescriptors,
  3045. - existingCompletions,
  3046. - containingTagName: "ul");
  3047. - var service = CreateTagHelperCompletionFactsService();
  3048. -
  3049. - // Act
  3050. - var completions = service.GetElementCompletions(completionContext);
  3051. -
  3052. - // Assert
  3053. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  3054. - }
  3055. -
  3056. - [Fact]
  3057. - public void GetElementCompletions_CombinesDescriptorsOnExistingCompletions()
  3058. - {
  3059. - // Arrange
  3060. - var documentDescriptors = new[]
  3061. - {
  3062. - TagHelperDescriptorBuilder.Create("LiTagHelper1", "TestAssembly")
  3063. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("li"))
  3064. - .Build(),
  3065. - TagHelperDescriptorBuilder.Create("LiTagHelper2", "TestAssembly")
  3066. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("li"))
  3067. - .Build(),
  3068. - };
  3069. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  3070. - {
  3071. - ["li"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0], documentDescriptors[1] },
  3072. - });
  3073. -
  3074. - var existingCompletions = new[] { "li" };
  3075. - var completionContext = BuildElementCompletionContext(documentDescriptors, existingCompletions, containingTagName: "ul");
  3076. - var service = CreateTagHelperCompletionFactsService();
  3077. -
  3078. - // Act
  3079. - var completions = service.GetElementCompletions(completionContext);
  3080. -
  3081. - // Assert
  3082. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  3083. - }
  3084. -
  3085. - [Fact]
  3086. - public void GetElementCompletions_NewCompletionsForSchemaTagsNotInExistingCompletionsAreIgnored()
  3087. - {
  3088. - // Arrange
  3089. - var documentDescriptors = new[]
  3090. - {
  3091. - TagHelperDescriptorBuilder.Create("SuperLiTagHelper", "TestAssembly")
  3092. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("superli"))
  3093. - .Build(),
  3094. - TagHelperDescriptorBuilder.Create("LiTagHelper", "TestAssembly")
  3095. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("li"))
  3096. - .TagOutputHint("strong")
  3097. - .Build(),
  3098. - TagHelperDescriptorBuilder.Create("DivTagHelper", "TestAssembly")
  3099. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
  3100. - .Build(),
  3101. - };
  3102. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  3103. - {
  3104. - ["li"] = new HashSet<TagHelperDescriptor> { documentDescriptors[1] },
  3105. - ["superli"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] },
  3106. - });
  3107. -
  3108. - var existingCompletions = new[] { "li" };
  3109. - var completionContext = BuildElementCompletionContext(documentDescriptors, existingCompletions, containingTagName: "ul");
  3110. - var service = CreateTagHelperCompletionFactsService();
  3111. -
  3112. - // Act
  3113. - var completions = service.GetElementCompletions(completionContext);
  3114. -
  3115. - // Assert
  3116. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  3117. - }
  3118. -
  3119. - [Fact]
  3120. - public void GetElementCompletions_OutputHintIsCrossReferencedWithExistingCompletions()
  3121. - {
  3122. - // Arrange
  3123. - var documentDescriptors = new[]
  3124. - {
  3125. - TagHelperDescriptorBuilder.Create("DivTagHelper", "TestAssembly")
  3126. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
  3127. - .TagOutputHint("li")
  3128. - .Build(),
  3129. - TagHelperDescriptorBuilder.Create("LiTagHelper", "TestAssembly")
  3130. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("li"))
  3131. - .TagOutputHint("strong")
  3132. - .Build(),
  3133. - };
  3134. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  3135. - {
  3136. - ["div"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] },
  3137. - ["li"] = new HashSet<TagHelperDescriptor> { documentDescriptors[1] },
  3138. - });
  3139. -
  3140. - var existingCompletions = new[] { "li" };
  3141. - var completionContext = BuildElementCompletionContext(documentDescriptors, existingCompletions, containingTagName: "ul");
  3142. - var service = CreateTagHelperCompletionFactsService();
  3143. -
  3144. - // Act
  3145. - var completions = service.GetElementCompletions(completionContext);
  3146. -
  3147. - // Assert
  3148. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  3149. - }
  3150. -
  3151. - [Fact]
  3152. - public void GetElementCompletions_EnsuresDescriptorsHaveSatisfiedParent()
  3153. - {
  3154. - // Arrange
  3155. - var documentDescriptors = new[]
  3156. - {
  3157. - TagHelperDescriptorBuilder.Create("LiTagHelper1", "TestAssembly")
  3158. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("li"))
  3159. - .Build(),
  3160. - TagHelperDescriptorBuilder.Create("LiTagHelper2", "TestAssembly")
  3161. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("li").RequireParentTag("ol"))
  3162. - .Build(),
  3163. - };
  3164. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  3165. - {
  3166. - ["li"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] },
  3167. - });
  3168. -
  3169. - var existingCompletions = new[] { "li" };
  3170. - var completionContext = BuildElementCompletionContext(documentDescriptors, existingCompletions, containingTagName: "ul");
  3171. - var service = CreateTagHelperCompletionFactsService();
  3172. -
  3173. - // Act
  3174. - var completions = service.GetElementCompletions(completionContext);
  3175. -
  3176. - // Assert
  3177. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  3178. - }
  3179. -
  3180. - [Fact]
  3181. - public void GetElementCompletions_AllowedChildrenAreIgnoredWhenAtRoot()
  3182. - {
  3183. - // Arrange
  3184. - var documentDescriptors = new[]
  3185. - {
  3186. - TagHelperDescriptorBuilder.Create("CatchAll", "TestAssembly")
  3187. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
  3188. - .AllowChildTag("b")
  3189. - .AllowChildTag("bold")
  3190. - .AllowChildTag("div")
  3191. - .Build(),
  3192. - };
  3193. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>());
  3194. -
  3195. - var existingCompletions = Enumerable.Empty<string>();
  3196. - var completionContext = BuildElementCompletionContext(
  3197. - documentDescriptors,
  3198. - existingCompletions,
  3199. - containingTagName: null,
  3200. - containingParentTagName: null);
  3201. - var service = CreateTagHelperCompletionFactsService();
  3202. -
  3203. - // Act
  3204. - var completions = service.GetElementCompletions(completionContext);
  3205. -
  3206. - // Assert
  3207. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  3208. - }
  3209. -
  3210. - [Fact]
  3211. - public void GetElementCompletions_DoesNotReturnExistingCompletionsWhenAllowedChildren()
  3212. - {
  3213. - // Arrange
  3214. - var documentDescriptors = new[]
  3215. - {
  3216. - TagHelperDescriptorBuilder.Create("BoldParent", "TestAssembly")
  3217. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
  3218. - .AllowChildTag("b")
  3219. - .AllowChildTag("bold")
  3220. - .AllowChildTag("div")
  3221. - .Build(),
  3222. - };
  3223. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  3224. - {
  3225. - ["b"] = new HashSet<TagHelperDescriptor>(),
  3226. - ["bold"] = new HashSet<TagHelperDescriptor>(),
  3227. - ["div"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] }
  3228. - });
  3229. -
  3230. - var existingCompletions = new[] { "p", "em" };
  3231. - var completionContext = BuildElementCompletionContext(documentDescriptors, existingCompletions, containingTagName: "div");
  3232. - var service = CreateTagHelperCompletionFactsService();
  3233. -
  3234. - // Act
  3235. - var completions = service.GetElementCompletions(completionContext);
  3236. -
  3237. - // Assert
  3238. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  3239. - }
  3240. -
  3241. - [Fact]
  3242. - public void GetElementCompletions_CapturesAllAllowedChildTagsFromParentTagHelpers_NoneTagHelpers()
  3243. - {
  3244. - // Arrange
  3245. - var documentDescriptors = new[]
  3246. - {
  3247. - TagHelperDescriptorBuilder.Create("BoldParent", "TestAssembly")
  3248. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
  3249. - .AllowChildTag("b")
  3250. - .AllowChildTag("bold")
  3251. - .Build(),
  3252. - };
  3253. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  3254. - {
  3255. - ["b"] = new HashSet<TagHelperDescriptor>(),
  3256. - ["bold"] = new HashSet<TagHelperDescriptor>(),
  3257. - });
  3258. -
  3259. - var completionContext = BuildElementCompletionContext(documentDescriptors, Enumerable.Empty<string>(), containingTagName: "div");
  3260. - var service = CreateTagHelperCompletionFactsService();
  3261. -
  3262. - // Act
  3263. - var completions = service.GetElementCompletions(completionContext);
  3264. -
  3265. - // Assert
  3266. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  3267. - }
  3268. -
  3269. - [Fact]
  3270. - public void GetElementCompletions_CapturesAllAllowedChildTagsFromParentTagHelpers_SomeTagHelpers()
  3271. - {
  3272. - // Arrange
  3273. - var documentDescriptors = new[]
  3274. - {
  3275. - TagHelperDescriptorBuilder.Create("BoldParent", "TestAssembly")
  3276. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
  3277. - .AllowChildTag("b")
  3278. - .AllowChildTag("bold")
  3279. - .AllowChildTag("div")
  3280. - .Build(),
  3281. - };
  3282. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  3283. - {
  3284. - ["b"] = new HashSet<TagHelperDescriptor>(),
  3285. - ["bold"] = new HashSet<TagHelperDescriptor>(),
  3286. - ["div"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] }
  3287. - });
  3288. -
  3289. - var completionContext = BuildElementCompletionContext(documentDescriptors, Enumerable.Empty<string>(), containingTagName: "div");
  3290. - var service = CreateTagHelperCompletionFactsService();
  3291. -
  3292. - // Act
  3293. - var completions = service.GetElementCompletions(completionContext);
  3294. -
  3295. - // Assert
  3296. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  3297. - }
  3298. -
  3299. - [Fact]
  3300. - public void GetElementCompletions_CapturesAllAllowedChildTagsFromParentTagHelpers_AllTagHelpers()
  3301. - {
  3302. - // Arrange
  3303. - var documentDescriptors = new[]
  3304. - {
  3305. - TagHelperDescriptorBuilder.Create("BoldParentCatchAll", "TestAssembly")
  3306. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
  3307. - .AllowChildTag("strong")
  3308. - .AllowChildTag("div")
  3309. - .AllowChildTag("b")
  3310. - .Build(),
  3311. - TagHelperDescriptorBuilder.Create("BoldParent", "TestAssembly")
  3312. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
  3313. - .AllowChildTag("b")
  3314. - .AllowChildTag("bold")
  3315. - .Build(),
  3316. - };
  3317. - var expectedCompletions = ElementCompletionResult.Create(new Dictionary<string, HashSet<TagHelperDescriptor>>()
  3318. - {
  3319. - ["strong"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] },
  3320. - ["b"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] },
  3321. - ["bold"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0] },
  3322. - ["div"] = new HashSet<TagHelperDescriptor> { documentDescriptors[0], documentDescriptors[1] },
  3323. - });
  3324. -
  3325. - var completionContext = BuildElementCompletionContext(documentDescriptors, Enumerable.Empty<string>(), containingTagName: "div");
  3326. - var service = CreateTagHelperCompletionFactsService();
  3327. -
  3328. - // Act
  3329. - var completions = service.GetElementCompletions(completionContext);
  3330. -
  3331. - // Assert
  3332. - AssertCompletionsAreEquivalent(expectedCompletions, completions);
  3333. - }
  3334. -
  3335. - private static DefaultTagHelperCompletionService CreateTagHelperCompletionFactsService()
  3336. - {
  3337. - var tagHelperFactService = new DefaultTagHelperFactsService();
  3338. - var completionFactService = new DefaultTagHelperCompletionService(tagHelperFactService);
  3339. -
  3340. - return completionFactService;
  3341. - }
  3342. -
  3343. - private static void AssertCompletionsAreEquivalent(ElementCompletionResult expected, ElementCompletionResult actual)
  3344. - {
  3345. - Assert.Equal(expected.Completions.Count, actual.Completions.Count);
  3346. -
  3347. - foreach (var expectedCompletion in expected.Completions)
  3348. - {
  3349. - var actualValue = actual.Completions[expectedCompletion.Key];
  3350. - Assert.NotNull(actualValue);
  3351. - Assert.Equal(expectedCompletion.Value, actualValue, TagHelperDescriptorComparer.CaseSensitive);
  3352. - }
  3353. - }
  3354. -
  3355. - private static void AssertCompletionsAreEquivalent(AttributeCompletionResult expected, AttributeCompletionResult actual)
  3356. - {
  3357. - Assert.Equal(expected.Completions.Count, actual.Completions.Count);
  3358. -
  3359. - foreach (var expectedCompletion in expected.Completions)
  3360. - {
  3361. - var actualValue = actual.Completions[expectedCompletion.Key];
  3362. - Assert.NotNull(actualValue);
  3363. - Assert.Equal(expectedCompletion.Value, actualValue, BoundAttributeDescriptorComparer.CaseSensitive);
  3364. - }
  3365. - }
  3366. -
  3367. - private static ElementCompletionContext BuildElementCompletionContext(
  3368. - IEnumerable<TagHelperDescriptor> descriptors,
  3369. - IEnumerable<string> existingCompletions,
  3370. - string containingTagName,
  3371. - string containingParentTagName = "body",
  3372. - string tagHelperPrefix = "")
  3373. - {
  3374. - var documentContext = TagHelperDocumentContext.Create(tagHelperPrefix, descriptors);
  3375. - var completionContext = new ElementCompletionContext(
  3376. - documentContext,
  3377. - existingCompletions,
  3378. - containingTagName,
  3379. - attributes: Enumerable.Empty<KeyValuePair<string, string>>(),
  3380. - containingParentTagName: containingParentTagName,
  3381. - inHTMLSchema: (tag) => tag == "strong" || tag == "b" || tag == "bold" || tag == "li" || tag == "div");
  3382. -
  3383. - return completionContext;
  3384. - }
  3385. -
  3386. - private static AttributeCompletionContext BuildAttributeCompletionContext(
  3387. - IEnumerable<TagHelperDescriptor> descriptors,
  3388. - IEnumerable<string> existingCompletions,
  3389. - string currentTagName,
  3390. - IEnumerable<KeyValuePair<string, string>> attributes = null,
  3391. - string tagHelperPrefix = "")
  3392. - {
  3393. - attributes = attributes ?? Enumerable.Empty<KeyValuePair<string, string>>();
  3394. - var documentContext = TagHelperDocumentContext.Create(tagHelperPrefix, descriptors);
  3395. - var completionContext = new AttributeCompletionContext(
  3396. - documentContext,
  3397. - existingCompletions,
  3398. - currentTagName,
  3399. - attributes,
  3400. - currentParentTagName: "body",
  3401. - inHTMLSchema: (tag) => tag == "strong" || tag == "b" || tag == "bold" || tag == "li" || tag == "div");
  3402. -
  3403. - return completionContext;
  3404. - }
  3405. - }
  3406. -}
  3407. \ No newline at end of file
  3408. diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Legacy/DefaultTagHelperFactsServiceTest.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Legacy/DefaultTagHelperFactsServiceTest.cs
  3409. deleted file mode 100644
  3410. index f62597b32f2..00000000000
  3411. --- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Legacy/DefaultTagHelperFactsServiceTest.cs
  3412. +++ /dev/null
  3413. @@ -1,388 +0,0 @@
  3414. -// Copyright (c) .NET Foundation. All rights reserved.
  3415. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  3416. -
  3417. -using Microsoft.AspNetCore.Razor.Language;
  3418. -using System.Collections.Generic;
  3419. -using System.Linq;
  3420. -using Xunit;
  3421. -
  3422. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  3423. -{
  3424. - public class DefaultTagHelperFactsServiceTest
  3425. - {
  3426. - // Purposefully not thoroughly testing DefaultTagHelperFactsService.GetTagHelperBinding because it's a pass through
  3427. - // into TagHelperDescriptorProvider.GetTagHelperBinding.
  3428. -
  3429. - [Fact]
  3430. - public void GetTagHelperBinding_DoesNotAllowOptOutCharacterPrefix()
  3431. - {
  3432. - // Arrange
  3433. - var documentDescriptors = new[]
  3434. - {
  3435. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3436. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
  3437. - .Build()
  3438. - };
  3439. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3440. - var service = new DefaultTagHelperFactsService();
  3441. -
  3442. - // Act
  3443. - var binding = service.GetTagHelperBinding(documentContext, "!a", Enumerable.Empty<KeyValuePair<string, string>>(), parentTag: null);
  3444. -
  3445. - // Assert
  3446. - Assert.Null(binding);
  3447. - }
  3448. -
  3449. - [Fact]
  3450. - public void GetTagHelperBinding_WorksAsExpected()
  3451. - {
  3452. - // Arrange
  3453. - var documentDescriptors = new[]
  3454. - {
  3455. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3456. - .TagMatchingRuleDescriptor(rule =>
  3457. - rule
  3458. - .RequireTagName("a")
  3459. - .RequireAttributeDescriptor(attribute => attribute.Name("asp-for")))
  3460. - .BoundAttributeDescriptor(attribute =>
  3461. - attribute
  3462. - .Name("asp-for")
  3463. - .TypeName(typeof(string).FullName)
  3464. - .PropertyName("AspFor"))
  3465. - .BoundAttributeDescriptor(attribute =>
  3466. - attribute
  3467. - .Name("asp-route")
  3468. - .TypeName(typeof(IDictionary<string, string>).Namespace + "IDictionary<string, string>")
  3469. - .PropertyName("AspRoute")
  3470. - .AsDictionaryAttribute("asp-route-", typeof(string).FullName))
  3471. - .Build(),
  3472. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3473. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("input"))
  3474. - .BoundAttributeDescriptor(attribute =>
  3475. - attribute
  3476. - .Name("asp-for")
  3477. - .TypeName(typeof(string).FullName)
  3478. - .PropertyName("AspFor"))
  3479. - .Build(),
  3480. - };
  3481. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3482. - var service = new DefaultTagHelperFactsService();
  3483. - var attributes = new[]
  3484. - {
  3485. - new KeyValuePair<string, string>("asp-for", "Name")
  3486. - };
  3487. -
  3488. - // Act
  3489. - var binding = service.GetTagHelperBinding(documentContext, "a", attributes, parentTag: "p");
  3490. -
  3491. - // Assert
  3492. - var descriptor = Assert.Single(binding.Descriptors);
  3493. - Assert.Equal(documentDescriptors[0], descriptor, TagHelperDescriptorComparer.CaseSensitive);
  3494. - var boundRule = Assert.Single(binding.GetBoundRules(descriptor));
  3495. - Assert.Equal(documentDescriptors[0].TagMatchingRules.First(), boundRule, TagMatchingRuleDescriptorComparer.CaseSensitive);
  3496. - }
  3497. -
  3498. - [Fact]
  3499. - public void GetBoundTagHelperAttributes_MatchesPrefixedAttributeName()
  3500. - {
  3501. - // Arrange
  3502. - var documentDescriptors = new[]
  3503. - {
  3504. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3505. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("a"))
  3506. - .BoundAttributeDescriptor(attribute =>
  3507. - attribute
  3508. - .Name("asp-for")
  3509. - .TypeName(typeof(string).FullName)
  3510. - .PropertyName("AspFor"))
  3511. - .BoundAttributeDescriptor(attribute =>
  3512. - attribute
  3513. - .Name("asp-route")
  3514. - .TypeName(typeof(IDictionary<string, string>).Namespace + "IDictionary<string, string>")
  3515. - .PropertyName("AspRoute")
  3516. - .AsDictionaryAttribute("asp-route-", typeof(string).FullName))
  3517. - .Build()
  3518. - };
  3519. - var expectedAttributeDescriptors = new[]
  3520. - {
  3521. - documentDescriptors[0].BoundAttributes.Last()
  3522. - };
  3523. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3524. - var service = new DefaultTagHelperFactsService();
  3525. - var binding = service.GetTagHelperBinding(documentContext, "a", Enumerable.Empty<KeyValuePair<string, string>>(), parentTag: null);
  3526. -
  3527. - // Act
  3528. - var descriptors = service.GetBoundTagHelperAttributes(documentContext, "asp-route-something", binding);
  3529. -
  3530. - // Assert
  3531. - Assert.Equal(expectedAttributeDescriptors, descriptors, BoundAttributeDescriptorComparer.CaseSensitive);
  3532. - }
  3533. -
  3534. - [Fact]
  3535. - public void GetBoundTagHelperAttributes_MatchesAttributeName()
  3536. - {
  3537. - // Arrange
  3538. - var documentDescriptors = new[]
  3539. - {
  3540. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3541. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("input"))
  3542. - .BoundAttributeDescriptor(attribute =>
  3543. - attribute
  3544. - .Name("asp-for")
  3545. - .TypeName(typeof(string).FullName)
  3546. - .PropertyName("AspFor"))
  3547. - .BoundAttributeDescriptor(attribute =>
  3548. - attribute
  3549. - .Name("asp-extra")
  3550. - .TypeName(typeof(string).FullName)
  3551. - .PropertyName("AspExtra"))
  3552. - .Build()
  3553. - };
  3554. - var expectedAttributeDescriptors = new[]
  3555. - {
  3556. - documentDescriptors[0].BoundAttributes.First()
  3557. - };
  3558. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3559. - var service = new DefaultTagHelperFactsService();
  3560. - var binding = service.GetTagHelperBinding(documentContext, "input", Enumerable.Empty<KeyValuePair<string, string>>(), parentTag: null);
  3561. -
  3562. - // Act
  3563. - var descriptors = service.GetBoundTagHelperAttributes(documentContext, "asp-for", binding);
  3564. -
  3565. - // Assert
  3566. - Assert.Equal(expectedAttributeDescriptors, descriptors, BoundAttributeDescriptorComparer.CaseSensitive);
  3567. - }
  3568. -
  3569. - [Fact]
  3570. - public void GetTagHelpersGivenTag_DoesNotAllowOptOutCharacterPrefix()
  3571. - {
  3572. - // Arrange
  3573. - var documentDescriptors = new[]
  3574. - {
  3575. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3576. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
  3577. - .Build()
  3578. - };
  3579. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3580. - var service = new DefaultTagHelperFactsService();
  3581. -
  3582. - // Act
  3583. - var descriptors = service.GetTagHelpersGivenTag(documentContext, "!strong", parentTag: null);
  3584. -
  3585. - // Assert
  3586. - Assert.Empty(descriptors);
  3587. - }
  3588. -
  3589. - [Fact]
  3590. - public void GetTagHelpersGivenTag_RequiresTagName()
  3591. - {
  3592. - // Arrange
  3593. - var documentDescriptors = new[]
  3594. - {
  3595. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3596. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong"))
  3597. - .Build()
  3598. - };
  3599. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3600. - var service = new DefaultTagHelperFactsService();
  3601. -
  3602. - // Act
  3603. - var descriptors = service.GetTagHelpersGivenTag(documentContext, "strong", "p");
  3604. -
  3605. - // Assert
  3606. - Assert.Equal(documentDescriptors, descriptors, TagHelperDescriptorComparer.CaseSensitive);
  3607. - }
  3608. -
  3609. - [Fact]
  3610. - public void GetTagHelpersGivenTag_RestrictsTagHelpersBasedOnTagName()
  3611. - {
  3612. - // Arrange
  3613. - var expectedDescriptors = new[]
  3614. - {
  3615. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3616. - .TagMatchingRuleDescriptor(
  3617. - rule => rule
  3618. - .RequireTagName("a")
  3619. - .RequireParentTag("div"))
  3620. - .Build()
  3621. - };
  3622. - var documentDescriptors = new[]
  3623. - {
  3624. - expectedDescriptors[0],
  3625. - TagHelperDescriptorBuilder.Create("TestType2", "TestAssembly")
  3626. - .TagMatchingRuleDescriptor(
  3627. - rule => rule
  3628. - .RequireTagName("strong")
  3629. - .RequireParentTag("div"))
  3630. - .Build()
  3631. - };
  3632. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3633. - var service = new DefaultTagHelperFactsService();
  3634. -
  3635. - // Act
  3636. - var descriptors = service.GetTagHelpersGivenTag(documentContext, "a", "div");
  3637. -
  3638. - // Assert
  3639. - Assert.Equal(expectedDescriptors, descriptors, TagHelperDescriptorComparer.CaseSensitive);
  3640. - }
  3641. -
  3642. - [Fact]
  3643. - public void GetTagHelpersGivenTag_RestrictsTagHelpersBasedOnTagHelperPrefix()
  3644. - {
  3645. - // Arrange
  3646. - var expectedDescriptors = new[]
  3647. - {
  3648. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3649. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong"))
  3650. - .Build()
  3651. - };
  3652. - var documentDescriptors = new[]
  3653. - {
  3654. - expectedDescriptors[0],
  3655. - TagHelperDescriptorBuilder.Create("TestType2", "TestAssembly")
  3656. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("thstrong"))
  3657. - .Build()
  3658. - };
  3659. - var documentContext = TagHelperDocumentContext.Create("th", documentDescriptors);
  3660. - var service = new DefaultTagHelperFactsService();
  3661. -
  3662. - // Act
  3663. - var descriptors = service.GetTagHelpersGivenTag(documentContext, "thstrong", "div");
  3664. -
  3665. - // Assert
  3666. - Assert.Equal(expectedDescriptors, descriptors, TagHelperDescriptorComparer.CaseSensitive);
  3667. - }
  3668. -
  3669. - [Fact]
  3670. - public void GetTagHelpersGivenTag_RestrictsTagHelpersBasedOnParent()
  3671. - {
  3672. - // Arrange
  3673. - var expectedDescriptors = new[]
  3674. - {
  3675. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3676. - .TagMatchingRuleDescriptor(
  3677. - rule => rule
  3678. - .RequireTagName("strong")
  3679. - .RequireParentTag("div"))
  3680. - .Build()
  3681. - };
  3682. - var documentDescriptors = new[]
  3683. - {
  3684. - expectedDescriptors[0],
  3685. - TagHelperDescriptorBuilder.Create("TestType2", "TestAssembly")
  3686. - .TagMatchingRuleDescriptor(
  3687. - rule => rule
  3688. - .RequireTagName("strong")
  3689. - .RequireParentTag("p"))
  3690. - .Build()
  3691. - };
  3692. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3693. - var service = new DefaultTagHelperFactsService();
  3694. -
  3695. - // Act
  3696. - var descriptors = service.GetTagHelpersGivenTag(documentContext, "strong", "div");
  3697. -
  3698. - // Assert
  3699. - Assert.Equal(expectedDescriptors, descriptors, TagHelperDescriptorComparer.CaseSensitive);
  3700. - }
  3701. -
  3702. - [Fact]
  3703. - public void GetTagHelpersGivenParent_AllowsRootParentTag()
  3704. - {
  3705. - // Arrange
  3706. - var documentDescriptors = new[]
  3707. - {
  3708. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3709. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
  3710. - .Build()
  3711. - };
  3712. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3713. - var service = new DefaultTagHelperFactsService();
  3714. -
  3715. - // Act
  3716. - var descriptors = service.GetTagHelpersGivenParent(documentContext, parentTag: null /* root */);
  3717. -
  3718. - // Assert
  3719. - Assert.Equal(documentDescriptors, descriptors, TagHelperDescriptorComparer.CaseSensitive);
  3720. - }
  3721. -
  3722. - [Fact]
  3723. - public void GetTagHelpersGivenParent_AllowsRootParentTagForParentRestrictedTagHelperDescriptors()
  3724. - {
  3725. - // Arrange
  3726. - var documentDescriptors = new[]
  3727. - {
  3728. - TagHelperDescriptorBuilder.Create("DivTagHelper", "TestAssembly")
  3729. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
  3730. - .Build(),
  3731. - TagHelperDescriptorBuilder.Create("PTagHelper", "TestAssembly")
  3732. - .TagMatchingRuleDescriptor(rule => rule
  3733. - .RequireTagName("p")
  3734. - .RequireParentTag("body"))
  3735. - .Build()
  3736. - };
  3737. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3738. - var service = new DefaultTagHelperFactsService();
  3739. -
  3740. - // Act
  3741. - var descriptors = service.GetTagHelpersGivenParent(documentContext, parentTag: null /* root */);
  3742. -
  3743. - // Assert
  3744. - var descriptor = Assert.Single(descriptors);
  3745. - Assert.Equal(documentDescriptors[0], descriptor, TagHelperDescriptorComparer.CaseSensitive);
  3746. - }
  3747. -
  3748. - [Fact]
  3749. - public void GetTagHelpersGivenParent_AllowsUnspecifiedParentTagHelpers()
  3750. - {
  3751. - // Arrange
  3752. - var documentDescriptors = new[]
  3753. - {
  3754. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3755. - .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
  3756. - .Build()
  3757. - };
  3758. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3759. - var service = new DefaultTagHelperFactsService();
  3760. -
  3761. - // Act
  3762. - var descriptors = service.GetTagHelpersGivenParent(documentContext, "p");
  3763. -
  3764. - // Assert
  3765. - Assert.Equal(documentDescriptors, descriptors, TagHelperDescriptorComparer.CaseSensitive);
  3766. - }
  3767. -
  3768. - [Fact]
  3769. - public void GetTagHelpersGivenParent_RestrictsTagHelpersBasedOnParent()
  3770. - {
  3771. - // Arrange
  3772. - var expectedDescriptors = new[]
  3773. - {
  3774. - TagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
  3775. - .TagMatchingRuleDescriptor(
  3776. - rule => rule
  3777. - .RequireTagName("p")
  3778. - .RequireParentTag("div"))
  3779. - .Build()
  3780. - };
  3781. - var documentDescriptors = new[]
  3782. - {
  3783. - expectedDescriptors[0],
  3784. - TagHelperDescriptorBuilder.Create("TestType2", "TestAssembly")
  3785. - .TagMatchingRuleDescriptor(
  3786. - rule => rule
  3787. - .RequireTagName("strong")
  3788. - .RequireParentTag("p"))
  3789. - .Build()
  3790. - };
  3791. - var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
  3792. - var service = new DefaultTagHelperFactsService();
  3793. -
  3794. - // Act
  3795. - var descriptors = service.GetTagHelpersGivenParent(documentContext, "div");
  3796. -
  3797. - // Assert
  3798. - Assert.Equal(expectedDescriptors, descriptors, TagHelperDescriptorComparer.CaseSensitive);
  3799. - }
  3800. - }
  3801. -}
  3802. \ No newline at end of file
  3803. diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Legacy/RazorEditorParserTest.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Legacy/RazorEditorParserTest.cs
  3804. deleted file mode 100644
  3805. index 0f6e3e32e91..00000000000
  3806. --- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Legacy/RazorEditorParserTest.cs
  3807. +++ /dev/null
  3808. @@ -1,1345 +0,0 @@
  3809. -// Copyright (c) .NET Foundation. All rights reserved.
  3810. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  3811. -
  3812. -using System;
  3813. -using System.Collections.Generic;
  3814. -using System.Diagnostics;
  3815. -using System.Threading;
  3816. -using Microsoft.AspNetCore.Mvc.Razor.Extensions;
  3817. -using Microsoft.AspNetCore.Razor.Language;
  3818. -using Microsoft.AspNetCore.Razor.Language.Legacy;
  3819. -using Microsoft.VisualStudio.Text;
  3820. -using Xunit;
  3821. -
  3822. -namespace Microsoft.VisualStudio.LanguageServices.Razor
  3823. -{
  3824. - public class RazorEditorParserTest
  3825. - {
  3826. - private static readonly TestFile SimpleCSHTMLDocument = TestFile.Create("TestFiles/DesignTime/Simple.cshtml", typeof(RazorEditorParserTest));
  3827. - private static readonly TestFile SimpleCSHTMLDocumentGenerated = TestFile.Create("TestFiles/DesignTime/Simple.txt", typeof(RazorEditorParserTest));
  3828. - private const string TestLinePragmaFileName = "C:\\This\\Path\\Is\\Just\\For\\Line\\Pragmas.cshtml";
  3829. -
  3830. - public static TheoryData TagHelperPartialParseRejectData
  3831. - {
  3832. - get
  3833. - {
  3834. - return new TheoryData<TestEdit>
  3835. - {
  3836. - CreateInsertionChange("<p></p>", 2, " "),
  3837. - CreateInsertionChange("<p></p>", 6, " "),
  3838. - CreateInsertionChange("<p some-attr></p>", 12, " "),
  3839. - CreateInsertionChange("<p some-attr></p>", 12, "ibute"),
  3840. - CreateInsertionChange("<p some-attr></p>", 2, " before"),
  3841. - };
  3842. - }
  3843. - }
  3844. -
  3845. - [Theory]
  3846. - [MemberData(nameof(TagHelperPartialParseRejectData))]
  3847. - public void TagHelperTagBodiesRejectPartialChanges(object editObject)
  3848. - {
  3849. - // Arrange
  3850. - var edit = (TestEdit)editObject;
  3851. - var builder = TagHelperDescriptorBuilder.Create("PTagHelper", "TestAssembly");
  3852. - builder.SetTypeName("PTagHelper");
  3853. - builder.TagMatchingRule(rule => rule.TagName = "p");
  3854. - var descriptors = new[]
  3855. - {
  3856. - builder.Build()
  3857. - };
  3858. -
  3859. - var parser = new RazorEditorParser(CreateTemplateEngine(@"C:\This\Is\A\Test\Path"), @"C:\This\Is\A\Test\Path");
  3860. -
  3861. - using (var manager = new TestParserManager(parser))
  3862. - {
  3863. - manager.InitializeWithDocument(edit.OldSnapshot);
  3864. -
  3865. - // Act
  3866. - var result = manager.CheckForStructureChangesAndWait(edit);
  3867. -
  3868. - // Assert
  3869. - Assert.Equal(PartialParseResult.Rejected, result);
  3870. - Assert.Equal(2, manager.ParseCount);
  3871. - }
  3872. - }
  3873. -
  3874. - public static TheoryData TagHelperAttributeAcceptData
  3875. - {
  3876. - get
  3877. - {
  3878. - var factory = new SpanFactory();
  3879. -
  3880. - // change, (Block)expectedDocument, partialParseResult
  3881. - return new TheoryData<TestEdit, PartialParseResult>
  3882. - {
  3883. - {
  3884. - CreateInsertionChange("<p str-attr='@DateTime'></p>", 22, "."),
  3885. - PartialParseResult.Accepted | PartialParseResult.Provisional
  3886. - },
  3887. - {
  3888. - CreateInsertionChange("<p obj-attr='DateTime'></p>", 21, "."),
  3889. - PartialParseResult.Accepted
  3890. - },
  3891. - {
  3892. - CreateInsertionChange("<p obj-attr='1 + DateTime'></p>", 25, "."),
  3893. - PartialParseResult.Accepted
  3894. - },
  3895. - {
  3896. - CreateInsertionChange("<p before-attr str-attr='@DateTime' after-attr></p>", 34, "."),
  3897. - PartialParseResult.Accepted | PartialParseResult.Provisional
  3898. - },
  3899. - {
  3900. - CreateInsertionChange("<p str-attr='before @DateTime after'></p>", 29, "."),
  3901. - PartialParseResult.Accepted | PartialParseResult.Provisional
  3902. - },
  3903. - };
  3904. - }
  3905. - }
  3906. -
  3907. - [Theory]
  3908. - [MemberData(nameof(TagHelperAttributeAcceptData))]
  3909. - public void TagHelperAttributesAreLocatedAndAcceptChangesCorrectly(object editObject, PartialParseResult partialParseResult)
  3910. - {
  3911. - // Arrange
  3912. - var edit = (TestEdit)editObject;
  3913. - var builder = TagHelperDescriptorBuilder.Create("PTagHelper", "Test");
  3914. - builder.SetTypeName("PTagHelper");
  3915. - builder.TagMatchingRule(rule => rule.TagName = "p");
  3916. - builder.BindAttribute(attribute =>
  3917. - {
  3918. - attribute.Name = "obj-attr";
  3919. - attribute.TypeName = typeof(object).FullName;
  3920. - attribute.SetPropertyName("ObjectAttribute");
  3921. - });
  3922. - builder.BindAttribute(attribute =>
  3923. - {
  3924. - attribute.Name = "str-attr";
  3925. - attribute.TypeName = typeof(string).FullName;
  3926. - attribute.SetPropertyName("StringAttribute");
  3927. - });
  3928. - var descriptors = new[] { builder.Build() };
  3929. -
  3930. - var parser = new RazorEditorParser(CreateTemplateEngine(@"C:\This\Is\A\Test\Path", descriptors), @"C:\This\Is\A\Test\Path");
  3931. -
  3932. - using (var manager = new TestParserManager(parser))
  3933. - {
  3934. - manager.InitializeWithDocument(edit.OldSnapshot);
  3935. -
  3936. - // Act
  3937. - var result = manager.CheckForStructureChangesAndWait(edit);
  3938. -
  3939. - // Assert
  3940. - Assert.Equal(partialParseResult, result);
  3941. - Assert.Equal(1, manager.ParseCount);
  3942. - }
  3943. - }
  3944. -
  3945. - [Fact]
  3946. - public void ConstructorRequiresNonNullPhysicalPath()
  3947. - {
  3948. - Assert.Throws<ArgumentException>("filePath", () => new RazorEditorParser(CreateTemplateEngine(), null));
  3949. - }
  3950. -
  3951. - [Fact]
  3952. - public void ConstructorRequiresNonEmptyPhysicalPath()
  3953. - {
  3954. - Assert.Throws<ArgumentException>("filePath", () => new RazorEditorParser(CreateTemplateEngine(), string.Empty));
  3955. - }
  3956. -
  3957. - [Theory]
  3958. - [InlineData(" ")]
  3959. - [InlineData("\r\n")]
  3960. - [InlineData("abcdefg")]
  3961. - [InlineData("\f\r\n abcd \t")]
  3962. - public void TreesAreDifferentReturnsFalseForAddedContent(string content)
  3963. - {
  3964. - // Arrange
  3965. - var factory = new SpanFactory();
  3966. - var blockFactory = new BlockFactory(factory);
  3967. - var original = new MarkupBlock(
  3968. - blockFactory.MarkupTagBlock("<p>"),
  3969. - blockFactory.TagHelperBlock(
  3970. - tagName: "div",
  3971. - tagMode: TagMode.StartTagAndEndTag,
  3972. - start: new SourceLocation(3, 0, 3),
  3973. - startTag: blockFactory.MarkupTagBlock("<div>"),
  3974. - children: new SyntaxTreeNode[]
  3975. - {
  3976. - factory.Markup($"{Environment.NewLine}{Environment.NewLine}")
  3977. - },
  3978. - endTag: blockFactory.MarkupTagBlock("</div>")),
  3979. - blockFactory.MarkupTagBlock("</p>"));
  3980. -
  3981. - factory.Reset();
  3982. -
  3983. - var modified = new MarkupBlock(
  3984. - blockFactory.MarkupTagBlock("<p>"),
  3985. - blockFactory.TagHelperBlock(
  3986. - tagName: "div",
  3987. - tagMode: TagMode.StartTagAndEndTag,
  3988. - start: new SourceLocation(3, 0, 3),
  3989. - startTag: blockFactory.MarkupTagBlock("<div>"),
  3990. - children: new SyntaxTreeNode[]
  3991. - {
  3992. - factory.Markup($"{Environment.NewLine}{content}{Environment.NewLine}")
  3993. - },
  3994. - endTag: blockFactory.MarkupTagBlock("</div>")),
  3995. - blockFactory.MarkupTagBlock("</p>"));
  3996. - original.LinkNodes();
  3997. - modified.LinkNodes();
  3998. -
  3999. - // Act
  4000. - var treesAreDifferent = RazorEditorParser.BackgroundParser.TreesAreDifferent(
  4001. - original,
  4002. - modified,
  4003. - new[]
  4004. - {
  4005. - new SourceChange(
  4006. - absoluteIndex: 8 + Environment.NewLine.Length,
  4007. - length: 0,
  4008. - newText: content)
  4009. - },
  4010. - CancellationToken.None);
  4011. -
  4012. - // Assert
  4013. - Assert.False(treesAreDifferent);
  4014. - }
  4015. -
  4016. - [Fact]
  4017. - public void TreesAreDifferentReturnsTrueIfTreeStructureIsDifferent()
  4018. - {
  4019. - var factory = new SpanFactory();
  4020. - var original = new MarkupBlock(
  4021. - factory.Markup("<p>"),
  4022. - new ExpressionBlock(
  4023. - factory.CodeTransition()),
  4024. - factory.Markup("</p>"));
  4025. - var modified = new MarkupBlock(
  4026. - factory.Markup("<p>"),
  4027. - new ExpressionBlock(
  4028. - factory.CodeTransition("@"),
  4029. - factory.Code("f")
  4030. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)),
  4031. - factory.Markup("</p>"));
  4032. - Assert.True(RazorEditorParser.BackgroundParser.TreesAreDifferent(
  4033. - original,
  4034. - modified,
  4035. - new[]
  4036. - {
  4037. - new SourceChange(absoluteIndex: 4, length: 0, newText: "f")
  4038. - },
  4039. - CancellationToken.None));
  4040. - }
  4041. -
  4042. - [Fact]
  4043. - public void TreesAreDifferentReturnsFalseIfTreeStructureIsSame()
  4044. - {
  4045. - var factory = new SpanFactory();
  4046. - var original = new MarkupBlock(
  4047. - factory.Markup("<p>"),
  4048. - new ExpressionBlock(
  4049. - factory.CodeTransition(),
  4050. - factory.Code("f")
  4051. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)),
  4052. - factory.Markup("</p>"));
  4053. - factory.Reset();
  4054. - var modified = new MarkupBlock(
  4055. - factory.Markup("<p>"),
  4056. - new ExpressionBlock(
  4057. - factory.CodeTransition(),
  4058. - factory.Code("foo")
  4059. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)),
  4060. - factory.Markup("</p>"));
  4061. - original.LinkNodes();
  4062. - modified.LinkNodes();
  4063. - Assert.False(RazorEditorParser.BackgroundParser.TreesAreDifferent(
  4064. - original,
  4065. - modified,
  4066. - new[]
  4067. - {
  4068. - new SourceChange(absoluteIndex: 5, length: 0, newText: "oo")
  4069. - },
  4070. - CancellationToken.None));
  4071. - }
  4072. -
  4073. - [Fact]
  4074. - public void CheckForStructureChangesStartsFullReparseIfChangeOverlapsMultipleSpans()
  4075. - {
  4076. - // Arrange
  4077. - using (var parser = new RazorEditorParser(CreateTemplateEngine(), TestLinePragmaFileName))
  4078. - {
  4079. - var original = new StringTextSnapshot("Foo @bar Baz");
  4080. - var changed = new StringTextSnapshot("Foo @bap Daz");
  4081. - var change = new SourceChange(7, 3, "p D");
  4082. -
  4083. - var parseComplete = new ManualResetEventSlim();
  4084. - var parseCount = 0;
  4085. - parser.DocumentParseComplete += (sender, args) =>
  4086. - {
  4087. - Interlocked.Increment(ref parseCount);
  4088. - parseComplete.Set();
  4089. - };
  4090. -
  4091. - Assert.Equal(PartialParseResult.Rejected, parser.CheckForStructureChanges(change, original));
  4092. - DoWithTimeoutIfNotDebugging(parseComplete.Wait); // Wait for the parse to finish
  4093. - parseComplete.Reset();
  4094. -
  4095. - // Act
  4096. - var result = parser.CheckForStructureChanges(change, original);
  4097. -
  4098. - // Assert
  4099. - Assert.Equal(PartialParseResult.Rejected, result);
  4100. - DoWithTimeoutIfNotDebugging(parseComplete.Wait);
  4101. - Assert.Equal(2, parseCount);
  4102. - }
  4103. - }
  4104. -
  4105. - [Fact]
  4106. - public void AwaitPeriodInsertionAcceptedProvisionally()
  4107. - {
  4108. - // Arrange
  4109. - var factory = new SpanFactory();
  4110. - var changed = new StringTextSnapshot("foo @await Html. baz");
  4111. - var old = new StringTextSnapshot("foo @await Html baz");
  4112. -
  4113. - // Act and Assert
  4114. - RunPartialParseTest(new TestEdit(15, 0, old, 1, changed, "."),
  4115. - new MarkupBlock(
  4116. - factory.Markup("foo "),
  4117. - new ExpressionBlock(
  4118. - factory.CodeTransition(),
  4119. - factory.Code("await Html.").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.WhiteSpace | AcceptedCharactersInternal.NonWhiteSpace)),
  4120. - factory.Markup(" baz")), additionalFlags: PartialParseResult.Provisional);
  4121. - }
  4122. -
  4123. - [Fact]
  4124. - public void ImplicitExpressionAcceptsInnerInsertionsInStatementBlock()
  4125. - {
  4126. - // Arrange
  4127. - var factory = new SpanFactory();
  4128. - var changed = new StringTextSnapshot("@{" + Environment.NewLine
  4129. - + " @DateTime..Now" + Environment.NewLine
  4130. - + "}");
  4131. - var old = new StringTextSnapshot("@{" + Environment.NewLine
  4132. - + " @DateTime.Now" + Environment.NewLine
  4133. - + "}");
  4134. -
  4135. - // Act and Assert
  4136. - RunPartialParseTest(new TestEdit(17, 0, old, 1, changed, "."),
  4137. - new MarkupBlock(
  4138. - factory.EmptyHtml(),
  4139. - new StatementBlock(
  4140. - factory.CodeTransition(),
  4141. - factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
  4142. - factory.Code(Environment.NewLine + " ")
  4143. - .AsStatement()
  4144. - .AutoCompleteWith(autoCompleteString: null),
  4145. - new ExpressionBlock(
  4146. - factory.CodeTransition(),
  4147. - factory.Code("DateTime..Now")
  4148. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  4149. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4150. - factory.Code(Environment.NewLine).AsStatement(),
  4151. - factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
  4152. - factory.EmptyHtml()));
  4153. - }
  4154. -
  4155. - [Fact]
  4156. - public void ImplicitExpressionAcceptsInnerInsertions()
  4157. - {
  4158. - // Arrange
  4159. - var factory = new SpanFactory();
  4160. - var changed = new StringTextSnapshot("foo @DateTime..Now baz");
  4161. - var old = new StringTextSnapshot("foo @DateTime.Now baz");
  4162. -
  4163. - // Act and Assert
  4164. - RunPartialParseTest(new TestEdit(13, 0, old, 1, changed, "."),
  4165. - new MarkupBlock(
  4166. - factory.Markup("foo "),
  4167. - new ExpressionBlock(
  4168. - factory.CodeTransition(),
  4169. - factory.Code("DateTime..Now").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4170. - factory.Markup(" baz")), additionalFlags: PartialParseResult.Provisional);
  4171. - }
  4172. -
  4173. - [Fact]
  4174. - public void ImplicitExpressionAcceptsWholeIdentifierReplacement()
  4175. - {
  4176. - // Arrange
  4177. - var factory = new SpanFactory();
  4178. - var old = new StringTextSnapshot("foo @date baz");
  4179. - var changed = new StringTextSnapshot("foo @DateTime baz");
  4180. -
  4181. - // Act and Assert
  4182. - RunPartialParseTest(new TestEdit(5, 4, old, 8, changed, "DateTime"),
  4183. - new MarkupBlock(
  4184. - factory.Markup("foo "),
  4185. - new ExpressionBlock(
  4186. - factory.CodeTransition(),
  4187. - factory.Code("DateTime").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4188. - factory.Markup(" baz")));
  4189. - }
  4190. -
  4191. - [Fact]
  4192. - public void ImplicitExpressionRejectsWholeIdentifierReplacementToKeyword()
  4193. - {
  4194. - // Arrange
  4195. - var parser = new RazorEditorParser(CreateTemplateEngine(@"C:\This\Is\A\Test\Path"), @"C:\This\Is\A\Test\Path");
  4196. -
  4197. - using (var manager = new TestParserManager(parser))
  4198. - {
  4199. - var old = new StringTextSnapshot("foo @date baz");
  4200. - var changed = new StringTextSnapshot("foo @if baz");
  4201. - var edit = new TestEdit(5, 4, old, 2, changed, "if");
  4202. - manager.InitializeWithDocument(old);
  4203. -
  4204. - // Act
  4205. - var result = manager.CheckForStructureChangesAndWait(edit);
  4206. -
  4207. - // Assert
  4208. - Assert.Equal(PartialParseResult.Rejected, result);
  4209. - Assert.Equal(2, manager.ParseCount);
  4210. - }
  4211. - }
  4212. -
  4213. - [Fact]
  4214. - public void ImplicitExpressionRejectsWholeIdentifierReplacementToDirective()
  4215. - {
  4216. - // Arrange
  4217. - var parser = new RazorEditorParser(CreateTemplateEngine(@"C:\This\Is\A\Test\Path"), @"C:\This\Is\A\Test\Path");
  4218. -
  4219. - using (var manager = new TestParserManager(parser))
  4220. - {
  4221. - var old = new StringTextSnapshot("foo @date baz");
  4222. - var changed = new StringTextSnapshot("foo @inherits baz");
  4223. - var SourceChange = new TestEdit(5, 4, old, 8, changed, "inherits");
  4224. - manager.InitializeWithDocument(old);
  4225. -
  4226. - // Act
  4227. - var result = manager.CheckForStructureChangesAndWait(SourceChange);
  4228. -
  4229. - // Assert
  4230. - Assert.Equal(PartialParseResult.Rejected | PartialParseResult.SpanContextChanged, result);
  4231. - Assert.Equal(2, manager.ParseCount);
  4232. - }
  4233. - }
  4234. -
  4235. - [Fact]
  4236. - public void ImplicitExpressionAcceptsPrefixIdentifierReplacements_SingleSymbol()
  4237. - {
  4238. - // Arrange
  4239. - var factory = new SpanFactory();
  4240. - var old = new StringTextSnapshot("foo @dTime baz");
  4241. - var changed = new StringTextSnapshot("foo @DateTime baz");
  4242. -
  4243. - // Act and Assert
  4244. - RunPartialParseTest(new TestEdit(5, 1, old, 4, changed, "Date"),
  4245. - new MarkupBlock(
  4246. - factory.Markup("foo "),
  4247. - new ExpressionBlock(
  4248. - factory.CodeTransition(),
  4249. - factory.Code("DateTime").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4250. - factory.Markup(" baz")));
  4251. - }
  4252. -
  4253. - [Fact]
  4254. - public void ImplicitExpressionAcceptsPrefixIdentifierReplacements_MultipleSymbols()
  4255. - {
  4256. - // Arrange
  4257. - var factory = new SpanFactory();
  4258. - var old = new StringTextSnapshot("foo @dTime.Now baz");
  4259. - var changed = new StringTextSnapshot("foo @DateTime.Now baz");
  4260. -
  4261. - // Act and Assert
  4262. - RunPartialParseTest(new TestEdit(5, 1, old, 4, changed, "Date"),
  4263. - new MarkupBlock(
  4264. - factory.Markup("foo "),
  4265. - new ExpressionBlock(
  4266. - factory.CodeTransition(),
  4267. - factory.Code("DateTime.Now").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4268. - factory.Markup(" baz")));
  4269. - }
  4270. -
  4271. - [Fact]
  4272. - public void ImplicitExpressionAcceptsSuffixIdentifierReplacements_SingleSymbol()
  4273. - {
  4274. - // Arrange
  4275. - var factory = new SpanFactory();
  4276. - var old = new StringTextSnapshot("foo @Datet baz");
  4277. - var changed = new StringTextSnapshot("foo @DateTime baz");
  4278. -
  4279. - // Act and Assert
  4280. - RunPartialParseTest(new TestEdit(9, 1, old, 4, changed, "Time"),
  4281. - new MarkupBlock(
  4282. - factory.Markup("foo "),
  4283. - new ExpressionBlock(
  4284. - factory.CodeTransition(),
  4285. - factory.Code("DateTime").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4286. - factory.Markup(" baz")));
  4287. - }
  4288. -
  4289. - [Fact]
  4290. - public void ImplicitExpressionAcceptsSuffixIdentifierReplacements_MultipleSymbols()
  4291. - {
  4292. - // Arrange
  4293. - var factory = new SpanFactory();
  4294. - var old = new StringTextSnapshot("foo @DateTime.n baz");
  4295. - var changed = new StringTextSnapshot("foo @DateTime.Now baz");
  4296. -
  4297. - // Act and Assert
  4298. - RunPartialParseTest(new TestEdit(14, 1, old, 3, changed, "Now"),
  4299. - new MarkupBlock(
  4300. - factory.Markup("foo "),
  4301. - new ExpressionBlock(
  4302. - factory.CodeTransition(),
  4303. - factory.Code("DateTime.Now").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4304. - factory.Markup(" baz")));
  4305. - }
  4306. -
  4307. - [Fact]
  4308. - public void ImplicitExpressionAcceptsSurroundedIdentifierReplacements()
  4309. - {
  4310. - // Arrange
  4311. - var factory = new SpanFactory();
  4312. - var old = new StringTextSnapshot("foo @DateTime.n.ToString() baz");
  4313. - var changed = new StringTextSnapshot("foo @DateTime.Now.ToString() baz");
  4314. -
  4315. - // Act and Assert
  4316. - RunPartialParseTest(new TestEdit(14, 1, old, 3, changed, "Now"),
  4317. - new MarkupBlock(
  4318. - factory.Markup("foo "),
  4319. - new ExpressionBlock(
  4320. - factory.CodeTransition(),
  4321. - factory.Code("DateTime.Now.ToString()").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4322. - factory.Markup(" baz")));
  4323. - }
  4324. -
  4325. - [Fact]
  4326. - public void ImplicitExpressionAcceptsDotlessCommitInsertionsInStatementBlockAfterIdentifiers()
  4327. - {
  4328. - var factory = new SpanFactory();
  4329. - var changed = new StringTextSnapshot("@{" + Environment.NewLine
  4330. - + " @DateTime." + Environment.NewLine
  4331. - + "}");
  4332. - var old = new StringTextSnapshot("@{" + Environment.NewLine
  4333. - + " @DateTime" + Environment.NewLine
  4334. - + "}");
  4335. -
  4336. - var edit = new TestEdit(15 + Environment.NewLine.Length, 0, old, 1, changed, ".");
  4337. - using (var manager = CreateParserManager())
  4338. - {
  4339. - Action<TestEdit, PartialParseResult, string> applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) =>
  4340. - {
  4341. - var result = manager.CheckForStructureChangesAndWait(edit);
  4342. -
  4343. - // Assert
  4344. - Assert.Equal(expectedResult, result);
  4345. - Assert.Equal(1, manager.ParseCount);
  4346. - ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, new MarkupBlock(
  4347. - factory.EmptyHtml(),
  4348. - new StatementBlock(
  4349. - factory.CodeTransition(),
  4350. - factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
  4351. - factory.Code(Environment.NewLine + " ")
  4352. - .AsStatement()
  4353. - .AutoCompleteWith(autoCompleteString: null),
  4354. - new ExpressionBlock(
  4355. - factory.CodeTransition(),
  4356. - factory.Code(expectedCode)
  4357. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  4358. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4359. - factory.Code(Environment.NewLine).AsStatement(),
  4360. - factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
  4361. - factory.EmptyHtml()));
  4362. - };
  4363. -
  4364. - manager.InitializeWithDocument(edit.OldSnapshot);
  4365. -
  4366. - // This is the process of a dotless commit when doing "." insertions to commit intellisense changes.
  4367. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateTime.");
  4368. -
  4369. - old = changed;
  4370. - changed = new StringTextSnapshot("@{" + Environment.NewLine
  4371. - + " @DateTime.." + Environment.NewLine
  4372. - + "}");
  4373. - edit = new TestEdit(16 + Environment.NewLine.Length, 0, old, 1, changed, ".");
  4374. -
  4375. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateTime..");
  4376. -
  4377. - old = changed;
  4378. - changed = new StringTextSnapshot("@{" + Environment.NewLine
  4379. - + " @DateTime.Now." + Environment.NewLine
  4380. - + "}");
  4381. - edit = new TestEdit(16 + Environment.NewLine.Length, 0, old, 3, changed, "Now");
  4382. -
  4383. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateTime.Now.");
  4384. - }
  4385. - }
  4386. -
  4387. - [Fact]
  4388. - public void ImplicitExpressionAcceptsDotlessCommitInsertionsInStatementBlock()
  4389. - {
  4390. - var factory = new SpanFactory();
  4391. - var changed = new StringTextSnapshot("@{" + Environment.NewLine
  4392. - + " @DateT." + Environment.NewLine
  4393. - + "}");
  4394. - var old = new StringTextSnapshot("@{" + Environment.NewLine
  4395. - + " @DateT" + Environment.NewLine
  4396. - + "}");
  4397. -
  4398. - var edit = new TestEdit(12 + Environment.NewLine.Length, 0, old, 1, changed, ".");
  4399. - using (var manager = CreateParserManager())
  4400. - {
  4401. - Action<TestEdit, PartialParseResult, string> applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) =>
  4402. - {
  4403. - var result = manager.CheckForStructureChangesAndWait(edit);
  4404. -
  4405. - // Assert
  4406. - Assert.Equal(expectedResult, result);
  4407. - Assert.Equal(1, manager.ParseCount);
  4408. - ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, new MarkupBlock(
  4409. - factory.EmptyHtml(),
  4410. - new StatementBlock(
  4411. - factory.CodeTransition(),
  4412. - factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
  4413. - factory.Code(Environment.NewLine + " ")
  4414. - .AsStatement()
  4415. - .AutoCompleteWith(autoCompleteString: null),
  4416. - new ExpressionBlock(
  4417. - factory.CodeTransition(),
  4418. - factory.Code(expectedCode)
  4419. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  4420. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4421. - factory.Code(Environment.NewLine).AsStatement(),
  4422. - factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
  4423. - factory.EmptyHtml()));
  4424. - };
  4425. -
  4426. - manager.InitializeWithDocument(edit.OldSnapshot);
  4427. -
  4428. - // This is the process of a dotless commit when doing "." insertions to commit intellisense changes.
  4429. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateT.");
  4430. -
  4431. - old = changed;
  4432. - changed = new StringTextSnapshot("@{" + Environment.NewLine
  4433. - + " @DateTime." + Environment.NewLine
  4434. - + "}");
  4435. - edit = new TestEdit(12 + Environment.NewLine.Length, 0, old, 3, changed, "ime");
  4436. -
  4437. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateTime.");
  4438. - }
  4439. - }
  4440. -
  4441. - [Fact]
  4442. - public void ImplicitExpressionProvisionallyAcceptsDotlessCommitInsertions()
  4443. - {
  4444. - var factory = new SpanFactory();
  4445. - var changed = new StringTextSnapshot("foo @DateT. baz");
  4446. - var old = new StringTextSnapshot("foo @DateT baz");
  4447. - var edit = new TestEdit(10, 0, old, 1, changed, ".");
  4448. - using (var manager = CreateParserManager())
  4449. - {
  4450. - Action<TestEdit, PartialParseResult, string> applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) =>
  4451. - {
  4452. - var result = manager.CheckForStructureChangesAndWait(edit);
  4453. -
  4454. - // Assert
  4455. - Assert.Equal(expectedResult, result);
  4456. - Assert.Equal(1, manager.ParseCount);
  4457. -
  4458. - ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, new MarkupBlock(
  4459. - factory.Markup("foo "),
  4460. - new ExpressionBlock(
  4461. - factory.CodeTransition(),
  4462. - factory.Code(expectedCode).AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4463. - factory.Markup(" baz")));
  4464. - };
  4465. -
  4466. - manager.InitializeWithDocument(edit.OldSnapshot);
  4467. -
  4468. - // This is the process of a dotless commit when doing "." insertions to commit intellisense changes.
  4469. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateT.");
  4470. -
  4471. - old = changed;
  4472. - changed = new StringTextSnapshot("foo @DateTime. baz");
  4473. - edit = new TestEdit(10, 0, old, 3, changed, "ime");
  4474. -
  4475. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateTime.");
  4476. - }
  4477. - }
  4478. -
  4479. - [Fact]
  4480. - public void ImplicitExpressionProvisionallyAcceptsDotlessCommitInsertionsAfterIdentifiers()
  4481. - {
  4482. - var factory = new SpanFactory();
  4483. - var changed = new StringTextSnapshot("foo @DateTime. baz");
  4484. - var old = new StringTextSnapshot("foo @DateTime baz");
  4485. - var edit = new TestEdit(13, 0, old, 1, changed, ".");
  4486. - using (var manager = CreateParserManager())
  4487. - {
  4488. - Action<TestEdit, PartialParseResult, string> applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) =>
  4489. - {
  4490. - var result = manager.CheckForStructureChangesAndWait(edit);
  4491. -
  4492. - // Assert
  4493. - Assert.Equal(expectedResult, result);
  4494. - Assert.Equal(1, manager.ParseCount);
  4495. -
  4496. - ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, new MarkupBlock(
  4497. - factory.Markup("foo "),
  4498. - new ExpressionBlock(
  4499. - factory.CodeTransition(),
  4500. - factory.Code(expectedCode).AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4501. - factory.Markup(" baz")));
  4502. - };
  4503. -
  4504. - manager.InitializeWithDocument(edit.OldSnapshot);
  4505. -
  4506. - // This is the process of a dotless commit when doing "." insertions to commit intellisense changes.
  4507. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateTime.");
  4508. -
  4509. - old = changed;
  4510. - changed = new StringTextSnapshot("foo @DateTime.. baz");
  4511. - edit = new TestEdit(14, 0, old, 1, changed, ".");
  4512. -
  4513. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateTime..");
  4514. -
  4515. - old = changed;
  4516. - changed = new StringTextSnapshot("foo @DateTime.Now. baz");
  4517. - edit = new TestEdit(14, 0, old, 3, changed, "Now");
  4518. -
  4519. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateTime.Now.");
  4520. - }
  4521. - }
  4522. -
  4523. - [Fact]
  4524. - public void ImplicitExpressionProvisionallyAcceptsCaseInsensitiveDotlessCommitInsertions_NewRoslynIntegration()
  4525. - {
  4526. - var factory = new SpanFactory();
  4527. - var old = new StringTextSnapshot("foo @date baz");
  4528. - var changed = new StringTextSnapshot("foo @date. baz");
  4529. - var edit = new TestEdit(9, 0, old, 1, changed, ".");
  4530. - using (var manager = CreateParserManager())
  4531. - {
  4532. - Action<TestEdit, PartialParseResult, string> applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) =>
  4533. - {
  4534. - var result = manager.CheckForStructureChangesAndWait(edit);
  4535. -
  4536. - // Assert
  4537. - Assert.Equal(expectedResult, result);
  4538. - Assert.Equal(1, manager.ParseCount);
  4539. -
  4540. - ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, new MarkupBlock(
  4541. - factory.Markup("foo "),
  4542. - new ExpressionBlock(
  4543. - factory.CodeTransition(),
  4544. - factory.Code(expectedCode).AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4545. - factory.Markup(" baz")));
  4546. - };
  4547. -
  4548. - manager.InitializeWithDocument(edit.OldSnapshot);
  4549. -
  4550. - // This is the process of a dotless commit when doing "." insertions to commit intellisense changes.
  4551. -
  4552. - // @date => @date.
  4553. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "date.");
  4554. -
  4555. - old = changed;
  4556. - changed = new StringTextSnapshot("foo @date baz");
  4557. - edit = new TestEdit(9, 1, old, 0, changed, "");
  4558. -
  4559. - // @date. => @date
  4560. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "date");
  4561. -
  4562. - old = changed;
  4563. - changed = new StringTextSnapshot("foo @DateTime baz");
  4564. - edit = new TestEdit(5, 4, old, 8, changed, "DateTime");
  4565. -
  4566. - // @date => @DateTime
  4567. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted, "DateTime");
  4568. -
  4569. - old = changed;
  4570. - changed = new StringTextSnapshot("foo @DateTime. baz");
  4571. - edit = new TestEdit(13, 0, old, 1, changed, ".");
  4572. -
  4573. - // @DateTime => @DateTime.
  4574. - applyAndVerifyPartialChange(edit, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateTime.");
  4575. - }
  4576. - }
  4577. -
  4578. - [Fact]
  4579. - public void ImplicitExpressionProvisionallyAcceptsDeleteOfIdentifierPartsIfDotRemains()
  4580. - {
  4581. - var factory = new SpanFactory();
  4582. - var changed = new StringTextSnapshot("foo @User. baz");
  4583. - var old = new StringTextSnapshot("foo @User.Name baz");
  4584. - RunPartialParseTest(new TestEdit(10, 4, old, 0, changed, string.Empty),
  4585. - new MarkupBlock(
  4586. - factory.Markup("foo "),
  4587. - new ExpressionBlock(
  4588. - factory.CodeTransition(),
  4589. - factory.Code("User.").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4590. - factory.Markup(" baz")),
  4591. - additionalFlags: PartialParseResult.Provisional);
  4592. - }
  4593. -
  4594. - [Fact]
  4595. - public void ImplicitExpressionAcceptsDeleteOfIdentifierPartsIfSomeOfIdentifierRemains()
  4596. - {
  4597. - var factory = new SpanFactory();
  4598. - var changed = new StringTextSnapshot("foo @Us baz");
  4599. - var old = new StringTextSnapshot("foo @User baz");
  4600. - RunPartialParseTest(new TestEdit(7, 2, old, 0, changed, string.Empty),
  4601. - new MarkupBlock(
  4602. - factory.Markup("foo "),
  4603. - new ExpressionBlock(
  4604. - factory.CodeTransition(),
  4605. - factory.Code("Us").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4606. - factory.Markup(" baz")));
  4607. - }
  4608. -
  4609. - [Fact]
  4610. - public void ImplicitExpressionProvisionallyAcceptsMultipleInsertionIfItCausesIdentifierExpansionAndTrailingDot()
  4611. - {
  4612. - var factory = new SpanFactory();
  4613. - var changed = new StringTextSnapshot("foo @User. baz");
  4614. - var old = new StringTextSnapshot("foo @U baz");
  4615. - RunPartialParseTest(new TestEdit(6, 0, old, 4, changed, "ser."),
  4616. - new MarkupBlock(
  4617. - factory.Markup("foo "),
  4618. - new ExpressionBlock(
  4619. - factory.CodeTransition(),
  4620. - factory.Code("User.").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4621. - factory.Markup(" baz")),
  4622. - additionalFlags: PartialParseResult.Provisional);
  4623. - }
  4624. -
  4625. - [Fact]
  4626. - public void ImplicitExpressionAcceptsMultipleInsertionIfItOnlyCausesIdentifierExpansion()
  4627. - {
  4628. - var factory = new SpanFactory();
  4629. - var changed = new StringTextSnapshot("foo @barbiz baz");
  4630. - var old = new StringTextSnapshot("foo @bar baz");
  4631. - RunPartialParseTest(new TestEdit(8, 0, old, 3, changed, "biz"),
  4632. - new MarkupBlock(
  4633. - factory.Markup("foo "),
  4634. - new ExpressionBlock(
  4635. - factory.CodeTransition(),
  4636. - factory.Code("barbiz").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4637. - factory.Markup(" baz")));
  4638. - }
  4639. -
  4640. - [Fact]
  4641. - public void ImplicitExpressionAcceptsIdentifierExpansionAtEndOfNonWhitespaceCharacters()
  4642. - {
  4643. - var factory = new SpanFactory();
  4644. - var changed = new StringTextSnapshot("@{" + Environment.NewLine
  4645. - + " @food" + Environment.NewLine
  4646. - + "}");
  4647. - var old = new StringTextSnapshot("@{" + Environment.NewLine
  4648. - + " @foo" + Environment.NewLine
  4649. - + "}");
  4650. - RunPartialParseTest(new TestEdit(10 + Environment.NewLine.Length, 0, old, 1, changed, "d"),
  4651. - new MarkupBlock(
  4652. - factory.EmptyHtml(),
  4653. - new StatementBlock(
  4654. - factory.CodeTransition(),
  4655. - factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
  4656. - factory.Code(Environment.NewLine + " ")
  4657. - .AsStatement()
  4658. - .AutoCompleteWith(autoCompleteString: null),
  4659. - new ExpressionBlock(
  4660. - factory.CodeTransition(),
  4661. - factory.Code("food")
  4662. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  4663. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4664. - factory.Code(Environment.NewLine).AsStatement(),
  4665. - factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
  4666. - factory.EmptyHtml()));
  4667. - }
  4668. -
  4669. - [Fact]
  4670. - public void ImplicitExpressionAcceptsIdentifierAfterDotAtEndOfNonWhitespaceCharacters()
  4671. - {
  4672. - var factory = new SpanFactory();
  4673. - var changed = new StringTextSnapshot("@{" + Environment.NewLine
  4674. - + " @foo.d" + Environment.NewLine
  4675. - + "}");
  4676. - var old = new StringTextSnapshot("@{" + Environment.NewLine
  4677. - + " @foo." + Environment.NewLine
  4678. - + "}");
  4679. - RunPartialParseTest(new TestEdit(11 + Environment.NewLine.Length, 0, old, 1, changed, "d"),
  4680. - new MarkupBlock(
  4681. - factory.EmptyHtml(),
  4682. - new StatementBlock(
  4683. - factory.CodeTransition(),
  4684. - factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
  4685. - factory.Code(Environment.NewLine + " ")
  4686. - .AsStatement()
  4687. - .AutoCompleteWith(autoCompleteString: null),
  4688. - new ExpressionBlock(
  4689. - factory.CodeTransition(),
  4690. - factory.Code("foo.d")
  4691. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  4692. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4693. - factory.Code(Environment.NewLine).AsStatement(),
  4694. - factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
  4695. - factory.EmptyHtml()));
  4696. - }
  4697. -
  4698. - [Fact]
  4699. - public void ImplicitExpressionAcceptsDotAtEndOfNonWhitespaceCharacters()
  4700. - {
  4701. - var factory = new SpanFactory();
  4702. - var changed = new StringTextSnapshot("@{" + Environment.NewLine
  4703. - + " @foo." + Environment.NewLine
  4704. - + "}");
  4705. - var old = new StringTextSnapshot("@{" + Environment.NewLine
  4706. - + " @foo" + Environment.NewLine
  4707. - + "}");
  4708. - RunPartialParseTest(new TestEdit(10 + Environment.NewLine.Length, 0, old, 1, changed, "."),
  4709. - new MarkupBlock(
  4710. - factory.EmptyHtml(),
  4711. - new StatementBlock(
  4712. - factory.CodeTransition(),
  4713. - factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
  4714. - factory.Code(Environment.NewLine + " ")
  4715. - .AsStatement()
  4716. - .AutoCompleteWith(autoCompleteString: null),
  4717. - new ExpressionBlock(
  4718. - factory.CodeTransition(),
  4719. - factory.Code(@"foo.")
  4720. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  4721. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4722. - factory.Code(Environment.NewLine).AsStatement(),
  4723. - factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
  4724. - factory.EmptyHtml()));
  4725. - }
  4726. -
  4727. - [Fact]
  4728. - public void ImplicitExpressionRejectsChangeWhichWouldHaveBeenAcceptedIfLastChangeWasProvisionallyAcceptedOnDifferentSpan()
  4729. - {
  4730. - var factory = new SpanFactory();
  4731. -
  4732. - // Arrange
  4733. - var dotTyped = new TestEdit(8, 0, new StringTextSnapshot("foo @foo @bar"), 1, new StringTextSnapshot("foo @foo. @bar"), ".");
  4734. - var charTyped = new TestEdit(14, 0, new StringTextSnapshot("foo @foo. @bar"), 1, new StringTextSnapshot("foo @foo. @barb"), "b");
  4735. - using (var manager = CreateParserManager())
  4736. - {
  4737. - manager.InitializeWithDocument(dotTyped.OldSnapshot);
  4738. -
  4739. - // Apply the dot change
  4740. - Assert.Equal(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped));
  4741. -
  4742. - // Act (apply the identifier start char change)
  4743. - var result = manager.CheckForStructureChangesAndWait(charTyped);
  4744. -
  4745. - // Assert
  4746. - Assert.Equal(PartialParseResult.Rejected, result);
  4747. - Assert.False(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not");
  4748. - ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root,
  4749. - new MarkupBlock(
  4750. - factory.Markup("foo "),
  4751. - new ExpressionBlock(
  4752. - factory.CodeTransition(),
  4753. - factory.Code("foo")
  4754. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
  4755. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4756. - factory.Markup(". "),
  4757. - new ExpressionBlock(
  4758. - factory.CodeTransition(),
  4759. - factory.Code("barb")
  4760. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
  4761. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4762. - factory.EmptyHtml()));
  4763. - }
  4764. - }
  4765. -
  4766. - [Fact]
  4767. - public void ImplicitExpressionAcceptsIdentifierTypedAfterDotIfLastChangeWasProvisionalAcceptanceOfDot()
  4768. - {
  4769. - var factory = new SpanFactory();
  4770. -
  4771. - // Arrange
  4772. - var dotTyped = new TestEdit(8, 0, new StringTextSnapshot("foo @foo bar"), 1, new StringTextSnapshot("foo @foo. bar"), ".");
  4773. - var charTyped = new TestEdit(9, 0, new StringTextSnapshot("foo @foo. bar"), 1, new StringTextSnapshot("foo @foo.b bar"), "b");
  4774. - using (var manager = CreateParserManager())
  4775. - {
  4776. - manager.InitializeWithDocument(dotTyped.OldSnapshot);
  4777. -
  4778. - // Apply the dot change
  4779. - Assert.Equal(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped));
  4780. -
  4781. - // Act (apply the identifier start char change)
  4782. - var result = manager.CheckForStructureChangesAndWait(charTyped);
  4783. -
  4784. - // Assert
  4785. - Assert.Equal(PartialParseResult.Accepted, result);
  4786. - Assert.False(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not");
  4787. - ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root,
  4788. - new MarkupBlock(
  4789. - factory.Markup("foo "),
  4790. - new ExpressionBlock(
  4791. - factory.CodeTransition(),
  4792. - factory.Code("foo.b")
  4793. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
  4794. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4795. - factory.Markup(" bar")));
  4796. - }
  4797. - }
  4798. -
  4799. - [Fact]
  4800. - public void ImplicitExpressionProvisionallyAcceptsDotAfterIdentifierInMarkup()
  4801. - {
  4802. - var factory = new SpanFactory();
  4803. - var changed = new StringTextSnapshot("foo @foo. bar");
  4804. - var old = new StringTextSnapshot("foo @foo bar");
  4805. - RunPartialParseTest(new TestEdit(8, 0, old, 1, changed, "."),
  4806. - new MarkupBlock(
  4807. - factory.Markup("foo "),
  4808. - new ExpressionBlock(
  4809. - factory.CodeTransition(),
  4810. - factory.Code("foo.")
  4811. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
  4812. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4813. - factory.Markup(" bar")),
  4814. - additionalFlags: PartialParseResult.Provisional);
  4815. - }
  4816. -
  4817. - [Fact]
  4818. - public void ImplicitExpressionAcceptsAdditionalIdentifierCharactersIfEndOfSpanIsIdentifier()
  4819. - {
  4820. - var factory = new SpanFactory();
  4821. - var changed = new StringTextSnapshot("foo @foob bar");
  4822. - var old = new StringTextSnapshot("foo @foo bar");
  4823. - RunPartialParseTest(new TestEdit(8, 0, old, 1, changed, "b"),
  4824. - new MarkupBlock(
  4825. - factory.Markup("foo "),
  4826. - new ExpressionBlock(
  4827. - factory.CodeTransition(),
  4828. - factory.Code("foob")
  4829. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
  4830. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4831. - factory.Markup(" bar")));
  4832. - }
  4833. -
  4834. - [Fact]
  4835. - public void ImplicitExpressionAcceptsAdditionalIdentifierStartCharactersIfEndOfSpanIsDot()
  4836. - {
  4837. - var factory = new SpanFactory();
  4838. - var changed = new StringTextSnapshot("@{@foo.b}");
  4839. - var old = new StringTextSnapshot("@{@foo.}");
  4840. - RunPartialParseTest(new TestEdit(7, 0, old, 1, changed, "b"),
  4841. - new MarkupBlock(
  4842. - factory.EmptyHtml(),
  4843. - new StatementBlock(
  4844. - factory.CodeTransition(),
  4845. - factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
  4846. - factory.EmptyCSharp()
  4847. - .AsStatement()
  4848. - .AutoCompleteWith(autoCompleteString: null),
  4849. - new ExpressionBlock(
  4850. - factory.CodeTransition(),
  4851. - factory.Code("foo.b")
  4852. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  4853. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4854. - factory.EmptyCSharp().AsStatement(),
  4855. - factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
  4856. - factory.EmptyHtml()));
  4857. - }
  4858. -
  4859. - [Fact]
  4860. - public void ImplicitExpressionAcceptsDotIfTrailingDotsAreAllowed()
  4861. - {
  4862. - var factory = new SpanFactory();
  4863. - var changed = new StringTextSnapshot("@{@foo.}");
  4864. - var old = new StringTextSnapshot("@{@foo}");
  4865. - RunPartialParseTest(new TestEdit(6, 0, old, 1, changed, "."),
  4866. - new MarkupBlock(
  4867. - factory.EmptyHtml(),
  4868. - new StatementBlock(
  4869. - factory.CodeTransition(),
  4870. - factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
  4871. - factory.EmptyCSharp()
  4872. - .AsStatement()
  4873. - .AutoCompleteWith(autoCompleteString: null),
  4874. - new ExpressionBlock(
  4875. - factory.CodeTransition(),
  4876. - factory.Code("foo.")
  4877. - .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
  4878. - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
  4879. - factory.EmptyCSharp().AsStatement(),
  4880. - factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
  4881. - factory.EmptyHtml()));
  4882. - }
  4883. -
  4884. - [Fact]
  4885. - public void ImplicitExpressionCorrectlyTriggersReparseIfIfKeywordTyped()
  4886. - {
  4887. - RunTypeKeywordTest("if");
  4888. - }
  4889. -
  4890. - [Fact]
  4891. - public void ImplicitExpressionCorrectlyTriggersReparseIfDoKeywordTyped()
  4892. - {
  4893. - RunTypeKeywordTest("do");
  4894. - }
  4895. -
  4896. - [Fact]
  4897. - public void ImplicitExpressionCorrectlyTriggersReparseIfTryKeywordTyped()
  4898. - {
  4899. - RunTypeKeywordTest("try");
  4900. - }
  4901. -
  4902. - [Fact]
  4903. - public void ImplicitExpressionCorrectlyTriggersReparseIfForKeywordTyped()
  4904. - {
  4905. - RunTypeKeywordTest("for");
  4906. - }
  4907. -
  4908. - [Fact]
  4909. - public void ImplicitExpressionCorrectlyTriggersReparseIfForEachKeywordTyped()
  4910. - {
  4911. - RunTypeKeywordTest("foreach");
  4912. - }
  4913. -
  4914. - [Fact]
  4915. - public void ImplicitExpressionCorrectlyTriggersReparseIfWhileKeywordTyped()
  4916. - {
  4917. - RunTypeKeywordTest("while");
  4918. - }
  4919. -
  4920. - [Fact]
  4921. - public void ImplicitExpressionCorrectlyTriggersReparseIfSwitchKeywordTyped()
  4922. - {
  4923. - RunTypeKeywordTest("switch");
  4924. - }
  4925. -
  4926. - [Fact]
  4927. - public void ImplicitExpressionCorrectlyTriggersReparseIfLockKeywordTyped()
  4928. - {
  4929. - RunTypeKeywordTest("lock");
  4930. - }
  4931. -
  4932. - [Fact]
  4933. - public void ImplicitExpressionCorrectlyTriggersReparseIfUsingKeywordTyped()
  4934. - {
  4935. - RunTypeKeywordTest("using");
  4936. - }
  4937. -
  4938. - [Fact]
  4939. - public void ImplicitExpressionCorrectlyTriggersReparseIfSectionKeywordTyped()
  4940. - {
  4941. - RunTypeKeywordTest("section");
  4942. - }
  4943. -
  4944. - [Fact]
  4945. - public void ImplicitExpressionCorrectlyTriggersReparseIfInheritsKeywordTyped()
  4946. - {
  4947. - RunTypeKeywordTest("inherits");
  4948. - }
  4949. -
  4950. - [Fact]
  4951. - public void ImplicitExpressionCorrectlyTriggersReparseIfFunctionsKeywordTyped()
  4952. - {
  4953. - RunTypeKeywordTest("functions");
  4954. - }
  4955. -
  4956. - [Fact]
  4957. - public void ImplicitExpressionCorrectlyTriggersReparseIfNamespaceKeywordTyped()
  4958. - {
  4959. - RunTypeKeywordTest("namespace");
  4960. - }
  4961. -
  4962. - [Fact]
  4963. - public void ImplicitExpressionCorrectlyTriggersReparseIfClassKeywordTyped()
  4964. - {
  4965. - RunTypeKeywordTest("class");
  4966. - }
  4967. -
  4968. - private static TestEdit CreateInsertionChange(string initialText, int insertionLocation, string insertionText)
  4969. - {
  4970. - var changedText = initialText.Insert(insertionLocation, insertionText);
  4971. - var sourceChange = new SourceChange(insertionLocation, 0, insertionText);
  4972. - var oldSnapshot = new StringTextSnapshot(initialText);
  4973. - var changedSnapshot = new StringTextSnapshot(changedText);
  4974. - return new TestEdit
  4975. - {
  4976. - Change = sourceChange,
  4977. - OldSnapshot = oldSnapshot,
  4978. - NewSnapshot = changedSnapshot,
  4979. - };
  4980. - }
  4981. -
  4982. - private static void RunFullReparseTest(TestEdit edit, PartialParseResult additionalFlags = (PartialParseResult)0)
  4983. - {
  4984. - // Arrange
  4985. - using (var manager = CreateParserManager())
  4986. - {
  4987. - manager.InitializeWithDocument(edit.OldSnapshot);
  4988. -
  4989. - // Act
  4990. - var result = manager.CheckForStructureChangesAndWait(edit);
  4991. -
  4992. - // Assert
  4993. - Assert.Equal(PartialParseResult.Rejected | additionalFlags, result);
  4994. - Assert.Equal(2, manager.ParseCount);
  4995. - }
  4996. - }
  4997. -
  4998. - private static void RunPartialParseTest(TestEdit edit, Block newTreeRoot, PartialParseResult additionalFlags = (PartialParseResult)0)
  4999. - {
  5000. - // Arrange
  5001. - using (var manager = CreateParserManager())
  5002. - {
  5003. - manager.InitializeWithDocument(edit.OldSnapshot);
  5004. -
  5005. - // Act
  5006. - var result = manager.CheckForStructureChangesAndWait(edit);
  5007. -
  5008. - // Assert
  5009. - Assert.Equal(PartialParseResult.Accepted | additionalFlags, result);
  5010. - Assert.Equal(1, manager.ParseCount);
  5011. - ParserTestBase.EvaluateParseTree(manager.Parser.CurrentSyntaxTree.Root, newTreeRoot);
  5012. - }
  5013. - }
  5014. -
  5015. - private static TestParserManager CreateParserManager()
  5016. - {
  5017. - var parser = new RazorEditorParser(CreateTemplateEngine(), TestLinePragmaFileName);
  5018. - return new TestParserManager(parser);
  5019. - }
  5020. -
  5021. - private static RazorTemplateEngine CreateTemplateEngine(
  5022. - string path = TestLinePragmaFileName,
  5023. - IEnumerable<TagHelperDescriptor> tagHelpers = null)
  5024. - {
  5025. - var engine = RazorEngine.CreateDesignTime(builder =>
  5026. - {
  5027. - RazorExtensions.Register(builder);
  5028. -
  5029. - if (tagHelpers != null)
  5030. - {
  5031. - builder.AddTagHelpers(tagHelpers);
  5032. - }
  5033. - });
  5034. -
  5035. - // GetImports on RazorTemplateEngine will at least check that the item exists, so we need to pretend
  5036. - // that it does.
  5037. - var items = new List<RazorProjectItem>();
  5038. - items.Add(new TestRazorProjectItem(path));
  5039. -
  5040. - var project = new TestRazorProject(items);
  5041. -
  5042. - var templateEngine = new RazorTemplateEngine(engine, project);
  5043. - templateEngine.Options.DefaultImports = RazorSourceDocument.Create("@addTagHelper *, Test", "_TestImports.cshtml");
  5044. - return templateEngine;
  5045. - }
  5046. -
  5047. - private static void RunTypeKeywordTest(string keyword)
  5048. - {
  5049. - var before = "@" + keyword.Substring(0, keyword.Length - 1);
  5050. - var after = "@" + keyword;
  5051. - var changed = new StringTextSnapshot(after);
  5052. - var old = new StringTextSnapshot(before);
  5053. - var change = new SourceChange(keyword.Length, 0, keyword[keyword.Length - 1].ToString());
  5054. - var edit = new TestEdit
  5055. - {
  5056. - Change = change,
  5057. - NewSnapshot = changed,
  5058. - OldSnapshot = old
  5059. - };
  5060. - RunFullReparseTest(edit, additionalFlags: PartialParseResult.SpanContextChanged);
  5061. - }
  5062. -
  5063. - private static void DoWithTimeoutIfNotDebugging(Func<int, bool> withTimeout)
  5064. - {
  5065. -#if DEBUG
  5066. - if (Debugger.IsAttached)
  5067. - {
  5068. - withTimeout(Timeout.Infinite);
  5069. - }
  5070. - else
  5071. - {
  5072. -#endif
  5073. - Assert.True(withTimeout((int)TimeSpan.FromSeconds(1).TotalMilliseconds), "Timeout expired!");
  5074. -#if DEBUG
  5075. - }
  5076. -#endif
  5077. - }
  5078. -
  5079. - private class TestParserManager : IDisposable
  5080. - {
  5081. - public int ParseCount;
  5082. -
  5083. - private readonly ManualResetEventSlim _parserComplete;
  5084. -
  5085. - public TestParserManager(RazorEditorParser parser)
  5086. - {
  5087. - _parserComplete = new ManualResetEventSlim();
  5088. - ParseCount = 0;
  5089. - Parser = parser;
  5090. - parser.DocumentParseComplete += (sender, args) =>
  5091. - {
  5092. - Interlocked.Increment(ref ParseCount);
  5093. - _parserComplete.Set();
  5094. - };
  5095. - }
  5096. -
  5097. - public RazorEditorParser Parser { get; }
  5098. -
  5099. - public void InitializeWithDocument(ITextSnapshot snapshot)
  5100. - {
  5101. - var initialChange = new SourceChange(0, 0, string.Empty);
  5102. - var edit = new TestEdit
  5103. - {
  5104. - Change = initialChange,
  5105. - OldSnapshot = snapshot,
  5106. - NewSnapshot = snapshot
  5107. - };
  5108. - CheckForStructureChangesAndWait(edit);
  5109. - }
  5110. -
  5111. - public PartialParseResult CheckForStructureChangesAndWait(TestEdit edit)
  5112. - {
  5113. - var result = Parser.CheckForStructureChanges(edit.Change, edit.NewSnapshot);
  5114. - if (result.HasFlag(PartialParseResult.Rejected))
  5115. - {
  5116. - WaitForParse();
  5117. - }
  5118. - return result;
  5119. - }
  5120. -
  5121. - public void WaitForParse()
  5122. - {
  5123. - DoWithTimeoutIfNotDebugging(_parserComplete.Wait); // Wait for the parse to finish
  5124. - _parserComplete.Reset();
  5125. - }
  5126. -
  5127. - public void Dispose()
  5128. - {
  5129. - Parser.Dispose();
  5130. - }
  5131. - }
  5132. -
  5133. - private class TestEdit
  5134. - {
  5135. - public TestEdit()
  5136. - {
  5137. - }
  5138. -
  5139. - public TestEdit(int position, int oldLength, ITextSnapshot oldSnapshot, int newLength, ITextSnapshot newSnapshot, string newText)
  5140. - {
  5141. - Change = new SourceChange(position, oldLength, newText);
  5142. - OldSnapshot = oldSnapshot;
  5143. - NewSnapshot = newSnapshot;
  5144. - }
  5145. -
  5146. - public SourceChange Change { get; set; }
  5147. -
  5148. - public ITextSnapshot OldSnapshot { get; set; }
  5149. -
  5150. - public ITextSnapshot NewSnapshot { get; set; }
  5151. - }
  5152. - }
  5153. -}
  5154. \ No newline at end of file